doorkeeper 5.5.4 → 5.8.1
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/CHANGELOG.md +111 -8
- data/README.md +5 -9
- data/app/controllers/doorkeeper/authorizations_controller.rb +34 -11
- data/app/controllers/doorkeeper/tokens_controller.rb +28 -6
- data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
- data/app/views/doorkeeper/authorizations/form_post.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/new.html.erb +16 -16
- data/config/locales/en.yml +4 -1
- data/lib/doorkeeper/config/abstract_builder.rb +1 -1
- data/lib/doorkeeper/config/validations.rb +15 -3
- data/lib/doorkeeper/config.rb +95 -55
- data/lib/doorkeeper/engine.rb +10 -3
- data/lib/doorkeeper/errors.rb +32 -0
- data/lib/doorkeeper/helpers/controller.rb +1 -1
- data/lib/doorkeeper/models/access_token_mixin.rb +71 -9
- data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
- 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/token.rb +7 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +36 -12
- data/lib/doorkeeper/oauth/base_request.rb +14 -12
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +13 -13
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +5 -4
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -5
- data/lib/doorkeeper/oauth/client_credentials_request.rb +10 -2
- data/lib/doorkeeper/oauth/code_request.rb +1 -1
- data/lib/doorkeeper/oauth/error.rb +4 -3
- data/lib/doorkeeper/oauth/error_response.rb +19 -4
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +4 -4
- data/lib/doorkeeper/oauth/invalid_request_response.rb +4 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +6 -6
- data/lib/doorkeeper/oauth/pre_authorization.rb +31 -23
- data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -9
- data/lib/doorkeeper/oauth/scopes.rb +55 -1
- data/lib/doorkeeper/oauth/token_introspection.rb +34 -20
- data/lib/doorkeeper/oauth/token_request.rb +1 -1
- data/lib/doorkeeper/oauth/token_response.rb +5 -3
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +0 -6
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +21 -4
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +22 -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 +30 -37
- data/lib/doorkeeper/rails/routes.rb +12 -3
- data/lib/doorkeeper/rake/setup.rake +0 -5
- data/lib/doorkeeper/revocable_tokens/revocable_access_token.rb +21 -0
- data/lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb +21 -0
- data/lib/doorkeeper/version.rb +2 -2
- data/lib/doorkeeper.rb +78 -5
- data/lib/generators/doorkeeper/remove_applications_secret_not_null_constraint_generator.rb +33 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +44 -6
- data/lib/generators/doorkeeper/templates/migration.rb.erb +15 -4
- data/lib/generators/doorkeeper/templates/remove_applications_secret_not_null_constraint.rb.erb +7 -0
- metadata +28 -21
@@ -3,12 +3,12 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class AuthorizationCodeRequest < BaseRequest
|
6
|
-
validate :params, error:
|
7
|
-
validate :client, error:
|
8
|
-
validate :grant, error:
|
6
|
+
validate :params, error: Errors::InvalidRequest
|
7
|
+
validate :client, error: Errors::InvalidClient
|
8
|
+
validate :grant, error: Errors::InvalidGrant
|
9
9
|
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
10
|
-
validate :redirect_uri, error:
|
11
|
-
validate :code_verifier, error:
|
10
|
+
validate :redirect_uri, error: Errors::InvalidGrant
|
11
|
+
validate :code_verifier, error: Errors::InvalidGrant
|
12
12
|
|
13
13
|
attr_reader :grant, :client, :redirect_uri, :access_token, :code_verifier,
|
14
14
|
:invalid_request_reason, :missing_param
|
@@ -29,12 +29,17 @@ module Doorkeeper
|
|
29
29
|
grant.lock!
|
30
30
|
raise Errors::InvalidGrantReuse if grant.revoked?
|
31
31
|
|
32
|
+
if Doorkeeper.config.revoke_previous_authorization_code_token?
|
33
|
+
revoke_previous_tokens(grant.application, resource_owner)
|
34
|
+
end
|
35
|
+
|
32
36
|
grant.revoke
|
33
37
|
|
34
38
|
find_or_create_access_token(
|
35
|
-
|
39
|
+
client,
|
36
40
|
resource_owner,
|
37
41
|
grant.scopes,
|
42
|
+
custom_token_attributes_with_data,
|
38
43
|
server,
|
39
44
|
)
|
40
45
|
end
|
@@ -54,12 +59,19 @@ module Doorkeeper
|
|
54
59
|
Doorkeeper.config.access_grant_model.pkce_supported?
|
55
60
|
end
|
56
61
|
|
62
|
+
def confidential?
|
63
|
+
client&.confidential
|
64
|
+
end
|
65
|
+
|
57
66
|
def validate_params
|
58
|
-
@missing_param =
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
67
|
+
@missing_param =
|
68
|
+
if grant&.uses_pkce? && code_verifier.blank?
|
69
|
+
:code_verifier
|
70
|
+
elsif !confidential? && Doorkeeper.config.force_pkce? && code_verifier.blank?
|
71
|
+
:code_verifier
|
72
|
+
elsif redirect_uri.blank?
|
73
|
+
:redirect_uri
|
74
|
+
end
|
63
75
|
|
64
76
|
@missing_param.nil?
|
65
77
|
end
|
@@ -97,7 +109,19 @@ module Doorkeeper
|
|
97
109
|
end
|
98
110
|
|
99
111
|
def generate_code_challenge(code_verifier)
|
100
|
-
|
112
|
+
Doorkeeper.config.access_grant_model.generate_code_challenge(code_verifier)
|
113
|
+
end
|
114
|
+
|
115
|
+
def custom_token_attributes_with_data
|
116
|
+
grant
|
117
|
+
.attributes
|
118
|
+
.with_indifferent_access
|
119
|
+
.slice(*Doorkeeper.config.custom_access_token_attributes)
|
120
|
+
.symbolize_keys
|
121
|
+
end
|
122
|
+
|
123
|
+
def revoke_previous_tokens(application, resource_owner)
|
124
|
+
Doorkeeper.config.access_token_model.revoke_all_for(application.id, resource_owner)
|
101
125
|
end
|
102
126
|
end
|
103
127
|
end
|
@@ -15,7 +15,7 @@ module Doorkeeper
|
|
15
15
|
@response = TokenResponse.new(access_token)
|
16
16
|
after_successful_response
|
17
17
|
@response
|
18
|
-
elsif error ==
|
18
|
+
elsif error == Errors::InvalidRequest
|
19
19
|
@response = InvalidRequestResponse.from_request(self)
|
20
20
|
else
|
21
21
|
@response = ErrorResponse.from_request(self)
|
@@ -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
|
@@ -58,7 +59,8 @@ module Doorkeeper
|
|
58
59
|
client_scopes = @client&.scopes
|
59
60
|
return default_scopes if client_scopes.blank?
|
60
61
|
|
61
|
-
|
62
|
+
# Avoid using Scope#& for dynamic scopes
|
63
|
+
client_scopes.allowed(default_scopes)
|
62
64
|
end
|
63
65
|
end
|
64
66
|
end
|
@@ -5,7 +5,7 @@ module Doorkeeper
|
|
5
5
|
class Client
|
6
6
|
attr_reader :application
|
7
7
|
|
8
|
-
delegate :id, :name, :uid, :redirect_uri, :scopes, to: :@application
|
8
|
+
delegate :id, :name, :uid, :redirect_uri, :scopes, :confidential, to: :@application
|
9
9
|
|
10
10
|
def initialize(application)
|
11
11
|
@application = application
|
@@ -8,13 +8,14 @@ module Doorkeeper
|
|
8
8
|
existing_token = nil
|
9
9
|
|
10
10
|
if lookup_existing_token?
|
11
|
-
existing_token =
|
12
|
-
return existing_token if
|
11
|
+
existing_token = find_active_existing_token_for(client, scopes, attributes)
|
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
|
-
|
17
|
-
|
16
|
+
application = client.is_a?(Doorkeeper.config.application_model) ? client : client&.application
|
17
|
+
Doorkeeper.config.access_token_model.create_for(
|
18
|
+
application: application,
|
18
19
|
resource_owner: nil,
|
19
20
|
scopes: scopes,
|
20
21
|
**attributes,
|
@@ -25,7 +26,7 @@ module Doorkeeper
|
|
25
26
|
private
|
26
27
|
|
27
28
|
def with_revocation(existing_token:)
|
28
|
-
if existing_token &&
|
29
|
+
if existing_token && Doorkeeper.config.revoke_previous_client_credentials_token?
|
29
30
|
existing_token.with_lock do
|
30
31
|
raise Errors::DoorkeeperError, :invalid_token_reuse if existing_token.revoked?
|
31
32
|
|
@@ -39,16 +40,15 @@ module Doorkeeper
|
|
39
40
|
end
|
40
41
|
|
41
42
|
def lookup_existing_token?
|
42
|
-
|
43
|
-
|
43
|
+
Doorkeeper.config.reuse_access_token ||
|
44
|
+
Doorkeeper.config.revoke_previous_client_credentials_token?
|
44
45
|
end
|
45
46
|
|
46
|
-
def
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
Doorkeeper.config
|
47
|
+
def find_active_existing_token_for(client, scopes, attributes)
|
48
|
+
custom_attributes = Doorkeeper.config.access_token_model.
|
49
|
+
extract_custom_attributes(attributes).presence
|
50
|
+
Doorkeeper.config.access_token_model.matching_token_for(
|
51
|
+
client, nil, scopes, custom_attributes: custom_attributes, include_expired: false)
|
52
52
|
end
|
53
53
|
end
|
54
54
|
end
|
@@ -11,10 +11,10 @@ module Doorkeeper
|
|
11
11
|
@validator = validator
|
12
12
|
end
|
13
13
|
|
14
|
-
def create(client, scopes, creator = Creator.new)
|
14
|
+
def create(client, scopes, attributes = {}, creator = Creator.new)
|
15
15
|
if validator.valid?
|
16
|
-
@token = create_token(client, scopes, creator)
|
17
|
-
@error =
|
16
|
+
@token = create_token(client, scopes, attributes, creator)
|
17
|
+
@error = Errors::ServerError unless @token
|
18
18
|
else
|
19
19
|
@token = false
|
20
20
|
@error = validator.error
|
@@ -25,7 +25,7 @@ module Doorkeeper
|
|
25
25
|
|
26
26
|
private
|
27
27
|
|
28
|
-
def create_token(client, scopes, creator)
|
28
|
+
def create_token(client, scopes, attributes, creator)
|
29
29
|
context = Authorization::Token.build_context(
|
30
30
|
client,
|
31
31
|
Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
@@ -39,6 +39,7 @@ module Doorkeeper
|
|
39
39
|
scopes,
|
40
40
|
use_refresh_token: false,
|
41
41
|
expires_in: ttl,
|
42
|
+
**attributes
|
42
43
|
)
|
43
44
|
end
|
44
45
|
end
|
@@ -7,9 +7,9 @@ module Doorkeeper
|
|
7
7
|
include Validations
|
8
8
|
include OAuth::Helpers
|
9
9
|
|
10
|
-
validate :client, error:
|
11
|
-
validate :client_supports_grant_flow, error:
|
12
|
-
validate :scopes, error:
|
10
|
+
validate :client, error: Errors::InvalidClient
|
11
|
+
validate :client_supports_grant_flow, error: Errors::UnauthorizedClient
|
12
|
+
validate :scopes, error: Errors::InvalidScope
|
13
13
|
|
14
14
|
def initialize(server, request)
|
15
15
|
@server = server
|
@@ -35,13 +35,12 @@ module Doorkeeper
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def validate_scopes
|
38
|
-
return true if @request.scopes.blank?
|
39
|
-
|
40
38
|
application_scopes = if @client.present?
|
41
39
|
@client.application.scopes
|
42
40
|
else
|
43
41
|
""
|
44
42
|
end
|
43
|
+
return true if @request.scopes.blank? && application_scopes.blank?
|
45
44
|
|
46
45
|
ScopeChecker.valid?(
|
47
46
|
scope_str: @request.scopes.to_s,
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class ClientCredentialsRequest < BaseRequest
|
6
|
-
attr_reader :client, :original_scopes, :response
|
6
|
+
attr_reader :client, :original_scopes, :parameters, :response
|
7
7
|
|
8
8
|
alias error_response response
|
9
9
|
|
@@ -14,6 +14,7 @@ module Doorkeeper
|
|
14
14
|
@server = server
|
15
15
|
@response = nil
|
16
16
|
@original_scopes = parameters[:scope]
|
17
|
+
@parameters = parameters.except(:scope)
|
17
18
|
end
|
18
19
|
|
19
20
|
def access_token
|
@@ -30,7 +31,14 @@ module Doorkeeper
|
|
30
31
|
private
|
31
32
|
|
32
33
|
def valid?
|
33
|
-
issuer.create(client, scopes)
|
34
|
+
issuer.create(client, scopes, custom_token_attributes_with_data)
|
35
|
+
end
|
36
|
+
|
37
|
+
def custom_token_attributes_with_data
|
38
|
+
parameters
|
39
|
+
.with_indifferent_access
|
40
|
+
.slice(*Doorkeeper.config.custom_access_token_attributes)
|
41
|
+
.symbolize_keys
|
34
42
|
end
|
35
43
|
end
|
36
44
|
end
|
@@ -2,13 +2,14 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
|
-
Error = Struct.new(:name, :state) do
|
5
|
+
Error = Struct.new(:name, :state, :translate_options) do
|
6
6
|
def description
|
7
|
-
|
8
|
-
name,
|
7
|
+
options = (translate_options || {}).merge(
|
9
8
|
scope: %i[doorkeeper errors messages],
|
10
9
|
default: :server_error,
|
11
10
|
)
|
11
|
+
|
12
|
+
I18n.translate(name, **options)
|
12
13
|
end
|
13
14
|
end
|
14
15
|
end
|
@@ -10,17 +10,32 @@ module Doorkeeper
|
|
10
10
|
def self.from_request(request, attributes = {})
|
11
11
|
new(
|
12
12
|
attributes.merge(
|
13
|
-
name: request.error,
|
13
|
+
name: error_name_for(request.error),
|
14
|
+
exception_class: exception_class_for(request.error),
|
15
|
+
translate_options: request.error.try(:translate_options),
|
14
16
|
state: request.try(:state),
|
15
17
|
redirect_uri: request.try(:redirect_uri),
|
16
18
|
),
|
17
19
|
)
|
18
20
|
end
|
19
21
|
|
22
|
+
def self.error_name_for(error)
|
23
|
+
error.respond_to?(:name_for_response) ? error.name_for_response : error
|
24
|
+
end
|
25
|
+
|
26
|
+
def self.exception_class_for(error)
|
27
|
+
return error if error.respond_to?(:name_for_response)
|
28
|
+
|
29
|
+
"Doorkeeper::Errors::#{error.to_s.classify}".safe_constantize
|
30
|
+
end
|
31
|
+
|
32
|
+
private_class_method :error_name_for, :exception_class_for
|
33
|
+
|
20
34
|
delegate :name, :description, :state, to: :@error
|
21
35
|
|
22
36
|
def initialize(attributes = {})
|
23
|
-
@error = OAuth::Error.new(*attributes.values_at(:name, :state))
|
37
|
+
@error = OAuth::Error.new(*attributes.values_at(:name, :state, :translate_options))
|
38
|
+
@exception_class = attributes[:exception_class]
|
24
39
|
@redirect_uri = attributes[:redirect_uri]
|
25
40
|
@response_on_fragment = attributes[:response_on_fragment]
|
26
41
|
end
|
@@ -55,8 +70,7 @@ module Doorkeeper
|
|
55
70
|
|
56
71
|
def headers
|
57
72
|
{
|
58
|
-
"Cache-Control" => "no-store",
|
59
|
-
"Pragma" => "no-cache",
|
73
|
+
"Cache-Control" => "no-store, no-cache",
|
60
74
|
"Content-Type" => "application/json; charset=utf-8",
|
61
75
|
"WWW-Authenticate" => authenticate_info,
|
62
76
|
}
|
@@ -73,6 +87,7 @@ module Doorkeeper
|
|
73
87
|
end
|
74
88
|
|
75
89
|
def exception_class
|
90
|
+
return @exception_class if @exception_class
|
76
91
|
raise NotImplementedError, "error response must define #exception_class"
|
77
92
|
end
|
78
93
|
|
@@ -40,7 +40,7 @@ module Doorkeeper
|
|
40
40
|
|
41
41
|
def self.loopback_uri?(uri)
|
42
42
|
IPAddr.new(uri.host).loopback?
|
43
|
-
rescue IPAddr::Error
|
43
|
+
rescue IPAddr::Error, IPAddr::InvalidAddressError
|
44
44
|
false
|
45
45
|
end
|
46
46
|
|
@@ -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)
|
@@ -5,10 +5,10 @@ module Doorkeeper
|
|
5
5
|
class PasswordAccessTokenRequest < BaseRequest
|
6
6
|
include OAuth::Helpers
|
7
7
|
|
8
|
-
validate :client, error:
|
9
|
-
validate :client_supports_grant_flow, error:
|
10
|
-
validate :resource_owner, error:
|
11
|
-
validate :scopes, error:
|
8
|
+
validate :client, error: Errors::InvalidClient
|
9
|
+
validate :client_supports_grant_flow, error: Errors::UnauthorizedClient
|
10
|
+
validate :resource_owner, error: Errors::InvalidGrant
|
11
|
+
validate :scopes, error: Errors::InvalidScope
|
12
12
|
|
13
13
|
attr_reader :client, :credentials, :resource_owner, :parameters, :access_token
|
14
14
|
|
@@ -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
|
@@ -5,32 +5,34 @@ module Doorkeeper
|
|
5
5
|
class PreAuthorization
|
6
6
|
include Validations
|
7
7
|
|
8
|
-
validate :client_id, error:
|
9
|
-
validate :client, error:
|
10
|
-
validate :client_supports_grant_flow, error:
|
11
|
-
validate :resource_owner_authorize_for_client, error:
|
12
|
-
validate :redirect_uri, error:
|
13
|
-
validate :params, error:
|
14
|
-
validate :response_type, error:
|
15
|
-
validate :response_mode, error:
|
16
|
-
validate :scopes, error:
|
17
|
-
validate :
|
8
|
+
validate :client_id, error: Errors::InvalidRequest
|
9
|
+
validate :client, error: Errors::InvalidClient
|
10
|
+
validate :client_supports_grant_flow, error: Errors::UnauthorizedClient
|
11
|
+
validate :resource_owner_authorize_for_client, error: Errors::InvalidClient
|
12
|
+
validate :redirect_uri, error: Errors::InvalidRedirectUri
|
13
|
+
validate :params, error: Errors::InvalidRequest
|
14
|
+
validate :response_type, error: Errors::UnsupportedResponseType
|
15
|
+
validate :response_mode, error: Errors::UnsupportedResponseMode
|
16
|
+
validate :scopes, error: Errors::InvalidScope
|
17
|
+
validate :code_challenge, error: Errors::InvalidCodeChallenge
|
18
|
+
validate :code_challenge_method, error: Errors::InvalidCodeChallengeMethod
|
18
19
|
|
19
20
|
attr_reader :client, :code_challenge, :code_challenge_method, :missing_param,
|
20
21
|
:redirect_uri, :resource_owner, :response_type, :state,
|
21
|
-
:authorization_response_flow, :response_mode
|
22
|
+
:authorization_response_flow, :response_mode, :custom_access_token_attributes
|
22
23
|
|
23
24
|
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
|
25
|
+
@server = server
|
26
|
+
@client_id = parameters[:client_id]
|
27
|
+
@response_type = parameters[:response_type]
|
28
|
+
@response_mode = parameters[:response_mode]
|
29
|
+
@redirect_uri = parameters[:redirect_uri]
|
30
|
+
@scope = parameters[:scope]
|
31
|
+
@state = parameters[:state]
|
32
|
+
@code_challenge = parameters[:code_challenge]
|
32
33
|
@code_challenge_method = parameters[:code_challenge_method]
|
33
|
-
@resource_owner
|
34
|
+
@resource_owner = resource_owner
|
35
|
+
@custom_access_token_attributes = parameters.slice(*Doorkeeper.config.custom_access_token_attributes).to_h
|
34
36
|
end
|
35
37
|
|
36
38
|
def authorizable?
|
@@ -46,7 +48,7 @@ module Doorkeeper
|
|
46
48
|
end
|
47
49
|
|
48
50
|
def error_response
|
49
|
-
if error ==
|
51
|
+
if error == Errors::InvalidRequest
|
50
52
|
OAuth::InvalidRequestResponse.from_request(
|
51
53
|
self,
|
52
54
|
response_on_fragment: response_on_fragment?,
|
@@ -73,7 +75,7 @@ module Doorkeeper
|
|
73
75
|
if client_scopes.blank?
|
74
76
|
server.default_scopes.to_s
|
75
77
|
else
|
76
|
-
|
78
|
+
server.default_scopes.allowed(client_scopes).to_s
|
77
79
|
end
|
78
80
|
end
|
79
81
|
|
@@ -142,11 +144,17 @@ module Doorkeeper
|
|
142
144
|
)
|
143
145
|
end
|
144
146
|
|
147
|
+
def validate_code_challenge
|
148
|
+
return true unless Doorkeeper.config.force_pkce?
|
149
|
+
return true if client.confidential
|
150
|
+
code_challenge.present?
|
151
|
+
end
|
152
|
+
|
145
153
|
def validate_code_challenge_method
|
146
154
|
return true unless Doorkeeper.config.access_grant_model.pkce_supported?
|
147
155
|
|
148
156
|
code_challenge.blank? ||
|
149
|
-
(code_challenge_method.present? && code_challenge_method
|
157
|
+
(code_challenge_method.present? && Doorkeeper.config.pkce_code_challenge_methods_supported.include?(code_challenge_method))
|
150
158
|
end
|
151
159
|
|
152
160
|
def response_on_fragment?
|
@@ -5,11 +5,11 @@ module Doorkeeper
|
|
5
5
|
class RefreshTokenRequest < BaseRequest
|
6
6
|
include OAuth::Helpers
|
7
7
|
|
8
|
-
validate :token_presence, error:
|
9
|
-
validate :token, error:
|
10
|
-
validate :client, error:
|
11
|
-
validate :client_match, error:
|
12
|
-
validate :scope, error:
|
8
|
+
validate :token_presence, error: Errors::InvalidRequest
|
9
|
+
validate :token, error: Errors::InvalidGrant
|
10
|
+
validate :client, error: Errors::InvalidClient
|
11
|
+
validate :client_match, error: Errors::InvalidGrant
|
12
|
+
validate :scope, error: Errors::InvalidScope
|
13
13
|
|
14
14
|
attr_reader :access_token, :client, :credentials, :refresh_token
|
15
15
|
attr_reader :missing_param
|
@@ -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
|