doorkeeper 5.6.2 → 5.6.6
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/CHANGELOG.md +35 -8
- data/README.md +1 -1
- data/app/controllers/doorkeeper/authorizations_controller.rb +17 -5
- data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
- data/lib/doorkeeper/config/abstract_builder.rb +1 -1
- data/lib/doorkeeper/config.rb +9 -75
- data/lib/doorkeeper/engine.rb +7 -5
- data/lib/doorkeeper/models/access_token_mixin.rb +4 -3
- data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +7 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +16 -6
- data/lib/doorkeeper/oauth/base_request.rb +11 -10
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +7 -11
- data/lib/doorkeeper/oauth/error_response.rb +1 -2
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +3 -3
- data/lib/doorkeeper/oauth/password_access_token_request.rb +2 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +11 -10
- data/lib/doorkeeper/oauth/refresh_token_request.rb +12 -4
- data/lib/doorkeeper/oauth/token_introspection.rb +1 -1
- data/lib/doorkeeper/oauth/token_response.rb +1 -2
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +0 -6
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +0 -4
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +0 -4
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +2 -2
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +5 -2
- data/lib/doorkeeper/orm/active_record.rb +7 -11
- data/lib/doorkeeper/rails/routes.rb +6 -1
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +72 -5
- data/lib/generators/doorkeeper/templates/initializer.rb +17 -0
- data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -4
- metadata +5 -18
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b62a0472a97d06b40362817c9d5c0dd7dd6e0d0e600437a19f5cf2fd18c4be46
|
4
|
+
data.tar.gz: 9850cef14c21a1f0df2fb451a485ab5b8066360a3008124f7aed287409364e36
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: de0c7021c4735b26249e5b267db11ede06f55b23d8f9bd51641d1cf3eee3812e14a2deec986e8aa6ee81de98097083fdb634a441fd4928cb47286fa977ba5d96
|
7
|
+
data.tar.gz: 3865639c837771ceeafceec8a110e506f88fef45c61f7274782c637e794f9185be18ee98270852bac6fecb0fc90e4893dfed08d715c761507e87396e5a559bc2
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,33 @@ User-visible changes worth mentioning.
|
|
9
9
|
|
10
10
|
- [#ID] Add your PR description here.
|
11
11
|
|
12
|
+
## 5.6.6
|
13
|
+
|
14
|
+
- [#1644] Update HTTP headers.
|
15
|
+
- [#1646] Block public clients automatic authorization skip.
|
16
|
+
- [#1648] Add custom token attributes to Refresh Token Request.
|
17
|
+
- [#1649] Fixed custom_access_token_attributes related errors.
|
18
|
+
|
19
|
+
# 5.6.5
|
20
|
+
|
21
|
+
- [#1602] Allow custom data to be stored inside access grants/tokens.
|
22
|
+
- [#1634] Code refactoring for custom token attributes.
|
23
|
+
- [#1639] Add grant type validation to avoid Internal Server Error for DELETE /oauth/authorize endpoint.
|
24
|
+
|
25
|
+
# 5.6.4
|
26
|
+
|
27
|
+
- [#1633] Apply ORM configuration in #to_prepare block to avoid autoloading errors.
|
28
|
+
|
29
|
+
# 5.6.3
|
30
|
+
|
31
|
+
- [#1622] Drop support for Rubies 2.5 and 2.6
|
32
|
+
- [#1605] Fix URI validation for Ruby 3.2+.
|
33
|
+
- [#1625] Exclude endless access tokens from `StaleRecordsCleaner`.
|
34
|
+
- [#1626] Remove deprecated `active_record_options` config option.
|
35
|
+
- [#1631] Fix regression with redirect behavior after token lookup optimizations (redirect to app URI when found).
|
36
|
+
- [#1630] Special case unique index creation for refresh_token on SQL Server.
|
37
|
+
- [#1627] Lazy evaluate Doorkeeper config when loading files and executing initializers.
|
38
|
+
|
12
39
|
## 5.6.2
|
13
40
|
|
14
41
|
- [#1604] Fix fetching of the application when custom application_class defined.
|
@@ -23,9 +50,9 @@ User-visible changes worth mentioning.
|
|
23
50
|
|
24
51
|
- [#1581] Consider `token_type_hint` when searching for access token in TokensController to avoid extra database calls.
|
25
52
|
|
26
|
-
## 5.6.0.
|
53
|
+
## 5.6.0.rc2
|
27
54
|
|
28
|
-
- [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
|
55
|
+
- [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
|
29
56
|
application scopes when using client credentials.
|
30
57
|
- [#1567] Only filter `code` parameter if authorization_code grant flow is enabled.
|
31
58
|
|
@@ -60,7 +87,7 @@ User-visible changes worth mentioning.
|
|
60
87
|
## 5.5.1
|
61
88
|
|
62
89
|
- [#1496] Revoke `old_refresh_token` if `previous_refresh_token` is present.
|
63
|
-
- [#1495] Fix `respond_to` undefined in API-only mode
|
90
|
+
- [#1495] Fix `respond_to` undefined in API-only mode
|
64
91
|
- [#1488] Verify client authentication for Resource Owner Password Grant when
|
65
92
|
`config.skip_client_authentication_for_password_grant` is set and the client credentials
|
66
93
|
are sent in a HTTP Basic auth header.
|
@@ -74,10 +101,10 @@ User-visible changes worth mentioning.
|
|
74
101
|
## 5.5.0.rc2
|
75
102
|
|
76
103
|
- [#1473] Enable `Applications` and `AuthorizedApplications` controllers in API mode.
|
77
|
-
|
78
|
-
**[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
|
104
|
+
|
105
|
+
**[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
|
79
106
|
`use_doorkeeper` inside `routes.rb`. Please do it in case you don't need them.
|
80
|
-
|
107
|
+
|
81
108
|
- [#1472] Fix `establish_connection` configuration for custom defined models.
|
82
109
|
- [#1471] Add support for Ruby 3.0.
|
83
110
|
- [#1469] Check if `redirect_uri` exists.
|
@@ -284,7 +311,7 @@ User-visible changes worth mentioning.
|
|
284
311
|
- [#1237] Allow to set blank redirect URI if Doorkeeper configured to use redirect URI-less grant flows.
|
285
312
|
- [#1234] Fix `StaleRecordsCleaner` to properly work with big amount of records.
|
286
313
|
- [#1228] Allow to explicitly set non-expiring tokens in `custom_access_token_expires_in` configuration
|
287
|
-
option using `Float::
|
314
|
+
option using `Float::INFINITY` return value.
|
288
315
|
- [#1224] Do not try to store token if not found by fallback hashing strategy.
|
289
316
|
- [#1223] Update Hound/Rubocop rules, correct Doorkeeper codebase to follow style-guides.
|
290
317
|
- [#1220] Drop Rails 4.2 & Ruby < 2.4 support.
|
@@ -369,7 +396,7 @@ User-visible changes worth mentioning.
|
|
369
396
|
- [#1116] `AccessGrant`s will now be revoked along with `AccessToken`s when
|
370
397
|
hitting the `AuthorizedApplicationController#destroy` route.
|
371
398
|
- [#1114] Make token info endpoint's attributes consistent with token creation
|
372
|
-
- [#1108] Simple
|
399
|
+
- [#1108] Simple formatting of callback URLs when listing oauth applications
|
373
400
|
- [#1106] Restrict access to AdminController with 'Forbidden 403' if admin_authenticator is not
|
374
401
|
configured by developers.
|
375
402
|
|
data/README.md
CHANGED
@@ -105,7 +105,7 @@ Extensions that are not included by default and can be installed separately.
|
|
105
105
|
| JWT Token support | [doorkeeper-gem/doorkeeper-jwt](https://github.com/doorkeeper-gem/doorkeeper-jwt) |
|
106
106
|
| Assertion grant extension | [doorkeeper-gem/doorkeeper-grants\_assertion](https://github.com/doorkeeper-gem/doorkeeper-grants_assertion) |
|
107
107
|
| I18n translations | [doorkeeper-gem/doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) |
|
108
|
-
| CIBA - Client Initiated Backchannel Authentication Flow
|
108
|
+
| CIBA - Client Initiated Backchannel Authentication Flow extension | [doorkeeper-ciba](https://github.com/autoseg/doorkeeper-ciba) |
|
109
109
|
| Device Authorization Grant | [doorkeeper-device_authorization_grant](https://github.com/exop-group/doorkeeper-device_authorization_grant) |
|
110
110
|
|
111
111
|
## Example Applications
|
@@ -13,17 +13,25 @@ module Doorkeeper
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def create
|
16
|
-
redirect_or_render
|
16
|
+
redirect_or_render(authorize_response)
|
17
17
|
end
|
18
18
|
|
19
19
|
def destroy
|
20
|
-
redirect_or_render
|
20
|
+
redirect_or_render(authorization.deny)
|
21
|
+
rescue Doorkeeper::Errors::InvalidTokenStrategy => e
|
22
|
+
error_response = get_error_response_from_exception(e)
|
23
|
+
|
24
|
+
if Doorkeeper.configuration.api_only
|
25
|
+
render json: error_response.body, status: :bad_request
|
26
|
+
else
|
27
|
+
render :error, locals: { error_response: error_response }
|
28
|
+
end
|
21
29
|
end
|
22
30
|
|
23
31
|
private
|
24
32
|
|
25
33
|
def render_success
|
26
|
-
if skip_authorization? || matching_token?
|
34
|
+
if skip_authorization? || (matching_token? && pre_auth.client.application.confidential?)
|
27
35
|
redirect_or_render(authorize_response)
|
28
36
|
elsif Doorkeeper.configuration.api_only
|
29
37
|
render json: pre_auth
|
@@ -37,7 +45,7 @@ module Doorkeeper
|
|
37
45
|
render json: pre_auth.error_response.body,
|
38
46
|
status: :bad_request
|
39
47
|
else
|
40
|
-
render :error
|
48
|
+
render :error, locals: { error_response: pre_auth.error_response }
|
41
49
|
end
|
42
50
|
end
|
43
51
|
|
@@ -88,7 +96,7 @@ module Doorkeeper
|
|
88
96
|
end
|
89
97
|
|
90
98
|
def pre_auth_param_fields
|
91
|
-
%i[
|
99
|
+
custom_access_token_attributes + %i[
|
92
100
|
client_id
|
93
101
|
code_challenge
|
94
102
|
code_challenge_method
|
@@ -100,6 +108,10 @@ module Doorkeeper
|
|
100
108
|
]
|
101
109
|
end
|
102
110
|
|
111
|
+
def custom_access_token_attributes
|
112
|
+
Doorkeeper.config.custom_access_token_attributes.map(&:to_sym)
|
113
|
+
end
|
114
|
+
|
103
115
|
def authorization
|
104
116
|
@authorization ||= strategy.request
|
105
117
|
end
|
data/lib/doorkeeper/config.rb
CHANGED
@@ -5,81 +5,11 @@ require "doorkeeper/config/option"
|
|
5
5
|
require "doorkeeper/config/validations"
|
6
6
|
|
7
7
|
module Doorkeeper
|
8
|
-
# Defines a MissingConfiguration error for a missing Doorkeeper configuration
|
9
|
-
#
|
10
|
-
class MissingConfiguration < StandardError
|
11
|
-
def initialize
|
12
|
-
super("Configuration for doorkeeper missing. Do you have doorkeeper initializer?")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
8
|
# Doorkeeper option DSL could be reused in extensions to build their own
|
17
9
|
# configurations. To use the Option DSL gems need to define `builder_class` method
|
18
10
|
# that returns configuration Builder class. This exception raises when they don't
|
19
11
|
# define it.
|
20
12
|
#
|
21
|
-
class MissingConfigurationBuilderClass < StandardError; end
|
22
|
-
|
23
|
-
class << self
|
24
|
-
attr_reader :orm_adapter
|
25
|
-
|
26
|
-
def configure(&block)
|
27
|
-
@config = Config::Builder.new(&block).build
|
28
|
-
end
|
29
|
-
|
30
|
-
# @return [Doorkeeper::Config] configuration instance
|
31
|
-
#
|
32
|
-
def configuration
|
33
|
-
@config || (raise MissingConfiguration)
|
34
|
-
end
|
35
|
-
|
36
|
-
alias config configuration
|
37
|
-
|
38
|
-
def setup
|
39
|
-
setup_orm_adapter
|
40
|
-
run_orm_hooks
|
41
|
-
config.clear_cache!
|
42
|
-
|
43
|
-
# Deprecated, will be removed soon
|
44
|
-
unless configuration.orm == :active_record
|
45
|
-
setup_orm_models
|
46
|
-
setup_application_owner
|
47
|
-
end
|
48
|
-
end
|
49
|
-
|
50
|
-
def setup_orm_adapter
|
51
|
-
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
52
|
-
rescue NameError => e
|
53
|
-
raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
|
54
|
-
[DOORKEEPER] ORM adapter not found (#{configuration.orm}), or there was an error
|
55
|
-
trying to load it.
|
56
|
-
|
57
|
-
You probably need to add the related gem for this adapter to work with
|
58
|
-
doorkeeper.
|
59
|
-
ERROR_MSG
|
60
|
-
end
|
61
|
-
|
62
|
-
def run_orm_hooks
|
63
|
-
if @orm_adapter.respond_to?(:run_hooks)
|
64
|
-
@orm_adapter.run_hooks
|
65
|
-
else
|
66
|
-
::Kernel.warn <<~MSG.strip_heredoc
|
67
|
-
[DOORKEEPER] ORM "#{configuration.orm}" should move all it's setup logic under `#run_hooks` method for
|
68
|
-
the #{@orm_adapter.name}. Later versions of Doorkeeper will no longer support `setup_orm_models` and
|
69
|
-
`setup_application_owner` API.
|
70
|
-
MSG
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def setup_orm_models
|
75
|
-
@orm_adapter.initialize_models!
|
76
|
-
end
|
77
|
-
|
78
|
-
def setup_application_owner
|
79
|
-
@orm_adapter.initialize_application_owner!
|
80
|
-
end
|
81
|
-
end
|
82
|
-
|
83
13
|
class Config
|
84
14
|
# Default Doorkeeper configuration builder
|
85
15
|
class Builder < AbstractBuilder
|
@@ -324,11 +254,6 @@ module Doorkeeper
|
|
324
254
|
option :skip_client_authentication_for_password_grant,
|
325
255
|
default: false
|
326
256
|
|
327
|
-
# TODO: remove the option
|
328
|
-
option :active_record_options,
|
329
|
-
default: {},
|
330
|
-
deprecated: { message: "Customize Doorkeeper models instead" }
|
331
|
-
|
332
257
|
# Hook to allow arbitrary user-client authorization
|
333
258
|
option :authorize_resource_owner_for_client,
|
334
259
|
default: ->(_client, _resource_owner) { true }
|
@@ -396,6 +321,15 @@ module Doorkeeper
|
|
396
321
|
option :access_token_generator,
|
397
322
|
default: "Doorkeeper::OAuth::Helpers::UniqueToken"
|
398
323
|
|
324
|
+
# Allows additional data to be received when granting access to an Application, and for this
|
325
|
+
# additional data to be sent with subsequently generated access tokens. The access grant and
|
326
|
+
# access token models will both need to respond to the specified attribute names.
|
327
|
+
#
|
328
|
+
# @param attributes [Array] The array of custom attribute names to be saved
|
329
|
+
#
|
330
|
+
option :custom_access_token_attributes,
|
331
|
+
default: []
|
332
|
+
|
399
333
|
# Use a custom class for generating the application secret.
|
400
334
|
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-application-secret-generator
|
401
335
|
#
|
data/lib/doorkeeper/engine.rb
CHANGED
@@ -2,10 +2,12 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
class Engine < Rails::Engine
|
5
|
-
initializer "doorkeeper.params.filter" do |app|
|
6
|
-
|
7
|
-
|
8
|
-
|
5
|
+
initializer "doorkeeper.params.filter", after: :load_config_initializers do |app|
|
6
|
+
if Doorkeeper.configured?
|
7
|
+
parameters = %w[client_secret authentication_token access_token refresh_token]
|
8
|
+
parameters << "code" if Doorkeeper.config.grant_flows.include?("authorization_code")
|
9
|
+
app.config.filter_parameters << /^(#{Regexp.union(parameters)})$/
|
10
|
+
end
|
9
11
|
end
|
10
12
|
|
11
13
|
initializer "doorkeeper.routes" do
|
@@ -19,7 +21,7 @@ module Doorkeeper
|
|
19
21
|
end
|
20
22
|
|
21
23
|
config.to_prepare do
|
22
|
-
Doorkeeper.
|
24
|
+
Doorkeeper.run_orm_hooks
|
23
25
|
end
|
24
26
|
|
25
27
|
if defined?(Sprockets) && Sprockets::VERSION.chr.to_i >= 4
|
@@ -87,8 +87,9 @@ module Doorkeeper
|
|
87
87
|
# @return [Doorkeeper::AccessToken, nil] Access Token instance or
|
88
88
|
# nil if matching record was not found
|
89
89
|
#
|
90
|
-
def matching_token_for(application, resource_owner, scopes)
|
91
|
-
tokens = authorized_tokens_for(application&.id, resource_owner)
|
90
|
+
def matching_token_for(application, resource_owner, scopes, include_expired: true)
|
91
|
+
tokens = authorized_tokens_for(application&.id, resource_owner)
|
92
|
+
tokens = tokens.not_expired unless include_expired
|
92
93
|
find_matching_token(tokens, application, scopes)
|
93
94
|
end
|
94
95
|
|
@@ -180,7 +181,7 @@ module Doorkeeper
|
|
180
181
|
#
|
181
182
|
def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes)
|
182
183
|
if Doorkeeper.config.reuse_access_token
|
183
|
-
access_token = matching_token_for(application, resource_owner, scopes)
|
184
|
+
access_token = matching_token_for(application, resource_owner, scopes, include_expired: false)
|
184
185
|
|
185
186
|
return access_token if access_token&.reusable?
|
186
187
|
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Models
|
5
|
+
module PolymorphicResourceOwner
|
6
|
+
module ForAccessGrant
|
7
|
+
extend ActiveSupport::Concern
|
8
|
+
|
9
|
+
included do
|
10
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
11
|
+
belongs_to :resource_owner, polymorphic: true, optional: false
|
12
|
+
else
|
13
|
+
validates :resource_owner_id, presence: true
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
module ForAccessToken
|
19
|
+
extend ActiveSupport::Concern
|
20
|
+
|
21
|
+
included do
|
22
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
23
|
+
belongs_to :resource_owner, polymorphic: true, optional: true
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
@@ -45,7 +45,13 @@ module Doorkeeper
|
|
45
45
|
attributes[:resource_owner_id] = resource_owner.id
|
46
46
|
end
|
47
47
|
|
48
|
-
pkce_attributes.merge(attributes)
|
48
|
+
pkce_attributes.merge(attributes).merge(custom_attributes)
|
49
|
+
end
|
50
|
+
|
51
|
+
def custom_attributes
|
52
|
+
# Custom access token attributes are saved into the access grant,
|
53
|
+
# and then included in subsequently generated access tokens.
|
54
|
+
@pre_auth.custom_access_token_attributes.to_h.with_indifferent_access
|
49
55
|
end
|
50
56
|
|
51
57
|
def pkce_attributes
|
@@ -35,6 +35,7 @@ module Doorkeeper
|
|
35
35
|
grant.application,
|
36
36
|
resource_owner,
|
37
37
|
grant.scopes,
|
38
|
+
custom_token_attributes_with_data,
|
38
39
|
server,
|
39
40
|
)
|
40
41
|
end
|
@@ -55,11 +56,12 @@ module Doorkeeper
|
|
55
56
|
end
|
56
57
|
|
57
58
|
def validate_params
|
58
|
-
@missing_param =
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
59
|
+
@missing_param =
|
60
|
+
if grant&.uses_pkce? && code_verifier.blank?
|
61
|
+
:code_verifier
|
62
|
+
elsif redirect_uri.blank?
|
63
|
+
:redirect_uri
|
64
|
+
end
|
63
65
|
|
64
66
|
@missing_param.nil?
|
65
67
|
end
|
@@ -97,7 +99,15 @@ module Doorkeeper
|
|
97
99
|
end
|
98
100
|
|
99
101
|
def generate_code_challenge(code_verifier)
|
100
|
-
|
102
|
+
Doorkeeper.config.access_grant_model.generate_code_challenge(code_verifier)
|
103
|
+
end
|
104
|
+
|
105
|
+
def custom_token_attributes_with_data
|
106
|
+
grant
|
107
|
+
.attributes
|
108
|
+
.with_indifferent_access
|
109
|
+
.slice(*Doorkeeper.config.custom_access_token_attributes)
|
110
|
+
.symbolize_keys
|
101
111
|
end
|
102
112
|
end
|
103
113
|
end
|
@@ -26,27 +26,28 @@ module Doorkeeper
|
|
26
26
|
@scopes ||= build_scopes
|
27
27
|
end
|
28
28
|
|
29
|
-
def find_or_create_access_token(client, resource_owner, scopes, server)
|
29
|
+
def find_or_create_access_token(client, resource_owner, scopes, custom_attributes, server)
|
30
30
|
context = Authorization::Token.build_context(client, grant_type, scopes, resource_owner)
|
31
|
-
|
32
|
-
|
31
|
+
application = client.is_a?(Doorkeeper.config.application_model) ? client : client&.application
|
32
|
+
|
33
|
+
token_attributes = {
|
34
|
+
application: application,
|
33
35
|
resource_owner: resource_owner,
|
34
36
|
scopes: scopes,
|
35
37
|
expires_in: Authorization::Token.access_token_expires_in(server, context),
|
36
38
|
use_refresh_token: Authorization::Token.refresh_token_enabled?(server, context),
|
37
|
-
|
39
|
+
}
|
40
|
+
|
41
|
+
@access_token =
|
42
|
+
Doorkeeper.config.access_token_model.find_or_create_for(**token_attributes.merge(custom_attributes))
|
38
43
|
end
|
39
44
|
|
40
45
|
def before_successful_response
|
41
|
-
|
46
|
+
Doorkeeper.config.before_successful_strategy_response.call(self)
|
42
47
|
end
|
43
48
|
|
44
49
|
def after_successful_response
|
45
|
-
|
46
|
-
end
|
47
|
-
|
48
|
-
def server_config
|
49
|
-
Doorkeeper.config
|
50
|
+
Doorkeeper.config.after_successful_strategy_response.call(self, @response)
|
50
51
|
end
|
51
52
|
|
52
53
|
private
|
@@ -9,12 +9,12 @@ module Doorkeeper
|
|
9
9
|
|
10
10
|
if lookup_existing_token?
|
11
11
|
existing_token = find_active_existing_token_for(client, scopes)
|
12
|
-
return existing_token if
|
12
|
+
return existing_token if Doorkeeper.config.reuse_access_token && existing_token&.reusable?
|
13
13
|
end
|
14
14
|
|
15
15
|
with_revocation(existing_token: existing_token) do
|
16
|
-
application = client.is_a?(
|
17
|
-
|
16
|
+
application = client.is_a?(Doorkeeper.config.application_model) ? client : client&.application
|
17
|
+
Doorkeeper.config.access_token_model.create_for(
|
18
18
|
application: application,
|
19
19
|
resource_owner: nil,
|
20
20
|
scopes: scopes,
|
@@ -26,7 +26,7 @@ module Doorkeeper
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def with_revocation(existing_token:)
|
29
|
-
if existing_token &&
|
29
|
+
if existing_token && Doorkeeper.config.revoke_previous_client_credentials_token?
|
30
30
|
existing_token.with_lock do
|
31
31
|
raise Errors::DoorkeeperError, :invalid_token_reuse if existing_token.revoked?
|
32
32
|
|
@@ -40,16 +40,12 @@ module Doorkeeper
|
|
40
40
|
end
|
41
41
|
|
42
42
|
def lookup_existing_token?
|
43
|
-
|
44
|
-
|
43
|
+
Doorkeeper.config.reuse_access_token ||
|
44
|
+
Doorkeeper.config.revoke_previous_client_credentials_token?
|
45
45
|
end
|
46
46
|
|
47
47
|
def find_active_existing_token_for(client, scopes)
|
48
|
-
|
49
|
-
end
|
50
|
-
|
51
|
-
def server_config
|
52
|
-
Doorkeeper.config
|
48
|
+
Doorkeeper.config.access_token_model.matching_token_for(client, nil, scopes, include_expired: false)
|
53
49
|
end
|
54
50
|
end
|
55
51
|
end
|
@@ -61,9 +61,9 @@ module Doorkeeper
|
|
61
61
|
end
|
62
62
|
|
63
63
|
def self.valid_scheme?(uri)
|
64
|
-
return false if uri.scheme.
|
64
|
+
return false if uri.scheme.blank?
|
65
65
|
|
66
|
-
%w[localhost].
|
66
|
+
%w[localhost].exclude?(uri.scheme)
|
67
67
|
end
|
68
68
|
|
69
69
|
def self.hypertext_scheme?(uri)
|
@@ -71,7 +71,7 @@ module Doorkeeper
|
|
71
71
|
end
|
72
72
|
|
73
73
|
def self.iff_host?(uri)
|
74
|
-
!(hypertext_scheme?(uri) && uri.host.
|
74
|
+
!(hypertext_scheme?(uri) && uri.host.blank?)
|
75
75
|
end
|
76
76
|
|
77
77
|
def self.oob_uri?(uri)
|
@@ -25,7 +25,7 @@ module Doorkeeper
|
|
25
25
|
private
|
26
26
|
|
27
27
|
def before_successful_response
|
28
|
-
find_or_create_access_token(client, resource_owner, scopes, server)
|
28
|
+
find_or_create_access_token(client, resource_owner, scopes, {}, server)
|
29
29
|
super
|
30
30
|
end
|
31
31
|
|
@@ -68,7 +68,7 @@ module Doorkeeper
|
|
68
68
|
end
|
69
69
|
|
70
70
|
def validate_client_supports_grant_flow
|
71
|
-
|
71
|
+
Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client&.application)
|
72
72
|
end
|
73
73
|
end
|
74
74
|
end
|
@@ -18,19 +18,20 @@ module Doorkeeper
|
|
18
18
|
|
19
19
|
attr_reader :client, :code_challenge, :code_challenge_method, :missing_param,
|
20
20
|
:redirect_uri, :resource_owner, :response_type, :state,
|
21
|
-
:authorization_response_flow, :response_mode
|
21
|
+
:authorization_response_flow, :response_mode, :custom_access_token_attributes
|
22
22
|
|
23
23
|
def initialize(server, parameters = {}, resource_owner = nil)
|
24
|
-
@server
|
25
|
-
@client_id
|
26
|
-
@response_type
|
27
|
-
@response_mode
|
28
|
-
@redirect_uri
|
29
|
-
@scope
|
30
|
-
@state
|
31
|
-
@code_challenge
|
24
|
+
@server = server
|
25
|
+
@client_id = parameters[:client_id]
|
26
|
+
@response_type = parameters[:response_type]
|
27
|
+
@response_mode = parameters[:response_mode]
|
28
|
+
@redirect_uri = parameters[:redirect_uri]
|
29
|
+
@scope = parameters[:scope]
|
30
|
+
@state = parameters[:state]
|
31
|
+
@code_challenge = parameters[:code_challenge]
|
32
32
|
@code_challenge_method = parameters[:code_challenge_method]
|
33
|
-
@resource_owner
|
33
|
+
@resource_owner = resource_owner
|
34
|
+
@custom_access_token_attributes = parameters.slice(*Doorkeeper.config.custom_access_token_attributes)
|
34
35
|
end
|
35
36
|
|
36
37
|
def authorizable?
|
@@ -26,7 +26,7 @@ module Doorkeeper
|
|
26
26
|
private
|
27
27
|
|
28
28
|
def load_client(credentials)
|
29
|
-
|
29
|
+
Doorkeeper.config.application_model.by_uid_and_secret(credentials.uid, credentials.secret)
|
30
30
|
end
|
31
31
|
|
32
32
|
def before_successful_response
|
@@ -41,7 +41,7 @@ module Doorkeeper
|
|
41
41
|
end
|
42
42
|
|
43
43
|
def refresh_token_revoked_on_use?
|
44
|
-
|
44
|
+
Doorkeeper.config.access_token_model.refresh_token_revoked_on_use?
|
45
45
|
end
|
46
46
|
|
47
47
|
def default_scopes
|
@@ -49,7 +49,7 @@ module Doorkeeper
|
|
49
49
|
end
|
50
50
|
|
51
51
|
def create_access_token
|
52
|
-
attributes = {}
|
52
|
+
attributes = {}.merge(custom_token_attributes_with_data)
|
53
53
|
|
54
54
|
resource_owner =
|
55
55
|
if Doorkeeper.config.polymorphic_resource_owner?
|
@@ -75,7 +75,7 @@ module Doorkeeper
|
|
75
75
|
# Here we assume that TTL of the token received after refreshing should be
|
76
76
|
# the same as that of the original token.
|
77
77
|
#
|
78
|
-
@access_token =
|
78
|
+
@access_token = Doorkeeper.config.access_token_model.create_for(
|
79
79
|
application: refresh_token.application,
|
80
80
|
resource_owner: resource_owner,
|
81
81
|
scopes: scopes,
|
@@ -119,6 +119,14 @@ module Doorkeeper
|
|
119
119
|
true
|
120
120
|
end
|
121
121
|
end
|
122
|
+
|
123
|
+
def custom_token_attributes_with_data
|
124
|
+
refresh_token
|
125
|
+
.attributes
|
126
|
+
.with_indifferent_access
|
127
|
+
.slice(*Doorkeeper.config.custom_access_token_attributes)
|
128
|
+
.symbolize_keys
|
129
|
+
end
|
122
130
|
end
|
123
131
|
end
|
124
132
|
end
|
@@ -134,7 +134,7 @@ module Doorkeeper
|
|
134
134
|
# Since resource servers using token introspection rely on the
|
135
135
|
# authorization server to determine the state of a token, the
|
136
136
|
# authorization server MUST perform all applicable checks against a
|
137
|
-
# token's state.
|
137
|
+
# token's state. For instance, these tests include the following:
|
138
138
|
#
|
139
139
|
# o If the token can expire, the authorization server MUST determine
|
140
140
|
# whether or not the token has expired.
|
@@ -14,12 +14,6 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
14
14
|
optional: true,
|
15
15
|
inverse_of: :access_grants
|
16
16
|
|
17
|
-
if Doorkeeper.config.polymorphic_resource_owner?
|
18
|
-
belongs_to :resource_owner, polymorphic: true, optional: false
|
19
|
-
else
|
20
|
-
validates :resource_owner_id, presence: true
|
21
|
-
end
|
22
|
-
|
23
17
|
validates :application_id,
|
24
18
|
:token,
|
25
19
|
:expires_in,
|
@@ -14,10 +14,6 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
14
14
|
inverse_of: :access_tokens,
|
15
15
|
optional: true
|
16
16
|
|
17
|
-
if Doorkeeper.config.polymorphic_resource_owner?
|
18
|
-
belongs_to :resource_owner, polymorphic: true, optional: true
|
19
|
-
end
|
20
|
-
|
21
17
|
validates :token, presence: true, uniqueness: { case_sensitive: true }
|
22
18
|
validates :refresh_token, uniqueness: { case_sensitive: true }, if: :use_refresh_token?
|
23
19
|
|
@@ -10,10 +10,6 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
10
10
|
|
11
11
|
include ::Doorkeeper::ApplicationMixin
|
12
12
|
|
13
|
-
if Doorkeeper.config.enable_application_owner?
|
14
|
-
include ::Doorkeeper::Models::Ownership
|
15
|
-
end
|
16
|
-
|
17
13
|
has_many :access_grants,
|
18
14
|
foreign_key: :application_id,
|
19
15
|
dependent: :delete_all,
|
@@ -45,11 +45,11 @@ module Doorkeeper
|
|
45
45
|
end
|
46
46
|
|
47
47
|
def unspecified_host?(uri)
|
48
|
-
uri.is_a?(URI::HTTP) && uri.host.
|
48
|
+
uri.is_a?(URI::HTTP) && uri.host.blank?
|
49
49
|
end
|
50
50
|
|
51
51
|
def relative_uri?(uri)
|
52
|
-
uri.scheme.nil? && uri.host.
|
52
|
+
uri.scheme.nil? && uri.host.blank?
|
53
53
|
end
|
54
54
|
|
55
55
|
def invalid_ssl_uri?(uri)
|
@@ -15,7 +15,8 @@ module Doorkeeper
|
|
15
15
|
def clean_revoked
|
16
16
|
table = @base_scope.arel_table
|
17
17
|
|
18
|
-
@base_scope
|
18
|
+
@base_scope
|
19
|
+
.where.not(revoked_at: nil)
|
19
20
|
.where(table[:revoked_at].lt(Time.current))
|
20
21
|
.in_batches(&:delete_all)
|
21
22
|
end
|
@@ -24,7 +25,9 @@ module Doorkeeper
|
|
24
25
|
def clean_expired(ttl)
|
25
26
|
table = @base_scope.arel_table
|
26
27
|
|
27
|
-
@base_scope
|
28
|
+
@base_scope
|
29
|
+
.where.not(expires_in: nil)
|
30
|
+
.where(table[:created_at].lt(Time.current - ttl))
|
28
31
|
.in_batches(&:delete_all)
|
29
32
|
end
|
30
33
|
end
|
@@ -29,20 +29,16 @@ module Doorkeeper
|
|
29
29
|
end
|
30
30
|
|
31
31
|
def self.run_hooks
|
32
|
-
|
33
|
-
|
32
|
+
initialize_configured_associations
|
33
|
+
end
|
34
34
|
|
35
|
-
|
36
|
-
|
35
|
+
def self.initialize_configured_associations
|
36
|
+
if Doorkeeper.config.enable_application_owner?
|
37
|
+
Doorkeeper.config.application_model.include ::Doorkeeper::Models::Ownership
|
37
38
|
end
|
38
|
-
end
|
39
39
|
|
40
|
-
|
41
|
-
|
42
|
-
Doorkeeper.config.access_grant_model,
|
43
|
-
Doorkeeper.config.access_token_model,
|
44
|
-
Doorkeeper.config.application_model,
|
45
|
-
]
|
40
|
+
Doorkeeper.config.access_grant_model.include ::Doorkeeper::Models::PolymorphicResourceOwner::ForAccessGrant
|
41
|
+
Doorkeeper.config.access_token_model.include ::Doorkeeper::Models::PolymorphicResourceOwner::ForAccessToken
|
46
42
|
end
|
47
43
|
end
|
48
44
|
end
|
@@ -36,7 +36,7 @@ module Doorkeeper
|
|
36
36
|
map_route(:authorizations, :authorization_routes)
|
37
37
|
map_route(:tokens, :token_routes)
|
38
38
|
map_route(:tokens, :revoke_routes)
|
39
|
-
map_route(:tokens, :introspect_routes)
|
39
|
+
map_route(:tokens, :introspect_routes) if introspection_routes?
|
40
40
|
map_route(:applications, :application_routes)
|
41
41
|
map_route(:authorized_applications, :authorized_applications_routes)
|
42
42
|
map_route(:token_info, :token_info_routes)
|
@@ -100,6 +100,11 @@ module Doorkeeper
|
|
100
100
|
def native_authorization_code_route
|
101
101
|
Doorkeeper.configuration.native_authorization_code_route
|
102
102
|
end
|
103
|
+
|
104
|
+
def introspection_routes?
|
105
|
+
Doorkeeper.configured? &&
|
106
|
+
!Doorkeeper.config.allow_token_introspection.is_a?(FalseClass)
|
107
|
+
end
|
103
108
|
end
|
104
109
|
end
|
105
110
|
end
|
data/lib/doorkeeper/version.rb
CHANGED
data/lib/doorkeeper.rb
CHANGED
@@ -90,6 +90,7 @@ module Doorkeeper
|
|
90
90
|
autoload :Expirable, "doorkeeper/models/concerns/expirable"
|
91
91
|
autoload :ExpirationTimeSqlMath, "doorkeeper/models/concerns/expiration_time_sql_math"
|
92
92
|
autoload :Orderable, "doorkeeper/models/concerns/orderable"
|
93
|
+
autoload :PolymorphicResourceOwner, "doorkeeper/models/concerns/polymorphic_resource_owner"
|
93
94
|
autoload :Scopes, "doorkeeper/models/concerns/scopes"
|
94
95
|
autoload :Reusable, "doorkeeper/models/concerns/reusable"
|
95
96
|
autoload :ResourceOwnerable, "doorkeeper/models/concerns/resource_ownerable"
|
@@ -113,11 +114,77 @@ module Doorkeeper
|
|
113
114
|
autoload :BCrypt, "doorkeeper/secret_storing/bcrypt"
|
114
115
|
end
|
115
116
|
|
116
|
-
|
117
|
-
|
118
|
-
|
117
|
+
class << self
|
118
|
+
attr_reader :orm_adapter
|
119
|
+
|
120
|
+
def configure(&block)
|
121
|
+
@config = Config::Builder.new(&block).build
|
122
|
+
setup
|
123
|
+
@config
|
124
|
+
end
|
125
|
+
|
126
|
+
# @return [Doorkeeper::Config] configuration instance
|
127
|
+
#
|
128
|
+
def configuration
|
129
|
+
@config || configure
|
130
|
+
end
|
131
|
+
|
132
|
+
def configured?
|
133
|
+
!@config.nil?
|
134
|
+
end
|
135
|
+
|
136
|
+
alias config configuration
|
137
|
+
|
138
|
+
def setup
|
139
|
+
setup_orm_adapter
|
140
|
+
|
141
|
+
# Deprecated, will be removed soon
|
142
|
+
unless configuration.orm == :active_record
|
143
|
+
setup_orm_models
|
144
|
+
setup_application_owner
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
def setup_orm_adapter
|
149
|
+
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
150
|
+
rescue NameError => e
|
151
|
+
raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
|
152
|
+
[DOORKEEPER] ORM adapter not found (#{configuration.orm}), or there was an error
|
153
|
+
trying to load it.
|
119
154
|
|
120
|
-
|
121
|
-
|
155
|
+
You probably need to add the related gem for this adapter to work with
|
156
|
+
doorkeeper.
|
157
|
+
ERROR_MSG
|
158
|
+
end
|
159
|
+
|
160
|
+
def run_orm_hooks
|
161
|
+
config.clear_cache!
|
162
|
+
|
163
|
+
if @orm_adapter.respond_to?(:run_hooks)
|
164
|
+
@orm_adapter.run_hooks
|
165
|
+
else
|
166
|
+
::Kernel.warn <<~MSG.strip_heredoc
|
167
|
+
[DOORKEEPER] ORM "#{configuration.orm}" should move all it's setup logic under `#run_hooks` method for
|
168
|
+
the #{@orm_adapter.name}. Later versions of Doorkeeper will no longer support `setup_orm_models` and
|
169
|
+
`setup_application_owner` API.
|
170
|
+
MSG
|
171
|
+
end
|
172
|
+
end
|
173
|
+
|
174
|
+
def setup_orm_models
|
175
|
+
@orm_adapter.initialize_models!
|
176
|
+
end
|
177
|
+
|
178
|
+
def setup_application_owner
|
179
|
+
@orm_adapter.initialize_application_owner!
|
180
|
+
end
|
181
|
+
|
182
|
+
def authenticate(request, methods = Doorkeeper.config.access_token_methods)
|
183
|
+
OAuth::Token.authenticate(request, *methods)
|
184
|
+
end
|
185
|
+
|
186
|
+
def gem_version
|
187
|
+
::Gem::Version.new(::Doorkeeper::VERSION::STRING)
|
188
|
+
end
|
122
189
|
end
|
123
190
|
end
|
@@ -391,6 +391,23 @@ Doorkeeper.configure do
|
|
391
391
|
# resource_owner.admin? || client.owners_allowlist.include?(resource_owner)
|
392
392
|
# end
|
393
393
|
|
394
|
+
# Allows additional data fields to be sent while granting access to an application,
|
395
|
+
# and for this additional data to be included in subsequently generated access tokens.
|
396
|
+
# The 'authorizations/new' page will need to be overridden to include this additional data
|
397
|
+
# in the request params when granting access. The access grant and access token models
|
398
|
+
# will both need to respond to these additional data fields, and have a database column
|
399
|
+
# to store them in.
|
400
|
+
#
|
401
|
+
# Example:
|
402
|
+
# You have a multi-tenanted platform and want to be able to grant access to a specific
|
403
|
+
# tenant, rather than all the tenants a user has access to. You can use this config
|
404
|
+
# option to specify that a ':tenant_id' will be passed when authorizing. This tenant_id
|
405
|
+
# will be included in the access tokens. When a request is made with one of these access
|
406
|
+
# tokens, you can check that the requested data belongs to the specified tenant.
|
407
|
+
#
|
408
|
+
# Default value is an empty Array: []
|
409
|
+
# custom_access_token_attributes [:tenant_id]
|
410
|
+
|
394
411
|
# Hook into the strategies' request & response life-cycle in case your
|
395
412
|
# application needs advanced customization or logging:
|
396
413
|
#
|
@@ -24,9 +24,9 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
24
24
|
t.string :token, null: false
|
25
25
|
t.integer :expires_in, null: false
|
26
26
|
t.text :redirect_uri, null: false
|
27
|
+
t.string :scopes, null: false, default: ''
|
27
28
|
t.datetime :created_at, null: false
|
28
29
|
t.datetime :revoked_at
|
29
|
-
t.string :scopes, null: false, default: ''
|
30
30
|
end
|
31
31
|
|
32
32
|
add_index :oauth_access_grants, :token, unique: true
|
@@ -53,9 +53,9 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
53
53
|
|
54
54
|
t.string :refresh_token
|
55
55
|
t.integer :expires_in
|
56
|
-
t.datetime :revoked_at
|
57
|
-
t.datetime :created_at, null: false
|
58
56
|
t.string :scopes
|
57
|
+
t.datetime :created_at, null: false
|
58
|
+
t.datetime :revoked_at
|
59
59
|
|
60
60
|
# The authorization server MAY issue a new refresh token, in which case
|
61
61
|
# *the client MUST discard the old refresh token* and replace it with the
|
@@ -74,7 +74,17 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
|
|
74
74
|
end
|
75
75
|
|
76
76
|
add_index :oauth_access_tokens, :token, unique: true
|
77
|
-
|
77
|
+
|
78
|
+
# See https://github.com/doorkeeper-gem/doorkeeper/issues/1592
|
79
|
+
if ActiveRecord::Base.connection.adapter_name == "SQLServer"
|
80
|
+
execute <<~SQL.squish
|
81
|
+
CREATE UNIQUE NONCLUSTERED INDEX index_oauth_access_tokens_on_refresh_token ON oauth_access_tokens(refresh_token)
|
82
|
+
WHERE refresh_token IS NOT NULL
|
83
|
+
SQL
|
84
|
+
else
|
85
|
+
add_index :oauth_access_tokens, :refresh_token, unique: true
|
86
|
+
end
|
87
|
+
|
78
88
|
add_foreign_key(
|
79
89
|
:oauth_access_tokens,
|
80
90
|
:oauth_applications,
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: doorkeeper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 5.6.
|
4
|
+
version: 5.6.6
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felipe Elias Philipp
|
@@ -11,7 +11,7 @@ authors:
|
|
11
11
|
autorequire:
|
12
12
|
bindir: bin
|
13
13
|
cert_chain: []
|
14
|
-
date:
|
14
|
+
date: 2023-03-29 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -69,20 +69,6 @@ dependencies:
|
|
69
69
|
- - ">="
|
70
70
|
- !ruby/object:Gem::Version
|
71
71
|
version: '0'
|
72
|
-
- !ruby/object:Gem::Dependency
|
73
|
-
name: danger
|
74
|
-
requirement: !ruby/object:Gem::Requirement
|
75
|
-
requirements:
|
76
|
-
- - "~>"
|
77
|
-
- !ruby/object:Gem::Version
|
78
|
-
version: '8.0'
|
79
|
-
type: :development
|
80
|
-
prerelease: false
|
81
|
-
version_requirements: !ruby/object:Gem::Requirement
|
82
|
-
requirements:
|
83
|
-
- - "~>"
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version: '8.0'
|
86
72
|
- !ruby/object:Gem::Dependency
|
87
73
|
name: database_cleaner
|
88
74
|
requirement: !ruby/object:Gem::Requirement
|
@@ -238,6 +224,7 @@ files:
|
|
238
224
|
- lib/doorkeeper/models/concerns/expiration_time_sql_math.rb
|
239
225
|
- lib/doorkeeper/models/concerns/orderable.rb
|
240
226
|
- lib/doorkeeper/models/concerns/ownership.rb
|
227
|
+
- lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb
|
241
228
|
- lib/doorkeeper/models/concerns/resource_ownerable.rb
|
242
229
|
- lib/doorkeeper/models/concerns/reusable.rb
|
243
230
|
- lib/doorkeeper/models/concerns/revocable.rb
|
@@ -352,14 +339,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
352
339
|
requirements:
|
353
340
|
- - ">="
|
354
341
|
- !ruby/object:Gem::Version
|
355
|
-
version: '2.
|
342
|
+
version: '2.7'
|
356
343
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
357
344
|
requirements:
|
358
345
|
- - ">="
|
359
346
|
- !ruby/object:Gem::Version
|
360
347
|
version: '0'
|
361
348
|
requirements: []
|
362
|
-
rubygems_version: 3.1.
|
349
|
+
rubygems_version: 3.1.6
|
363
350
|
signing_key:
|
364
351
|
specification_version: 4
|
365
352
|
summary: OAuth 2 provider for Rails and Grape
|