doorkeeper 5.1.0 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (163) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +3 -3
  3. data/CHANGELOG.md +881 -0
  4. data/CONTRIBUTING.md +11 -9
  5. data/Dangerfile +2 -2
  6. data/Dockerfile +29 -0
  7. data/Gemfile +4 -3
  8. data/NEWS.md +1 -814
  9. data/README.md +11 -3
  10. data/RELEASING.md +6 -5
  11. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  12. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  13. data/app/controllers/doorkeeper/applications_controller.rb +1 -0
  14. data/app/controllers/doorkeeper/authorizations_controller.rb +16 -9
  15. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  16. data/app/controllers/doorkeeper/tokens_controller.rb +32 -9
  17. data/app/views/doorkeeper/applications/_form.html.erb +0 -6
  18. data/app/views/doorkeeper/applications/show.html.erb +1 -1
  19. data/config/locales/en.yml +8 -2
  20. data/doorkeeper.gemspec +9 -1
  21. data/gemfiles/rails_5_0.gemfile +3 -2
  22. data/gemfiles/rails_5_1.gemfile +3 -2
  23. data/gemfiles/rails_5_2.gemfile +3 -2
  24. data/gemfiles/rails_6_0.gemfile +4 -3
  25. data/gemfiles/rails_master.gemfile +3 -2
  26. data/lib/doorkeeper/config/option.rb +13 -7
  27. data/lib/doorkeeper/config.rb +157 -42
  28. data/lib/doorkeeper/errors.rb +13 -18
  29. data/lib/doorkeeper/grape/helpers.rb +6 -2
  30. data/lib/doorkeeper/helpers/controller.rb +28 -7
  31. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  32. data/lib/doorkeeper/models/access_token_mixin.rb +99 -20
  33. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  34. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  35. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  37. data/lib/doorkeeper/oauth/authorization/code.rb +12 -14
  38. data/lib/doorkeeper/oauth/authorization/token.rb +10 -7
  39. data/lib/doorkeeper/oauth/authorization_code_request.rb +31 -15
  40. data/lib/doorkeeper/oauth/base_request.rb +10 -4
  41. data/lib/doorkeeper/oauth/client.rb +7 -8
  42. data/lib/doorkeeper/oauth/client_credentials/creator.rb +23 -2
  43. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  44. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +10 -2
  45. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  46. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  47. data/lib/doorkeeper/oauth/code_response.rb +4 -4
  48. data/lib/doorkeeper/oauth/error.rb +1 -1
  49. data/lib/doorkeeper/oauth/error_response.rb +6 -6
  50. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  51. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  52. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -5
  53. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  54. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  55. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  56. data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
  57. data/lib/doorkeeper/oauth/pre_authorization.rb +76 -38
  58. data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -14
  59. data/lib/doorkeeper/oauth/token.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_introspection.rb +26 -16
  61. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  62. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  63. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  64. data/lib/doorkeeper/orm/active_record/application.rb +5 -83
  65. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  66. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  67. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  68. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  69. data/lib/doorkeeper/orm/active_record.rb +21 -6
  70. data/lib/doorkeeper/rails/helpers.rb +4 -4
  71. data/lib/doorkeeper/rails/routes.rb +5 -7
  72. data/lib/doorkeeper/rake/db.rake +3 -3
  73. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  74. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  75. data/lib/doorkeeper/request/password.rb +2 -2
  76. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  77. data/lib/doorkeeper/request.rb +7 -12
  78. data/lib/doorkeeper/server.rb +3 -7
  79. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  80. data/lib/doorkeeper/version.rb +1 -1
  81. data/lib/doorkeeper.rb +6 -3
  82. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  83. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  84. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  85. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  86. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  87. data/lib/generators/doorkeeper/templates/initializer.rb +149 -33
  88. data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  90. data/spec/controllers/applications_controller_spec.rb +95 -1
  91. data/spec/controllers/authorizations_controller_spec.rb +156 -75
  92. data/spec/controllers/protected_resources_controller_spec.rb +28 -20
  93. data/spec/controllers/token_info_controller_spec.rb +1 -1
  94. data/spec/controllers/tokens_controller_spec.rb +206 -38
  95. data/spec/dummy/config/application.rb +3 -1
  96. data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
  97. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  98. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  99. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  100. data/spec/generators/install_generator_spec.rb +1 -1
  101. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  102. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  103. data/spec/lib/config_spec.rb +104 -7
  104. data/spec/lib/doorkeeper_spec.rb +1 -1
  105. data/spec/lib/models/revocable_spec.rb +3 -3
  106. data/spec/lib/oauth/authorization_code_request_spec.rb +129 -115
  107. data/spec/lib/oauth/base_request_spec.rb +154 -135
  108. data/spec/lib/oauth/base_response_spec.rb +27 -29
  109. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  110. data/spec/lib/oauth/client_credentials/creator_spec.rb +43 -3
  111. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  112. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  113. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  114. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  115. data/spec/lib/oauth/client_spec.rb +26 -26
  116. data/spec/lib/oauth/code_request_spec.rb +34 -35
  117. data/spec/lib/oauth/code_response_spec.rb +21 -25
  118. data/spec/lib/oauth/error_response_spec.rb +42 -44
  119. data/spec/lib/oauth/error_spec.rb +12 -14
  120. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  121. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  122. data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
  123. data/spec/lib/oauth/invalid_request_response_spec.rb +73 -0
  124. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  125. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  126. data/spec/lib/oauth/pre_authorization_spec.rb +161 -153
  127. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -138
  128. data/spec/lib/oauth/scopes_spec.rb +104 -106
  129. data/spec/lib/oauth/token_request_spec.rb +117 -110
  130. data/spec/lib/oauth/token_response_spec.rb +71 -73
  131. data/spec/lib/oauth/token_spec.rb +121 -123
  132. data/spec/lib/server_spec.rb +0 -12
  133. data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
  134. data/spec/models/doorkeeper/access_token_spec.rb +42 -11
  135. data/spec/models/doorkeeper/application_spec.rb +114 -77
  136. data/spec/requests/applications/applications_request_spec.rb +1 -1
  137. data/spec/requests/endpoints/authorization_spec.rb +26 -8
  138. data/spec/requests/endpoints/token_spec.rb +1 -1
  139. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  140. data/spec/requests/flows/authorization_code_spec.rb +123 -45
  141. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  142. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  143. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  144. data/spec/requests/flows/password_spec.rb +67 -10
  145. data/spec/requests/flows/refresh_token_spec.rb +20 -20
  146. data/spec/requests/flows/revoke_token_spec.rb +37 -23
  147. data/spec/spec_helper.rb +1 -4
  148. data/spec/support/doorkeeper_rspec.rb +1 -1
  149. data/spec/support/helpers/request_spec_helper.rb +14 -2
  150. data/spec/support/shared/controllers_shared_context.rb +33 -23
  151. data/spec/validators/redirect_uri_validator_spec.rb +41 -16
  152. metadata +19 -16
  153. data/.coveralls.yml +0 -1
  154. data/.github/ISSUE_TEMPLATE.md +0 -25
  155. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  156. data/.gitignore +0 -20
  157. data/.gitlab-ci.yml +0 -16
  158. data/.hound.yml +0 -3
  159. data/.rspec +0 -1
  160. data/.rubocop.yml +0 -50
  161. data/.travis.yml +0 -35
  162. data/app/validators/redirect_uri_validator.rb +0 -50
  163. data/spec/support/http_method_shim.rb +0 -29
@@ -11,36 +11,40 @@ module Doorkeeper
11
11
  end
12
12
  end
13
13
 
14
- def self.configure(&block)
15
- @config = Config::Builder.new(&block).build
16
- setup_orm_adapter
17
- setup_orm_models
18
- setup_application_owner if @config.enable_application_owner?
19
- @config
20
- end
14
+ class << self
15
+ def configure(&block)
16
+ @config = Config::Builder.new(&block).build
17
+ setup_orm_adapter
18
+ setup_orm_models
19
+ setup_application_owner if @config.enable_application_owner?
20
+ @config
21
+ end
21
22
 
22
- def self.configuration
23
- @config || (raise MissingConfiguration)
24
- end
23
+ def configuration
24
+ @config || (raise MissingConfiguration)
25
+ end
25
26
 
26
- def self.setup_orm_adapter
27
- @orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
28
- rescue NameError => error
29
- raise error, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
30
- [doorkeeper] ORM adapter not found (#{configuration.orm}), or there was an error
31
- trying to load it.
27
+ alias config configuration
32
28
 
33
- You probably need to add the related gem for this adapter to work with
34
- doorkeeper.
35
- ERROR_MSG
36
- end
29
+ def setup_orm_adapter
30
+ @orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
31
+ rescue NameError => e
32
+ raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
33
+ [doorkeeper] ORM adapter not found (#{configuration.orm}), or there was an error
34
+ trying to load it.
37
35
 
38
- def self.setup_orm_models
39
- @orm_adapter.initialize_models!
40
- end
36
+ You probably need to add the related gem for this adapter to work with
37
+ doorkeeper.
38
+ ERROR_MSG
39
+ end
40
+
41
+ def setup_orm_models
42
+ @orm_adapter.initialize_models!
43
+ end
41
44
 
42
- def self.setup_application_owner
43
- @orm_adapter.initialize_application_owner!
45
+ def setup_application_owner
46
+ @orm_adapter.initialize_application_owner!
47
+ end
44
48
  end
45
49
 
46
50
  class Config
@@ -120,7 +124,7 @@ module Doorkeeper
120
124
  def use_refresh_token(enabled = true, &block)
121
125
  @config.instance_variable_set(
122
126
  :@refresh_token_enabled,
123
- block || enabled
127
+ block || enabled,
124
128
  )
125
129
  end
126
130
 
@@ -140,6 +144,14 @@ module Doorkeeper
140
144
  @config.instance_variable_set(:@token_reuse_limit, percentage)
141
145
  end
142
146
 
147
+ # TODO: maybe make it more generic for other flows too?
148
+ # Only allow one valid access token obtained via client credentials
149
+ # per client. If a new access token is obtained before the old one
150
+ # expired, the old one gets revoked (disabled by default)
151
+ def revoke_previous_client_credentials_token
152
+ @config.instance_variable_set(:@revoke_previous_client_credentials_token, true)
153
+ end
154
+
143
155
  # Use an API mode for applications generated with --api argument
144
156
  # It will skip applications controller, disable forgery protection
145
157
  def api_only
@@ -195,8 +207,7 @@ module Doorkeeper
195
207
  def configure_secrets_for(type, using:, fallback:)
196
208
  raise ArgumentError, "Invalid type #{type}" if %i[application token].exclude?(type)
197
209
 
198
- @config.instance_variable_set(:"@#{type}_secret_strategy",
199
- using.constantize)
210
+ @config.instance_variable_set(:"@#{type}_secret_strategy", using.constantize)
200
211
 
201
212
  if fallback.nil?
202
213
  return
@@ -204,8 +215,7 @@ module Doorkeeper
204
215
  fallback = "::Doorkeeper::SecretStoring::Plain"
205
216
  end
206
217
 
207
- @config.instance_variable_set(:"@#{type}_secret_fallback_strategy",
208
- fallback.constantize)
218
+ @config.instance_variable_set(:"@#{type}_secret_fallback_strategy", fallback.constantize)
209
219
  end
210
220
  end
211
221
 
@@ -215,7 +225,7 @@ module Doorkeeper
215
225
  as: :authenticate_resource_owner,
216
226
  default: (lambda do |_routes|
217
227
  ::Rails.logger.warn(
218
- I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured")
228
+ I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured"),
219
229
  )
220
230
 
221
231
  nil
@@ -225,7 +235,7 @@ module Doorkeeper
225
235
  as: :authenticate_admin,
226
236
  default: (lambda do |_routes|
227
237
  ::Rails.logger.warn(
228
- I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured")
238
+ I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured"),
229
239
  )
230
240
 
231
241
  head :forbidden
@@ -234,7 +244,7 @@ module Doorkeeper
234
244
  option :resource_owner_from_credentials,
235
245
  default: (lambda do |_routes|
236
246
  ::Rails.logger.warn(
237
- I18n.t("doorkeeper.errors.messages.credential_flow_not_configured")
247
+ I18n.t("doorkeeper.errors.messages.credential_flow_not_configured"),
238
248
  )
239
249
 
240
250
  nil
@@ -254,11 +264,37 @@ module Doorkeeper
254
264
  option :custom_access_token_expires_in, default: ->(_context) { nil }
255
265
  option :authorization_code_expires_in, default: 600
256
266
  option :orm, default: :active_record
257
- option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob"
267
+ option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob", deprecated: true
258
268
  option :active_record_options, default: {}
259
269
  option :grant_flows, default: %w[authorization_code client_credentials]
260
270
  option :handle_auth_errors, default: :render
261
271
 
272
+ # Allows to customize OAuth grant flows that +each+ application support.
273
+ # You can configure a custom block (or use a class respond to `#call`) that must
274
+ # return `true` in case Application instance supports requested OAuth grant flow
275
+ # during the authorization request to the server. This configuration +doesn't+
276
+ # set flows per application, it only allows to check if application supports
277
+ # specific grant flow.
278
+ #
279
+ # For example you can add an additional database column to `oauth_applications` table,
280
+ # say `t.array :grant_flows, default: []`, and store allowed grant flows that can
281
+ # be used with this application there. Then when authorization requested Doorkeeper
282
+ # will call this block to check if specific Application (passed with client_id and/or
283
+ # client_secret) is allowed to perform the request for the specific grant type
284
+ # (authorization, password, client_credentials, etc).
285
+ #
286
+ # Example of the block:
287
+ #
288
+ # ->(flow, client) { client.grant_flows.include?(flow) }
289
+ #
290
+ # In case this option invocation result is `false`, Doorkeeper server returns
291
+ # :unauthorized_client error and stops the request.
292
+ #
293
+ # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
294
+ # @return [Boolean] `true` if allow or `false` if forbid the request
295
+ #
296
+ option :allow_grant_flow_for_client, default: ->(_grant_flow, _client) { true }
297
+
262
298
  # Allows to forbid specific Application redirect URI's by custom rules.
263
299
  # Doesn't forbid any URI by default.
264
300
  #
@@ -288,7 +324,7 @@ module Doorkeeper
288
324
  option :force_ssl_in_redirect_uri, default: !Rails.env.development?
289
325
 
290
326
  # Use a custom class for generating the access token.
291
- # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
327
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
292
328
  #
293
329
  # @param access_token_generator [String]
294
330
  # the name of the access token generator class
@@ -306,11 +342,29 @@ module Doorkeeper
306
342
 
307
343
  # The controller Doorkeeper::ApplicationController inherits from.
308
344
  # Defaults to ActionController::Base.
309
- # https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller
345
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-base-controller
310
346
  #
311
347
  # @param base_controller [String] the name of the base controller
312
348
  option :base_controller,
313
- default: "ActionController::Base"
349
+ default: (lambda do
350
+ api_only ? "ActionController::API" : "ActionController::Base"
351
+ end)
352
+
353
+ # The controller Doorkeeper::ApplicationMetalController inherits from.
354
+ # Defaults to ActionController::API.
355
+ #
356
+ # @param base_metal_controller [String] the name of the base controller
357
+ option :base_metal_controller,
358
+ default: "ActionController::API"
359
+
360
+ option :access_token_class,
361
+ default: "Doorkeeper::AccessToken"
362
+
363
+ option :access_grant_class,
364
+ default: "Doorkeeper::AccessGrant"
365
+
366
+ option :application_class,
367
+ default: "Doorkeeper::Application"
314
368
 
315
369
  # Allows to set blank redirect URIs for Applications in case
316
370
  # server configured to use URI-less grant flows.
@@ -321,9 +375,37 @@ module Doorkeeper
321
375
  grant_flows.exclude?("implicit")
322
376
  end)
323
377
 
324
- attr_reader :api_only,
325
- :enforce_content_type,
326
- :reuse_access_token,
378
+ # Configure protection of token introspection request.
379
+ # By default this configuration allows to introspect a token by
380
+ # another token of the same application, or to introspect the token
381
+ # that belongs to authorized client, or access token has been introspected
382
+ # is a public one (doesn't belong to any client)
383
+ #
384
+ # You can define any custom rule you need or just disable token
385
+ # introspection at all.
386
+ #
387
+ # @param token [Doorkeeper::AccessToken]
388
+ # token to be introspected
389
+ #
390
+ # @param authorized_client [Doorkeeper::Application]
391
+ # authorized client (if request is authorized using Basic auth with
392
+ # Client Credentials for example)
393
+ #
394
+ # @param authorized_token [Doorkeeper::AccessToken]
395
+ # Bearer token used to authorize the request
396
+ #
397
+ option :allow_token_introspection,
398
+ default: (lambda do |token, authorized_client, authorized_token|
399
+ if authorized_token
400
+ authorized_token.application == token&.application
401
+ elsif token.application
402
+ authorized_client == token.application
403
+ else
404
+ true
405
+ end
406
+ end)
407
+
408
+ attr_reader :reuse_access_token,
327
409
  :token_secret_fallback_strategy,
328
410
  :application_secret_fallback_strategy
329
411
 
@@ -334,6 +416,18 @@ module Doorkeeper
334
416
  validate_secret_strategies
335
417
  end
336
418
 
419
+ def access_token_model
420
+ @access_token_model ||= access_token_class.constantize
421
+ end
422
+
423
+ def access_grant_model
424
+ @access_grant_model ||= access_grant_class.constantize
425
+ end
426
+
427
+ def application_model
428
+ @application_model ||= application_class.constantize
429
+ end
430
+
337
431
  def api_only
338
432
  @api_only ||= false
339
433
  end
@@ -354,6 +448,21 @@ module Doorkeeper
354
448
  @token_reuse_limit ||= 100
355
449
  end
356
450
 
451
+ def revoke_previous_client_credentials_token
452
+ @revoke_previous_client_credentials_token || false
453
+ end
454
+
455
+ def resolve_controller(name)
456
+ config_option = public_send(:"#{name}_controller")
457
+ controller_name = if config_option.respond_to?(:call)
458
+ instance_exec(&config_option)
459
+ else
460
+ config_option
461
+ end
462
+
463
+ controller_name.constantize
464
+ end
465
+
357
466
  def enforce_configured_scopes?
358
467
  option_set? :enforce_configured_scopes
359
468
  end
@@ -422,6 +531,12 @@ module Doorkeeper
422
531
  end
423
532
  end
424
533
 
534
+ def allow_grant_flow_for_client?(grant_flow, client)
535
+ return true unless option_defined?(:allow_grant_flow_for_client)
536
+
537
+ allow_grant_flow_for_client.call(grant_flow, client)
538
+ end
539
+
425
540
  def option_defined?(name)
426
541
  instance_variable_defined?("@#{name}")
427
542
  end
@@ -464,7 +579,7 @@ module Doorkeeper
464
579
  ::Rails.logger.warn(
465
580
  "You have configured both reuse_access_token " \
466
581
  "AND strategy strategy '#{strategy}' that cannot restore tokens. " \
467
- "This combination is unsupported. reuse_access_token will be disabled"
582
+ "This combination is unsupported. reuse_access_token will be disabled",
468
583
  )
469
584
  @reuse_access_token = false
470
585
  end
@@ -482,7 +597,7 @@ module Doorkeeper
482
597
 
483
598
  ::Rails.logger.warn(
484
599
  "You have configured an invalid value for token_reuse_limit option. " \
485
- "It will be set to default 100"
600
+ "It will be set to default 100",
486
601
  )
487
602
  @token_reuse_limit = 100
488
603
  end
@@ -8,18 +8,6 @@ module Doorkeeper
8
8
  end
9
9
  end
10
10
 
11
- class InvalidAuthorizationStrategy < DoorkeeperError
12
- def type
13
- :unsupported_response_type
14
- end
15
- end
16
-
17
- class InvalidTokenReuse < DoorkeeperError
18
- def type
19
- :invalid_request
20
- end
21
- end
22
-
23
11
  class InvalidGrantReuse < DoorkeeperError
24
12
  def type
25
13
  :invalid_grant
@@ -32,7 +20,14 @@ module Doorkeeper
32
20
  end
33
21
  end
34
22
 
35
- class MissingRequestStrategy < DoorkeeperError
23
+ class MissingRequiredParameter < DoorkeeperError
24
+ attr_reader :missing_param
25
+
26
+ def initialize(missing_param)
27
+ super
28
+ @missing_param = missing_param
29
+ end
30
+
36
31
  def type
37
32
  :invalid_request
38
33
  end
@@ -50,10 +45,10 @@ module Doorkeeper
50
45
  TokenGeneratorNotFound = Class.new(DoorkeeperError)
51
46
  NoOrmCleaner = Class.new(DoorkeeperError)
52
47
 
53
- InvalidToken = Class.new BaseResponseError
54
- TokenExpired = Class.new InvalidToken
55
- TokenRevoked = Class.new InvalidToken
56
- TokenUnknown = Class.new InvalidToken
57
- TokenForbidden = Class.new InvalidToken
48
+ InvalidToken = Class.new(BaseResponseError)
49
+ TokenExpired = Class.new(InvalidToken)
50
+ TokenRevoked = Class.new(InvalidToken)
51
+ TokenUnknown = Class.new(InvalidToken)
52
+ TokenForbidden = Class.new(InvalidToken)
58
53
  end
59
54
  end
@@ -4,6 +4,8 @@ require "doorkeeper/grape/authorization_decorator"
4
4
 
5
5
  module Doorkeeper
6
6
  module Grape
7
+ # Doorkeeper helpers for Grape applications.
8
+ # Provides helpers for endpoints authorization based on defined set of scopes.
7
9
  module Helpers
8
10
  # These helpers are for grape >= 0.10
9
11
  extend ::Grape::API::Helpers
@@ -11,7 +13,9 @@ module Doorkeeper
11
13
 
12
14
  # endpoint specific scopes > parameter scopes > default scopes
13
15
  def doorkeeper_authorize!(*scopes)
14
- endpoint_scopes = endpoint.route_setting(:scopes) || endpoint.options[:route_options][:scopes]
16
+ endpoint_scopes = endpoint.route_setting(:scopes) ||
17
+ endpoint.options[:route_options][:scopes]
18
+
15
19
  scopes = if endpoint_scopes
16
20
  Doorkeeper::OAuth::Scopes.from_array(endpoint_scopes)
17
21
  elsif scopes && !scopes.empty?
@@ -35,7 +39,7 @@ module Doorkeeper
35
39
  def doorkeeper_token
36
40
  @doorkeeper_token ||= OAuth::Token.authenticate(
37
41
  decorated_request,
38
- *Doorkeeper.configuration.access_token_methods
42
+ *Doorkeeper.config.access_token_methods,
39
43
  )
40
44
  end
41
45
 
@@ -4,6 +4,8 @@
4
4
  # Doorkeeper::ApplicationMetalController or Doorkeeper::ApplicationController
5
5
  module Doorkeeper
6
6
  module Helpers
7
+ # Rails controller helpers.
8
+ #
7
9
  module Controller
8
10
  private
9
11
 
@@ -14,16 +16,18 @@ module Doorkeeper
14
16
 
15
17
  # :doc:
16
18
  def current_resource_owner
17
- instance_eval(&Doorkeeper.configuration.authenticate_resource_owner)
19
+ @current_resource_owner ||= begin
20
+ instance_eval(&Doorkeeper.config.authenticate_resource_owner)
21
+ end
18
22
  end
19
23
 
20
24
  def resource_owner_from_credentials
21
- instance_eval(&Doorkeeper.configuration.resource_owner_from_credentials)
25
+ instance_eval(&Doorkeeper.config.resource_owner_from_credentials)
22
26
  end
23
27
 
24
28
  # :doc:
25
29
  def authenticate_admin!
26
- instance_eval(&Doorkeeper.configuration.authenticate_admin)
30
+ instance_eval(&Doorkeeper.config.authenticate_admin)
27
31
  end
28
32
 
29
33
  def server
@@ -36,11 +40,21 @@ module Doorkeeper
36
40
  end
37
41
 
38
42
  def config_methods
39
- @config_methods ||= Doorkeeper.configuration.access_token_methods
43
+ @config_methods ||= Doorkeeper.config.access_token_methods
40
44
  end
41
45
 
42
46
  def get_error_response_from_exception(exception)
43
- OAuth::ErrorResponse.new name: exception.type, state: params[:state]
47
+ if exception.respond_to?(:response)
48
+ exception.response
49
+ elsif exception.type == :invalid_request
50
+ OAuth::InvalidRequestResponse.new(
51
+ name: exception.type,
52
+ state: params[:state],
53
+ missing_param: exception.missing_param,
54
+ )
55
+ else
56
+ OAuth::ErrorResponse.new(name: exception.type, state: params[:state])
57
+ end
44
58
  end
45
59
 
46
60
  def handle_token_exception(exception)
@@ -51,14 +65,21 @@ module Doorkeeper
51
65
  end
52
66
 
53
67
  def skip_authorization?
54
- !!instance_exec([@server.current_resource_owner, @pre_auth.client], &Doorkeeper.configuration.skip_authorization)
68
+ !!instance_exec(
69
+ [server.current_resource_owner, @pre_auth.client],
70
+ &Doorkeeper.config.skip_authorization
71
+ )
55
72
  end
56
73
 
57
74
  def enforce_content_type
58
- if (request.put? || request.post? || request.patch?) && request.content_type != "application/x-www-form-urlencoded"
75
+ if (request.put? || request.post? || request.patch?) && !x_www_form_urlencoded?
59
76
  render json: {}, status: :unsupported_media_type
60
77
  end
61
78
  end
79
+
80
+ def x_www_form_urlencoded?
81
+ request.content_type == "application/x-www-form-urlencoded"
82
+ end
62
83
  end
63
84
  end
64
85
  end
@@ -43,10 +43,11 @@ module Doorkeeper
43
43
  # instance of the Resource Owner model
44
44
  #
45
45
  def revoke_all_for(application_id, resource_owner, clock = Time)
46
- where(application_id: application_id,
47
- resource_owner_id: resource_owner.id,
48
- revoked_at: nil)
49
- .update_all(revoked_at: clock.now.utc)
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)
50
51
  end
51
52
 
52
53
  # Implements PKCE code_challenge encoding without base64 padding as described in the spec.
@@ -102,14 +103,14 @@ module Doorkeeper
102
103
  # Determines the secret storing transformer
103
104
  # Unless configured otherwise, uses the plain secret strategy
104
105
  def secret_strategy
105
- ::Doorkeeper.configuration.token_secret_strategy
106
+ ::Doorkeeper.config.token_secret_strategy
106
107
  end
107
108
 
108
109
  ##
109
110
  # Determine the fallback storing strategy
110
111
  # Unless configured, there will be no fallback
111
112
  def fallback_secret_strategy
112
- ::Doorkeeper.configuration.token_secret_fallback_strategy
113
+ ::Doorkeeper.config.token_secret_fallback_strategy
113
114
  end
114
115
  end
115
116
  end