doorkeeper 5.5.4 → 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 +64 -7
- data/README.md +4 -3
- data/app/controllers/doorkeeper/authorizations_controller.rb +20 -6
- data/app/controllers/doorkeeper/tokens_controller.rb +8 -5
- data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
- data/app/views/doorkeeper/authorizations/new.html.erb +16 -16
- data/lib/doorkeeper/config/abstract_builder.rb +1 -1
- data/lib/doorkeeper/config/validations.rb +3 -3
- data/lib/doorkeeper/config.rb +44 -54
- data/lib/doorkeeper/engine.rb +10 -3
- data/lib/doorkeeper/helpers/controller.rb +1 -1
- data/lib/doorkeeper/models/access_token_mixin.rb +6 -6
- 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 +16 -6
- data/lib/doorkeeper/oauth/base_request.rb +11 -10
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +10 -13
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -2
- 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 +21 -4
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +12 -1
- 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/version.rb +2 -2
- data/lib/doorkeeper.rb +73 -5
- data/lib/generators/doorkeeper/templates/initializer.rb +21 -3
- data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -4
- metadata +21 -19
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,63 @@ 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
|
+
|
39
|
+
## 5.6.2
|
40
|
+
|
41
|
+
- [#1604] Fix fetching of the application when custom application_class defined.
|
42
|
+
|
43
|
+
## 5.6.1
|
44
|
+
|
45
|
+
- [#1593] Add support for Trilogy ActiveRecord adapter.
|
46
|
+
- [#1597] Add optional support to use the url path for the native authorization code flow. Ports forward [#1143] from 4.4.3
|
47
|
+
- [#1599] Remove unnecessarily re-fetch of application object when creating an access token.
|
48
|
+
|
49
|
+
## 5.6.0
|
50
|
+
|
51
|
+
- [#1581] Consider `token_type_hint` when searching for access token in TokensController to avoid extra database calls.
|
52
|
+
|
53
|
+
## 5.6.0.rc2
|
54
|
+
|
55
|
+
- [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
|
56
|
+
application scopes when using client credentials.
|
57
|
+
- [#1567] Only filter `code` parameter if authorization_code grant flow is enabled.
|
58
|
+
|
59
|
+
## 5.6.0.rc1
|
60
|
+
|
61
|
+
- [#1551] Change lazy loading for ORM to be Ruby standard autoload.
|
62
|
+
- [#1552] Remove duplicate IDs on Auth form to improve accessibility.
|
63
|
+
- [#1542] Improve performance of `Doorkeeper::AccessToken#matching_token_for` using database specific SQL time math.
|
64
|
+
|
65
|
+
**[IMPORTANT]**: API of the `Doorkeeper::AccessToken#matching_token_for` method has changed and now it returns
|
66
|
+
only **active** access tokens (previously they were just not revoked). Please remember that the idea of the
|
67
|
+
`reuse_access_token` option is to check for existing _active_ token (see configuration option description).
|
68
|
+
|
12
69
|
## 5.5.4
|
13
70
|
|
14
71
|
- [#1535] Revert changes introduced in #1528 to allow query params in `redirect_uri` as per the spec.
|
@@ -25,12 +82,12 @@ User-visible changes worth mentioning.
|
|
25
82
|
- [#1502] Drop support for Ruby 2.4 because of EOL.
|
26
83
|
- [#1504] Updated the url fragment in the comment for code documentation.
|
27
84
|
- [#1512] Fix form behavior when response mode is form_post.
|
28
|
-
- [#1511] Fix that authorization code is returned by fragment if response_mode is
|
85
|
+
- [#1511] Fix that authorization code is returned by fragment if response_mode is fragment.
|
29
86
|
|
30
87
|
## 5.5.1
|
31
88
|
|
32
89
|
- [#1496] Revoke `old_refresh_token` if `previous_refresh_token` is present.
|
33
|
-
- [#1495] Fix `respond_to` undefined in API-only mode
|
90
|
+
- [#1495] Fix `respond_to` undefined in API-only mode
|
34
91
|
- [#1488] Verify client authentication for Resource Owner Password Grant when
|
35
92
|
`config.skip_client_authentication_for_password_grant` is set and the client credentials
|
36
93
|
are sent in a HTTP Basic auth header.
|
@@ -44,10 +101,10 @@ User-visible changes worth mentioning.
|
|
44
101
|
## 5.5.0.rc2
|
45
102
|
|
46
103
|
- [#1473] Enable `Applications` and `AuthorizedApplications` controllers in API mode.
|
47
|
-
|
48
|
-
**[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
|
104
|
+
|
105
|
+
**[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
|
49
106
|
`use_doorkeeper` inside `routes.rb`. Please do it in case you don't need them.
|
50
|
-
|
107
|
+
|
51
108
|
- [#1472] Fix `establish_connection` configuration for custom defined models.
|
52
109
|
- [#1471] Add support for Ruby 3.0.
|
53
110
|
- [#1469] Check if `redirect_uri` exists.
|
@@ -254,7 +311,7 @@ User-visible changes worth mentioning.
|
|
254
311
|
- [#1237] Allow to set blank redirect URI if Doorkeeper configured to use redirect URI-less grant flows.
|
255
312
|
- [#1234] Fix `StaleRecordsCleaner` to properly work with big amount of records.
|
256
313
|
- [#1228] Allow to explicitly set non-expiring tokens in `custom_access_token_expires_in` configuration
|
257
|
-
option using `Float::
|
314
|
+
option using `Float::INFINITY` return value.
|
258
315
|
- [#1224] Do not try to store token if not found by fallback hashing strategy.
|
259
316
|
- [#1223] Update Hound/Rubocop rules, correct Doorkeeper codebase to follow style-guides.
|
260
317
|
- [#1220] Drop Rails 4.2 & Ruby < 2.4 support.
|
@@ -339,7 +396,7 @@ User-visible changes worth mentioning.
|
|
339
396
|
- [#1116] `AccessGrant`s will now be revoked along with `AccessToken`s when
|
340
397
|
hitting the `AuthorizedApplicationController#destroy` route.
|
341
398
|
- [#1114] Make token info endpoint's attributes consistent with token creation
|
342
|
-
- [#1108] Simple
|
399
|
+
- [#1108] Simple formatting of callback URLs when listing oauth applications
|
343
400
|
- [#1106] Restrict access to AdminController with 'Forbidden 403' if admin_authenticator is not
|
344
401
|
configured by developers.
|
345
402
|
|
data/README.md
CHANGED
@@ -1,10 +1,9 @@
|
|
1
1
|
# Doorkeeper — awesome OAuth 2 provider for your Rails / Grape app.
|
2
2
|
|
3
3
|
[![Gem Version](https://badge.fury.io/rb/doorkeeper.svg)](https://rubygems.org/gems/doorkeeper)
|
4
|
-
[![
|
4
|
+
[![CI](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml/badge.svg)](https://github.com/doorkeeper-gem/doorkeeper/actions/workflows/ci.yml)
|
5
5
|
[![Code Climate](https://codeclimate.com/github/doorkeeper-gem/doorkeeper.svg)](https://codeclimate.com/github/doorkeeper-gem/doorkeeper)
|
6
6
|
[![Coverage Status](https://coveralls.io/repos/github/doorkeeper-gem/doorkeeper/badge.svg?branch=main)](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=main)
|
7
|
-
[![Security](https://hakiri.io/github/doorkeeper-gem/doorkeeper/main.svg)](https://hakiri.io/github/doorkeeper-gem/doorkeeper/main)
|
8
7
|
[![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
|
9
8
|
[![GuardRails badge](https://badges.guardrails.io/doorkeeper-gem/doorkeeper.svg?token=66768ce8f6995814df81f65a2cff40f739f688492704f973e62809e15599bb62)](https://dashboard.guardrails.io/default/gh/doorkeeper-gem/doorkeeper)
|
10
9
|
[![Dependabot](https://img.shields.io/badge/dependabot-enabled-success.svg)](https://dependabot.com)
|
@@ -106,6 +105,8 @@ Extensions that are not included by default and can be installed separately.
|
|
106
105
|
| JWT Token support | [doorkeeper-gem/doorkeeper-jwt](https://github.com/doorkeeper-gem/doorkeeper-jwt) |
|
107
106
|
| Assertion grant extension | [doorkeeper-gem/doorkeeper-grants\_assertion](https://github.com/doorkeeper-gem/doorkeeper-grants_assertion) |
|
108
107
|
| I18n translations | [doorkeeper-gem/doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) |
|
108
|
+
| CIBA - Client Initiated Backchannel Authentication Flow extension | [doorkeeper-ciba](https://github.com/autoseg/doorkeeper-ciba) |
|
109
|
+
| Device Authorization Grant | [doorkeeper-device_authorization_grant](https://github.com/exop-group/doorkeeper-device_authorization_grant) |
|
109
110
|
|
110
111
|
## Example Applications
|
111
112
|
|
@@ -188,4 +189,4 @@ contributors](https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors)!
|
|
188
189
|
|
189
190
|
## License
|
190
191
|
|
191
|
-
MIT License.
|
192
|
+
MIT License. Created in Applicake. Maintained by the community.
|
@@ -13,18 +13,26 @@ 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?
|
27
|
-
redirect_or_render
|
34
|
+
if skip_authorization? || (matching_token? && pre_auth.client.application.confidential?)
|
35
|
+
redirect_or_render(authorize_response)
|
28
36
|
elsif Doorkeeper.configuration.api_only
|
29
37
|
render json: pre_auth
|
30
38
|
else
|
@@ -37,10 +45,12 @@ 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
|
|
52
|
+
# Active access token issued for the same client and resource owner with
|
53
|
+
# the same set of the scopes exists?
|
44
54
|
def matching_token?
|
45
55
|
Doorkeeper.config.access_token_model.matching_token_for(
|
46
56
|
pre_auth.client,
|
@@ -86,7 +96,7 @@ module Doorkeeper
|
|
86
96
|
end
|
87
97
|
|
88
98
|
def pre_auth_param_fields
|
89
|
-
%i[
|
99
|
+
custom_access_token_attributes + %i[
|
90
100
|
client_id
|
91
101
|
code_challenge
|
92
102
|
code_challenge_method
|
@@ -98,6 +108,10 @@ module Doorkeeper
|
|
98
108
|
]
|
99
109
|
end
|
100
110
|
|
111
|
+
def custom_access_token_attributes
|
112
|
+
Doorkeeper.config.custom_access_token_attributes.map(&:to_sym)
|
113
|
+
end
|
114
|
+
|
101
115
|
def authorization
|
102
116
|
@authorization ||= strategy.request
|
103
117
|
end
|
@@ -30,6 +30,7 @@ module Doorkeeper
|
|
30
30
|
end
|
31
31
|
end
|
32
32
|
|
33
|
+
# OAuth 2.0 Token Introspection - https://datatracker.ietf.org/doc/html/rfc7662
|
33
34
|
def introspect
|
34
35
|
introspection = OAuth::TokenIntrospection.new(server, token)
|
35
36
|
|
@@ -115,12 +116,14 @@ module Doorkeeper
|
|
115
116
|
token.revoke if token&.accessible?
|
116
117
|
end
|
117
118
|
|
118
|
-
# Doorkeeper does not use the token_type_hint logic described in the
|
119
|
-
# RFC 7009 due to the refresh token implementation that is a field in
|
120
|
-
# the access token model.
|
121
119
|
def token
|
122
|
-
@token ||=
|
123
|
-
|
120
|
+
@token ||=
|
121
|
+
if params[:token_type_hint] == "refresh_token"
|
122
|
+
Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
|
123
|
+
else
|
124
|
+
Doorkeeper.config.access_token_model.by_token(params["token"]) ||
|
125
|
+
Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
|
126
|
+
end
|
124
127
|
end
|
125
128
|
|
126
129
|
def strategy
|
@@ -21,25 +21,25 @@
|
|
21
21
|
|
22
22
|
<div class="actions">
|
23
23
|
<%= form_tag oauth_authorization_path, method: :post do %>
|
24
|
-
<%= hidden_field_tag :client_id, @pre_auth.client.uid %>
|
25
|
-
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
|
26
|
-
<%= hidden_field_tag :state, @pre_auth.state %>
|
27
|
-
<%= hidden_field_tag :response_type, @pre_auth.response_type %>
|
28
|
-
<%= hidden_field_tag :response_mode, @pre_auth.response_mode %>
|
29
|
-
<%= hidden_field_tag :scope, @pre_auth.scope %>
|
30
|
-
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge %>
|
31
|
-
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method %>
|
24
|
+
<%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %>
|
25
|
+
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %>
|
26
|
+
<%= hidden_field_tag :state, @pre_auth.state, id: nil %>
|
27
|
+
<%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %>
|
28
|
+
<%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %>
|
29
|
+
<%= hidden_field_tag :scope, @pre_auth.scope, id: nil %>
|
30
|
+
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %>
|
31
|
+
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %>
|
32
32
|
<%= submit_tag t('doorkeeper.authorizations.buttons.authorize'), class: "btn btn-success btn-lg btn-block" %>
|
33
33
|
<% end %>
|
34
34
|
<%= form_tag oauth_authorization_path, method: :delete do %>
|
35
|
-
<%= hidden_field_tag :client_id, @pre_auth.client.uid %>
|
36
|
-
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri %>
|
37
|
-
<%= hidden_field_tag :state, @pre_auth.state %>
|
38
|
-
<%= hidden_field_tag :response_type, @pre_auth.response_type %>
|
39
|
-
<%= hidden_field_tag :response_mode, @pre_auth.response_mode %>
|
40
|
-
<%= hidden_field_tag :scope, @pre_auth.scope %>
|
41
|
-
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge %>
|
42
|
-
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method %>
|
35
|
+
<%= hidden_field_tag :client_id, @pre_auth.client.uid, id: nil %>
|
36
|
+
<%= hidden_field_tag :redirect_uri, @pre_auth.redirect_uri, id: nil %>
|
37
|
+
<%= hidden_field_tag :state, @pre_auth.state, id: nil %>
|
38
|
+
<%= hidden_field_tag :response_type, @pre_auth.response_type, id: nil %>
|
39
|
+
<%= hidden_field_tag :response_mode, @pre_auth.response_mode, id: nil %>
|
40
|
+
<%= hidden_field_tag :scope, @pre_auth.scope, id: nil %>
|
41
|
+
<%= hidden_field_tag :code_challenge, @pre_auth.code_challenge, id: nil %>
|
42
|
+
<%= hidden_field_tag :code_challenge_method, @pre_auth.code_challenge_method, id: nil %>
|
43
43
|
<%= submit_tag t('doorkeeper.authorizations.buttons.deny'), class: "btn btn-danger btn-lg btn-block" %>
|
44
44
|
<% end %>
|
45
45
|
</div>
|
@@ -24,8 +24,8 @@ module Doorkeeper
|
|
24
24
|
return if !reuse_access_token || strategy.allows_restoring_secrets?
|
25
25
|
|
26
26
|
::Rails.logger.warn(
|
27
|
-
"You have configured both reuse_access_token " \
|
28
|
-
"AND
|
27
|
+
"[DOORKEEPER] You have configured both reuse_access_token " \
|
28
|
+
"AND '#{strategy}' strategy which cannot restore tokens. " \
|
29
29
|
"This combination is unsupported. reuse_access_token will be disabled",
|
30
30
|
)
|
31
31
|
@reuse_access_token = false
|
@@ -43,7 +43,7 @@ module Doorkeeper
|
|
43
43
|
(token_reuse_limit > 0 && token_reuse_limit <= 100)
|
44
44
|
|
45
45
|
::Rails.logger.warn(
|
46
|
-
"You have configured an invalid value for token_reuse_limit option. " \
|
46
|
+
"[DOORKEEPER] You have configured an invalid value for token_reuse_limit option. " \
|
47
47
|
"It will be set to default 100",
|
48
48
|
)
|
49
49
|
@token_reuse_limit = 100
|
data/lib/doorkeeper/config.rb
CHANGED
@@ -5,59 +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
|
-
def configure(&block)
|
25
|
-
@config = Config::Builder.new(&block).build
|
26
|
-
setup_orm_adapter
|
27
|
-
setup_orm_models
|
28
|
-
setup_application_owner if @config.enable_application_owner?
|
29
|
-
@config
|
30
|
-
end
|
31
|
-
|
32
|
-
# @return [Doorkeeper::Config] configuration instance
|
33
|
-
#
|
34
|
-
def configuration
|
35
|
-
@config || (raise MissingConfiguration)
|
36
|
-
end
|
37
|
-
|
38
|
-
alias config configuration
|
39
|
-
|
40
|
-
def setup_orm_adapter
|
41
|
-
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
42
|
-
rescue NameError => e
|
43
|
-
raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
|
44
|
-
[DOORKEEPER] ORM adapter not found (#{configuration.orm}), or there was an error
|
45
|
-
trying to load it.
|
46
|
-
|
47
|
-
You probably need to add the related gem for this adapter to work with
|
48
|
-
doorkeeper.
|
49
|
-
ERROR_MSG
|
50
|
-
end
|
51
|
-
|
52
|
-
def setup_orm_models
|
53
|
-
@orm_adapter.initialize_models!
|
54
|
-
end
|
55
|
-
|
56
|
-
def setup_application_owner
|
57
|
-
@orm_adapter.initialize_application_owner!
|
58
|
-
end
|
59
|
-
end
|
60
|
-
|
61
13
|
class Config
|
62
14
|
# Default Doorkeeper configuration builder
|
63
15
|
class Builder < AbstractBuilder
|
@@ -137,6 +89,15 @@ module Doorkeeper
|
|
137
89
|
@config.instance_variable_set(:@reuse_access_token, true)
|
138
90
|
end
|
139
91
|
|
92
|
+
# Choose to use the url path for native autorization codes
|
93
|
+
# Enabling this flag sets the authorization code response route for
|
94
|
+
# native redirect uris to oauth/authorize/<code>. The default is
|
95
|
+
# oauth/authorize/native?code=<code>.
|
96
|
+
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1143
|
97
|
+
def use_url_path_for_native_authorization
|
98
|
+
@config.instance_variable_set(:@use_url_path_for_native_authorization, true)
|
99
|
+
end
|
100
|
+
|
140
101
|
# TODO: maybe make it more generic for other flows too?
|
141
102
|
# Only allow one valid access token obtained via client credentials
|
142
103
|
# per client. If a new access token is obtained before the old one
|
@@ -293,10 +254,6 @@ module Doorkeeper
|
|
293
254
|
option :skip_client_authentication_for_password_grant,
|
294
255
|
default: false
|
295
256
|
|
296
|
-
option :active_record_options,
|
297
|
-
default: {},
|
298
|
-
deprecated: { message: "Customize Doorkeeper models instead" }
|
299
|
-
|
300
257
|
# Hook to allow arbitrary user-client authorization
|
301
258
|
option :authorize_resource_owner_for_client,
|
302
259
|
default: ->(_client, _resource_owner) { true }
|
@@ -364,11 +321,29 @@ module Doorkeeper
|
|
364
321
|
option :access_token_generator,
|
365
322
|
default: "Doorkeeper::OAuth::Helpers::UniqueToken"
|
366
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
|
+
|
333
|
+
# Use a custom class for generating the application secret.
|
334
|
+
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-application-secret-generator
|
335
|
+
#
|
336
|
+
# @param application_secret_generator [String]
|
337
|
+
# the name of the application secret generator class
|
338
|
+
#
|
339
|
+
option :application_secret_generator,
|
340
|
+
default: "Doorkeeper::OAuth::Helpers::UniqueToken"
|
341
|
+
|
367
342
|
# Default access token generator is a SecureRandom class from Ruby stdlib.
|
368
343
|
# This option defines which method will be used to generate a unique token value.
|
369
344
|
#
|
370
|
-
# @param
|
371
|
-
# the name of the access token generator
|
345
|
+
# @param default_generator_method [Symbol]
|
346
|
+
# the method name of the default access token generator
|
372
347
|
#
|
373
348
|
option :default_generator_method, default: :urlsafe_base64
|
374
349
|
|
@@ -441,6 +416,16 @@ module Doorkeeper
|
|
441
416
|
:token_secret_fallback_strategy,
|
442
417
|
:application_secret_fallback_strategy
|
443
418
|
|
419
|
+
def clear_cache!
|
420
|
+
%i[
|
421
|
+
application_model
|
422
|
+
access_token_model
|
423
|
+
access_grant_model
|
424
|
+
].each do |var|
|
425
|
+
remove_instance_variable("@#{var}") if instance_variable_defined?("@#{var}")
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
444
429
|
# Doorkeeper Access Token model class.
|
445
430
|
#
|
446
431
|
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
@@ -581,6 +566,11 @@ module Doorkeeper
|
|
581
566
|
def deprecated_token_grant_types_resolver
|
582
567
|
@deprecated_token_grant_types ||= calculate_token_grant_types
|
583
568
|
end
|
569
|
+
|
570
|
+
def native_authorization_code_route
|
571
|
+
@use_url_path_for_native_authorization = false unless defined?(@use_url_path_for_native_authorization)
|
572
|
+
@use_url_path_for_native_authorization ? '/:code' : '/native'
|
573
|
+
end
|
584
574
|
|
585
575
|
# [NOTE]: deprecated and will be removed soon
|
586
576
|
def deprecated_authorization_flows
|
data/lib/doorkeeper/engine.rb
CHANGED
@@ -2,9 +2,12 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
class Engine < Rails::Engine
|
5
|
-
initializer "doorkeeper.params.filter" do |app|
|
6
|
-
|
7
|
-
|
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
|
8
11
|
end
|
9
12
|
|
10
13
|
initializer "doorkeeper.routes" do
|
@@ -17,6 +20,10 @@ module Doorkeeper
|
|
17
20
|
end
|
18
21
|
end
|
19
22
|
|
23
|
+
config.to_prepare do
|
24
|
+
Doorkeeper.run_orm_hooks
|
25
|
+
end
|
26
|
+
|
20
27
|
if defined?(Sprockets) && Sprockets::VERSION.chr.to_i >= 4
|
21
28
|
initializer "doorkeeper.assets.precompile" do |app|
|
22
29
|
# Force users to use:
|
@@ -13,6 +13,7 @@ module Doorkeeper
|
|
13
13
|
include Models::SecretStorable
|
14
14
|
include Models::Scopes
|
15
15
|
include Models::ResourceOwnerable
|
16
|
+
include Models::ExpirationTimeSqlMath
|
16
17
|
|
17
18
|
module ClassMethods
|
18
19
|
# Returns an instance of the Doorkeeper::AccessToken with
|
@@ -86,8 +87,9 @@ module Doorkeeper
|
|
86
87
|
# @return [Doorkeeper::AccessToken, nil] Access Token instance or
|
87
88
|
# nil if matching record was not found
|
88
89
|
#
|
89
|
-
def matching_token_for(application, resource_owner, scopes)
|
90
|
+
def matching_token_for(application, resource_owner, scopes, include_expired: true)
|
90
91
|
tokens = authorized_tokens_for(application&.id, resource_owner)
|
92
|
+
tokens = tokens.not_expired unless include_expired
|
91
93
|
find_matching_token(tokens, application, scopes)
|
92
94
|
end
|
93
95
|
|
@@ -104,9 +106,7 @@ module Doorkeeper
|
|
104
106
|
#
|
105
107
|
# ActiveRecord 5.x - 6.x ignores custom ordering so we can't perform a
|
106
108
|
# database sort by created_at, so we need to load all the matching records,
|
107
|
-
# sort them and find latest one.
|
108
|
-
# query using Time math if possible, but we n eed to consider ORM and
|
109
|
-
# different databases support.
|
109
|
+
# sort them and find latest one.
|
110
110
|
#
|
111
111
|
# @param relation [ActiveRecord::Relation]
|
112
112
|
# Access tokens relation
|
@@ -181,7 +181,7 @@ module Doorkeeper
|
|
181
181
|
#
|
182
182
|
def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes)
|
183
183
|
if Doorkeeper.config.reuse_access_token
|
184
|
-
access_token = matching_token_for(application, resource_owner, scopes)
|
184
|
+
access_token = matching_token_for(application, resource_owner, scopes, include_expired: false)
|
185
185
|
|
186
186
|
return access_token if access_token&.reusable?
|
187
187
|
end
|
@@ -213,7 +213,7 @@ module Doorkeeper
|
|
213
213
|
# @return [Doorkeeper::AccessToken] new access token
|
214
214
|
#
|
215
215
|
def create_for(application:, resource_owner:, scopes:, **token_attributes)
|
216
|
-
token_attributes[:
|
216
|
+
token_attributes[:application] = application
|
217
217
|
token_attributes[:scopes] = scopes.to_s
|
218
218
|
|
219
219
|
if Doorkeeper.config.polymorphic_resource_owner?
|
@@ -0,0 +1,88 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module Models
|
5
|
+
module ExpirationTimeSqlMath
|
6
|
+
extend ::ActiveSupport::Concern
|
7
|
+
|
8
|
+
class ExpirationTimeSqlGenerator
|
9
|
+
attr_reader :model
|
10
|
+
|
11
|
+
delegate :table_name, to: :@model
|
12
|
+
|
13
|
+
def initialize(model)
|
14
|
+
@model = model
|
15
|
+
end
|
16
|
+
|
17
|
+
def generate_sql
|
18
|
+
raise "`generate_sql` should be overridden for a #{self.class.name}!"
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
class MySqlExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
23
|
+
def generate_sql
|
24
|
+
Arel.sql("DATE_ADD(#{table_name}.created_at, INTERVAL #{table_name}.expires_in SECOND)")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class SqlLiteExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
29
|
+
def generate_sql
|
30
|
+
Arel.sql("DATETIME(#{table_name}.created_at, '+' || #{table_name}.expires_in || ' SECONDS')")
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class SqlServerExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
35
|
+
def generate_sql
|
36
|
+
Arel.sql("DATEADD(second, #{table_name}.expires_in, #{table_name}.created_at) AT TIME ZONE 'UTC'")
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
class OracleExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
41
|
+
def generate_sql
|
42
|
+
Arel.sql("#{table_name}.created_at + INTERVAL to_char(#{table_name}.expires_in) second")
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
46
|
+
class PostgresExpirationTimeSqlGenerator < ExpirationTimeSqlGenerator
|
47
|
+
def generate_sql
|
48
|
+
Arel.sql("#{table_name}.created_at + #{table_name}.expires_in * INTERVAL '1 SECOND'")
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
ADAPTERS_MAPPING = {
|
53
|
+
"sqlite" => SqlLiteExpirationTimeSqlGenerator,
|
54
|
+
"sqlite3" => SqlLiteExpirationTimeSqlGenerator,
|
55
|
+
"postgis" => PostgresExpirationTimeSqlGenerator,
|
56
|
+
"postgresql" => PostgresExpirationTimeSqlGenerator,
|
57
|
+
"mysql" => MySqlExpirationTimeSqlGenerator,
|
58
|
+
"mysql2" => MySqlExpirationTimeSqlGenerator,
|
59
|
+
"trilogy" => MySqlExpirationTimeSqlGenerator,
|
60
|
+
"sqlserver" => SqlServerExpirationTimeSqlGenerator,
|
61
|
+
"oracleenhanced" => OracleExpirationTimeSqlGenerator,
|
62
|
+
}.freeze
|
63
|
+
|
64
|
+
module ClassMethods
|
65
|
+
def supports_expiration_time_math?
|
66
|
+
ADAPTERS_MAPPING.key?(adapter_name.downcase) ||
|
67
|
+
respond_to?(:custom_expiration_time_sql)
|
68
|
+
end
|
69
|
+
|
70
|
+
def expiration_time_sql
|
71
|
+
if respond_to?(:custom_expiration_time_sql)
|
72
|
+
custom_expiration_time_sql
|
73
|
+
else
|
74
|
+
expiration_time_sql_expression
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
def expiration_time_sql_expression
|
79
|
+
ADAPTERS_MAPPING.fetch(adapter_name.downcase).new(self).generate_sql
|
80
|
+
end
|
81
|
+
|
82
|
+
def adapter_name
|
83
|
+
ActiveRecord::Base.connection.adapter_name
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
87
|
+
end
|
88
|
+
end
|