doorkeeper 5.4.0 → 5.5.0.rc2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of doorkeeper might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +49 -9
- data/app/controllers/doorkeeper/authorizations_controller.rb +16 -5
- data/app/controllers/doorkeeper/tokens_controller.rb +34 -26
- data/app/views/doorkeeper/applications/show.html.erb +16 -12
- data/app/views/doorkeeper/authorizations/form_post.html.erb +11 -0
- data/config/locales/en.yml +3 -1
- data/lib/doorkeeper/config/option.rb +1 -3
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +87 -62
- data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
- data/lib/doorkeeper/grant_flow/flow.rb +44 -0
- data/lib/doorkeeper/grant_flow/registry.rb +50 -0
- data/lib/doorkeeper/grant_flow.rb +45 -0
- data/lib/doorkeeper/helpers/controller.rb +4 -0
- data/lib/doorkeeper/models/access_grant_mixin.rb +1 -2
- data/lib/doorkeeper/models/access_token_mixin.rb +3 -3
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
- data/lib/doorkeeper/oauth/authorization/code.rb +4 -0
- data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/token.rb +10 -4
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +1 -1
- data/lib/doorkeeper/oauth/authorization_code_request.rb +10 -17
- data/lib/doorkeeper/oauth/base_request.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +1 -0
- data/lib/doorkeeper/oauth/code_response.rb +17 -11
- data/lib/doorkeeper/oauth/error_response.rb +4 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -3
- data/lib/doorkeeper/oauth/password_access_token_request.rb +20 -1
- data/lib/doorkeeper/oauth/pre_authorization.rb +33 -8
- data/lib/doorkeeper/oauth/refresh_token_request.rb +13 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +6 -3
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +5 -0
- data/lib/doorkeeper/orm/active_record.rb +4 -5
- data/lib/doorkeeper/rails/routes.rb +1 -3
- data/lib/doorkeeper/request.rb +49 -12
- data/lib/doorkeeper/version.rb +2 -6
- data/lib/doorkeeper.rb +5 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +1 -1
- data/lib/generators/doorkeeper/templates/initializer.rb +9 -7
- metadata +21 -8
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module GrantFlow
|
5
|
+
module Registry
|
6
|
+
mattr_accessor :flows
|
7
|
+
self.flows = {}
|
8
|
+
|
9
|
+
mattr_accessor :aliases
|
10
|
+
self.aliases = {}
|
11
|
+
|
12
|
+
# Allows to register custom OAuth grant flow so that Doorkeeper
|
13
|
+
# could recognize and process it.
|
14
|
+
#
|
15
|
+
def register(name_or_flow, **options)
|
16
|
+
unless name_or_flow.is_a?(Doorkeeper::GrantFlow::Flow)
|
17
|
+
name_or_flow = Flow.new(name_or_flow, **options)
|
18
|
+
end
|
19
|
+
|
20
|
+
flow_key = name_or_flow.name.to_sym
|
21
|
+
|
22
|
+
if flows.key?(flow_key)
|
23
|
+
::Kernel.warn <<~WARNING
|
24
|
+
[DOORKEEPER] '#{flow_key}' grant flow already registered and will be overridden
|
25
|
+
in #{caller(1..1).first}
|
26
|
+
WARNING
|
27
|
+
end
|
28
|
+
|
29
|
+
flows[flow_key] = name_or_flow
|
30
|
+
end
|
31
|
+
|
32
|
+
# Allows to register aliases that could be used in `grant_flows`
|
33
|
+
# configuration option. It is possible to have aliases like 1:1 or
|
34
|
+
# 1:N, i.e. "implicit_oidc" => ['token', 'id_token', 'id_token token'].
|
35
|
+
#
|
36
|
+
def register_alias(alias_name, **options)
|
37
|
+
aliases[alias_name.to_sym] = Array.wrap(options.fetch(:as))
|
38
|
+
end
|
39
|
+
|
40
|
+
def expand_alias(alias_name)
|
41
|
+
aliases.fetch(alias_name.to_sym, [])
|
42
|
+
end
|
43
|
+
|
44
|
+
# [NOTE]: make it to use #fetch after removing fallbacks
|
45
|
+
def get(name)
|
46
|
+
flows[name.to_sym]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "doorkeeper/grant_flow/flow"
|
4
|
+
require "doorkeeper/grant_flow/fallback_flow"
|
5
|
+
require "doorkeeper/grant_flow/registry"
|
6
|
+
|
7
|
+
module Doorkeeper
|
8
|
+
module GrantFlow
|
9
|
+
extend Registry
|
10
|
+
|
11
|
+
register(
|
12
|
+
:implicit,
|
13
|
+
response_type_matches: "token",
|
14
|
+
response_mode_matches: %w[fragment form_post],
|
15
|
+
response_type_strategy: Doorkeeper::Request::Token,
|
16
|
+
)
|
17
|
+
|
18
|
+
register(
|
19
|
+
:authorization_code,
|
20
|
+
response_type_matches: "code",
|
21
|
+
response_mode_matches: %w[query fragment form_post],
|
22
|
+
response_type_strategy: Doorkeeper::Request::Code,
|
23
|
+
grant_type_matches: "authorization_code",
|
24
|
+
grant_type_strategy: Doorkeeper::Request::AuthorizationCode,
|
25
|
+
)
|
26
|
+
|
27
|
+
register(
|
28
|
+
:client_credentials,
|
29
|
+
grant_type_matches: "client_credentials",
|
30
|
+
grant_type_strategy: Doorkeeper::Request::ClientCredentials,
|
31
|
+
)
|
32
|
+
|
33
|
+
register(
|
34
|
+
:password,
|
35
|
+
grant_type_matches: "password",
|
36
|
+
grant_type_strategy: Doorkeeper::Request::Password,
|
37
|
+
)
|
38
|
+
|
39
|
+
register(
|
40
|
+
:refresh_token,
|
41
|
+
grant_type_matches: "refresh_token",
|
42
|
+
grant_type_strategy: Doorkeeper::Request::RefreshToken,
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
@@ -16,6 +16,8 @@ module Doorkeeper
|
|
16
16
|
|
17
17
|
# :doc:
|
18
18
|
def current_resource_owner
|
19
|
+
return @current_resource_owner if defined?(@current_resource_owner)
|
20
|
+
|
19
21
|
@current_resource_owner ||= begin
|
20
22
|
instance_eval(&Doorkeeper.config.authenticate_resource_owner)
|
21
23
|
end
|
@@ -36,6 +38,8 @@ module Doorkeeper
|
|
36
38
|
|
37
39
|
# :doc:
|
38
40
|
def doorkeeper_token
|
41
|
+
return @doorkeeper_token if defined?(@doorkeeper_token)
|
42
|
+
|
39
43
|
@doorkeeper_token ||= OAuth::Token.authenticate(request, *config_methods)
|
40
44
|
end
|
41
45
|
|
@@ -89,8 +89,7 @@ module Doorkeeper
|
|
89
89
|
# suitable for PKCE validation
|
90
90
|
#
|
91
91
|
def generate_code_challenge(code_verifier)
|
92
|
-
|
93
|
-
padded_result.split("=")[0] # Remove any trailing '='
|
92
|
+
Base64.urlsafe_encode64(Digest::SHA256.digest(code_verifier), padding: false)
|
94
93
|
end
|
95
94
|
|
96
95
|
def pkce_supported?
|
@@ -94,8 +94,8 @@ module Doorkeeper
|
|
94
94
|
# Interface to enumerate access token records in batches in order not
|
95
95
|
# to bloat the memory. Could be overloaded in any ORM extension.
|
96
96
|
#
|
97
|
-
def find_access_token_in_batches(relation,
|
98
|
-
relation.find_in_batches(
|
97
|
+
def find_access_token_in_batches(relation, **args, &block)
|
98
|
+
relation.find_in_batches(**args, &block)
|
99
99
|
end
|
100
100
|
|
101
101
|
# Enumerates AccessToken records in batches to find a matching token.
|
@@ -377,7 +377,7 @@ module Doorkeeper
|
|
377
377
|
return unless self.class.refresh_token_revoked_on_use?
|
378
378
|
|
379
379
|
old_refresh_token&.revoke
|
380
|
-
|
380
|
+
update_attribute(:previous_refresh_token, "") if previous_refresh_token.present?
|
381
381
|
end
|
382
382
|
|
383
383
|
private
|
@@ -4,12 +4,12 @@ module Doorkeeper
|
|
4
4
|
module OAuth
|
5
5
|
module Authorization
|
6
6
|
class Context
|
7
|
-
attr_reader :client, :grant_type, :scopes
|
7
|
+
attr_reader :client, :grant_type, :resource_owner, :scopes
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def initialize(**attributes)
|
10
|
+
attributes.each do |name, value|
|
11
|
+
instance_variable_set(:"@#{name}", value) if respond_to?(name)
|
12
|
+
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -7,7 +7,7 @@ module Doorkeeper
|
|
7
7
|
attr_reader :pre_auth, :resource_owner, :token
|
8
8
|
|
9
9
|
class << self
|
10
|
-
def build_context(pre_auth_or_oauth_client, grant_type, scopes)
|
10
|
+
def build_context(pre_auth_or_oauth_client, grant_type, scopes, resource_owner)
|
11
11
|
oauth_client = if pre_auth_or_oauth_client.respond_to?(:application)
|
12
12
|
pre_auth_or_oauth_client.application
|
13
13
|
elsif pre_auth_or_oauth_client.respond_to?(:client)
|
@@ -17,9 +17,10 @@ module Doorkeeper
|
|
17
17
|
end
|
18
18
|
|
19
19
|
Doorkeeper::OAuth::Authorization::Context.new(
|
20
|
-
oauth_client,
|
21
|
-
grant_type,
|
22
|
-
scopes,
|
20
|
+
client: oauth_client,
|
21
|
+
grant_type: grant_type,
|
22
|
+
scopes: scopes,
|
23
|
+
resource_owner: resource_owner,
|
23
24
|
)
|
24
25
|
end
|
25
26
|
|
@@ -55,6 +56,7 @@ module Doorkeeper
|
|
55
56
|
pre_auth.client,
|
56
57
|
Doorkeeper::OAuth::IMPLICIT,
|
57
58
|
pre_auth.scopes,
|
59
|
+
resource_owner,
|
58
60
|
)
|
59
61
|
|
60
62
|
@token = Doorkeeper.config.access_token_model.find_or_create_for(
|
@@ -74,6 +76,10 @@ module Doorkeeper
|
|
74
76
|
}
|
75
77
|
end
|
76
78
|
|
79
|
+
def access_token?
|
80
|
+
true
|
81
|
+
end
|
82
|
+
|
77
83
|
private
|
78
84
|
|
79
85
|
def controller
|
@@ -3,7 +3,6 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class AuthorizationCodeRequest < BaseRequest
|
6
|
-
validate :pkce_support, error: :invalid_request
|
7
6
|
validate :params, error: :invalid_request
|
8
7
|
validate :client, error: :invalid_client
|
9
8
|
validate :grant, error: :invalid_grant
|
@@ -32,12 +31,6 @@ module Doorkeeper
|
|
32
31
|
|
33
32
|
grant.revoke
|
34
33
|
|
35
|
-
resource_owner = if Doorkeeper.config.polymorphic_resource_owner?
|
36
|
-
grant.resource_owner
|
37
|
-
else
|
38
|
-
grant.resource_owner_id
|
39
|
-
end
|
40
|
-
|
41
34
|
find_or_create_access_token(
|
42
35
|
grant.application,
|
43
36
|
resource_owner,
|
@@ -49,16 +42,16 @@ module Doorkeeper
|
|
49
42
|
super
|
50
43
|
end
|
51
44
|
|
52
|
-
def
|
53
|
-
Doorkeeper.config.
|
45
|
+
def resource_owner
|
46
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
47
|
+
grant.resource_owner
|
48
|
+
else
|
49
|
+
grant.resource_owner_id
|
50
|
+
end
|
54
51
|
end
|
55
52
|
|
56
|
-
def
|
57
|
-
|
58
|
-
!pkce_supported? &&
|
59
|
-
code_verifier.present?
|
60
|
-
|
61
|
-
@invalid_request_reason.nil?
|
53
|
+
def pkce_supported?
|
54
|
+
Doorkeeper.config.access_grant_model.pkce_supported?
|
62
55
|
end
|
63
56
|
|
64
57
|
def validate_params
|
@@ -91,8 +84,8 @@ module Doorkeeper
|
|
91
84
|
# if either side (server or client) request PKCE, check the verifier
|
92
85
|
# against the DB - if PKCE is supported
|
93
86
|
def validate_code_verifier
|
94
|
-
return true unless
|
95
|
-
return
|
87
|
+
return true unless pkce_supported?
|
88
|
+
return grant.code_challenge.blank? if code_verifier.blank?
|
96
89
|
|
97
90
|
if grant.code_challenge_method == "S256"
|
98
91
|
grant.code_challenge == generate_code_challenge(code_verifier)
|
@@ -27,7 +27,7 @@ module Doorkeeper
|
|
27
27
|
end
|
28
28
|
|
29
29
|
def find_or_create_access_token(client, resource_owner, scopes, server)
|
30
|
-
context = Authorization::Token.build_context(client, grant_type, scopes)
|
30
|
+
context = Authorization::Token.build_context(client, grant_type, scopes, resource_owner)
|
31
31
|
@access_token = server_config.access_token_model.find_or_create_for(
|
32
32
|
application: client,
|
33
33
|
resource_owner: resource_owner,
|
@@ -39,7 +39,8 @@ module Doorkeeper
|
|
39
39
|
end
|
40
40
|
|
41
41
|
def lookup_existing_token?
|
42
|
-
server_config.reuse_access_token ||
|
42
|
+
server_config.reuse_access_token ||
|
43
|
+
server_config.revoke_previous_client_credentials_token?
|
43
44
|
end
|
44
45
|
|
45
46
|
def find_existing_token_for(client, scopes)
|
@@ -21,23 +21,29 @@ module Doorkeeper
|
|
21
21
|
auth.token
|
22
22
|
end
|
23
23
|
|
24
|
-
def
|
25
|
-
if
|
26
|
-
|
27
|
-
elsif response_on_fragment
|
28
|
-
Authorization::URIBuilder.uri_with_fragment(
|
29
|
-
pre_auth.redirect_uri,
|
24
|
+
def body
|
25
|
+
if auth.try(:access_token?)
|
26
|
+
{
|
30
27
|
access_token: auth.token.plaintext_token,
|
31
28
|
token_type: auth.token.token_type,
|
32
29
|
expires_in: auth.token.expires_in_seconds,
|
33
30
|
state: pre_auth.state,
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
pre_auth.redirect_uri,
|
31
|
+
}
|
32
|
+
elsif auth.try(:access_grant?)
|
33
|
+
{
|
38
34
|
code: auth.token.plaintext_token,
|
39
35
|
state: pre_auth.state,
|
40
|
-
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def redirect_uri
|
41
|
+
if URIChecker.oob_uri?(pre_auth.redirect_uri)
|
42
|
+
auth.oob_redirect
|
43
|
+
elsif response_on_fragment
|
44
|
+
Authorization::URIBuilder.uri_with_fragment(pre_auth.redirect_uri, body)
|
45
|
+
else
|
46
|
+
Authorization::URIBuilder.uri_with_query(pre_auth.redirect_uri, body)
|
41
47
|
end
|
42
48
|
end
|
43
49
|
end
|
@@ -5,6 +5,8 @@ module Doorkeeper
|
|
5
5
|
class ErrorResponse < BaseResponse
|
6
6
|
include OAuth::Helpers
|
7
7
|
|
8
|
+
NON_REDIRECTABLE_STATES = %i[invalid_redirect_uri invalid_client unauthorized_client].freeze
|
9
|
+
|
8
10
|
def self.from_request(request, attributes = {})
|
9
11
|
new(
|
10
12
|
attributes.merge(
|
@@ -32,7 +34,7 @@ module Doorkeeper
|
|
32
34
|
end
|
33
35
|
|
34
36
|
def status
|
35
|
-
if name == :invalid_client
|
37
|
+
if name == :invalid_client || name == :unauthorized_client
|
36
38
|
:unauthorized
|
37
39
|
else
|
38
40
|
:bad_request
|
@@ -40,8 +42,7 @@ module Doorkeeper
|
|
40
42
|
end
|
41
43
|
|
42
44
|
def redirectable?
|
43
|
-
name
|
44
|
-
!URIChecker.oob_uri?(@redirect_uri)
|
45
|
+
!NON_REDIRECTABLE_STATES.include?(name) && !URIChecker.oob_uri?(@redirect_uri)
|
45
46
|
end
|
46
47
|
|
47
48
|
def redirect_uri
|
@@ -12,9 +12,7 @@ module Doorkeeper
|
|
12
12
|
@scope_str = scope_str
|
13
13
|
@valid_scopes = valid_scopes(server_scopes, app_scopes)
|
14
14
|
|
15
|
-
if grant_type
|
16
|
-
@scopes_by_grant_type = Doorkeeper.config.scopes_by_grant_type[grant_type.to_sym]
|
17
|
-
end
|
15
|
+
@scopes_by_grant_type = Doorkeeper.config.scopes_by_grant_type[grant_type.to_sym] if grant_type
|
18
16
|
end
|
19
17
|
|
20
18
|
def valid?
|
@@ -43,8 +43,27 @@ module Doorkeeper
|
|
43
43
|
resource_owner.present?
|
44
44
|
end
|
45
45
|
|
46
|
+
# Section 4.3.2. Access Token Request for Resource Owner Password Credentials Grant:
|
47
|
+
#
|
48
|
+
# If the client type is confidential or the client was issued client credentials (or assigned
|
49
|
+
# other authentication requirements), the client MUST authenticate with the authorization
|
50
|
+
# server as described in Section 3.2.1.
|
51
|
+
#
|
52
|
+
# The authorization server MUST:
|
53
|
+
#
|
54
|
+
# o require client authentication for confidential clients or for any client that was
|
55
|
+
# issued client credentials (or with other authentication requirements)
|
56
|
+
#
|
57
|
+
# o authenticate the client if client authentication is included,
|
58
|
+
#
|
59
|
+
# @see https://tools.ietf.org/html/rfc6749#section-4.3
|
60
|
+
#
|
46
61
|
def validate_client
|
47
|
-
|
62
|
+
if Doorkeeper.config.skip_client_authentication_for_password_grant
|
63
|
+
!parameters[:client_id] || client.present?
|
64
|
+
else
|
65
|
+
client.present?
|
66
|
+
end
|
48
67
|
end
|
49
68
|
|
50
69
|
def validate_client_supports_grant_flow
|
@@ -12,16 +12,19 @@ module Doorkeeper
|
|
12
12
|
validate :redirect_uri, error: :invalid_redirect_uri
|
13
13
|
validate :params, error: :invalid_request
|
14
14
|
validate :response_type, error: :unsupported_response_type
|
15
|
+
validate :response_mode, error: :unsupported_response_mode
|
15
16
|
validate :scopes, error: :invalid_scope
|
16
17
|
validate :code_challenge_method, error: :invalid_code_challenge_method
|
17
18
|
|
18
19
|
attr_reader :client, :code_challenge, :code_challenge_method, :missing_param,
|
19
|
-
:redirect_uri, :resource_owner, :response_type, :state
|
20
|
+
:redirect_uri, :resource_owner, :response_type, :state,
|
21
|
+
:authorization_response_flow, :response_mode
|
20
22
|
|
21
23
|
def initialize(server, parameters = {}, resource_owner = nil)
|
22
24
|
@server = server
|
23
25
|
@client_id = parameters[:client_id]
|
24
26
|
@response_type = parameters[:response_type]
|
27
|
+
@response_mode = parameters[:response_mode]
|
25
28
|
@redirect_uri = parameters[:redirect_uri]
|
26
29
|
@scope = parameters[:scope]
|
27
30
|
@state = parameters[:state]
|
@@ -57,6 +60,10 @@ module Doorkeeper
|
|
57
60
|
pre_auth_hash
|
58
61
|
end
|
59
62
|
|
63
|
+
def form_post_response?
|
64
|
+
response_mode == "form_post"
|
65
|
+
end
|
66
|
+
|
60
67
|
private
|
61
68
|
|
62
69
|
attr_reader :client_id, :server
|
@@ -84,6 +91,11 @@ module Doorkeeper
|
|
84
91
|
Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client.application)
|
85
92
|
end
|
86
93
|
|
94
|
+
def validate_resource_owner_authorize_for_client
|
95
|
+
# The `authorize_resource_owner_for_client` config option is used for this validation
|
96
|
+
client.application.authorized_for_resource_owner?(@resource_owner)
|
97
|
+
end
|
98
|
+
|
87
99
|
def validate_redirect_uri
|
88
100
|
return false if redirect_uri.blank?
|
89
101
|
|
@@ -104,7 +116,21 @@ module Doorkeeper
|
|
104
116
|
end
|
105
117
|
|
106
118
|
def validate_response_type
|
107
|
-
server.
|
119
|
+
server.authorization_response_flows.any? do |flow|
|
120
|
+
if flow.matches_response_type?(response_type)
|
121
|
+
@authorization_response_flow = flow
|
122
|
+
true
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
|
127
|
+
def validate_response_mode
|
128
|
+
if response_mode.blank?
|
129
|
+
@response_mode = authorization_response_flow.default_response_mode
|
130
|
+
return true
|
131
|
+
end
|
132
|
+
|
133
|
+
authorization_response_flow.matches_response_mode?(response_mode)
|
108
134
|
end
|
109
135
|
|
110
136
|
def validate_scopes
|
@@ -117,17 +143,16 @@ module Doorkeeper
|
|
117
143
|
end
|
118
144
|
|
119
145
|
def validate_code_challenge_method
|
146
|
+
return true unless Doorkeeper.config.access_grant_model.pkce_supported?
|
147
|
+
|
120
148
|
code_challenge.blank? ||
|
121
149
|
(code_challenge_method.present? && code_challenge_method =~ /^plain$|^S256$/)
|
122
150
|
end
|
123
151
|
|
124
|
-
def validate_resource_owner_authorize_for_client
|
125
|
-
# The `authorize_resource_owner_for_client` config option is used for this validation
|
126
|
-
client.application.authorized_for_resource_owner?(@resource_owner)
|
127
|
-
end
|
128
|
-
|
129
152
|
def response_on_fragment?
|
130
|
-
response_type == "token"
|
153
|
+
return response_type == "token" if response_mode.nil?
|
154
|
+
|
155
|
+
response_mode == "fragment"
|
131
156
|
end
|
132
157
|
|
133
158
|
def grant_type
|
@@ -62,6 +62,19 @@ module Doorkeeper
|
|
62
62
|
attributes[:previous_refresh_token] = refresh_token.refresh_token
|
63
63
|
end
|
64
64
|
|
65
|
+
# RFC6749
|
66
|
+
# 1.5. Refresh Token
|
67
|
+
#
|
68
|
+
# Refresh tokens are issued to the client by the authorization server and are
|
69
|
+
# used to obtain a new access token when the current access token
|
70
|
+
# becomes invalid or expires, or to obtain additional access tokens
|
71
|
+
# with identical or narrower scope (access tokens may have a shorter
|
72
|
+
# lifetime and fewer permissions than authorized by the resource
|
73
|
+
# owner).
|
74
|
+
#
|
75
|
+
# Here we assume that TTL of the token received after refreshing should be
|
76
|
+
# the same as that of the original token.
|
77
|
+
#
|
65
78
|
@access_token = server_config.access_token_model.create_for(
|
66
79
|
application: refresh_token.application,
|
67
80
|
resource_owner: resource_owner,
|
@@ -137,9 +137,9 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
137
137
|
only = Array.wrap(opts[:only]).map(&:to_s)
|
138
138
|
|
139
139
|
only = if only.blank?
|
140
|
-
|
140
|
+
client_serializable_attributes
|
141
141
|
else
|
142
|
-
only &
|
142
|
+
only & client_serializable_attributes
|
143
143
|
end
|
144
144
|
|
145
145
|
only -= Array.wrap(opts[:except]).map(&:to_s) if opts.key?(:except)
|
@@ -150,7 +150,10 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
|
|
150
150
|
# Override this method if you need additional attributes to be serialized.
|
151
151
|
#
|
152
152
|
# @return [Array<String>] collection of serializable attributes
|
153
|
-
|
153
|
+
#
|
154
|
+
# NOTE: `serializable_attributes` method already taken by Rails >= 6
|
155
|
+
#
|
156
|
+
def client_serializable_attributes
|
154
157
|
attributes = %w[id name created_at]
|
155
158
|
attributes << "uid" unless confidential?
|
156
159
|
attributes
|
@@ -21,6 +21,7 @@ module Doorkeeper
|
|
21
21
|
record.errors.add(attribute, :unspecified_scheme) if unspecified_scheme?(uri)
|
22
22
|
record.errors.add(attribute, :relative_uri) if relative_uri?(uri)
|
23
23
|
record.errors.add(attribute, :secured_uri) if invalid_ssl_uri?(uri)
|
24
|
+
record.errors.add(attribute, :invalid_uri) if unspecified_host?(uri)
|
24
25
|
end
|
25
26
|
end
|
26
27
|
rescue URI::InvalidURIError
|
@@ -43,6 +44,10 @@ module Doorkeeper
|
|
43
44
|
%w[localhost].include?(uri.try(:scheme))
|
44
45
|
end
|
45
46
|
|
47
|
+
def unspecified_host?(uri)
|
48
|
+
uri.is_a?(URI::HTTP) && uri.host.nil?
|
49
|
+
end
|
50
|
+
|
46
51
|
def relative_uri?(uri)
|
47
52
|
uri.scheme.nil? && uri.host.nil?
|
48
53
|
end
|
@@ -20,9 +20,8 @@ module Doorkeeper
|
|
20
20
|
require "doorkeeper/orm/active_record/access_token"
|
21
21
|
require "doorkeeper/orm/active_record/application"
|
22
22
|
|
23
|
-
if Doorkeeper.config.active_record_options[:establish_connection]
|
23
|
+
if (options = Doorkeeper.config.active_record_options[:establish_connection])
|
24
24
|
Doorkeeper::Orm::ActiveRecord.models.each do |model|
|
25
|
-
options = Doorkeeper.config.active_record_options[:establish_connection]
|
26
25
|
model.establish_connection(options)
|
27
26
|
end
|
28
27
|
end
|
@@ -51,9 +50,9 @@ module Doorkeeper
|
|
51
50
|
|
52
51
|
def self.models
|
53
52
|
[
|
54
|
-
Doorkeeper
|
55
|
-
Doorkeeper
|
56
|
-
Doorkeeper
|
53
|
+
Doorkeeper.config.access_grant_model,
|
54
|
+
Doorkeeper.config.access_token_model,
|
55
|
+
Doorkeeper.config.application_model,
|
57
56
|
]
|
58
57
|
end
|
59
58
|
end
|
@@ -29,8 +29,6 @@ module Doorkeeper
|
|
29
29
|
|
30
30
|
def initialize(routes, mapper = Mapper.new, &block)
|
31
31
|
super
|
32
|
-
|
33
|
-
@mapping.skips.push(:applications, :authorized_applications) if Doorkeeper.config.api_only
|
34
32
|
end
|
35
33
|
|
36
34
|
def generate_routes!(options)
|
@@ -38,7 +36,7 @@ module Doorkeeper
|
|
38
36
|
map_route(:authorizations, :authorization_routes)
|
39
37
|
map_route(:tokens, :token_routes)
|
40
38
|
map_route(:tokens, :revoke_routes)
|
41
|
-
map_route(:tokens, :introspect_routes)
|
39
|
+
map_route(:tokens, :introspect_routes) unless Doorkeeper.config.allow_token_introspection.is_a?(FalseClass)
|
42
40
|
map_route(:applications, :application_routes)
|
43
41
|
map_route(:authorized_applications, :authorized_applications_routes)
|
44
42
|
map_route(:token_info, :token_info_routes)
|