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.
- checksums.yaml +4 -4
- data/Appraisals +3 -3
- data/CHANGELOG.md +881 -0
- data/CONTRIBUTING.md +11 -9
- data/Dangerfile +2 -2
- data/Dockerfile +29 -0
- data/Gemfile +4 -3
- data/NEWS.md +1 -814
- data/README.md +11 -3
- data/RELEASING.md +6 -5
- data/app/controllers/doorkeeper/application_controller.rb +2 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
- data/app/controllers/doorkeeper/applications_controller.rb +1 -0
- data/app/controllers/doorkeeper/authorizations_controller.rb +16 -9
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +32 -9
- data/app/views/doorkeeper/applications/_form.html.erb +0 -6
- data/app/views/doorkeeper/applications/show.html.erb +1 -1
- data/config/locales/en.yml +8 -2
- data/doorkeeper.gemspec +9 -1
- data/gemfiles/rails_5_0.gemfile +3 -2
- data/gemfiles/rails_5_1.gemfile +3 -2
- data/gemfiles/rails_5_2.gemfile +3 -2
- data/gemfiles/rails_6_0.gemfile +4 -3
- data/gemfiles/rails_master.gemfile +3 -2
- data/lib/doorkeeper/config/option.rb +13 -7
- data/lib/doorkeeper/config.rb +157 -42
- data/lib/doorkeeper/errors.rb +13 -18
- data/lib/doorkeeper/grape/helpers.rb +6 -2
- data/lib/doorkeeper/helpers/controller.rb +28 -7
- data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +99 -20
- data/lib/doorkeeper/models/application_mixin.rb +3 -3
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
- data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
- data/lib/doorkeeper/oauth/authorization/code.rb +12 -14
- data/lib/doorkeeper/oauth/authorization/token.rb +10 -7
- data/lib/doorkeeper/oauth/authorization_code_request.rb +31 -15
- data/lib/doorkeeper/oauth/base_request.rb +10 -4
- data/lib/doorkeeper/oauth/client.rb +7 -8
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +23 -2
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +10 -2
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_request.rb +5 -11
- data/lib/doorkeeper/oauth/code_response.rb +4 -4
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +6 -6
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -5
- data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +9 -4
- data/lib/doorkeeper/oauth/pre_authorization.rb +76 -38
- data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -14
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +26 -16
- data/lib/doorkeeper/oauth/token_request.rb +4 -18
- data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
- data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
- data/lib/doorkeeper/orm/active_record/application.rb +5 -83
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
- data/lib/doorkeeper/orm/active_record.rb +21 -6
- data/lib/doorkeeper/rails/helpers.rb +4 -4
- data/lib/doorkeeper/rails/routes.rb +5 -7
- data/lib/doorkeeper/rake/db.rake +3 -3
- data/lib/doorkeeper/request/authorization_code.rb +5 -3
- data/lib/doorkeeper/request/client_credentials.rb +2 -2
- data/lib/doorkeeper/request/password.rb +2 -2
- data/lib/doorkeeper/request/refresh_token.rb +3 -3
- data/lib/doorkeeper/request.rb +7 -12
- data/lib/doorkeeper/server.rb +3 -7
- data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +6 -3
- data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
- data/lib/generators/doorkeeper/migration_generator.rb +1 -1
- data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
- data/lib/generators/doorkeeper/templates/initializer.rb +149 -33
- data/lib/generators/doorkeeper/templates/migration.rb.erb +4 -1
- data/spec/controllers/application_metal_controller_spec.rb +1 -1
- data/spec/controllers/applications_controller_spec.rb +95 -1
- data/spec/controllers/authorizations_controller_spec.rb +156 -75
- data/spec/controllers/protected_resources_controller_spec.rb +28 -20
- data/spec/controllers/token_info_controller_spec.rb +1 -1
- data/spec/controllers/tokens_controller_spec.rb +206 -38
- data/spec/dummy/config/application.rb +3 -1
- data/spec/dummy/config/initializers/doorkeeper.rb +54 -9
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
- data/spec/generators/install_generator_spec.rb +1 -1
- data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
- data/spec/lib/config_spec.rb +104 -7
- data/spec/lib/doorkeeper_spec.rb +1 -1
- data/spec/lib/models/revocable_spec.rb +3 -3
- data/spec/lib/oauth/authorization_code_request_spec.rb +129 -115
- data/spec/lib/oauth/base_request_spec.rb +154 -135
- data/spec/lib/oauth/base_response_spec.rb +27 -29
- data/spec/lib/oauth/client/credentials_spec.rb +1 -1
- data/spec/lib/oauth/client_credentials/creator_spec.rb +43 -3
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
- data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
- data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
- data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
- data/spec/lib/oauth/client_spec.rb +26 -26
- data/spec/lib/oauth/code_request_spec.rb +34 -35
- data/spec/lib/oauth/code_response_spec.rb +21 -25
- data/spec/lib/oauth/error_response_spec.rb +42 -44
- data/spec/lib/oauth/error_spec.rb +12 -14
- data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +17 -2
- data/spec/lib/oauth/invalid_request_response_spec.rb +73 -0
- data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
- data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
- data/spec/lib/oauth/pre_authorization_spec.rb +161 -153
- data/spec/lib/oauth/refresh_token_request_spec.rb +138 -138
- data/spec/lib/oauth/scopes_spec.rb +104 -106
- data/spec/lib/oauth/token_request_spec.rb +117 -110
- data/spec/lib/oauth/token_response_spec.rb +71 -73
- data/spec/lib/oauth/token_spec.rb +121 -123
- data/spec/lib/server_spec.rb +0 -12
- data/spec/models/doorkeeper/access_grant_spec.rb +21 -4
- data/spec/models/doorkeeper/access_token_spec.rb +42 -11
- data/spec/models/doorkeeper/application_spec.rb +114 -77
- data/spec/requests/applications/applications_request_spec.rb +1 -1
- data/spec/requests/endpoints/authorization_spec.rb +26 -8
- data/spec/requests/endpoints/token_spec.rb +1 -1
- data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
- data/spec/requests/flows/authorization_code_spec.rb +123 -45
- data/spec/requests/flows/client_credentials_spec.rb +38 -0
- data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
- data/spec/requests/flows/implicit_grant_spec.rb +9 -8
- data/spec/requests/flows/password_spec.rb +67 -10
- data/spec/requests/flows/refresh_token_spec.rb +20 -20
- data/spec/requests/flows/revoke_token_spec.rb +37 -23
- data/spec/spec_helper.rb +1 -4
- data/spec/support/doorkeeper_rspec.rb +1 -1
- data/spec/support/helpers/request_spec_helper.rb +14 -2
- data/spec/support/shared/controllers_shared_context.rb +33 -23
- data/spec/validators/redirect_uri_validator_spec.rb +41 -16
- metadata +19 -16
- data/.coveralls.yml +0 -1
- data/.github/ISSUE_TEMPLATE.md +0 -25
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
- data/.gitignore +0 -20
- data/.gitlab-ci.yml +0 -16
- data/.hound.yml +0 -3
- data/.rspec +0 -1
- data/.rubocop.yml +0 -50
- data/.travis.yml +0 -35
- data/app/validators/redirect_uri_validator.rb +0 -50
- data/spec/support/http_method_shim.rb +0 -29
data/lib/doorkeeper/config.rb
CHANGED
|
@@ -11,36 +11,40 @@ module Doorkeeper
|
|
|
11
11
|
end
|
|
12
12
|
end
|
|
13
13
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
def configuration
|
|
24
|
+
@config || (raise MissingConfiguration)
|
|
25
|
+
end
|
|
25
26
|
|
|
26
|
-
|
|
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
|
-
|
|
34
|
-
doorkeeper.
|
|
35
|
-
|
|
36
|
-
|
|
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
|
-
|
|
39
|
-
|
|
40
|
-
|
|
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
|
-
|
|
43
|
-
|
|
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://
|
|
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://
|
|
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:
|
|
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
|
-
|
|
325
|
-
|
|
326
|
-
|
|
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
|
data/lib/doorkeeper/errors.rb
CHANGED
|
@@ -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
|
|
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
|
|
54
|
-
TokenExpired = Class.new
|
|
55
|
-
TokenRevoked = Class.new
|
|
56
|
-
TokenUnknown = Class.new
|
|
57
|
-
TokenForbidden = Class.new
|
|
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) ||
|
|
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.
|
|
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
|
-
|
|
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.
|
|
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.
|
|
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.
|
|
43
|
+
@config_methods ||= Doorkeeper.config.access_token_methods
|
|
40
44
|
end
|
|
41
45
|
|
|
42
46
|
def get_error_response_from_exception(exception)
|
|
43
|
-
|
|
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(
|
|
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?) &&
|
|
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(
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
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.
|
|
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.
|
|
113
|
+
::Doorkeeper.config.token_secret_fallback_strategy
|
|
113
114
|
end
|
|
114
115
|
end
|
|
115
116
|
end
|