doorkeeper 5.8.0 → 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 +7 -0
- data/app/controllers/doorkeeper/tokens_controller.rb +24 -5
- data/config/locales/en.yml +4 -1
- data/lib/doorkeeper/errors.rb +14 -1
- data/lib/doorkeeper/oauth/base_request.rb +2 -1
- data/lib/doorkeeper/oauth/error.rb +4 -3
- data/lib/doorkeeper/oauth/error_response.rb +2 -1
- data/lib/doorkeeper/oauth/pre_authorization.rb +1 -1
- data/lib/doorkeeper/oauth/scopes.rb +18 -0
- 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 +1 -1
- data/lib/doorkeeper.rb +5 -0
- metadata +5 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8364fc5d75f9cbe96cc3ef67c8010dde471eb51ced0cf328f9ca84705553976f
|
4
|
+
data.tar.gz: db817023f41b070185ae9d6fae32b9d9b0eb0fc7abf8bdd99961c80e8bece1dd
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 940f6253760d9117390495e97fa270aa0337a7379d2070d2be5ce2a44cf8148f451ffe7a3ba0451ab88d1cbb5bd4242f6d4a7de90204cf2749a57bdeaa4005ed
|
7
|
+
data.tar.gz: 728ea65c1e37f7f77183e5528c441cf7b9c8a4493428bbafbfe7815dec4b227d8bd033e05c4ee2dde50b9cc252cad7241b5d287d2df28e6631f9ccada5c7afc5
|
data/CHANGELOG.md
CHANGED
@@ -9,6 +9,13 @@ User-visible changes worth mentioning.
|
|
9
9
|
|
10
10
|
Add your entry here.
|
11
11
|
|
12
|
+
## 5.8.1
|
13
|
+
|
14
|
+
- [#1752] Bump the range of supported Ruby and Rails versions
|
15
|
+
- [#1747] Fix unknown pkce method error when configured
|
16
|
+
- [#1744] Allow for expired refresh tokens to be revoked
|
17
|
+
- [#1754] Fix refresh tokens with dynamic scopes
|
18
|
+
|
12
19
|
## 5.8.0
|
13
20
|
|
14
21
|
- [#1739] Add support for dynamic scopes
|
@@ -113,19 +113,38 @@ module Doorkeeper
|
|
113
113
|
# The authorization server responds with HTTP status code 200 if the token
|
114
114
|
# has been revoked successfully or if the client submitted an invalid
|
115
115
|
# token
|
116
|
-
|
116
|
+
revocable_token.revoke if revocable_token.revocable?
|
117
117
|
end
|
118
118
|
|
119
119
|
def token
|
120
|
-
|
120
|
+
revocable_token&.token
|
121
|
+
end
|
122
|
+
|
123
|
+
def revocable_token
|
124
|
+
return @revocable_token if defined? @revocable_token
|
125
|
+
|
126
|
+
@revocable_token =
|
121
127
|
if params[:token_type_hint] == "refresh_token"
|
122
|
-
|
128
|
+
refresh_token
|
123
129
|
else
|
124
|
-
|
125
|
-
Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
|
130
|
+
access_token || refresh_token
|
126
131
|
end
|
127
132
|
end
|
128
133
|
|
134
|
+
def refresh_token
|
135
|
+
token = Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
|
136
|
+
return unless token
|
137
|
+
|
138
|
+
RevocableTokens::RevocableRefreshToken.new(token)
|
139
|
+
end
|
140
|
+
|
141
|
+
def access_token
|
142
|
+
token = Doorkeeper.config.access_token_model.by_token(params["token"])
|
143
|
+
return unless token
|
144
|
+
|
145
|
+
RevocableTokens::RevocableAccessToken.new(token)
|
146
|
+
end
|
147
|
+
|
129
148
|
def strategy
|
130
149
|
@strategy ||= server.token_request(params[:grant_type])
|
131
150
|
end
|
data/config/locales/en.yml
CHANGED
@@ -100,7 +100,10 @@ en:
|
|
100
100
|
unauthorized_client: 'The client is not authorized to perform this request using this method.'
|
101
101
|
access_denied: 'The resource owner or authorization server denied the request.'
|
102
102
|
invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
|
103
|
-
invalid_code_challenge_method:
|
103
|
+
invalid_code_challenge_method:
|
104
|
+
zero: 'The authorization server does not support PKCE as there are no accepted code_challenge_method values.'
|
105
|
+
one: 'The code_challenge_method must be %{challenge_methods}.'
|
106
|
+
other: 'The code_challenge_method must be one of %{challenge_methods}.'
|
104
107
|
server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
|
105
108
|
temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
|
106
109
|
|
data/lib/doorkeeper/errors.rb
CHANGED
@@ -6,6 +6,10 @@ module Doorkeeper
|
|
6
6
|
def type
|
7
7
|
message
|
8
8
|
end
|
9
|
+
|
10
|
+
def self.translate_options
|
11
|
+
{}
|
12
|
+
end
|
9
13
|
end
|
10
14
|
|
11
15
|
class InvalidGrantReuse < DoorkeeperError
|
@@ -45,6 +49,16 @@ module Doorkeeper
|
|
45
49
|
end
|
46
50
|
end
|
47
51
|
|
52
|
+
class InvalidCodeChallengeMethod < BaseResponseError
|
53
|
+
def self.translate_options
|
54
|
+
challenge_methods = Doorkeeper.config.pkce_code_challenge_methods_supported
|
55
|
+
{
|
56
|
+
challenge_methods: challenge_methods.join(", "),
|
57
|
+
count: challenge_methods.length
|
58
|
+
}
|
59
|
+
end
|
60
|
+
end
|
61
|
+
|
48
62
|
UnableToGenerateToken = Class.new(DoorkeeperError)
|
49
63
|
TokenGeneratorNotFound = Class.new(DoorkeeperError)
|
50
64
|
NoOrmCleaner = Class.new(DoorkeeperError)
|
@@ -55,7 +69,6 @@ module Doorkeeper
|
|
55
69
|
InvalidScope = Class.new(BaseResponseError)
|
56
70
|
InvalidRedirectUri = Class.new(BaseResponseError)
|
57
71
|
InvalidCodeChallenge = Class.new(BaseResponseError)
|
58
|
-
InvalidCodeChallengeMethod = Class.new(BaseResponseError)
|
59
72
|
InvalidGrant = Class.new(BaseResponseError)
|
60
73
|
|
61
74
|
UnauthorizedClient = Class.new(BaseResponseError)
|
@@ -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
|
@@ -12,6 +12,7 @@ module Doorkeeper
|
|
12
12
|
attributes.merge(
|
13
13
|
name: error_name_for(request.error),
|
14
14
|
exception_class: exception_class_for(request.error),
|
15
|
+
translate_options: request.error.try(:translate_options),
|
15
16
|
state: request.try(:state),
|
16
17
|
redirect_uri: request.try(:redirect_uri),
|
17
18
|
),
|
@@ -33,7 +34,7 @@ module Doorkeeper
|
|
33
34
|
delegate :name, :description, :state, to: :@error
|
34
35
|
|
35
36
|
def initialize(attributes = {})
|
36
|
-
@error = OAuth::Error.new(*attributes.values_at(:name, :state))
|
37
|
+
@error = OAuth::Error.new(*attributes.values_at(:name, :state, :translate_options))
|
37
38
|
@exception_class = attributes[:exception_class]
|
38
39
|
@redirect_uri = attributes[:redirect_uri]
|
39
40
|
@response_on_fragment = attributes[:response_on_fragment]
|
@@ -70,10 +70,28 @@ module Doorkeeper
|
|
70
70
|
end
|
71
71
|
end
|
72
72
|
|
73
|
+
# DEPRECATED: With dynamic scopes, #allowed should be called because
|
74
|
+
# A & B doesn't really make sense with dynamic scopes.
|
75
|
+
#
|
76
|
+
# For example, if A = user:* and B is user:1, A & B = [].
|
77
|
+
# If we modified this method to take dynamic scopes into an account, then order
|
78
|
+
# becomes important, and this would violate the principle that A & B = B & A.
|
73
79
|
def &(other)
|
80
|
+
return allowed(other) if dynamic_scopes_enabled?
|
81
|
+
|
74
82
|
self.class.from_array(all & to_array(other))
|
75
83
|
end
|
76
84
|
|
85
|
+
# Returns a set of scopes that are allowed, taking dynamic
|
86
|
+
# scopes into account. This instance's scopes is taken as the allowed set,
|
87
|
+
# and the passed value is the set to filter.
|
88
|
+
#
|
89
|
+
# @param other The set of scopes to filter
|
90
|
+
def allowed(other)
|
91
|
+
filtered_scopes = other.select { |scope| self.exists?(scope) }
|
92
|
+
self.class.from_array(filtered_scopes)
|
93
|
+
end
|
94
|
+
|
77
95
|
private
|
78
96
|
|
79
97
|
def dynamic_scopes_enabled?
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module RevocableTokens
|
5
|
+
class RevocableAccessToken
|
6
|
+
attr_reader :token
|
7
|
+
|
8
|
+
def initialize(token)
|
9
|
+
@token = token
|
10
|
+
end
|
11
|
+
|
12
|
+
def revocable?
|
13
|
+
token.accessible?
|
14
|
+
end
|
15
|
+
|
16
|
+
def revoke
|
17
|
+
token.revoke
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module RevocableTokens
|
5
|
+
class RevocableRefreshToken
|
6
|
+
attr_reader :token
|
7
|
+
|
8
|
+
def initialize(token)
|
9
|
+
@token = token
|
10
|
+
end
|
11
|
+
|
12
|
+
def revocable?
|
13
|
+
!token.revoked?
|
14
|
+
end
|
15
|
+
|
16
|
+
def revoke
|
17
|
+
token.revoke
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/doorkeeper/version.rb
CHANGED
data/lib/doorkeeper.rb
CHANGED
@@ -34,6 +34,11 @@ module Doorkeeper
|
|
34
34
|
autoload :Token, "doorkeeper/request/token"
|
35
35
|
end
|
36
36
|
|
37
|
+
module RevocableTokens
|
38
|
+
autoload :RevocableAccessToken, "doorkeeper/revocable_tokens/revocable_access_token"
|
39
|
+
autoload :RevocableRefreshToken, "doorkeeper/revocable_tokens/revocable_refresh_token"
|
40
|
+
end
|
41
|
+
|
37
42
|
module OAuth
|
38
43
|
autoload :BaseRequest, "doorkeeper/oauth/base_request"
|
39
44
|
autoload :AuthorizationCodeRequest, "doorkeeper/oauth/authorization_code_request"
|
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.8.
|
4
|
+
version: 5.8.1
|
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: 2024-
|
14
|
+
date: 2024-12-09 00:00:00.000000000 Z
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
17
17
|
name: railties
|
@@ -290,6 +290,8 @@ files:
|
|
290
290
|
- lib/doorkeeper/request/refresh_token.rb
|
291
291
|
- lib/doorkeeper/request/strategy.rb
|
292
292
|
- lib/doorkeeper/request/token.rb
|
293
|
+
- lib/doorkeeper/revocable_tokens/revocable_access_token.rb
|
294
|
+
- lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb
|
293
295
|
- lib/doorkeeper/secret_storing/base.rb
|
294
296
|
- lib/doorkeeper/secret_storing/bcrypt.rb
|
295
297
|
- lib/doorkeeper/secret_storing/plain.rb
|
@@ -326,6 +328,7 @@ metadata:
|
|
326
328
|
source_code_uri: https://github.com/doorkeeper-gem/doorkeeper
|
327
329
|
bug_tracker_uri: https://github.com/doorkeeper-gem/doorkeeper/issues
|
328
330
|
documentation_uri: https://doorkeeper.gitbook.io/guides/
|
331
|
+
funding_uri: https://opencollective.com/doorkeeper-gem
|
329
332
|
post_install_message: "Starting from 5.5.0 RC1 Doorkeeper requires client authentication
|
330
333
|
for Resource Owner Password Grant\nas stated in the OAuth RFC. You have to create
|
331
334
|
a new OAuth client (Doorkeeper::Application) if you didn't\nhave it before and use
|