doorkeeper 5.5.4 → 5.8.2

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.
Files changed (57) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +118 -8
  3. data/README.md +5 -9
  4. data/app/controllers/doorkeeper/authorizations_controller.rb +34 -11
  5. data/app/controllers/doorkeeper/tokens_controller.rb +32 -8
  6. data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
  7. data/app/views/doorkeeper/authorizations/form_post.html.erb +1 -1
  8. data/app/views/doorkeeper/authorizations/new.html.erb +16 -16
  9. data/config/locales/en.yml +5 -1
  10. data/lib/doorkeeper/config/abstract_builder.rb +1 -1
  11. data/lib/doorkeeper/config/validations.rb +15 -3
  12. data/lib/doorkeeper/config.rb +95 -55
  13. data/lib/doorkeeper/engine.rb +10 -3
  14. data/lib/doorkeeper/errors.rb +31 -0
  15. data/lib/doorkeeper/helpers/controller.rb +1 -1
  16. data/lib/doorkeeper/models/access_token_mixin.rb +71 -9
  17. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  18. data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
  19. data/lib/doorkeeper/oauth/authorization/code.rb +7 -1
  20. data/lib/doorkeeper/oauth/authorization/token.rb +7 -1
  21. data/lib/doorkeeper/oauth/authorization_code_request.rb +32 -12
  22. data/lib/doorkeeper/oauth/base_request.rb +14 -12
  23. data/lib/doorkeeper/oauth/client.rb +1 -1
  24. data/lib/doorkeeper/oauth/client_credentials/creator.rb +13 -13
  25. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +5 -4
  26. data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -5
  27. data/lib/doorkeeper/oauth/client_credentials_request.rb +10 -2
  28. data/lib/doorkeeper/oauth/code_request.rb +1 -1
  29. data/lib/doorkeeper/oauth/error.rb +4 -3
  30. data/lib/doorkeeper/oauth/error_response.rb +19 -4
  31. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +4 -4
  32. data/lib/doorkeeper/oauth/invalid_request_response.rb +4 -0
  33. data/lib/doorkeeper/oauth/password_access_token_request.rb +6 -6
  34. data/lib/doorkeeper/oauth/pre_authorization.rb +35 -23
  35. data/lib/doorkeeper/oauth/refresh_token_request.rb +17 -9
  36. data/lib/doorkeeper/oauth/scopes.rb +55 -1
  37. data/lib/doorkeeper/oauth/token_introspection.rb +34 -20
  38. data/lib/doorkeeper/oauth/token_request.rb +1 -1
  39. data/lib/doorkeeper/oauth/token_response.rb +5 -3
  40. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +0 -6
  41. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +21 -4
  42. data/lib/doorkeeper/orm/active_record/mixins/application.rb +22 -4
  43. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +2 -2
  44. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +5 -2
  45. data/lib/doorkeeper/orm/active_record.rb +30 -37
  46. data/lib/doorkeeper/rails/helpers.rb +3 -1
  47. data/lib/doorkeeper/rails/routes.rb +12 -3
  48. data/lib/doorkeeper/rake/setup.rake +0 -5
  49. data/lib/doorkeeper/revocable_tokens/revocable_access_token.rb +21 -0
  50. data/lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb +21 -0
  51. data/lib/doorkeeper/version.rb +2 -2
  52. data/lib/doorkeeper.rb +78 -5
  53. data/lib/generators/doorkeeper/remove_applications_secret_not_null_constraint_generator.rb +33 -0
  54. data/lib/generators/doorkeeper/templates/initializer.rb +44 -6
  55. data/lib/generators/doorkeeper/templates/migration.rb.erb +15 -4
  56. data/lib/generators/doorkeeper/templates/remove_applications_secret_not_null_constraint.rb.erb +7 -0
  57. metadata +28 -21
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 55c17555b9591b1a06b8164b0508ab733df8dca59e4b555e1dac3b3cc7a1112e
4
- data.tar.gz: 56fd2b8475c97f0bc755086cc22ee1aa14d2ac47263f0e218f3cf4f9f80d5b38
3
+ metadata.gz: de574cec8c17af2fd1026081acc0bf592c71ecbf947d92546df6b4d48ce3b5ce
4
+ data.tar.gz: eb282ce352bbd4491014b753535ff24e804ca801e02aef8a6ded3f7ca5951e64
5
5
  SHA512:
6
- metadata.gz: b21d497b70266436f0446eec977f9ff074f646c0cdf417e08c8806529474ea91d112f0f1357a614f9e136b0dd042d665f7ea7325740254770ff01469df595390
7
- data.tar.gz: eb23ac65993cf89d82b66e5616b231d58fd0ac928486354a2bc36fdf7173fb3ba807f434f85a45f4ea6d1600847b46bdd5ad76ea9d317c16908a114b18fdb94a
6
+ metadata.gz: 68b668d79eb5532cb4dbe660eb26269d67eb545b5dbd12bae15c087752c7e5447e1f60326725c0d838189a746de5718e8644605dcdd946d4f2cf29a556297369
7
+ data.tar.gz: 8ad2d79f707129abd0787710cc86ee563af9887f986dec03edc396c691ffb26e18279b3693bc15658d059e78dd7dc2ce3093a137c03bb16e7858832d9e80c368
data/CHANGELOG.md CHANGED
@@ -7,7 +7,117 @@ User-visible changes worth mentioning.
7
7
 
8
8
  ## main
9
9
 
10
- - [#ID] Add your PR description here.
10
+ Add your entry here.
11
+
12
+ ## 5.8.2
13
+
14
+ - [#1755] Fix the error message for force_pkce
15
+ - [#1761] Memoize authentication failure
16
+ - [#1762] Allow missing client to trigger invalid client error when force_pkce is enabled
17
+ - [#1767] Make sure error handling happens on a controller level opposed to action level to account for the controller being extended
18
+
19
+ ## 5.8.1
20
+
21
+ - [#1752] Bump the range of supported Ruby and Rails versions
22
+ - [#1747] Fix unknown pkce method error when configured
23
+ - [#1744] Allow for expired refresh tokens to be revoked
24
+ - [#1754] Fix refresh tokens with dynamic scopes
25
+
26
+ ## 5.8.0
27
+
28
+ - [#1739] Add support for dynamic scopes
29
+ - [#1715] Fix token introspection invalid request reason
30
+ - [#1714] Fix `Doorkeeper::AccessToken.find_or_create_for` with empty scopes which raises NoMethodError
31
+ - [#1712] Add `Pragma: no-cache` to token response
32
+ - [#1726] Refactor token introspection class.
33
+ - [#1727] Allow to set null secret value for Applications if they are public.
34
+ - [#1735] Add `pkce_code_challenge_methods` config option.
35
+
36
+ ## 5.7.1
37
+
38
+ - [#1705] Add `force_pkce` option that requires non-confidential clients to use PKCE when requesting an access_token using an authorization code
39
+
40
+ ## 5.7.0
41
+
42
+ - [#1696] Add missing `#issued_token` method to `OAuth::TokenResponse`
43
+ - [#1697] Allow a TokenResponse body to be customized (memoize response body).
44
+ - [#1702] Fix bugs for error response in the form_post and error view
45
+ - [#1660] Custom access token attributes are now considered when finding matching tokens (fixes #1665).
46
+ Introduce `revoke_previous_client_credentials_token` configuration option.
47
+
48
+ ## 5.6.9
49
+
50
+ - [#1691] Make new Doorkeeper errors backward compatible with older extensions.
51
+
52
+ ## 5.6.8
53
+
54
+ - [#1680] Fix handle_auth_errors :raise NotImplementedError
55
+
56
+ ## 5.6.7
57
+
58
+ - [#1662] Specify uri_redirect validation class explicitly.
59
+ - [#1652] Add custom attributes support to token generator.
60
+ - [#1667] Pass `client` instead of `grant.application` to `find_or_create_access_token`.
61
+ - [#1673] Honor `custom_access_token_attributes` in client credentials grant flow.
62
+ - [#1676] Improve AuthorizationsController error response handling
63
+ - [#1677] Fix URIHelper.valid_for_authorization? breaking for non url URIs.
64
+
65
+ ## 5.6.6
66
+
67
+ - [#1644] Update HTTP headers.
68
+ - [#1646] Block public clients automatic authorization skip.
69
+ - [#1648] Add custom token attributes to Refresh Token Request.
70
+ - [#1649] Fixed custom_access_token_attributes related errors.
71
+
72
+ ## 5.6.5
73
+
74
+ - [#1602] Allow custom data to be stored inside access grants/tokens.
75
+ - [#1634] Code refactoring for custom token attributes.
76
+ - [#1639] Add grant type validation to avoid Internal Server Error for DELETE /oauth/authorize endpoint.
77
+
78
+ ## 5.6.4
79
+
80
+ - [#1633] Apply ORM configuration in #to_prepare block to avoid autoloading errors.
81
+
82
+ ## 5.6.3
83
+
84
+ - [#1622] Drop support for Rubies 2.5 and 2.6
85
+ - [#1605] Fix URI validation for Ruby 3.2+.
86
+ - [#1625] Exclude endless access tokens from `StaleRecordsCleaner`.
87
+ - [#1626] Remove deprecated `active_record_options` config option.
88
+ - [#1631] Fix regression with redirect behavior after token lookup optimizations (redirect to app URI when found).
89
+ - [#1630] Special case unique index creation for refresh_token on SQL Server.
90
+ - [#1627] Lazy evaluate Doorkeeper config when loading files and executing initializers.
91
+
92
+ ## 5.6.2
93
+
94
+ - [#1604] Fix fetching of the application when custom application_class defined.
95
+
96
+ ## 5.6.1
97
+
98
+ - [#1593] Add support for Trilogy ActiveRecord adapter.
99
+ - [#1597] Add optional support to use the url path for the native authorization code flow. Ports forward [#1143] from 4.4.3
100
+ - [#1599] Remove unnecessarily re-fetch of application object when creating an access token.
101
+
102
+ ## 5.6.0
103
+
104
+ - [#1581] Consider `token_type_hint` when searching for access token in TokensController to avoid extra database calls.
105
+
106
+ ## 5.6.0.rc2
107
+
108
+ - [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
109
+ application scopes when using client credentials.
110
+ - [#1567] Only filter `code` parameter if authorization_code grant flow is enabled.
111
+
112
+ ## 5.6.0.rc1
113
+
114
+ - [#1551] Change lazy loading for ORM to be Ruby standard autoload.
115
+ - [#1552] Remove duplicate IDs on Auth form to improve accessibility.
116
+ - [#1542] Improve performance of `Doorkeeper::AccessToken#matching_token_for` using database specific SQL time math.
117
+
118
+ **[IMPORTANT]**: API of the `Doorkeeper::AccessToken#matching_token_for` method has changed and now it returns
119
+ only **active** access tokens (previously they were just not revoked). Please remember that the idea of the
120
+ `reuse_access_token` option is to check for existing _active_ token (see configuration option description).
11
121
 
12
122
  ## 5.5.4
13
123
 
@@ -25,12 +135,12 @@ User-visible changes worth mentioning.
25
135
  - [#1502] Drop support for Ruby 2.4 because of EOL.
26
136
  - [#1504] Updated the url fragment in the comment for code documentation.
27
137
  - [#1512] Fix form behavior when response mode is form_post.
28
- - [#1511] Fix that authorization code is returned by fragment if response_mode is fragament.
138
+ - [#1511] Fix that authorization code is returned by fragment if response_mode is fragment.
29
139
 
30
140
  ## 5.5.1
31
141
 
32
142
  - [#1496] Revoke `old_refresh_token` if `previous_refresh_token` is present.
33
- - [#1495] Fix `respond_to` undefined in API-only mode
143
+ - [#1495] Fix `respond_to` undefined in API-only mode
34
144
  - [#1488] Verify client authentication for Resource Owner Password Grant when
35
145
  `config.skip_client_authentication_for_password_grant` is set and the client credentials
36
146
  are sent in a HTTP Basic auth header.
@@ -44,10 +154,10 @@ User-visible changes worth mentioning.
44
154
  ## 5.5.0.rc2
45
155
 
46
156
  - [#1473] Enable `Applications` and `AuthorizedApplications` controllers in API mode.
47
-
48
- **[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
157
+
158
+ **[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
49
159
  `use_doorkeeper` inside `routes.rb`. Please do it in case you don't need them.
50
-
160
+
51
161
  - [#1472] Fix `establish_connection` configuration for custom defined models.
52
162
  - [#1471] Add support for Ruby 3.0.
53
163
  - [#1469] Check if `redirect_uri` exists.
@@ -254,7 +364,7 @@ User-visible changes worth mentioning.
254
364
  - [#1237] Allow to set blank redirect URI if Doorkeeper configured to use redirect URI-less grant flows.
255
365
  - [#1234] Fix `StaleRecordsCleaner` to properly work with big amount of records.
256
366
  - [#1228] Allow to explicitly set non-expiring tokens in `custom_access_token_expires_in` configuration
257
- option using `Float::INIFINITY` return value.
367
+ option using `Float::INFINITY` return value.
258
368
  - [#1224] Do not try to store token if not found by fallback hashing strategy.
259
369
  - [#1223] Update Hound/Rubocop rules, correct Doorkeeper codebase to follow style-guides.
260
370
  - [#1220] Drop Rails 4.2 & Ruby < 2.4 support.
@@ -339,7 +449,7 @@ User-visible changes worth mentioning.
339
449
  - [#1116] `AccessGrant`s will now be revoked along with `AccessToken`s when
340
450
  hitting the `AuthorizedApplicationController#destroy` route.
341
451
  - [#1114] Make token info endpoint's attributes consistent with token creation
342
- - [#1108] Simple formating of callback URLs when listing oauth applications
452
+ - [#1108] Simple formatting of callback URLs when listing oauth applications
343
453
  - [#1106] Restrict access to AdminController with 'Forbidden 403' if admin_authenticator is not
344
454
  configured by developers.
345
455
 
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
- [![Build Status](https://app.travis-ci.com/doorkeeper-gem/doorkeeper.svg?branch=main)](https://app.travis-ci.com/doorkeeper-gem/doorkeeper)
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)
@@ -40,7 +39,6 @@ Supported features:
40
39
  - [ORMs](#orms)
41
40
  - [Extensions](#extensions)
42
41
  - [Example Applications](#example-applications)
43
- - [Tutorials](#tutorials)
44
42
  - [Sponsors](#sponsors)
45
43
  - [Development](#development)
46
44
  - [Contributing](#contributing)
@@ -57,7 +55,7 @@ https://github.com/doorkeeper-gem/doorkeeper/releases.
57
55
  Additionally, other resources can be found on:
58
56
 
59
57
  - [Guides](https://doorkeeper.gitbook.io/guides/) with how-to get started and configuration documentation
60
- - See the [Wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki) with articles and other documentation
58
+ - See the [Wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki) for articles on how to integrate with other solutions
61
59
  - Screencast from [railscasts.com](http://railscasts.com/): [#353
62
60
  OAuth with
63
61
  Doorkeeper](http://railscasts.com/episodes/353-oauth-with-doorkeeper)
@@ -106,6 +104,8 @@ Extensions that are not included by default and can be installed separately.
106
104
  | JWT Token support | [doorkeeper-gem/doorkeeper-jwt](https://github.com/doorkeeper-gem/doorkeeper-jwt) |
107
105
  | Assertion grant extension | [doorkeeper-gem/doorkeeper-grants\_assertion](https://github.com/doorkeeper-gem/doorkeeper-grants_assertion) |
108
106
  | I18n translations | [doorkeeper-gem/doorkeeper-i18n](https://github.com/doorkeeper-gem/doorkeeper-i18n) |
107
+ | CIBA - Client Initiated Backchannel Authentication Flow extension | [doorkeeper-ciba](https://github.com/autoseg/doorkeeper-ciba) |
108
+ | Device Authorization Grant | [doorkeeper-device_authorization_grant](https://github.com/exop-group/doorkeeper-device_authorization_grant) |
109
109
 
110
110
  ## Example Applications
111
111
 
@@ -123,10 +123,6 @@ examples](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications
123
123
  in our wiki or follow this [tutorial
124
124
  here](https://github.com/doorkeeper-gem/doorkeeper/wiki/Testing-your-provider-with-OAuth2-gem).
125
125
 
126
- ## Tutorials
127
-
128
- See [list of tutorials](https://github.com/doorkeeper-gem/doorkeeper/wiki#how-tos--tutorials) in order to learn how to use the gem or integrate it with other solutions / gems.
129
-
130
126
  ## Sponsors
131
127
 
132
128
  [![OpenCollective](https://opencollective.com/doorkeeper-gem/backers/badge.svg)](#backers)
@@ -188,4 +184,4 @@ contributors](https://github.com/doorkeeper-gem/doorkeeper/graphs/contributors)!
188
184
 
189
185
  ## License
190
186
 
191
- MIT License. Copyright 2011 Applicake.
187
+ 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 authorize_response
16
+ redirect_or_render(authorize_response)
17
17
  end
18
18
 
19
19
  def destroy
20
- redirect_or_render authorization.deny
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 authorize_response
34
+ if skip_authorization? || can_authorize_response?
35
+ redirect_or_render(authorize_response)
28
36
  elsif Doorkeeper.configuration.api_only
29
37
  render json: pre_auth
30
38
  else
@@ -33,16 +41,27 @@ module Doorkeeper
33
41
  end
34
42
 
35
43
  def render_error
36
- if Doorkeeper.configuration.api_only
37
- render json: pre_auth.error_response.body,
38
- status: :bad_request
44
+ pre_auth.error_response.raise_exception! if Doorkeeper.config.raise_on_errors?
45
+
46
+ if Doorkeeper.configuration.redirect_on_errors? && pre_auth.error_response.redirectable?
47
+ redirect_or_render(pre_auth.error_response)
48
+ elsif Doorkeeper.configuration.api_only
49
+ render json: pre_auth.error_response.body, status: pre_auth.error_response.status
39
50
  else
40
- render :error
51
+ render :error, locals: { error_response: pre_auth.error_response }, status: pre_auth.error_response.status
41
52
  end
42
53
  end
43
54
 
55
+ def can_authorize_response?
56
+ Doorkeeper.config.custom_access_token_attributes.empty? && pre_auth.client.application.confidential? && matching_token?
57
+ end
58
+
59
+ # Active access token issued for the same client and resource owner with
60
+ # the same set of the scopes exists?
44
61
  def matching_token?
45
- Doorkeeper.config.access_token_model.matching_token_for(
62
+ # We don't match tokens on the custom attributes here - we're in the pre-auth here,
63
+ # so they haven't been supplied yet (there are no custom attributes to match on yet)
64
+ @matching_token ||= Doorkeeper.config.access_token_model.matching_token_for(
46
65
  pre_auth.client,
47
66
  current_resource_owner,
48
67
  pre_auth.scopes,
@@ -64,7 +83,7 @@ module Doorkeeper
64
83
  )
65
84
  end
66
85
  elsif pre_auth.form_post_response?
67
- render :form_post
86
+ render :form_post, locals: { auth: auth }
68
87
  else
69
88
  redirect_to auth.redirect_uri, allow_other_host: true
70
89
  end
@@ -86,7 +105,7 @@ module Doorkeeper
86
105
  end
87
106
 
88
107
  def pre_auth_param_fields
89
- %i[
108
+ custom_access_token_attributes + %i[
90
109
  client_id
91
110
  code_challenge
92
111
  code_challenge_method
@@ -98,6 +117,10 @@ module Doorkeeper
98
117
  ]
99
118
  end
100
119
 
120
+ def custom_access_token_attributes
121
+ Doorkeeper.config.custom_access_token_attributes.map(&:to_sym)
122
+ end
123
+
101
124
  def authorization
102
125
  @authorization ||= strategy.request
103
126
  end
@@ -4,12 +4,14 @@ module Doorkeeper
4
4
  class TokensController < Doorkeeper::ApplicationMetalController
5
5
  before_action :validate_presence_of_client, only: [:revoke]
6
6
 
7
+ rescue_from Errors::DoorkeeperError do |e|
8
+ handle_token_exception(e)
9
+ end
10
+
7
11
  def create
8
12
  headers.merge!(authorize_response.headers)
9
13
  render json: authorize_response.body,
10
14
  status: authorize_response.status
11
- rescue Errors::DoorkeeperError => e
12
- handle_token_exception(e)
13
15
  end
14
16
 
15
17
  # OAuth 2.0 Token Revocation - https://datatracker.ietf.org/doc/html/rfc7009
@@ -30,6 +32,7 @@ module Doorkeeper
30
32
  end
31
33
  end
32
34
 
35
+ # OAuth 2.0 Token Introspection - https://datatracker.ietf.org/doc/html/rfc7662
33
36
  def introspect
34
37
  introspection = OAuth::TokenIntrospection.new(server, token)
35
38
 
@@ -112,15 +115,36 @@ module Doorkeeper
112
115
  # The authorization server responds with HTTP status code 200 if the token
113
116
  # has been revoked successfully or if the client submitted an invalid
114
117
  # token
115
- token.revoke if token&.accessible?
118
+ revocable_token.revoke if revocable_token.revocable?
116
119
  end
117
120
 
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
121
  def token
122
- @token ||= Doorkeeper.config.access_token_model.by_token(params["token"]) ||
123
- Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
122
+ revocable_token&.token
123
+ end
124
+
125
+ def revocable_token
126
+ return @revocable_token if defined? @revocable_token
127
+
128
+ @revocable_token =
129
+ if params[:token_type_hint] == "refresh_token"
130
+ refresh_token
131
+ else
132
+ access_token || refresh_token
133
+ end
134
+ end
135
+
136
+ def refresh_token
137
+ token = Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
138
+ return unless token
139
+
140
+ RevocableTokens::RevocableRefreshToken.new(token)
141
+ end
142
+
143
+ def access_token
144
+ token = Doorkeeper.config.access_token_model.by_token(params["token"])
145
+ return unless token
146
+
147
+ RevocableTokens::RevocableAccessToken.new(token)
124
148
  end
125
149
 
126
150
  def strategy
@@ -3,5 +3,7 @@
3
3
  </div>
4
4
 
5
5
  <main role="main">
6
- <pre><%= @pre_auth.error_response.body[:error_description] %></pre>
6
+ <pre>
7
+ <%= (local_assigns[:error_response] ? error_response : @pre_auth.error_response).body[:error_description] %>
8
+ </pre>
7
9
  </main>
@@ -3,7 +3,7 @@
3
3
  </header>
4
4
 
5
5
  <%= form_tag @pre_auth.redirect_uri, method: :post, name: :redirect_form, authenticity_token: false do %>
6
- <% @authorize_response.body.compact.each do |key, value| %>
6
+ <% auth.body.compact.each do |key, value| %>
7
7
  <%= hidden_field_tag key, value %>
8
8
  <% end %>
9
9
  <% end %>
@@ -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>
@@ -96,11 +96,15 @@ en:
96
96
  unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
97
97
  missing_param: 'Missing required parameter: %{value}.'
98
98
  request_not_authorized: 'Request need to be authorized. Required parameter for authorizing request is missing or invalid.'
99
+ invalid_code_challenge: 'Code challenge is required.'
99
100
  invalid_redirect_uri: "The requested redirect uri is malformed or doesn't match client redirect URI."
100
101
  unauthorized_client: 'The client is not authorized to perform this request using this method.'
101
102
  access_denied: 'The resource owner or authorization server denied the request.'
102
103
  invalid_scope: 'The requested scope is invalid, unknown, or malformed.'
103
- invalid_code_challenge_method: 'The code challenge method must be plain or S256.'
104
+ invalid_code_challenge_method:
105
+ zero: 'The authorization server does not support PKCE as there are no accepted code_challenge_method values.'
106
+ one: 'The code_challenge_method must be %{challenge_methods}.'
107
+ other: 'The code_challenge_method must be one of %{challenge_methods}.'
104
108
  server_error: 'The authorization server encountered an unexpected condition which prevented it from fulfilling the request.'
105
109
  temporarily_unavailable: 'The authorization server is currently unable to handle the request due to a temporary overloading or maintenance of the server.'
106
110
 
@@ -12,7 +12,7 @@ module Doorkeeper
12
12
  #
13
13
  def initialize(config = Config.new, &block)
14
14
  @config = config
15
- instance_eval(&block)
15
+ instance_eval(&block) if block_given?
16
16
  end
17
17
 
18
18
  # Builds and validates configuration.
@@ -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_pkce_code_challenge_methods
14
15
  end
15
16
 
16
17
  private
@@ -24,8 +25,8 @@ module Doorkeeper
24
25
  return if !reuse_access_token || strategy.allows_restoring_secrets?
25
26
 
26
27
  ::Rails.logger.warn(
27
- "You have configured both reuse_access_token " \
28
- "AND strategy strategy '#{strategy}' that cannot restore tokens. " \
28
+ "[DOORKEEPER] You have configured both reuse_access_token " \
29
+ "AND '#{strategy}' strategy which cannot restore tokens. " \
29
30
  "This combination is unsupported. reuse_access_token will be disabled",
30
31
  )
31
32
  @reuse_access_token = false
@@ -43,11 +44,22 @@ module Doorkeeper
43
44
  (token_reuse_limit > 0 && token_reuse_limit <= 100)
44
45
 
45
46
  ::Rails.logger.warn(
46
- "You have configured an invalid value for token_reuse_limit option. " \
47
+ "[DOORKEEPER] You have configured an invalid value for token_reuse_limit option. " \
47
48
  "It will be set to default 100",
48
49
  )
49
50
  @token_reuse_limit = 100
50
51
  end
52
+
53
+ def validate_pkce_code_challenge_methods
54
+ return if pkce_code_challenge_methods.all? {|method| method =~ /^plain$|^S256$/ }
55
+
56
+ ::Rails.logger.warn(
57
+ "[DOORKEEPER] You have configured an invalid value for pkce_code_challenge_methods option. " \
58
+ "It will be set to default ['plain', 'S256']",
59
+ )
60
+
61
+ @pkce_code_challenge_methods = ['plain', 'S256']
62
+ end
51
63
  end
52
64
  end
53
65
  end