doorkeeper 5.2.4 → 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 +2 -2
- data/CHANGELOG.md +18 -3
- 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 -39
- 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 +55 -18
- 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 -95
- 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 +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 -8
- 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 +61 -21
- 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 +104 -77
- 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
|
|
@@ -110,9 +126,8 @@ module Doorkeeper
|
|
|
110
126
|
return nil unless relation
|
|
111
127
|
|
|
112
128
|
matching_tokens = []
|
|
113
|
-
batch_size = Doorkeeper.configuration.token_lookup_batch_size
|
|
114
129
|
|
|
115
|
-
find_access_token_in_batches(relation
|
|
130
|
+
find_access_token_in_batches(relation) do |batch|
|
|
116
131
|
tokens = batch.select do |token|
|
|
117
132
|
scopes_match?(token.scopes, scopes, application.try(:scopes))
|
|
118
133
|
end
|
|
@@ -143,8 +158,8 @@ module Doorkeeper
|
|
|
143
158
|
(token_scopes.sort == param_scopes.sort) &&
|
|
144
159
|
Doorkeeper::OAuth::Helpers::ScopeChecker.valid?(
|
|
145
160
|
scope_str: param_scopes.to_s,
|
|
146
|
-
server_scopes: Doorkeeper.
|
|
147
|
-
app_scopes: app_scopes
|
|
161
|
+
server_scopes: Doorkeeper.config.scopes,
|
|
162
|
+
app_scopes: app_scopes,
|
|
148
163
|
)
|
|
149
164
|
end
|
|
150
165
|
|
|
@@ -166,7 +181,7 @@ module Doorkeeper
|
|
|
166
181
|
# @return [Doorkeeper::AccessToken] existing record or a new one
|
|
167
182
|
#
|
|
168
183
|
def find_or_create_for(application, resource_owner_id, scopes, expires_in, use_refresh_token)
|
|
169
|
-
if Doorkeeper.
|
|
184
|
+
if Doorkeeper.config.reuse_access_token
|
|
170
185
|
access_token = matching_token_for(application, resource_owner_id, scopes)
|
|
171
186
|
|
|
172
187
|
return access_token if access_token&.reusable?
|
|
@@ -177,7 +192,7 @@ module Doorkeeper
|
|
|
177
192
|
resource_owner_id: resource_owner_id,
|
|
178
193
|
scopes: scopes.to_s,
|
|
179
194
|
expires_in: expires_in,
|
|
180
|
-
use_refresh_token: use_refresh_token
|
|
195
|
+
use_refresh_token: use_refresh_token,
|
|
181
196
|
)
|
|
182
197
|
end
|
|
183
198
|
|
|
@@ -192,9 +207,11 @@ module Doorkeeper
|
|
|
192
207
|
# @return [Doorkeeper::AccessToken] array of matching AccessToken objects
|
|
193
208
|
#
|
|
194
209
|
def authorized_tokens_for(application_id, resource_owner_id)
|
|
195
|
-
where(
|
|
196
|
-
|
|
197
|
-
|
|
210
|
+
where(
|
|
211
|
+
application_id: application_id,
|
|
212
|
+
resource_owner_id: resource_owner_id,
|
|
213
|
+
revoked_at: nil,
|
|
214
|
+
)
|
|
198
215
|
end
|
|
199
216
|
|
|
200
217
|
# Convenience method for backwards-compatibility, return the last
|
|
@@ -217,14 +234,14 @@ module Doorkeeper
|
|
|
217
234
|
# Determines the secret storing transformer
|
|
218
235
|
# Unless configured otherwise, uses the plain secret strategy
|
|
219
236
|
def secret_strategy
|
|
220
|
-
::Doorkeeper.
|
|
237
|
+
::Doorkeeper.config.token_secret_strategy
|
|
221
238
|
end
|
|
222
239
|
|
|
223
240
|
##
|
|
224
241
|
# Determine the fallback storing strategy
|
|
225
242
|
# Unless configured, there will be no fallback
|
|
226
243
|
def fallback_secret_strategy
|
|
227
|
-
::Doorkeeper.
|
|
244
|
+
::Doorkeeper.config.token_secret_fallback_strategy
|
|
228
245
|
end
|
|
229
246
|
end
|
|
230
247
|
|
|
@@ -301,8 +318,28 @@ module Doorkeeper
|
|
|
301
318
|
end
|
|
302
319
|
end
|
|
303
320
|
|
|
321
|
+
# Revokes token with `:refresh_token` equal to `:previous_refresh_token`
|
|
322
|
+
# and clears `:previous_refresh_token` attribute.
|
|
323
|
+
#
|
|
324
|
+
def revoke_previous_refresh_token!
|
|
325
|
+
return unless self.class.refresh_token_revoked_on_use?
|
|
326
|
+
|
|
327
|
+
old_refresh_token&.revoke
|
|
328
|
+
update_attribute :previous_refresh_token, ""
|
|
329
|
+
end
|
|
330
|
+
|
|
304
331
|
private
|
|
305
332
|
|
|
333
|
+
# Searches for Access Token record with `:refresh_token` equal to
|
|
334
|
+
# `:previous_refresh_token` value.
|
|
335
|
+
#
|
|
336
|
+
# @return [Doorkeeper::AccessToken, nil]
|
|
337
|
+
# Access Token record or nil if nothing found
|
|
338
|
+
#
|
|
339
|
+
def old_refresh_token
|
|
340
|
+
@old_refresh_token ||= self.class.by_previous_refresh_token(previous_refresh_token)
|
|
341
|
+
end
|
|
342
|
+
|
|
306
343
|
# Generates refresh token with UniqueToken generator.
|
|
307
344
|
#
|
|
308
345
|
# @return [String] refresh token value
|
|
@@ -313,7 +350,7 @@ module Doorkeeper
|
|
|
313
350
|
end
|
|
314
351
|
|
|
315
352
|
# Generates and sets the token value with the
|
|
316
|
-
# configured Generator class (see Doorkeeper.
|
|
353
|
+
# configured Generator class (see Doorkeeper.config).
|
|
317
354
|
#
|
|
318
355
|
# @return [String] generated token value
|
|
319
356
|
#
|
|
@@ -330,7 +367,7 @@ module Doorkeeper
|
|
|
330
367
|
scopes: scopes,
|
|
331
368
|
application: application,
|
|
332
369
|
expires_in: expires_in,
|
|
333
|
-
created_at: created_at
|
|
370
|
+
created_at: created_at,
|
|
334
371
|
)
|
|
335
372
|
|
|
336
373
|
secret_strategy.store_secret(self, :token, @raw_token)
|
|
@@ -338,7 +375,7 @@ module Doorkeeper
|
|
|
338
375
|
end
|
|
339
376
|
|
|
340
377
|
def token_generator
|
|
341
|
-
generator_name = Doorkeeper.
|
|
378
|
+
generator_name = Doorkeeper.config.access_token_generator
|
|
342
379
|
generator = generator_name.constantize
|
|
343
380
|
|
|
344
381
|
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
|