doorkeeper 5.6.4 → 5.6.5
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 +6 -0
- data/app/controllers/doorkeeper/authorizations_controller.rb +16 -4
- data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
- data/lib/doorkeeper/config/validations.rb +15 -0
- data/lib/doorkeeper/config.rb +9 -0
- data/lib/doorkeeper/errors.rb +1 -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/password_access_token_request.rb +2 -2
- data/lib/doorkeeper/oauth/pre_authorization.rb +11 -10
- data/lib/doorkeeper/oauth/refresh_token_request.rb +3 -3
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/generators/doorkeeper/templates/initializer.rb +17 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8430b36ebe602cb716e1d404c53e17cbe41a6e122fb3004e77dc5b16ea70a7bd
|
4
|
+
data.tar.gz: 7d8033e2051e21776c0d57e3bbe23d6d2cea04e615c48b9d82a7a704373ff7cb
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: a89cf897778ebd53736ff57f9e7f5eb587ffa6da110e04a62a99816b3719ab9d109700a6cace1d36208bfb34eeb4fd7153aeaef7792275b57cde34e189904510
|
7
|
+
data.tar.gz: bc943f37ca582f1badaa25d98715f1e5ec2a86f8da3f99ef7367cbcc63a99a20a0cc3458d1c2919bb1088e6a09ffd47e33a6634b78b8fcc0e49993681c56a683
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,12 @@ User-visible changes worth mentioning.
|
|
9
9
|
|
10
10
|
- [#ID] Add your PR description here.
|
11
11
|
|
12
|
+
# 5.6.5
|
13
|
+
|
14
|
+
- [#1602] Allow custom data to be stored inside access grants/tokens.
|
15
|
+
- [#1634] Code refactoring for custom token attributes.
|
16
|
+
- [#1639] Add grant type validation to avoid Internal Server Error for DELETE /oauth/authorize endpoint.
|
17
|
+
|
12
18
|
# 5.6.4
|
13
19
|
|
14
20
|
- [#1633] Apply ORM configuration in #to_prepare block to avoid autoloading errors.
|
@@ -13,11 +13,19 @@ 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
|
@@ -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
|
@@ -11,6 +11,7 @@ module Doorkeeper
|
|
11
11
|
validate_reuse_access_token_value
|
12
12
|
validate_token_reuse_limit
|
13
13
|
validate_secret_strategies
|
14
|
+
validate_custom_access_token_attributes
|
14
15
|
end
|
15
16
|
|
16
17
|
private
|
@@ -48,6 +49,20 @@ module Doorkeeper
|
|
48
49
|
)
|
49
50
|
@token_reuse_limit = 100
|
50
51
|
end
|
52
|
+
|
53
|
+
# Validate that the access_token and access_grant models
|
54
|
+
# both respond to all of the custom attributes
|
55
|
+
def validate_custom_access_token_attributes
|
56
|
+
return if custom_access_token_attributes.blank?
|
57
|
+
|
58
|
+
custom_access_token_attributes.each do |attribute_name|
|
59
|
+
[access_token_model, access_grant_model].each do |model|
|
60
|
+
next if model.has_attribute?(attribute_name)
|
61
|
+
|
62
|
+
raise Doorkeeper::Errors::ConfigError, "#{model} does not recognize custom attribute: #{attribute_name}."
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
51
66
|
end
|
52
67
|
end
|
53
68
|
end
|
data/lib/doorkeeper/config.rb
CHANGED
@@ -321,6 +321,15 @@ module Doorkeeper
|
|
321
321
|
option :access_token_generator,
|
322
322
|
default: "Doorkeeper::OAuth::Helpers::UniqueToken"
|
323
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
|
+
|
324
333
|
# Use a custom class for generating the application secret.
|
325
334
|
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-application-secret-generator
|
326
335
|
#
|
data/lib/doorkeeper/errors.rb
CHANGED
@@ -44,6 +44,7 @@ module Doorkeeper
|
|
44
44
|
UnableToGenerateToken = Class.new(DoorkeeperError)
|
45
45
|
TokenGeneratorNotFound = Class.new(DoorkeeperError)
|
46
46
|
NoOrmCleaner = Class.new(DoorkeeperError)
|
47
|
+
ConfigError = Class.new(DoorkeeperError)
|
47
48
|
|
48
49
|
InvalidToken = Class.new(BaseResponseError)
|
49
50
|
TokenExpired = Class.new(InvalidToken)
|
@@ -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
|
@@ -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
|
@@ -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,
|
data/lib/doorkeeper/version.rb
CHANGED
@@ -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
|
#
|
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.5
|
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: 2023-
|
14
|
+
date: 2023-02-22 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|