doorkeeper 5.3.3 → 5.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +0 -14
  3. data/CHANGELOG.md +35 -10
  4. data/Dangerfile +7 -7
  5. data/Dockerfile +2 -2
  6. data/Gemfile +9 -9
  7. data/README.md +6 -4
  8. data/app/controllers/doorkeeper/applications_controller.rb +7 -7
  9. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  11. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  12. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  13. data/bin/console +14 -0
  14. data/config/locales/en.yml +3 -1
  15. data/doorkeeper.gemspec +1 -1
  16. data/gemfiles/rails_5_0.gemfile +8 -7
  17. data/gemfiles/rails_5_1.gemfile +8 -7
  18. data/gemfiles/rails_5_2.gemfile +8 -7
  19. data/gemfiles/rails_6_0.gemfile +8 -7
  20. data/gemfiles/rails_master.gemfile +8 -7
  21. data/lib/doorkeeper.rb +106 -79
  22. data/lib/doorkeeper/config.rb +40 -17
  23. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  24. data/lib/doorkeeper/config/option.rb +28 -14
  25. data/lib/doorkeeper/grape/helpers.rb +1 -1
  26. data/lib/doorkeeper/models/access_grant_mixin.rb +9 -11
  27. data/lib/doorkeeper/models/access_token_mixin.rb +100 -41
  28. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  29. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  30. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  31. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  32. data/lib/doorkeeper/oauth/authorization/code.rb +14 -5
  33. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  34. data/lib/doorkeeper/oauth/authorization/token.rb +7 -11
  35. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  36. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  37. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  38. data/lib/doorkeeper/oauth/client.rb +1 -1
  39. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  40. data/lib/doorkeeper/oauth/client_credentials/creator.rb +25 -7
  41. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  42. data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -1
  43. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  44. data/lib/doorkeeper/oauth/code_request.rb +1 -1
  45. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  46. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  47. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  48. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  49. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  50. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -5
  51. data/lib/doorkeeper/oauth/pre_authorization.rb +32 -27
  52. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  53. data/lib/doorkeeper/oauth/token.rb +1 -1
  54. data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
  55. data/lib/doorkeeper/oauth/token_request.rb +2 -2
  56. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  57. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +7 -2
  58. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +6 -2
  59. data/lib/doorkeeper/orm/active_record/mixins/application.rb +9 -64
  60. data/lib/doorkeeper/rails/routes.rb +13 -17
  61. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  62. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  63. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  64. data/lib/doorkeeper/request/strategy.rb +2 -2
  65. data/lib/doorkeeper/server.rb +3 -3
  66. data/lib/doorkeeper/version.rb +3 -3
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  69. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  70. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  71. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  72. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  73. data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
  74. data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -0
  75. data/spec/controllers/applications_controller_spec.rb +2 -2
  76. data/spec/controllers/authorizations_controller_spec.rb +165 -30
  77. data/spec/controllers/tokens_controller_spec.rb +6 -5
  78. data/spec/dummy/app/helpers/application_helper.rb +1 -1
  79. data/spec/dummy/app/models/user.rb +5 -1
  80. data/spec/dummy/config/application.rb +6 -4
  81. data/spec/dummy/config/boot.rb +4 -4
  82. data/spec/dummy/config/environment.rb +1 -1
  83. data/spec/dummy/config/routes.rb +4 -4
  84. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +2 -2
  85. data/spec/dummy/db/schema.rb +3 -1
  86. data/spec/factories.rb +1 -1
  87. data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +47 -0
  88. data/spec/lib/config_spec.rb +15 -11
  89. data/spec/lib/models/revocable_spec.rb +2 -3
  90. data/spec/lib/models/scopes_spec.rb +8 -0
  91. data/spec/lib/oauth/authorization_code_request_spec.rb +25 -15
  92. data/spec/lib/oauth/base_request_spec.rb +6 -20
  93. data/spec/lib/oauth/client_credentials/creator_spec.rb +90 -89
  94. data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
  95. data/spec/lib/oauth/client_credentials/validation_spec.rb +38 -40
  96. data/spec/lib/oauth/client_credentials_request_spec.rb +5 -4
  97. data/spec/lib/oauth/code_request_spec.rb +1 -1
  98. data/spec/lib/oauth/code_response_spec.rb +5 -1
  99. data/spec/lib/oauth/error_response_spec.rb +1 -1
  100. data/spec/lib/oauth/password_access_token_request_spec.rb +24 -13
  101. data/spec/lib/oauth/pre_authorization_spec.rb +13 -18
  102. data/spec/lib/oauth/refresh_token_request_spec.rb +19 -30
  103. data/spec/lib/oauth/token_request_spec.rb +14 -7
  104. data/spec/lib/option_spec.rb +51 -0
  105. data/spec/lib/stale_records_cleaner_spec.rb +18 -5
  106. data/spec/models/doorkeeper/access_grant_spec.rb +18 -4
  107. data/spec/models/doorkeeper/access_token_spec.rb +507 -479
  108. data/spec/models/doorkeeper/application_spec.rb +22 -62
  109. data/spec/requests/endpoints/token_spec.rb +5 -1
  110. data/spec/requests/flows/authorization_code_errors_spec.rb +4 -1
  111. data/spec/requests/flows/authorization_code_spec.rb +6 -1
  112. data/spec/requests/flows/client_credentials_spec.rb +41 -0
  113. data/spec/requests/flows/refresh_token_spec.rb +16 -8
  114. data/spec/requests/flows/revoke_token_spec.rb +143 -104
  115. data/spec/support/helpers/access_token_request_helper.rb +1 -0
  116. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  117. data/spec/support/helpers/config_helper.rb +1 -1
  118. data/spec/support/shared/controllers_shared_context.rb +2 -2
  119. data/spec/support/shared/models_shared_examples.rb +6 -4
  120. metadata +16 -5
@@ -0,0 +1,28 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ class Config
5
+ # Abstract base class for Doorkeeper and it's extensions configuration
6
+ # builder. Instantiates and validates gem configuration.
7
+ #
8
+ class AbstractBuilder
9
+ attr_reader :config
10
+
11
+ # @param [Class] config class
12
+ #
13
+ def initialize(config = Config.new, &block)
14
+ @config = config
15
+ instance_eval(&block)
16
+ end
17
+
18
+ # Builds and validates configuration.
19
+ #
20
+ # @return [Doorkeeper::Config] config instance
21
+ #
22
+ def build
23
+ @config.validate if @config.respond_to?(:validate)
24
+ @config
25
+ end
26
+ end
27
+ end
28
+ end
@@ -36,22 +36,29 @@ module Doorkeeper
36
36
  attribute = options[:as] || name
37
37
  attribute_builder = options[:builder_class]
38
38
 
39
- Builder.instance_eval do
40
- remove_method name if method_defined?(name)
41
- if options[:deprecated]
42
- define_method name do |*_, &_|
43
- Kernel.warn "[DOORKEEPER] #{name} has been deprecated and will soon be removed"
44
- end
45
- else
46
- define_method name do |*args, &block|
47
- value = if attribute_builder
48
- attribute_builder.new(&block).build
49
- else
50
- block || args.first
51
- end
39
+ builder_class.instance_eval do
40
+ if method_defined?(name)
41
+ Kernel.warn "[DOORKEEPER] Option #{name} already defined and will be overridden"
42
+ remove_method name
43
+ end
52
44
 
53
- @config.instance_variable_set(:"@#{attribute}", value)
45
+ define_method name do |*args, &block|
46
+ if (deprecation_opts = options[:deprecated])
47
+ warning = "[DOORKEEPER] #{name} has been deprecated and will soon be removed"
48
+ if deprecation_opts.is_a?(Hash)
49
+ warning = "#{warning}\n#{deprecation_opts.fetch(:message)}"
50
+ end
51
+
52
+ Kernel.warn(warning)
54
53
  end
54
+
55
+ value = if attribute_builder
56
+ attribute_builder.new(&block).build
57
+ else
58
+ block || args.first
59
+ end
60
+
61
+ @config.instance_variable_set(:"@#{attribute}", value)
55
62
  end
56
63
  end
57
64
 
@@ -65,6 +72,13 @@ module Doorkeeper
65
72
 
66
73
  public attribute
67
74
  end
75
+
76
+ def self.extended(base)
77
+ return if base.respond_to?(:builder_class)
78
+
79
+ raise Doorkeeper::MissingConfigurationBuilderClass, "Define `self.builder_class` method " \
80
+ "for #{base} that returns your custom Builder class to use options DSL!"
81
+ end
68
82
  end
69
83
  end
70
84
  end
@@ -18,7 +18,7 @@ module Doorkeeper
18
18
 
19
19
  scopes = if endpoint_scopes
20
20
  Doorkeeper::OAuth::Scopes.from_array(endpoint_scopes)
21
- elsif scopes && !scopes.empty?
21
+ elsif scopes.present?
22
22
  Doorkeeper::OAuth::Scopes.from_array(scopes)
23
23
  end
24
24
 
@@ -11,14 +11,11 @@ module Doorkeeper
11
11
  include Models::Orderable
12
12
  include Models::SecretStorable
13
13
  include Models::Scopes
14
+ include Models::ResourceOwnerable
14
15
 
15
16
  # never uses pkce, if pkce migrations were not generated
16
17
  def uses_pkce?
17
- pkce_supported? && code_challenge.present?
18
- end
19
-
20
- def pkce_supported?
21
- respond_to? :code_challenge
18
+ self.class.pkce_supported? && code_challenge.present?
22
19
  end
23
20
 
24
21
  module ClassMethods
@@ -43,11 +40,12 @@ module Doorkeeper
43
40
  # instance of the Resource Owner model
44
41
  #
45
42
  def revoke_all_for(application_id, resource_owner, clock = Time)
46
- where(
47
- application_id: application_id,
48
- resource_owner_id: resource_owner.id,
49
- revoked_at: nil,
50
- ).update_all(revoked_at: clock.now.utc)
43
+ by_resource_owner(resource_owner)
44
+ .where(
45
+ application_id: application_id,
46
+ revoked_at: nil,
47
+ )
48
+ .update_all(revoked_at: clock.now.utc)
51
49
  end
52
50
 
53
51
  # Implements PKCE code_challenge encoding without base64 padding as described in the spec.
@@ -96,7 +94,7 @@ module Doorkeeper
96
94
  end
97
95
 
98
96
  def pkce_supported?
99
- new.pkce_supported?
97
+ column_names.include?("code_challenge")
100
98
  end
101
99
 
102
100
  ##
@@ -12,6 +12,7 @@ module Doorkeeper
12
12
  include Models::Orderable
13
13
  include Models::SecretStorable
14
14
  include Models::Scopes
15
+ include Models::ResourceOwnerable
15
16
 
16
17
  module ClassMethods
17
18
  # Returns an instance of the Doorkeeper::AccessToken with
@@ -64,11 +65,12 @@ module Doorkeeper
64
65
  # instance of the Resource Owner model
65
66
  #
66
67
  def revoke_all_for(application_id, resource_owner, clock = Time)
67
- where(
68
- application_id: application_id,
69
- resource_owner_id: resource_owner.id,
70
- revoked_at: nil,
71
- ).update_all(revoked_at: clock.now.utc)
68
+ by_resource_owner(resource_owner)
69
+ .where(
70
+ application_id: application_id,
71
+ revoked_at: nil,
72
+ )
73
+ .update_all(revoked_at: clock.now.utc)
72
74
  end
73
75
 
74
76
  # Looking for not revoked Access Token with a matching set of scopes
@@ -76,7 +78,7 @@ module Doorkeeper
76
78
  #
77
79
  # @param application [Doorkeeper::Application]
78
80
  # Application instance
79
- # @param resource_owner_or_id [ActiveRecord::Base, Integer]
81
+ # @param resource_owner [ActiveRecord::Base, Integer]
80
82
  # Resource Owner model instance or it's ID
81
83
  # @param scopes [String, Doorkeeper::OAuth::Scopes]
82
84
  # set of scopes
@@ -84,14 +86,8 @@ module Doorkeeper
84
86
  # @return [Doorkeeper::AccessToken, nil] Access Token instance or
85
87
  # nil if matching record was not found
86
88
  #
87
- def matching_token_for(application, resource_owner_or_id, scopes)
88
- resource_owner_id = if resource_owner_or_id.respond_to?(:to_key)
89
- resource_owner_or_id.id
90
- else
91
- resource_owner_or_id
92
- end
93
-
94
- tokens = authorized_tokens_for(application.try(:id), resource_owner_id)
89
+ def matching_token_for(application, resource_owner, scopes)
90
+ tokens = authorized_tokens_for(application&.id, resource_owner)
95
91
  find_matching_token(tokens, application, scopes)
96
92
  end
97
93
 
@@ -130,7 +126,7 @@ module Doorkeeper
130
126
 
131
127
  find_access_token_in_batches(relation, batch_size: batch_size) do |batch|
132
128
  tokens = batch.select do |token|
133
- scopes_match?(token.scopes, scopes, application.try(:scopes))
129
+ scopes_match?(token.scopes, scopes, application&.scopes)
134
130
  end
135
131
 
136
132
  matching_tokens.concat(tokens)
@@ -170,47 +166,78 @@ module Doorkeeper
170
166
  #
171
167
  # @param application [Doorkeeper::Application]
172
168
  # Application instance
173
- # @param resource_owner_id [ActiveRecord::Base, Integer]
169
+ # @param resource_owner [ActiveRecord::Base, Integer]
174
170
  # Resource Owner model instance or it's ID
175
171
  # @param scopes [#to_s]
176
172
  # set of scopes (any object that responds to `#to_s`)
177
- # @param expires_in [Integer]
173
+ # @param token_attributes [Hash]
174
+ # Additional attributes to use when creating a token
175
+ # @option token_attributes [Integer] :expires_in
178
176
  # token lifetime in seconds
179
- # @param use_refresh_token [Boolean]
177
+ # @option token_attributes [Boolean] :use_refresh_token
180
178
  # whether to use the refresh token
181
179
  #
182
180
  # @return [Doorkeeper::AccessToken] existing record or a new one
183
181
  #
184
- def find_or_create_for(application, resource_owner_id, scopes, expires_in, use_refresh_token)
182
+ def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes)
185
183
  if Doorkeeper.config.reuse_access_token
186
- access_token = matching_token_for(application, resource_owner_id, scopes)
184
+ access_token = matching_token_for(application, resource_owner, scopes)
187
185
 
188
186
  return access_token if access_token&.reusable?
189
187
  end
190
188
 
191
- create!(
192
- application_id: application.try(:id),
193
- resource_owner_id: resource_owner_id,
194
- scopes: scopes.to_s,
195
- expires_in: expires_in,
196
- use_refresh_token: use_refresh_token,
189
+ create_for(
190
+ application: application,
191
+ resource_owner: resource_owner,
192
+ scopes: scopes,
193
+ **token_attributes,
197
194
  )
198
195
  end
199
196
 
197
+ # Creates a not expired AccessToken record with a matching set of
198
+ # scopes that belongs to specific Application and Resource Owner.
199
+ #
200
+ # @param application [Doorkeeper::Application]
201
+ # Application instance
202
+ # @param resource_owner [ActiveRecord::Base, Integer]
203
+ # Resource Owner model instance or it's ID
204
+ # @param scopes [#to_s]
205
+ # set of scopes (any object that responds to `#to_s`)
206
+ # @param token_attributes [Hash]
207
+ # Additional attributes to use when creating a token
208
+ # @option token_attributes [Integer] :expires_in
209
+ # token lifetime in seconds
210
+ # @option token_attributes [Boolean] :use_refresh_token
211
+ # whether to use the refresh token
212
+ #
213
+ # @return [Doorkeeper::AccessToken] new access token
214
+ #
215
+ def create_for(application:, resource_owner:, scopes:, **token_attributes)
216
+ token_attributes[:application_id] = application&.id
217
+ token_attributes[:scopes] = scopes.to_s
218
+
219
+ if Doorkeeper.config.polymorphic_resource_owner?
220
+ token_attributes[:resource_owner] = resource_owner
221
+ else
222
+ token_attributes[:resource_owner_id] = resource_owner_id_for(resource_owner)
223
+ end
224
+
225
+ create!(token_attributes)
226
+ end
227
+
200
228
  # Looking for not revoked Access Token records that belongs to specific
201
229
  # Application and Resource Owner.
202
230
  #
203
231
  # @param application_id [Integer]
204
232
  # ID of the Application model instance
205
- # @param resource_owner_id [Integer]
233
+ # @param resource_owner [Integer]
206
234
  # ID of the Resource Owner model instance
207
235
  #
208
236
  # @return [Doorkeeper::AccessToken] array of matching AccessToken objects
209
237
  #
210
- def authorized_tokens_for(application_id, resource_owner_id)
211
- where(
238
+ def authorized_tokens_for(application_id, resource_owner)
239
+ by_resource_owner(resource_owner).where(
212
240
  application_id: application_id,
213
- resource_owner_id: resource_owner_id,
214
241
  revoked_at: nil,
215
242
  )
216
243
  end
@@ -220,15 +247,16 @@ module Doorkeeper
220
247
  #
221
248
  # @param application_id [Integer]
222
249
  # ID of the Application model instance
223
- # @param resource_owner_id [Integer]
250
+ # @param resource_owner [ActiveRecord::Base, Integer]
224
251
  # ID of the Resource Owner model instance
225
252
  #
226
253
  # @return [Doorkeeper::AccessToken, nil] matching AccessToken object or
227
254
  # nil if nothing was found
228
255
  #
229
- def last_authorized_token_for(application_id, resource_owner_id)
230
- authorized_tokens_for(application_id, resource_owner_id)
231
- .ordered_by(:created_at, :desc).first
256
+ def last_authorized_token_for(application_id, resource_owner)
257
+ authorized_tokens_for(application_id, resource_owner)
258
+ .ordered_by(:created_at, :desc)
259
+ .first
232
260
  end
233
261
 
234
262
  ##
@@ -269,7 +297,11 @@ module Doorkeeper
269
297
  expires_in: expires_in_seconds,
270
298
  application: { uid: application.try(:uid) },
271
299
  created_at: created_at.to_i,
272
- }
300
+ }.tap do |json|
301
+ if Doorkeeper.configuration.polymorphic_resource_owner?
302
+ json[:resource_owner_type] = resource_owner_type
303
+ end
304
+ end
273
305
  end
274
306
 
275
307
  # Indicates whether the token instance have the same credential
@@ -281,7 +313,22 @@ module Doorkeeper
281
313
  #
282
314
  def same_credential?(access_token)
283
315
  application_id == access_token.application_id &&
316
+ same_resource_owner?(access_token)
317
+ end
318
+
319
+ # Indicates whether the token instance have the same credential
320
+ # as the other Access Token.
321
+ #
322
+ # @param access_token [Doorkeeper::AccessToken] other token
323
+ #
324
+ # @return [Boolean] true if credentials are same of false in other cases
325
+ #
326
+ def same_resource_owner?(access_token)
327
+ if Doorkeeper.configuration.polymorphic_resource_owner?
328
+ resource_owner == access_token.resource_owner
329
+ else
284
330
  resource_owner_id == access_token.resource_owner_id
331
+ end
285
332
  end
286
333
 
287
334
  # Indicates if token is acceptable for specific scopes.
@@ -326,7 +373,7 @@ module Doorkeeper
326
373
  return unless self.class.refresh_token_revoked_on_use?
327
374
 
328
375
  old_refresh_token&.revoke
329
- update_attribute :previous_refresh_token, ""
376
+ update_column(:previous_refresh_token, "")
330
377
  end
331
378
 
332
379
  private
@@ -363,16 +410,28 @@ module Doorkeeper
363
410
  def generate_token
364
411
  self.created_at ||= Time.now.utc
365
412
 
366
- @raw_token = token_generator.generate(
413
+ @raw_token = token_generator.generate(attributes_for_token_generator)
414
+ secret_strategy.store_secret(self, :token, @raw_token)
415
+ @raw_token
416
+ end
417
+
418
+ # Set of attributes that would be passed to token generator to
419
+ # generate unique token based on them.
420
+ #
421
+ # @return [Hash] set of attributes
422
+ #
423
+ def attributes_for_token_generator
424
+ {
367
425
  resource_owner_id: resource_owner_id,
368
426
  scopes: scopes,
369
427
  application: application,
370
428
  expires_in: expires_in,
371
429
  created_at: created_at,
372
- )
373
-
374
- secret_strategy.store_secret(self, :token, @raw_token)
375
- @raw_token
430
+ }.tap do |attributes|
431
+ if Doorkeeper.config.polymorphic_resource_owner?
432
+ attributes[:resource_owner] = resource_owner
433
+ end
434
+ end
376
435
  end
377
436
 
378
437
  def token_generator
@@ -0,0 +1,47 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Models
5
+ module ResourceOwnerable
6
+ extend ActiveSupport::Concern
7
+
8
+ module ClassMethods
9
+ # Searches for record by Resource Owner considering Doorkeeper
10
+ # configuration for resource owner association.
11
+ #
12
+ # @param resource_owner [ActiveRecord::Base, Integer]
13
+ # resource owner
14
+ #
15
+ # @return [Doorkeeper::AccessGrant, Doorkeeper::AccessToken]
16
+ # collection of records
17
+ #
18
+ def by_resource_owner(resource_owner)
19
+ if Doorkeeper.configuration.polymorphic_resource_owner?
20
+ where(resource_owner: resource_owner)
21
+ else
22
+ where(resource_owner_id: resource_owner_id_for(resource_owner))
23
+ end
24
+ end
25
+
26
+ protected
27
+
28
+ # Backward compatible way to retrieve resource owner itself (if
29
+ # polymorphic association enabled) or just it's ID.
30
+ #
31
+ # @param resource_owner [ActiveRecord::Base, Integer]
32
+ # resource owner
33
+ #
34
+ # @return [ActiveRecord::Base, Integer]
35
+ # instance of Resource Owner or it's ID
36
+ #
37
+ def resource_owner_id_for(resource_owner)
38
+ if resource_owner.respond_to?(:to_key)
39
+ resource_owner.id
40
+ else
41
+ resource_owner
42
+ end
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
@@ -9,7 +9,7 @@ module Doorkeeper
9
9
  # @param clock [Time] time object
10
10
  #
11
11
  def revoke(clock = Time)
12
- update_attribute :revoked_at, clock.now.utc
12
+ update_column(:revoked_at, clock.now.utc)
13
13
  end
14
14
 
15
15
  # Indicates whether the object has been revoked.
@@ -8,7 +8,11 @@ module Doorkeeper
8
8
  end
9
9
 
10
10
  def scopes=(value)
11
- super Array(value).join(" ")
11
+ if value.is_a?(Array)
12
+ super(Doorkeeper::OAuth::Scopes.from_array(value).to_s)
13
+ else
14
+ super(Doorkeeper::OAuth::Scopes.from_string(value.to_s).to_s)
15
+ end
12
16
  end
13
17
 
14
18
  def scopes_string