doorkeeper-couchbase 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 26e72753a5fd06befb160626efc21a2ac90ca8ea
4
+ data.tar.gz: 904262def4b85471c00852ae725dfd849b3b0a13
5
+ SHA512:
6
+ metadata.gz: ee53b67b92991dbfe8f543826a4edb0a3022d07c182cfebade2e45109fa4f33051645d50170cc397fb3b5fea186da997774307a94c0fbd20e1033606592bd55c
7
+ data.tar.gz: c5e78c9475694985d89ac5c64d87e1d14d7f03387743d990173cfdda9f82b2fc00394c0b70d49d5fe0f93e674b80a886e74d9782f760942dd9f0debdc5214064
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2016 ACAProjects
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # doorkeeper-couchbase extension
2
+
3
+ ## Installation
4
+
5
+ doorkeeper-couchbase provides doorkeeper support to couchbase
6
+ To start using it, add to your Gemfile:
7
+
8
+ ``` ruby
9
+ gem "doorkeeper-couchbase"
10
+ ```
11
+
12
+ Run [doorkeeper’s installation generator]:
13
+
14
+ rails generate doorkeeper:install
15
+
16
+ [doorkeeper’s installation generator]: https://github.com/doorkeeper-gem/doorkeeper#installation
17
+
18
+ This will install the doorkeeper initializer into
19
+ `config/initializers/doorkeeper.rb`.
20
+
21
+ Set the ORM configuration:
22
+
23
+ ``` ruby
24
+ Doorkeeper.configure do
25
+ orm :couchbase
26
+ end
27
+ ```
28
+
29
+ ## Tests
30
+
31
+ To run tests, clone this repository and run `rake`. It will copy and run
32
+ doorkeeper’s original test suite, after configuring the ORM according to the
33
+ variables defined in `.travis.yml` file.
34
+
35
+
36
+ ---
37
+
38
+ Please refer to https://github.com/doorkeeper-gem/doorkeeper for instructions on
39
+ doorkeeper’s project.
data/Rakefile ADDED
@@ -0,0 +1,23 @@
1
+ require 'bundler/setup'
2
+ require 'rspec/core/rake_task'
3
+
4
+ task :load_doorkeeper do
5
+ `rm -rf spec/`
6
+ `git checkout -- spec`
7
+ `git submodule init`
8
+ `git submodule update`
9
+ `cp -r -n doorkeeper/spec .`
10
+ `bundle exec rspec`
11
+ end
12
+
13
+ desc 'Default: run specs.'
14
+ task default: :spec
15
+
16
+ desc 'Clone down doorkeeper specs'
17
+ task spec: :load_doorkeeper
18
+
19
+ RSpec::Core::RakeTask.new(:spec) do |config|
20
+ config.verbose = false
21
+ end
22
+
23
+ Bundler::GemHelper.install_tasks
@@ -0,0 +1,3 @@
1
+
2
+ require 'couchbase-orm'
3
+ require 'couchbase-orm/railtie'
@@ -0,0 +1,3 @@
1
+ module DoorkeeperCouchbase
2
+ VERSION = "1.0.0"
3
+ end
@@ -0,0 +1,7 @@
1
+ require 'doorkeeper-couchbase/version'
2
+
3
+ require 'doorkeeper'
4
+ require 'support/orm/couchbase'
5
+
6
+ module DoorkeeperCouchbase
7
+ end
@@ -0,0 +1,57 @@
1
+
2
+ module Doorkeeper
3
+ class AccessGrant < CouchbaseOrm::Base
4
+ design_document :dk_ag
5
+
6
+
7
+ include OAuth::Helpers
8
+ include Models::Expirable
9
+ include Models::Revocable
10
+ include Models::Accessible
11
+ include Models::Scopes
12
+
13
+ include ::Doorkeeper::Couchbase::Timestamps
14
+
15
+
16
+ belongs_to :application, class_name: 'Doorkeeper::Application', inverse_of: :access_grants
17
+
18
+ attribute :resource_owner_id,
19
+ :token,
20
+ :scopes,
21
+ :redirect_uri, type: String
22
+
23
+ attribute :expires_in, type: Integer
24
+
25
+
26
+ class << self
27
+ alias_method :by_token, :find_by_id
28
+ end
29
+
30
+
31
+ validates :resource_owner_id, :application, :token, :expires_in, :redirect_uri, presence: true
32
+
33
+
34
+ before_validation :generate_token, on: :create
35
+
36
+
37
+ # Lets make sure these keys are not clogging up the database forever
38
+ def save(**options)
39
+ options[:ttl] = self.created_at + self.expires_in + 30
40
+ super(**options)
41
+ end
42
+
43
+
44
+ private
45
+
46
+
47
+ # Generates token value with UniqueToken class.
48
+ #
49
+ # @return [String] token value
50
+ #
51
+ def generate_token
52
+ if self.token.blank?
53
+ self.id = self.token = UniqueToken.generate
54
+ end
55
+ end
56
+ end
57
+ end
@@ -0,0 +1,283 @@
1
+
2
+ module Doorkeeper
3
+ class AccessToken < CouchbaseOrm::Base
4
+ design_document :dk_at
5
+
6
+
7
+ include OAuth::Helpers
8
+ include Models::Expirable
9
+ include Models::Revocable
10
+ include Models::Accessible
11
+ include Models::Scopes
12
+
13
+ include ::Doorkeeper::Couchbase::Timestamps
14
+
15
+ attr_writer :use_refresh_token
16
+
17
+ belongs_to :application, class_name: 'Doorkeeper::Application', inverse_of: :access_grants
18
+
19
+ attribute :resource_owner_id,
20
+ :token,
21
+ :refresh_token,
22
+ :scopes, type: String
23
+ attribute :previous_refresh_token, type: String, default: proc { '' }
24
+
25
+ attribute :expires_in, type: Integer
26
+
27
+
28
+ validates :resource_owner_id, :application, :expires_in, :token, presence: true
29
+ ensure_unique :refresh_token, presence: false
30
+
31
+
32
+ index_view :resource_owner_id
33
+ view :by_application_id_and_resource_owner_id, map: <<-EMAP
34
+ function(doc) {
35
+ if(doc.type === 'dk_at' && doc.application_id && doc.resource_owner_id && !doc.revoked_at) {
36
+ emit([doc.application_id, doc.resource_owner_id], null);
37
+ }
38
+ }
39
+ EMAP
40
+
41
+
42
+ class << self
43
+ def refresh_token_revoked_on_use?
44
+ true
45
+ end
46
+
47
+ # Returns an instance of the Doorkeeper::AccessToken with
48
+ # specific token value.
49
+ #
50
+ # @param token [#to_s]
51
+ # token value (any object that responds to `#to_s`)
52
+ #
53
+ # @return [Doorkeeper::AccessToken, nil] AccessToken object or nil
54
+ # if there is no record with such token
55
+ #
56
+ alias_method :by_token, :find_by_id
57
+
58
+ # Returns an instance of the Doorkeeper::AccessToken
59
+ # with specific token value.
60
+ #
61
+ # @param refresh_token [#to_s]
62
+ # refresh token value (any object that responds to `#to_s`)
63
+ #
64
+ # @return [Doorkeeper::AccessToken, nil] AccessToken object or nil
65
+ # if there is no record with such refresh token
66
+ #
67
+ def by_refresh_token(refresh_token)
68
+ tok = self.find_by_refresh_token(refresh_token)
69
+ return tok if tok
70
+
71
+ # legacy - required for existing systems
72
+ id = AccessToken.bucket.get("refresh-#{refresh_token}", quiet: true)
73
+ find_by_id(id) if id
74
+ end
75
+
76
+ # Revokes AccessToken records that have not been revoked and associated
77
+ # with the specific Application and Resource Owner.
78
+ #
79
+ # @param application_id [Integer]
80
+ # ID of the Application
81
+ # @param resource_owner [ActiveRecord::Base]
82
+ # instance of the Resource Owner model
83
+ #
84
+ def revoke_all_for(application_id, resource_owner)
85
+ by_application_id_and_resource_owner_id(key: [application_id, resource_owner.id]).stream do |at|
86
+ at.revoke
87
+ end
88
+ end
89
+
90
+ # Looking for not revoked Access Token record that belongs to specific
91
+ # Application and Resource Owner.
92
+ #
93
+ # @param application_id [Integer]
94
+ # ID of the Application model instance
95
+ # @param resource_owner_id [Integer]
96
+ # ID of the Resource Owner model instance
97
+ #
98
+ # @return [Doorkeeper::AccessToken, nil] matching AccessToken object or
99
+ # nil if nothing was found
100
+ #
101
+ def last_authorized_token_for(application_id, resource_owner_id)
102
+ result = by_application_id_and_resource_owner_id(key: [application_id, resource_owner_id]).first
103
+ result[:revoked_at] ? result : nil
104
+ end
105
+
106
+ # Looking for not expired Access Token with a matching set of scopes
107
+ # that belongs to specific Application and Resource Owner.
108
+ #
109
+ # @param application [Doorkeeper::Application]
110
+ # Application instance
111
+ # @param resource_owner_or_id [ActiveRecord::Base, Integer]
112
+ # Resource Owner model instance or it's ID
113
+ # @param scopes [String, Doorkeeper::OAuth::Scopes]
114
+ # set of scopes
115
+ #
116
+ # @return [Doorkeeper::AccessToken, nil] Access Token instance or
117
+ # nil if matching record was not found
118
+ #
119
+ def matching_token_for(application, resource_owner_or_id, scopes)
120
+ resource_owner_id = resource_owner_or_id.try(:id) || resource_owner_or_id
121
+ token = last_authorized_token_for(application.try(:id), resource_owner_id)
122
+ if token && scopes_match?(token.scopes, scopes, application.try(:scopes))
123
+ token
124
+ end
125
+ end
126
+
127
+ # Checks whether the token scopes match the scopes from the parameters or
128
+ # Application scopes (if present).
129
+ #
130
+ # @param token_scopes [#to_s]
131
+ # set of scopes (any object that responds to `#to_s`)
132
+ # @param param_scopes [String]
133
+ # scopes from params
134
+ # @param app_scopes [String]
135
+ # Application scopes
136
+ #
137
+ # @return [Boolean] true if all scopes and blank or matches
138
+ # and false in other cases
139
+ #
140
+ def scopes_match?(token_scopes, param_scopes, app_scopes)
141
+ (!token_scopes.present? && !param_scopes.present?) ||
142
+ Doorkeeper::OAuth::Helpers::ScopeChecker.match?(
143
+ token_scopes.to_s,
144
+ param_scopes,
145
+ app_scopes
146
+ )
147
+ end
148
+
149
+ # Looking for not expired AccessToken record with a matching set of
150
+ # scopes that belongs to specific Application and Resource Owner.
151
+ # If it doesn't exists - then creates it.
152
+ #
153
+ # @param application [Doorkeeper::Application]
154
+ # Application instance
155
+ # @param resource_owner_id [ActiveRecord::Base, Integer]
156
+ # Resource Owner model instance or it's ID
157
+ # @param scopes [#to_s]
158
+ # set of scopes (any object that responds to `#to_s`)
159
+ # @param expires_in [Integer]
160
+ # token lifetime in seconds
161
+ # @param use_refresh_token [Boolean]
162
+ # whether to use the refresh token
163
+ #
164
+ # @return [Doorkeeper::AccessToken] existing record or a new one
165
+ #
166
+ def find_or_create_for(application, resource_owner_id, scopes, expires_in, use_refresh_token)
167
+ if Doorkeeper.configuration.reuse_access_token
168
+ access_token = matching_token_for(application, resource_owner_id, scopes)
169
+ if access_token && !access_token.expired?
170
+ return access_token
171
+ end
172
+ end
173
+
174
+ create!(
175
+ application_id: application.try(:id),
176
+ resource_owner_id: resource_owner_id,
177
+ scopes: scopes.to_s,
178
+ expires_in: expires_in,
179
+ use_refresh_token: use_refresh_token
180
+ )
181
+ end
182
+ end
183
+
184
+ # Access Token type: Bearer.
185
+ # @see https://tools.ietf.org/html/rfc6750
186
+ # The OAuth 2.0 Authorization Framework: Bearer Token Usage
187
+ #
188
+ def token_type
189
+ 'bearer'
190
+ end
191
+
192
+ def use_refresh_token?
193
+ @use_refresh_token ||= false
194
+ !!@use_refresh_token
195
+ end
196
+
197
+ # JSON representation of the Access Token instance.
198
+ #
199
+ # @return [Hash] hash with token data
200
+ def as_json(_options = {})
201
+ {
202
+ resource_owner_id: resource_owner_id,
203
+ scopes: scopes,
204
+ expires_in_seconds: expires_in_seconds,
205
+ application: { uid: application.try(:uid) },
206
+ created_at: created_at.to_i
207
+ }
208
+ end
209
+
210
+
211
+ # Lets make sure these keys are not clogging up the database forever
212
+ def save(**options)
213
+ if use_refresh_token?
214
+ options[:ttl] = self.created_at + 6.months
215
+ else
216
+ options[:ttl] = self.created_at + self.expires_in + 30
217
+ end
218
+ super(**options)
219
+ end
220
+
221
+
222
+
223
+ # Indicates whether the token instance have the same credential
224
+ # as the other Access Token.
225
+ #
226
+ # @param access_token [Doorkeeper::AccessToken] other token
227
+ #
228
+ # @return [Boolean] true if credentials are same of false in other cases
229
+ #
230
+ def same_credential?(access_token)
231
+ application_id == access_token.application_id &&
232
+ resource_owner_id == access_token.resource_owner_id
233
+ end
234
+
235
+
236
+ # Indicates if token is acceptable for specific scopes.
237
+ #
238
+ # @param scopes [Array<String>] scopes
239
+ #
240
+ # @return [Boolean] true if record is accessible and includes scopes or
241
+ # false in other cases
242
+ #
243
+ def acceptable?(scopes)
244
+ accessible? && includes_scope?(*scopes)
245
+ end
246
+
247
+ private
248
+
249
+
250
+ before_validation :generate_token, on: :create
251
+ before_validation :generate_refresh_token, on: :create, if: :use_refresh_token?
252
+
253
+
254
+ # Generates refresh token with UniqueToken generator.
255
+ #
256
+ # @return [String] refresh token value
257
+ #
258
+ def generate_refresh_token
259
+ if self.refresh_token.blank?
260
+ write_attribute :refresh_token, UniqueToken.generate
261
+ end
262
+ end
263
+
264
+ def generate_token
265
+ return if self.token.present?
266
+
267
+ self.created_at ||= Time.now.utc
268
+
269
+ generator = Doorkeeper.configuration.access_token_generator.constantize
270
+ self.id = self.token = generator.generate(
271
+ resource_owner_id: resource_owner_id,
272
+ scopes: scopes,
273
+ application: application,
274
+ expires_in: expires_in,
275
+ created_at: created_at
276
+ )
277
+ rescue NoMethodError
278
+ raise Errors::UnableToGenerateToken, "#{generator} does not respond to `.generate`."
279
+ rescue NameError
280
+ raise Errors::TokenGeneratorNotFound, "#{generator} not found"
281
+ end
282
+ end
283
+ end
@@ -0,0 +1,76 @@
1
+
2
+ # Load these before the has_many
3
+ require File.expand_path("../access_grant", __FILE__)
4
+ require File.expand_path("../access_token", __FILE__)
5
+
6
+
7
+ module Doorkeeper
8
+ class Application < CouchbaseOrm::Base
9
+ design_document :dk_app
10
+
11
+
12
+ include OAuth::Helpers
13
+ include Models::Scopes
14
+
15
+
16
+ attribute :name,
17
+ :uid,
18
+ :secret,
19
+ :scopes,
20
+ :redirect_uri, type: String
21
+
22
+
23
+ belongs_to :owner, polymorphic: true
24
+
25
+ validates :owner, presence: true, if: :validate_owner?
26
+ def validate_owner?
27
+ Doorkeeper.configuration.confirm_application_owner?
28
+ end
29
+
30
+
31
+ has_many :access_grants, dependent: :destroy, class_name: 'Doorkeeper::AccessGrant'
32
+ has_many :access_tokens, dependent: :destroy, class_name: 'Doorkeeper::AccessToken'
33
+
34
+
35
+ class << self
36
+ alias_method :by_uid, :find_by_id
37
+
38
+ def by_uid_and_secret(uid, secret)
39
+ app = find_by_id(uid)
40
+ if app
41
+ return app.secret == secret ? app : nil
42
+ end
43
+ nil
44
+ end
45
+
46
+ def authorized_for(resource_owner)
47
+ AccessToken.find_by_resource_owner_id(resource_owner.id).collect(&:application)
48
+ end
49
+ end
50
+
51
+
52
+ private
53
+
54
+
55
+ validates :name, :secret, :uid, presence: true
56
+ validates :redirect_uri, redirect_uri: true
57
+
58
+ before_validation :generate_uid, :generate_secret, on: :create
59
+
60
+ def has_scopes?
61
+ true
62
+ end
63
+
64
+ def generate_uid
65
+ if uid.blank?
66
+ self.id = self.uid = UniqueToken.generate
67
+ end
68
+ end
69
+
70
+ def generate_secret
71
+ if secret.blank?
72
+ self.secret = UniqueToken.generate
73
+ end
74
+ end
75
+ end
76
+ end
@@ -0,0 +1,34 @@
1
+ require 'date'
2
+
3
+ module Doorkeeper
4
+ module Couchbase
5
+ module Timestamps
6
+ extend ActiveSupport::Concern
7
+
8
+
9
+ included do
10
+ attribute :revoked_at, type: Integer
11
+ attribute :created_at, type: Integer, :default => lambda { Time.now.to_i + 1 }
12
+ end
13
+
14
+
15
+ def revoked_at
16
+ revoked = self[:revoked_at]
17
+ Time.at(revoked) unless revoked.nil?
18
+ end
19
+
20
+ def revoked_at=(time)
21
+ if time
22
+ number = time.is_a?(Numeric) ? time.to_i : time.to_time.to_i
23
+ self[:revoked_at] = number
24
+ else
25
+ self[:revoked_at] = nil
26
+ end
27
+ end
28
+
29
+ def created_at
30
+ Time.at(self[:created_at])
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,19 @@
1
+ module Doorkeeper
2
+ module Orm
3
+ module Couchbase
4
+ def self.initialize_models!
5
+ require 'support/orm/couchbase/timestamps'
6
+ require 'support/orm/couchbase/access_grant'
7
+ require 'support/orm/couchbase/access_token'
8
+ require 'support/orm/couchbase/application'
9
+ end
10
+
11
+ def self.initialize_application_owner!
12
+ #require 'doorkeeper/models/concerns/ownership'
13
+ #Doorkeeper::Application.send :include, Doorkeeper::Models::Ownership
14
+ end
15
+
16
+ def self.check_requirements!(_config); end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,17 @@
1
+ common: &common
2
+ hosts: localhost
3
+ password:
4
+
5
+ development:
6
+ <<: *common
7
+ bucket: default
8
+
9
+ test:
10
+ <<: *common
11
+ bucket: test
12
+ password: password123
13
+
14
+ # set these environment variables on your production server
15
+ production:
16
+ hosts: 127.0.0.1
17
+ bucket: default
metadata ADDED
@@ -0,0 +1,209 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: doorkeeper-couchbase
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Stephen von Takach
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-03 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: doorkeeper
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 4.0.0
20
+ - - "<"
21
+ - !ruby/object:Gem::Version
22
+ version: '5'
23
+ type: :runtime
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ version: 4.0.0
30
+ - - "<"
31
+ - !ruby/object:Gem::Version
32
+ version: '5'
33
+ - !ruby/object:Gem::Dependency
34
+ name: couchbase-orm
35
+ requirement: !ruby/object:Gem::Requirement
36
+ requirements:
37
+ - - ">="
38
+ - !ruby/object:Gem::Version
39
+ version: 0.0.0
40
+ - - "<"
41
+ - !ruby/object:Gem::Version
42
+ version: '2'
43
+ type: :runtime
44
+ prerelease: false
45
+ version_requirements: !ruby/object:Gem::Requirement
46
+ requirements:
47
+ - - ">="
48
+ - !ruby/object:Gem::Version
49
+ version: 0.0.0
50
+ - - "<"
51
+ - !ruby/object:Gem::Version
52
+ version: '2'
53
+ - !ruby/object:Gem::Dependency
54
+ name: sqlite3
55
+ requirement: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - "~>"
58
+ - !ruby/object:Gem::Version
59
+ version: '0'
60
+ type: :development
61
+ prerelease: false
62
+ version_requirements: !ruby/object:Gem::Requirement
63
+ requirements:
64
+ - - "~>"
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
67
+ - !ruby/object:Gem::Dependency
68
+ name: capybara
69
+ requirement: !ruby/object:Gem::Requirement
70
+ requirements:
71
+ - - "~>"
72
+ - !ruby/object:Gem::Version
73
+ version: '0'
74
+ type: :development
75
+ prerelease: false
76
+ version_requirements: !ruby/object:Gem::Requirement
77
+ requirements:
78
+ - - "~>"
79
+ - !ruby/object:Gem::Version
80
+ version: '0'
81
+ - !ruby/object:Gem::Dependency
82
+ name: database_cleaner
83
+ requirement: !ruby/object:Gem::Requirement
84
+ requirements:
85
+ - - "~>"
86
+ - !ruby/object:Gem::Version
87
+ version: '1.5'
88
+ type: :development
89
+ prerelease: false
90
+ version_requirements: !ruby/object:Gem::Requirement
91
+ requirements:
92
+ - - "~>"
93
+ - !ruby/object:Gem::Version
94
+ version: '1.5'
95
+ - !ruby/object:Gem::Dependency
96
+ name: factory_girl
97
+ requirement: !ruby/object:Gem::Requirement
98
+ requirements:
99
+ - - "~>"
100
+ - !ruby/object:Gem::Version
101
+ version: '4.7'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ requirements:
106
+ - - "~>"
107
+ - !ruby/object:Gem::Version
108
+ version: '4.7'
109
+ - !ruby/object:Gem::Dependency
110
+ name: generator_spec
111
+ requirement: !ruby/object:Gem::Requirement
112
+ requirements:
113
+ - - "~>"
114
+ - !ruby/object:Gem::Version
115
+ version: '0.9'
116
+ type: :development
117
+ prerelease: false
118
+ version_requirements: !ruby/object:Gem::Requirement
119
+ requirements:
120
+ - - "~>"
121
+ - !ruby/object:Gem::Version
122
+ version: '0.9'
123
+ - !ruby/object:Gem::Dependency
124
+ name: rake
125
+ requirement: !ruby/object:Gem::Requirement
126
+ requirements:
127
+ - - "~>"
128
+ - !ruby/object:Gem::Version
129
+ version: '11'
130
+ type: :development
131
+ prerelease: false
132
+ version_requirements: !ruby/object:Gem::Requirement
133
+ requirements:
134
+ - - "~>"
135
+ - !ruby/object:Gem::Version
136
+ version: '11'
137
+ - !ruby/object:Gem::Dependency
138
+ name: rspec-rails
139
+ requirement: !ruby/object:Gem::Requirement
140
+ requirements:
141
+ - - "~>"
142
+ - !ruby/object:Gem::Version
143
+ version: '0'
144
+ type: :development
145
+ prerelease: false
146
+ version_requirements: !ruby/object:Gem::Requirement
147
+ requirements:
148
+ - - "~>"
149
+ - !ruby/object:Gem::Version
150
+ version: '0'
151
+ - !ruby/object:Gem::Dependency
152
+ name: timecop
153
+ requirement: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - "~>"
156
+ - !ruby/object:Gem::Version
157
+ version: '0.8'
158
+ type: :development
159
+ prerelease: false
160
+ version_requirements: !ruby/object:Gem::Requirement
161
+ requirements:
162
+ - - "~>"
163
+ - !ruby/object:Gem::Version
164
+ version: '0.8'
165
+ description: Doorkeeper Couchbase ORMs
166
+ email:
167
+ - steve@aca.im
168
+ executables: []
169
+ extensions: []
170
+ extra_rdoc_files: []
171
+ files:
172
+ - MIT-LICENSE
173
+ - README.md
174
+ - Rakefile
175
+ - lib/couchbase/railtie.rb
176
+ - lib/doorkeeper-couchbase.rb
177
+ - lib/doorkeeper-couchbase/version.rb
178
+ - lib/support/orm/couchbase.rb
179
+ - lib/support/orm/couchbase/access_grant.rb
180
+ - lib/support/orm/couchbase/access_token.rb
181
+ - lib/support/orm/couchbase/application.rb
182
+ - lib/support/orm/couchbase/timestamps.rb
183
+ - spec/dummy/config/couchbase.yml
184
+ homepage: http://github.com/acaprojects/doorkeeper-couchbase
185
+ licenses:
186
+ - MIT
187
+ metadata: {}
188
+ post_install_message:
189
+ rdoc_options: []
190
+ require_paths:
191
+ - lib
192
+ required_ruby_version: !ruby/object:Gem::Requirement
193
+ requirements:
194
+ - - ">="
195
+ - !ruby/object:Gem::Version
196
+ version: '0'
197
+ required_rubygems_version: !ruby/object:Gem::Requirement
198
+ requirements:
199
+ - - ">="
200
+ - !ruby/object:Gem::Version
201
+ version: '0'
202
+ requirements: []
203
+ rubyforge_project:
204
+ rubygems_version: 2.6.10
205
+ signing_key:
206
+ specification_version: 4
207
+ summary: Doorkeeper Couchbase ORMs
208
+ test_files:
209
+ - spec/dummy/config/couchbase.yml