doorkeeper 5.6.4 → 5.6.6

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: e1f7bb9a1bb5e08c4b7c3ccb920bef61fbbd1dc0b11f76bba3a3d76a6fc8eeed
4
- data.tar.gz: 456ffe74dac831f3b797565041e46ecf241fb4cfc597d0bc39aa7a3893abeecb
3
+ metadata.gz: b62a0472a97d06b40362817c9d5c0dd7dd6e0d0e600437a19f5cf2fd18c4be46
4
+ data.tar.gz: 9850cef14c21a1f0df2fb451a485ab5b8066360a3008124f7aed287409364e36
5
5
  SHA512:
6
- metadata.gz: 6e23087c44495ce91c7e23f1bf8cd771dc82bdb92ffa1cac8f8bef2e42919bf8eea1ac86b1ed76580537c4b5a6b2ba571452470677259fb61e4be0e151091ad7
7
- data.tar.gz: fcafc844c46bab18f03d5dd7e8bd345111fb57530275adbf8d9954f8e8c1436b29ded79e15f6321e9f86c845836b713c65aca23398114cfdb5c77e9b87a01647
6
+ metadata.gz: de0c7021c4735b26249e5b267db11ede06f55b23d8f9bd51641d1cf3eee3812e14a2deec986e8aa6ee81de98097083fdb634a441fd4928cb47286fa977ba5d96
7
+ data.tar.gz: 3865639c837771ceeafceec8a110e506f88fef45c61f7274782c637e794f9185be18ee98270852bac6fecb0fc90e4893dfed08d715c761507e87396e5a559bc2
data/CHANGELOG.md CHANGED
@@ -9,6 +9,19 @@ 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
+
12
25
  # 5.6.4
13
26
 
14
27
  - [#1633] Apply ORM configuration in #to_prepare block to avoid autoloading errors.
@@ -39,7 +52,7 @@ User-visible changes worth mentioning.
39
52
 
40
53
  ## 5.6.0.rc2
41
54
 
42
- - [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
55
+ - [#1558] Fixed bug: able to obtain a token with default scopes even if they are not present in the
43
56
  application scopes when using client credentials.
44
57
  - [#1567] Only filter `code` parameter if authorization_code grant flow is enabled.
45
58
 
@@ -74,7 +87,7 @@ User-visible changes worth mentioning.
74
87
  ## 5.5.1
75
88
 
76
89
  - [#1496] Revoke `old_refresh_token` if `previous_refresh_token` is present.
77
- - [#1495] Fix `respond_to` undefined in API-only mode
90
+ - [#1495] Fix `respond_to` undefined in API-only mode
78
91
  - [#1488] Verify client authentication for Resource Owner Password Grant when
79
92
  `config.skip_client_authentication_for_password_grant` is set and the client credentials
80
93
  are sent in a HTTP Basic auth header.
@@ -88,10 +101,10 @@ User-visible changes worth mentioning.
88
101
  ## 5.5.0.rc2
89
102
 
90
103
  - [#1473] Enable `Applications` and `AuthorizedApplications` controllers in API mode.
91
-
92
- **[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
104
+
105
+ **[IMPORTANT]** you can still skip these controllers using `skip_controllers` in
93
106
  `use_doorkeeper` inside `routes.rb`. Please do it in case you don't need them.
94
-
107
+
95
108
  - [#1472] Fix `establish_connection` configuration for custom defined models.
96
109
  - [#1471] Add support for Ruby 3.0.
97
110
  - [#1469] Check if `redirect_uri` exists.
@@ -13,17 +13,25 @@ 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?
34
+ if skip_authorization? || (matching_token? && pre_auth.client.application.confidential?)
27
35
  redirect_or_render(authorize_response)
28
36
  elsif Doorkeeper.configuration.api_only
29
37
  render json: pre_auth
@@ -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
@@ -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
+ <%= (respond_to?(:error_response) ? error_response : @pre_auth.error_response).body[:error_description] %>
8
+ </pre>
7
9
  </main>
@@ -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
  #
@@ -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 = if grant&.uses_pkce? && code_verifier.blank?
59
- :code_verifier
60
- elsif redirect_uri.blank?
61
- :redirect_uri
62
- end
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
- server_config.access_grant_model.generate_code_challenge(code_verifier)
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
- @access_token = server_config.access_token_model.find_or_create_for(
32
- application: client.is_a?(server_config.application_model) ? client : client&.application,
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
- server_config.before_successful_strategy_response.call(self)
46
+ Doorkeeper.config.before_successful_strategy_response.call(self)
42
47
  end
43
48
 
44
49
  def after_successful_response
45
- server_config.after_successful_strategy_response.call(self, @response)
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 server_config.reuse_access_token && existing_token&.reusable?
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?(server_config.application_model) ? client : client&.application
17
- server_config.access_token_model.create_for(
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 && server_config.revoke_previous_client_credentials_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
- server_config.reuse_access_token ||
44
- server_config.revoke_previous_client_credentials_token?
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
- server_config.access_token_model.matching_token_for(client, nil, scopes, include_expired: false)
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
@@ -55,8 +55,7 @@ module Doorkeeper
55
55
 
56
56
  def headers
57
57
  {
58
- "Cache-Control" => "no-store",
59
- "Pragma" => "no-cache",
58
+ "Cache-Control" => "no-store, no-cache",
60
59
  "Content-Type" => "application/json; charset=utf-8",
61
60
  "WWW-Authenticate" => authenticate_info,
62
61
  }
@@ -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
- server_config.allow_grant_flow_for_client?(grant_type, client&.application)
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 = 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]
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 = 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
- server_config.application_model.by_uid_and_secret(credentials.uid, credentials.secret)
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
- server_config.access_token_model.refresh_token_revoked_on_use?
44
+ Doorkeeper.config.access_token_model.refresh_token_revoked_on_use?
45
45
  end
46
46
 
47
47
  def default_scopes
@@ -49,7 +49,7 @@ module Doorkeeper
49
49
  end
50
50
 
51
51
  def create_access_token
52
- attributes = {}
52
+ attributes = {}.merge(custom_token_attributes_with_data)
53
53
 
54
54
  resource_owner =
55
55
  if Doorkeeper.config.polymorphic_resource_owner?
@@ -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 = server_config.access_token_model.create_for(
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,
@@ -119,6 +119,14 @@ module Doorkeeper
119
119
  true
120
120
  end
121
121
  end
122
+
123
+ def custom_token_attributes_with_data
124
+ refresh_token
125
+ .attributes
126
+ .with_indifferent_access
127
+ .slice(*Doorkeeper.config.custom_access_token_attributes)
128
+ .symbolize_keys
129
+ end
122
130
  end
123
131
  end
124
132
  end
@@ -26,8 +26,7 @@ module Doorkeeper
26
26
 
27
27
  def headers
28
28
  {
29
- "Cache-Control" => "no-store",
30
- "Pragma" => "no-cache",
29
+ "Cache-Control" => "no-store, no-cache",
31
30
  "Content-Type" => "application/json; charset=utf-8",
32
31
  }
33
32
  end
@@ -5,7 +5,7 @@ module Doorkeeper
5
5
  # Semantic versioning
6
6
  MAJOR = 5
7
7
  MINOR = 6
8
- TINY = 4
8
+ TINY = 6
9
9
  PRE = nil
10
10
 
11
11
  # Full version number
@@ -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
4
+ version: 5.6.6
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-01-31 00:00:00.000000000 Z
14
+ date: 2023-03-29 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties