doorkeeper 5.2.6 → 5.3.3
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.
- checksums.yaml +4 -4
- data/Appraisals +2 -2
- data/CHANGELOG.md +24 -5
- data/Gemfile +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +2 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
- data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
- data/gemfiles/rails_5_0.gemfile +2 -2
- data/gemfiles/rails_5_1.gemfile +2 -2
- data/gemfiles/rails_5_2.gemfile +2 -2
- data/gemfiles/rails_6_0.gemfile +2 -2
- data/gemfiles/rails_master.gemfile +2 -2
- data/lib/doorkeeper/config.rb +71 -38
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/helpers/controller.rb +10 -8
- data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
- data/lib/doorkeeper/models/access_token_mixin.rb +54 -16
- 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 +4 -4
- data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
- data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
- data/lib/doorkeeper/oauth/base_request.rb +8 -4
- data/lib/doorkeeper/oauth/client.rb +7 -8
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
- data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
- data/lib/doorkeeper/oauth/code_response.rb +2 -2
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +5 -5
- 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 +1 -1
- data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
- data/lib/doorkeeper/oauth/pre_authorization.rb +7 -5
- data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
- data/lib/doorkeeper/oauth/token.rb +2 -2
- data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
- 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 +3 -155
- 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 +187 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
- data/lib/doorkeeper/orm/active_record.rb +3 -3
- 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 +3 -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 +1 -1
- data/lib/doorkeeper/server.rb +1 -1
- data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
- data/lib/doorkeeper/version.rb +2 -2
- data/lib/doorkeeper.rb +2 -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 +2 -2
- data/lib/generators/doorkeeper/templates/initializer.rb +39 -0
- data/spec/controllers/application_metal_controller_spec.rb +1 -1
- data/spec/controllers/applications_controller_spec.rb +3 -2
- data/spec/controllers/authorizations_controller_spec.rb +18 -18
- data/spec/controllers/protected_resources_controller_spec.rb +25 -17
- data/spec/controllers/token_info_controller_spec.rb +1 -1
- data/spec/controllers/tokens_controller_spec.rb +1 -1
- 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 +62 -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 +127 -125
- data/spec/lib/oauth/base_request_spec.rb +160 -158
- 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 +42 -5
- 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 -34
- 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/invalid_request_response_spec.rb +48 -50
- 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 +159 -161
- data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
- data/spec/lib/oauth/scopes_spec.rb +104 -106
- data/spec/lib/oauth/token_request_spec.rb +115 -111
- data/spec/lib/oauth/token_response_spec.rb +71 -73
- data/spec/lib/oauth/token_spec.rb +121 -123
- data/spec/models/doorkeeper/access_grant_spec.rb +3 -5
- data/spec/models/doorkeeper/access_token_spec.rb +7 -7
- data/spec/models/doorkeeper/application_spec.rb +2 -2
- data/spec/requests/applications/applications_request_spec.rb +1 -1
- data/spec/requests/endpoints/authorization_spec.rb +5 -3
- data/spec/requests/flows/authorization_code_spec.rb +34 -22
- data/spec/requests/flows/client_credentials_spec.rb +1 -1
- data/spec/requests/flows/password_spec.rb +32 -12
- data/spec/requests/flows/refresh_token_spec.rb +19 -19
- data/spec/requests/flows/revoke_token_spec.rb +18 -12
- data/spec/spec_helper.rb +1 -4
- data/spec/support/shared/controllers_shared_context.rb +33 -23
- data/spec/validators/redirect_uri_validator_spec.rb +1 -1
- metadata +6 -5
- data/spec/support/http_method_shim.rb +0 -29
@@ -40,6 +40,21 @@ module Doorkeeper
|
|
40
40
|
find_by_plaintext_token(:refresh_token, refresh_token)
|
41
41
|
end
|
42
42
|
|
43
|
+
# Returns an instance of the Doorkeeper::AccessToken
|
44
|
+
# found by previous refresh token. Keep in mind that value
|
45
|
+
# of the previous_refresh_token isn't encrypted using
|
46
|
+
# secrets strategy.
|
47
|
+
#
|
48
|
+
# @param previous_refresh_token [#to_s]
|
49
|
+
# previous refresh token value (any object that responds to `#to_s`)
|
50
|
+
#
|
51
|
+
# @return [Doorkeeper::AccessToken, nil] AccessToken object or nil
|
52
|
+
# if there is no record with such refresh token
|
53
|
+
#
|
54
|
+
def by_previous_refresh_token(previous_refresh_token)
|
55
|
+
find_by(refresh_token: previous_refresh_token)
|
56
|
+
end
|
57
|
+
|
43
58
|
# Revokes AccessToken records that have not been revoked and associated
|
44
59
|
# with the specific Application and Resource Owner.
|
45
60
|
#
|
@@ -49,10 +64,11 @@ module Doorkeeper
|
|
49
64
|
# instance of the Resource Owner model
|
50
65
|
#
|
51
66
|
def revoke_all_for(application_id, resource_owner, clock = Time)
|
52
|
-
where(
|
53
|
-
|
54
|
-
|
55
|
-
|
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)
|
56
72
|
end
|
57
73
|
|
58
74
|
# Looking for not revoked Access Token with a matching set of scopes
|
@@ -143,8 +159,8 @@ module Doorkeeper
|
|
143
159
|
(token_scopes.sort == param_scopes.sort) &&
|
144
160
|
Doorkeeper::OAuth::Helpers::ScopeChecker.valid?(
|
145
161
|
scope_str: param_scopes.to_s,
|
146
|
-
server_scopes: Doorkeeper.
|
147
|
-
app_scopes: app_scopes
|
162
|
+
server_scopes: Doorkeeper.config.scopes,
|
163
|
+
app_scopes: app_scopes,
|
148
164
|
)
|
149
165
|
end
|
150
166
|
|
@@ -166,7 +182,7 @@ module Doorkeeper
|
|
166
182
|
# @return [Doorkeeper::AccessToken] existing record or a new one
|
167
183
|
#
|
168
184
|
def find_or_create_for(application, resource_owner_id, scopes, expires_in, use_refresh_token)
|
169
|
-
if Doorkeeper.
|
185
|
+
if Doorkeeper.config.reuse_access_token
|
170
186
|
access_token = matching_token_for(application, resource_owner_id, scopes)
|
171
187
|
|
172
188
|
return access_token if access_token&.reusable?
|
@@ -177,7 +193,7 @@ module Doorkeeper
|
|
177
193
|
resource_owner_id: resource_owner_id,
|
178
194
|
scopes: scopes.to_s,
|
179
195
|
expires_in: expires_in,
|
180
|
-
use_refresh_token: use_refresh_token
|
196
|
+
use_refresh_token: use_refresh_token,
|
181
197
|
)
|
182
198
|
end
|
183
199
|
|
@@ -192,9 +208,11 @@ module Doorkeeper
|
|
192
208
|
# @return [Doorkeeper::AccessToken] array of matching AccessToken objects
|
193
209
|
#
|
194
210
|
def authorized_tokens_for(application_id, resource_owner_id)
|
195
|
-
where(
|
196
|
-
|
197
|
-
|
211
|
+
where(
|
212
|
+
application_id: application_id,
|
213
|
+
resource_owner_id: resource_owner_id,
|
214
|
+
revoked_at: nil,
|
215
|
+
)
|
198
216
|
end
|
199
217
|
|
200
218
|
# Convenience method for backwards-compatibility, return the last
|
@@ -217,14 +235,14 @@ module Doorkeeper
|
|
217
235
|
# Determines the secret storing transformer
|
218
236
|
# Unless configured otherwise, uses the plain secret strategy
|
219
237
|
def secret_strategy
|
220
|
-
::Doorkeeper.
|
238
|
+
::Doorkeeper.config.token_secret_strategy
|
221
239
|
end
|
222
240
|
|
223
241
|
##
|
224
242
|
# Determine the fallback storing strategy
|
225
243
|
# Unless configured, there will be no fallback
|
226
244
|
def fallback_secret_strategy
|
227
|
-
::Doorkeeper.
|
245
|
+
::Doorkeeper.config.token_secret_fallback_strategy
|
228
246
|
end
|
229
247
|
end
|
230
248
|
|
@@ -301,8 +319,28 @@ module Doorkeeper
|
|
301
319
|
end
|
302
320
|
end
|
303
321
|
|
322
|
+
# Revokes token with `:refresh_token` equal to `:previous_refresh_token`
|
323
|
+
# and clears `:previous_refresh_token` attribute.
|
324
|
+
#
|
325
|
+
def revoke_previous_refresh_token!
|
326
|
+
return unless self.class.refresh_token_revoked_on_use?
|
327
|
+
|
328
|
+
old_refresh_token&.revoke
|
329
|
+
update_attribute :previous_refresh_token, ""
|
330
|
+
end
|
331
|
+
|
304
332
|
private
|
305
333
|
|
334
|
+
# Searches for Access Token record with `:refresh_token` equal to
|
335
|
+
# `:previous_refresh_token` value.
|
336
|
+
#
|
337
|
+
# @return [Doorkeeper::AccessToken, nil]
|
338
|
+
# Access Token record or nil if nothing found
|
339
|
+
#
|
340
|
+
def old_refresh_token
|
341
|
+
@old_refresh_token ||= self.class.by_previous_refresh_token(previous_refresh_token)
|
342
|
+
end
|
343
|
+
|
306
344
|
# Generates refresh token with UniqueToken generator.
|
307
345
|
#
|
308
346
|
# @return [String] refresh token value
|
@@ -313,7 +351,7 @@ module Doorkeeper
|
|
313
351
|
end
|
314
352
|
|
315
353
|
# Generates and sets the token value with the
|
316
|
-
# configured Generator class (see Doorkeeper.
|
354
|
+
# configured Generator class (see Doorkeeper.config).
|
317
355
|
#
|
318
356
|
# @return [String] generated token value
|
319
357
|
#
|
@@ -330,7 +368,7 @@ module Doorkeeper
|
|
330
368
|
scopes: scopes,
|
331
369
|
application: application,
|
332
370
|
expires_in: expires_in,
|
333
|
-
created_at: created_at
|
371
|
+
created_at: created_at,
|
334
372
|
)
|
335
373
|
|
336
374
|
secret_strategy.store_secret(self, :token, @raw_token)
|
@@ -338,7 +376,7 @@ module Doorkeeper
|
|
338
376
|
end
|
339
377
|
|
340
378
|
def token_generator
|
341
|
-
generator_name = Doorkeeper.
|
379
|
+
generator_name = Doorkeeper.config.access_token_generator
|
342
380
|
generator = generator_name.constantize
|
343
381
|
|
344
382
|
return generator if generator.respond_to?(:generate)
|
@@ -47,14 +47,14 @@ module Doorkeeper
|
|
47
47
|
# Determines the secret storing transformer
|
48
48
|
# Unless configured otherwise, uses the plain secret strategy
|
49
49
|
def secret_strategy
|
50
|
-
::Doorkeeper.
|
50
|
+
::Doorkeeper.config.application_secret_strategy
|
51
51
|
end
|
52
52
|
|
53
53
|
##
|
54
54
|
# Determine the fallback storing strategy
|
55
55
|
# Unless configured, there will be no fallback
|
56
56
|
def fallback_secret_strategy
|
57
|
-
::Doorkeeper.
|
57
|
+
::Doorkeeper.config.application_secret_fallback_strategy
|
58
58
|
end
|
59
59
|
end
|
60
60
|
|
@@ -72,7 +72,7 @@ module Doorkeeper
|
|
72
72
|
# @param input [#to_s] Plain secret provided by user
|
73
73
|
# (any object that responds to `#to_s`)
|
74
74
|
#
|
75
|
-
# @return [
|
75
|
+
# @return [Boolean] Whether the given secret matches the stored secret
|
76
76
|
# of this application.
|
77
77
|
#
|
78
78
|
def secret_matches?(input)
|
@@ -11,7 +11,7 @@ module Doorkeeper
|
|
11
11
|
return false if expired?
|
12
12
|
return true unless expires_in
|
13
13
|
|
14
|
-
threshold_limit = 100 - Doorkeeper.
|
14
|
+
threshold_limit = 100 - Doorkeeper.config.token_reuse_limit
|
15
15
|
expires_in_seconds >= threshold_limit * expires_in / 100
|
16
16
|
end
|
17
17
|
end
|
@@ -19,33 +19,6 @@ module Doorkeeper
|
|
19
19
|
def revoked?
|
20
20
|
!!(revoked_at && revoked_at <= Time.now.utc)
|
21
21
|
end
|
22
|
-
|
23
|
-
# Revokes token with `:refresh_token` equal to `:previous_refresh_token`
|
24
|
-
# and clears `:previous_refresh_token` attribute.
|
25
|
-
#
|
26
|
-
def revoke_previous_refresh_token!
|
27
|
-
return unless refresh_token_revoked_on_use?
|
28
|
-
|
29
|
-
old_refresh_token&.revoke
|
30
|
-
update_attribute :previous_refresh_token, ""
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
# Searches for Access Token record with `:refresh_token` equal to
|
36
|
-
# `:previous_refresh_token` value.
|
37
|
-
#
|
38
|
-
# @return [Doorkeeper::AccessToken, nil]
|
39
|
-
# Access Token record or nil if nothing found
|
40
|
-
#
|
41
|
-
def old_refresh_token
|
42
|
-
@old_refresh_token ||=
|
43
|
-
AccessToken.by_refresh_token(previous_refresh_token)
|
44
|
-
end
|
45
|
-
|
46
|
-
def refresh_token_revoked_on_use?
|
47
|
-
AccessToken.refresh_token_revoked_on_use?
|
48
|
-
end
|
49
22
|
end
|
50
23
|
end
|
51
24
|
end
|
@@ -12,7 +12,7 @@ module Doorkeeper
|
|
12
12
|
end
|
13
13
|
|
14
14
|
def issue_token
|
15
|
-
@token ||=
|
15
|
+
@token ||= Doorkeeper.config.access_grant_model.create!(access_grant_attributes)
|
16
16
|
end
|
17
17
|
|
18
18
|
def oob_redirect
|
@@ -22,7 +22,7 @@ module Doorkeeper
|
|
22
22
|
private
|
23
23
|
|
24
24
|
def authorization_code_expires_in
|
25
|
-
Doorkeeper.
|
25
|
+
Doorkeeper.config.authorization_code_expires_in
|
26
26
|
end
|
27
27
|
|
28
28
|
def access_grant_attributes
|
@@ -31,7 +31,7 @@ module Doorkeeper
|
|
31
31
|
resource_owner_id: resource_owner.id,
|
32
32
|
expires_in: authorization_code_expires_in,
|
33
33
|
redirect_uri: pre_auth.redirect_uri,
|
34
|
-
scopes: pre_auth.scopes.to_s
|
34
|
+
scopes: pre_auth.scopes.to_s,
|
35
35
|
)
|
36
36
|
end
|
37
37
|
|
@@ -47,7 +47,7 @@ module Doorkeeper
|
|
47
47
|
# Ensures firstly, if migration with additional PKCE columns was
|
48
48
|
# generated and migrated
|
49
49
|
def pkce_supported?
|
50
|
-
Doorkeeper
|
50
|
+
Doorkeeper.config.access_grant_model.pkce_supported?
|
51
51
|
end
|
52
52
|
end
|
53
53
|
end
|
@@ -19,7 +19,7 @@ module Doorkeeper
|
|
19
19
|
Doorkeeper::OAuth::Authorization::Context.new(
|
20
20
|
oauth_client,
|
21
21
|
grant_type,
|
22
|
-
scopes
|
22
|
+
scopes,
|
23
23
|
)
|
24
24
|
end
|
25
25
|
|
@@ -35,7 +35,7 @@ module Doorkeeper
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def refresh_token_enabled?(server, context)
|
38
|
-
if server.refresh_token_enabled?.respond_to?
|
38
|
+
if server.refresh_token_enabled?.respond_to?(:call)
|
39
39
|
server.refresh_token_enabled?.call(context)
|
40
40
|
else
|
41
41
|
!!server.refresh_token_enabled?
|
@@ -49,17 +49,20 @@ module Doorkeeper
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def issue_token
|
52
|
+
return @token if defined?(@token)
|
53
|
+
|
52
54
|
context = self.class.build_context(
|
53
55
|
pre_auth.client,
|
54
56
|
Doorkeeper::OAuth::IMPLICIT,
|
55
|
-
pre_auth.scopes
|
57
|
+
pre_auth.scopes,
|
56
58
|
)
|
57
|
-
|
59
|
+
|
60
|
+
@token = configuration.access_token_model.find_or_create_for(
|
58
61
|
pre_auth.client,
|
59
62
|
resource_owner.id,
|
60
63
|
pre_auth.scopes,
|
61
64
|
self.class.access_token_expires_in(configuration, context),
|
62
|
-
false
|
65
|
+
false,
|
63
66
|
)
|
64
67
|
end
|
65
68
|
|
@@ -74,7 +77,7 @@ module Doorkeeper
|
|
74
77
|
private
|
75
78
|
|
76
79
|
def configuration
|
77
|
-
Doorkeeper.
|
80
|
+
Doorkeeper.config
|
78
81
|
end
|
79
82
|
|
80
83
|
def controller
|
@@ -32,10 +32,13 @@ module Doorkeeper
|
|
32
32
|
raise Errors::InvalidGrantReuse if grant.revoked?
|
33
33
|
|
34
34
|
grant.revoke
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
35
|
+
|
36
|
+
find_or_create_access_token(
|
37
|
+
grant.application,
|
38
|
+
grant.resource_owner_id,
|
39
|
+
grant.scopes,
|
40
|
+
server,
|
41
|
+
)
|
39
42
|
end
|
40
43
|
super
|
41
44
|
end
|
@@ -71,7 +74,7 @@ module Doorkeeper
|
|
71
74
|
def validate_redirect_uri
|
72
75
|
Helpers::URIChecker.valid_for_authorization?(
|
73
76
|
redirect_uri,
|
74
|
-
grant.redirect_uri
|
77
|
+
grant.redirect_uri,
|
75
78
|
)
|
76
79
|
end
|
77
80
|
|
@@ -82,13 +85,17 @@ module Doorkeeper
|
|
82
85
|
return false unless grant.pkce_supported?
|
83
86
|
|
84
87
|
if grant.code_challenge_method == "S256"
|
85
|
-
grant.code_challenge ==
|
88
|
+
grant.code_challenge == generate_code_challenge(code_verifier)
|
86
89
|
elsif grant.code_challenge_method == "plain"
|
87
90
|
grant.code_challenge == code_verifier
|
88
91
|
else
|
89
92
|
false
|
90
93
|
end
|
91
94
|
end
|
95
|
+
|
96
|
+
def generate_code_challenge(code_verifier)
|
97
|
+
server_config.access_grant_model.generate_code_challenge(code_verifier)
|
98
|
+
end
|
92
99
|
end
|
93
100
|
end
|
94
101
|
end
|
@@ -36,21 +36,25 @@ module Doorkeeper
|
|
36
36
|
|
37
37
|
def find_or_create_access_token(client, resource_owner_id, scopes, server)
|
38
38
|
context = Authorization::Token.build_context(client, grant_type, scopes)
|
39
|
-
@access_token =
|
39
|
+
@access_token = server_config.access_token_model.find_or_create_for(
|
40
40
|
client,
|
41
41
|
resource_owner_id,
|
42
42
|
scopes,
|
43
43
|
Authorization::Token.access_token_expires_in(server, context),
|
44
|
-
Authorization::Token.refresh_token_enabled?(server, context)
|
44
|
+
Authorization::Token.refresh_token_enabled?(server, context),
|
45
45
|
)
|
46
46
|
end
|
47
47
|
|
48
48
|
def before_successful_response
|
49
|
-
|
49
|
+
server_config.before_successful_strategy_response.call(self)
|
50
50
|
end
|
51
51
|
|
52
52
|
def after_successful_response
|
53
|
-
|
53
|
+
server_config.after_successful_strategy_response.call(self, @response)
|
54
|
+
end
|
55
|
+
|
56
|
+
def server_config
|
57
|
+
Doorkeeper.config
|
54
58
|
end
|
55
59
|
|
56
60
|
private
|
@@ -11,18 +11,17 @@ module Doorkeeper
|
|
11
11
|
@application = application
|
12
12
|
end
|
13
13
|
|
14
|
-
def self.find(uid, method =
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def self.find(uid, method = Doorkeeper.config.application_model.method(:by_uid))
|
15
|
+
return unless (application = method.call(uid))
|
16
|
+
|
17
|
+
new(application)
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.authenticate(credentials, method =
|
20
|
+
def self.authenticate(credentials, method = Doorkeeper.config.application_model.method(:by_uid_and_secret))
|
21
21
|
return if credentials.blank?
|
22
|
+
return unless (application = method.call(credentials.uid, credentials.secret))
|
22
23
|
|
23
|
-
|
24
|
-
new(application)
|
25
|
-
end
|
24
|
+
new(application)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -5,24 +5,31 @@ module Doorkeeper
|
|
5
5
|
class ClientCredentialsRequest < BaseRequest
|
6
6
|
class Creator
|
7
7
|
def call(client, scopes, attributes = {})
|
8
|
-
|
8
|
+
if lookup_existing_token?
|
9
|
+
existing_token = find_existing_token_for(client, scopes)
|
10
|
+
return existing_token if server_config.reuse_access_token && existing_token&.reusable?
|
9
11
|
|
10
|
-
|
11
|
-
return existing_token
|
12
|
+
existing_token&.revoke if server_config.revoke_previous_client_credentials_token
|
12
13
|
end
|
13
14
|
|
14
|
-
|
15
|
-
|
16
|
-
AccessToken.find_or_create_for(
|
15
|
+
server_config.access_token_model.find_or_create_for(
|
17
16
|
client, nil, scopes, attributes[:expires_in],
|
18
|
-
attributes[:use_refresh_token]
|
17
|
+
attributes[:use_refresh_token],
|
19
18
|
)
|
20
19
|
end
|
21
20
|
|
22
21
|
private
|
23
22
|
|
24
|
-
def
|
25
|
-
|
23
|
+
def lookup_existing_token?
|
24
|
+
server_config.reuse_access_token || server_config.revoke_previous_client_credentials_token
|
25
|
+
end
|
26
|
+
|
27
|
+
def find_existing_token_for(client, scopes)
|
28
|
+
server_config.access_token_model.matching_token_for(client, nil, scopes)
|
29
|
+
end
|
30
|
+
|
31
|
+
def server_config
|
32
|
+
Doorkeeper.config
|
26
33
|
end
|
27
34
|
end
|
28
35
|
end
|
@@ -4,20 +4,20 @@ module Doorkeeper
|
|
4
4
|
module OAuth
|
5
5
|
class ClientCredentialsRequest < BaseRequest
|
6
6
|
class Issuer
|
7
|
-
attr_accessor :token, :
|
7
|
+
attr_accessor :token, :validator, :error
|
8
8
|
|
9
|
-
def initialize(server,
|
9
|
+
def initialize(server, validator)
|
10
10
|
@server = server
|
11
|
-
@
|
11
|
+
@validator = validator
|
12
12
|
end
|
13
13
|
|
14
14
|
def create(client, scopes, creator = Creator.new)
|
15
|
-
if
|
15
|
+
if validator.valid?
|
16
16
|
@token = create_token(client, scopes, creator)
|
17
17
|
@error = :server_error unless @token
|
18
18
|
else
|
19
19
|
@token = false
|
20
|
-
@error =
|
20
|
+
@error = validator.error
|
21
21
|
end
|
22
22
|
@token
|
23
23
|
end
|
@@ -28,7 +28,7 @@ module Doorkeeper
|
|
28
28
|
context = Authorization::Token.build_context(
|
29
29
|
client,
|
30
30
|
Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
31
|
-
scopes
|
31
|
+
scopes,
|
32
32
|
)
|
33
33
|
ttl = Authorization::Token.access_token_expires_in(@server, context)
|
34
34
|
|
@@ -36,7 +36,7 @@ module Doorkeeper
|
|
36
36
|
client,
|
37
37
|
scopes,
|
38
38
|
use_refresh_token: false,
|
39
|
-
expires_in: ttl
|
39
|
+
expires_in: ttl,
|
40
40
|
)
|
41
41
|
end
|
42
42
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class ClientCredentialsRequest < BaseRequest
|
6
|
-
class
|
6
|
+
class Validator
|
7
7
|
include Validations
|
8
8
|
include OAuth::Helpers
|
9
9
|
|
@@ -26,9 +26,9 @@ module Doorkeeper
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def validate_client_supports_grant_flow
|
29
|
-
Doorkeeper.
|
29
|
+
Doorkeeper.config.allow_grant_flow_for_client?(
|
30
30
|
Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
31
|
-
@client
|
31
|
+
@client,
|
32
32
|
)
|
33
33
|
end
|
34
34
|
|
@@ -45,7 +45,7 @@ module Doorkeeper
|
|
45
45
|
scope_str: @request.scopes.to_s,
|
46
46
|
server_scopes: @server.scopes,
|
47
47
|
app_scopes: application_scopes,
|
48
|
-
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS
|
48
|
+
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
49
49
|
)
|
50
50
|
end
|
51
51
|
end
|
@@ -26,13 +26,13 @@ module Doorkeeper
|
|
26
26
|
access_token: auth.token.plaintext_token,
|
27
27
|
token_type: auth.token.token_type,
|
28
28
|
expires_in: auth.token.expires_in_seconds,
|
29
|
-
state: pre_auth.state
|
29
|
+
state: pre_auth.state,
|
30
30
|
)
|
31
31
|
else
|
32
32
|
Authorization::URIBuilder.uri_with_query(
|
33
33
|
pre_auth.redirect_uri,
|
34
34
|
code: auth.token.plaintext_token,
|
35
|
-
state: pre_auth.state
|
35
|
+
state: pre_auth.state,
|
36
36
|
)
|
37
37
|
end
|
38
38
|
end
|
@@ -10,8 +10,8 @@ module Doorkeeper
|
|
10
10
|
attributes.merge(
|
11
11
|
name: request.error,
|
12
12
|
state: request.try(:state),
|
13
|
-
redirect_uri: request.try(:redirect_uri)
|
14
|
-
)
|
13
|
+
redirect_uri: request.try(:redirect_uri),
|
14
|
+
),
|
15
15
|
)
|
16
16
|
end
|
17
17
|
|
@@ -46,9 +46,9 @@ module Doorkeeper
|
|
46
46
|
|
47
47
|
def redirect_uri
|
48
48
|
if @response_on_fragment
|
49
|
-
Authorization::URIBuilder.uri_with_fragment
|
49
|
+
Authorization::URIBuilder.uri_with_fragment(@redirect_uri, body)
|
50
50
|
else
|
51
|
-
Authorization::URIBuilder.uri_with_query
|
51
|
+
Authorization::URIBuilder.uri_with_query(@redirect_uri, body)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
|
@@ -70,7 +70,7 @@ module Doorkeeper
|
|
70
70
|
delegate :realm, to: :configuration
|
71
71
|
|
72
72
|
def configuration
|
73
|
-
Doorkeeper.
|
73
|
+
Doorkeeper.config
|
74
74
|
end
|
75
75
|
|
76
76
|
def exception_class
|
@@ -13,7 +13,7 @@ module Doorkeeper
|
|
13
13
|
@valid_scopes = valid_scopes(server_scopes, app_scopes)
|
14
14
|
|
15
15
|
if grant_type
|
16
|
-
@scopes_by_grant_type = Doorkeeper.
|
16
|
+
@scopes_by_grant_type = Doorkeeper.config.scopes_by_grant_type[grant_type.to_sym]
|
17
17
|
end
|
18
18
|
end
|
19
19
|
|
@@ -43,10 +43,12 @@ module Doorkeeper
|
|
43
43
|
end
|
44
44
|
|
45
45
|
def self.valid?(scope_str:, server_scopes:, app_scopes: nil, grant_type: nil)
|
46
|
-
Validator.new(
|
47
|
-
|
48
|
-
|
49
|
-
|
46
|
+
Validator.new(
|
47
|
+
scope_str,
|
48
|
+
server_scopes,
|
49
|
+
app_scopes,
|
50
|
+
grant_type,
|
51
|
+
).valid?
|
50
52
|
end
|
51
53
|
end
|
52
54
|
end
|
@@ -3,6 +3,9 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
module Helpers
|
6
|
+
# Default Doorkeeper token generator. Follows OAuth RFC and
|
7
|
+
# could be customized using `default_generator_method` in
|
8
|
+
# configuration.
|
6
9
|
module UniqueToken
|
7
10
|
def self.generate(options = {})
|
8
11
|
# Access Token value must be 1*VSCHAR or
|
@@ -11,15 +14,15 @@ module Doorkeeper
|
|
11
14
|
# @see https://tools.ietf.org/html/rfc6749#appendix-A.12
|
12
15
|
# @see https://tools.ietf.org/html/rfc6750#section-2.1
|
13
16
|
#
|
14
|
-
|
15
|
-
token_size
|
16
|
-
|
17
|
+
generator = options.delete(:generator) || SecureRandom.method(default_generator_method)
|
18
|
+
token_size = options.delete(:size) || 32
|
19
|
+
generator.call(token_size)
|
17
20
|
end
|
18
21
|
|
19
22
|
# Generator method for default generator class (SecureRandom)
|
20
23
|
#
|
21
|
-
def self.
|
22
|
-
Doorkeeper.
|
24
|
+
def self.default_generator_method
|
25
|
+
Doorkeeper.config.default_generator_method
|
23
26
|
end
|
24
27
|
end
|
25
28
|
end
|