doorkeeper 5.6.6 → 5.6.8

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: b62a0472a97d06b40362817c9d5c0dd7dd6e0d0e600437a19f5cf2fd18c4be46
4
- data.tar.gz: 9850cef14c21a1f0df2fb451a485ab5b8066360a3008124f7aed287409364e36
3
+ metadata.gz: b8a202451362fe346d53be4d16dcb92fea331ee1aad93461283585f93749960b
4
+ data.tar.gz: 2f042a729cdd68ce19d6181a54a98635715f83e93946de95b62a7521400d4951
5
5
  SHA512:
6
- metadata.gz: de0c7021c4735b26249e5b267db11ede06f55b23d8f9bd51641d1cf3eee3812e14a2deec986e8aa6ee81de98097083fdb634a441fd4928cb47286fa977ba5d96
7
- data.tar.gz: 3865639c837771ceeafceec8a110e506f88fef45c61f7274782c637e794f9185be18ee98270852bac6fecb0fc90e4893dfed08d715c761507e87396e5a559bc2
6
+ metadata.gz: ab8dab957c6cfa382f406c465a187b3d1301a38eac8666789ad87755f2f383cb7f6a0f10f5b18f15dd4cbe5bb80f41697d01486d58739c5fca342c13a1bfe196
7
+ data.tar.gz: c0490f4072de798755643890309ff8d2ff645a5fa00797e2f5c933c6f1ffa685190cb935b2569a26fff5d282d3efd34f544b8784f598b8228c01259e784fe63b
data/CHANGELOG.md CHANGED
@@ -7,7 +7,20 @@ User-visible changes worth mentioning.
7
7
 
8
8
  ## main
9
9
 
10
- - [#ID] Add your PR description here.
10
+ - [#PR ID] Add your changelog here.
11
+
12
+ ## 5.6.8
13
+
14
+ - [#1680] Fix handle_auth_errors :raise NotImplementedError
15
+
16
+ ## 5.6.7
17
+
18
+ - [#1662] Specify uri_redirect validation class explicitly.
19
+ - [#1652] Add custom attributes support to token generator.
20
+ - [#1667] Pass `client` instead of `grant.application` to `find_or_create_access_token`.
21
+ - [#1673] Honor `custom_access_token_attributes` in client credentials grant flow.
22
+ - [#1676] Improve AuthorizationsController error response handling
23
+ - [#1677] Fix URIHelper.valid_for_authorization? breaking for non url URIs.
11
24
 
12
25
  ## 5.6.6
13
26
 
@@ -41,11 +41,14 @@ module Doorkeeper
41
41
  end
42
42
 
43
43
  def render_error
44
- if Doorkeeper.configuration.api_only
45
- render json: pre_auth.error_response.body,
46
- 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
47
50
  else
48
- render :error, locals: { error_response: pre_auth.error_response }
51
+ render :error, locals: { error_response: pre_auth.error_response }, status: pre_auth.error_response.status
49
52
  end
50
53
  end
51
54
 
@@ -501,6 +501,10 @@ module Doorkeeper
501
501
  handle_auth_errors == :raise
502
502
  end
503
503
 
504
+ def redirect_on_errors?
505
+ handle_auth_errors == :redirect
506
+ end
507
+
504
508
  def application_secret_hashed?
505
509
  instance_variable_defined?(:"@application_secret_strategy")
506
510
  end
@@ -39,13 +39,31 @@ module Doorkeeper
39
39
  def initialize(response)
40
40
  @response = response
41
41
  end
42
+
43
+ def self.name_for_response
44
+ self.name.demodulize.underscore.to_sym
45
+ end
42
46
  end
43
47
 
44
48
  UnableToGenerateToken = Class.new(DoorkeeperError)
45
49
  TokenGeneratorNotFound = Class.new(DoorkeeperError)
46
50
  NoOrmCleaner = Class.new(DoorkeeperError)
47
51
 
52
+ InvalidRequest = Class.new(BaseResponseError)
48
53
  InvalidToken = Class.new(BaseResponseError)
54
+ InvalidClient = Class.new(BaseResponseError)
55
+ InvalidScope = Class.new(BaseResponseError)
56
+ InvalidRedirectUri = Class.new(BaseResponseError)
57
+ InvalidCodeChallengeMethod = Class.new(BaseResponseError)
58
+ InvalidGrant = Class.new(BaseResponseError)
59
+
60
+ UnauthorizedClient = Class.new(BaseResponseError)
61
+ UnsupportedResponseType = Class.new(BaseResponseError)
62
+ UnsupportedResponseMode = Class.new(BaseResponseError)
63
+
64
+ AccessDenied = Class.new(BaseResponseError)
65
+ ServerError = Class.new(BaseResponseError)
66
+
49
67
  TokenExpired = Class.new(InvalidToken)
50
68
  TokenRevoked = Class.new(InvalidToken)
51
69
  TokenUnknown = Class.new(InvalidToken)
@@ -435,6 +435,10 @@ module Doorkeeper
435
435
  if Doorkeeper.config.polymorphic_resource_owner?
436
436
  attributes[:resource_owner] = resource_owner
437
437
  end
438
+
439
+ Doorkeeper.config.custom_access_token_attributes.each do |attribute_name|
440
+ attributes[attribute_name] = public_send(attribute_name)
441
+ end
438
442
  end
439
443
  end
440
444
 
@@ -3,12 +3,12 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class AuthorizationCodeRequest < BaseRequest
6
- validate :params, error: :invalid_request
7
- validate :client, error: :invalid_client
8
- validate :grant, error: :invalid_grant
6
+ validate :params, error: Errors::InvalidRequest
7
+ validate :client, error: Errors::InvalidClient
8
+ validate :grant, error: Errors::InvalidGrant
9
9
  # @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
10
- validate :redirect_uri, error: :invalid_grant
11
- validate :code_verifier, error: :invalid_grant
10
+ validate :redirect_uri, error: Errors::InvalidGrant
11
+ validate :code_verifier, error: Errors::InvalidGrant
12
12
 
13
13
  attr_reader :grant, :client, :redirect_uri, :access_token, :code_verifier,
14
14
  :invalid_request_reason, :missing_param
@@ -32,7 +32,7 @@ module Doorkeeper
32
32
  grant.revoke
33
33
 
34
34
  find_or_create_access_token(
35
- grant.application,
35
+ client,
36
36
  resource_owner,
37
37
  grant.scopes,
38
38
  custom_token_attributes_with_data,
@@ -15,7 +15,7 @@ module Doorkeeper
15
15
  @response = TokenResponse.new(access_token)
16
16
  after_successful_response
17
17
  @response
18
- elsif error == :invalid_request
18
+ elsif error == Errors::InvalidRequest
19
19
  @response = InvalidRequestResponse.from_request(self)
20
20
  else
21
21
  @response = ErrorResponse.from_request(self)
@@ -11,10 +11,10 @@ module Doorkeeper
11
11
  @validator = validator
12
12
  end
13
13
 
14
- def create(client, scopes, creator = Creator.new)
14
+ def create(client, scopes, attributes = {}, creator = Creator.new)
15
15
  if validator.valid?
16
- @token = create_token(client, scopes, creator)
17
- @error = :server_error unless @token
16
+ @token = create_token(client, scopes, attributes, creator)
17
+ @error = Errors::ServerError unless @token
18
18
  else
19
19
  @token = false
20
20
  @error = validator.error
@@ -25,7 +25,7 @@ module Doorkeeper
25
25
 
26
26
  private
27
27
 
28
- def create_token(client, scopes, creator)
28
+ def create_token(client, scopes, attributes, creator)
29
29
  context = Authorization::Token.build_context(
30
30
  client,
31
31
  Doorkeeper::OAuth::CLIENT_CREDENTIALS,
@@ -39,6 +39,7 @@ module Doorkeeper
39
39
  scopes,
40
40
  use_refresh_token: false,
41
41
  expires_in: ttl,
42
+ **attributes
42
43
  )
43
44
  end
44
45
  end
@@ -7,9 +7,9 @@ module Doorkeeper
7
7
  include Validations
8
8
  include OAuth::Helpers
9
9
 
10
- validate :client, error: :invalid_client
11
- validate :client_supports_grant_flow, error: :unauthorized_client
12
- validate :scopes, error: :invalid_scope
10
+ validate :client, error: Errors::InvalidClient
11
+ validate :client_supports_grant_flow, error: Errors::UnauthorizedClient
12
+ validate :scopes, error: Errors::InvalidScope
13
13
 
14
14
  def initialize(server, request)
15
15
  @server = server
@@ -3,7 +3,7 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class ClientCredentialsRequest < BaseRequest
6
- attr_reader :client, :original_scopes, :response
6
+ attr_reader :client, :original_scopes, :parameters, :response
7
7
 
8
8
  alias error_response response
9
9
 
@@ -14,6 +14,7 @@ module Doorkeeper
14
14
  @server = server
15
15
  @response = nil
16
16
  @original_scopes = parameters[:scope]
17
+ @parameters = parameters.except(:scope)
17
18
  end
18
19
 
19
20
  def access_token
@@ -30,7 +31,14 @@ module Doorkeeper
30
31
  private
31
32
 
32
33
  def valid?
33
- issuer.create(client, scopes)
34
+ issuer.create(client, scopes, custom_token_attributes_with_data)
35
+ end
36
+
37
+ def custom_token_attributes_with_data
38
+ parameters
39
+ .with_indifferent_access
40
+ .slice(*Doorkeeper.config.custom_access_token_attributes)
41
+ .symbolize_keys
34
42
  end
35
43
  end
36
44
  end
@@ -17,7 +17,7 @@ module Doorkeeper
17
17
  end
18
18
 
19
19
  def deny
20
- pre_auth.error = :access_denied
20
+ pre_auth.error = Errors::AccessDenied
21
21
  pre_auth.error_response
22
22
  end
23
23
  end
@@ -10,7 +10,8 @@ module Doorkeeper
10
10
  def self.from_request(request, attributes = {})
11
11
  new(
12
12
  attributes.merge(
13
- name: request.error,
13
+ name: request.error&.name_for_response,
14
+ exception_class: request.error,
14
15
  state: request.try(:state),
15
16
  redirect_uri: request.try(:redirect_uri),
16
17
  ),
@@ -21,6 +22,7 @@ module Doorkeeper
21
22
 
22
23
  def initialize(attributes = {})
23
24
  @error = OAuth::Error.new(*attributes.values_at(:name, :state))
25
+ @exception_class = attributes[:exception_class]
24
26
  @redirect_uri = attributes[:redirect_uri]
25
27
  @response_on_fragment = attributes[:response_on_fragment]
26
28
  end
@@ -72,6 +74,7 @@ module Doorkeeper
72
74
  end
73
75
 
74
76
  def exception_class
77
+ return @exception_class if @exception_class
75
78
  raise NotImplementedError, "error response must define #exception_class"
76
79
  end
77
80
 
@@ -40,7 +40,7 @@ module Doorkeeper
40
40
 
41
41
  def self.loopback_uri?(uri)
42
42
  IPAddr.new(uri.host).loopback?
43
- rescue IPAddr::Error
43
+ rescue IPAddr::Error, IPAddr::InvalidAddressError
44
44
  false
45
45
  end
46
46
 
@@ -35,6 +35,10 @@ module Doorkeeper
35
35
  )
36
36
  end
37
37
 
38
+ def exception_class
39
+ Doorkeeper::Errors::InvalidRequest
40
+ end
41
+
38
42
  def redirectable?
39
43
  super && @missing_param != :client_id
40
44
  end
@@ -5,10 +5,10 @@ module Doorkeeper
5
5
  class PasswordAccessTokenRequest < BaseRequest
6
6
  include OAuth::Helpers
7
7
 
8
- validate :client, error: :invalid_client
9
- validate :client_supports_grant_flow, error: :unauthorized_client
10
- validate :resource_owner, error: :invalid_grant
11
- validate :scopes, error: :invalid_scope
8
+ validate :client, error: Errors::InvalidClient
9
+ validate :client_supports_grant_flow, error: Errors::UnauthorizedClient
10
+ validate :resource_owner, error: Errors::InvalidGrant
11
+ validate :scopes, error: Errors::InvalidScope
12
12
 
13
13
  attr_reader :client, :credentials, :resource_owner, :parameters, :access_token
14
14
 
@@ -5,16 +5,16 @@ module Doorkeeper
5
5
  class PreAuthorization
6
6
  include Validations
7
7
 
8
- validate :client_id, error: :invalid_request
9
- validate :client, error: :invalid_client
10
- validate :client_supports_grant_flow, error: :unauthorized_client
11
- validate :resource_owner_authorize_for_client, error: :invalid_client
12
- validate :redirect_uri, error: :invalid_redirect_uri
13
- validate :params, error: :invalid_request
14
- validate :response_type, error: :unsupported_response_type
15
- validate :response_mode, error: :unsupported_response_mode
16
- validate :scopes, error: :invalid_scope
17
- validate :code_challenge_method, error: :invalid_code_challenge_method
8
+ validate :client_id, error: Errors::InvalidRequest
9
+ validate :client, error: Errors::InvalidClient
10
+ validate :client_supports_grant_flow, error: Errors::UnauthorizedClient
11
+ validate :resource_owner_authorize_for_client, error: Errors::InvalidClient
12
+ validate :redirect_uri, error: Errors::InvalidRedirectUri
13
+ validate :params, error: Errors::InvalidRequest
14
+ validate :response_type, error: Errors::UnsupportedResponseType
15
+ validate :response_mode, error: Errors::UnsupportedResponseMode
16
+ validate :scopes, error: Errors::InvalidScope
17
+ validate :code_challenge_method, error: Errors::InvalidCodeChallengeMethod
18
18
 
19
19
  attr_reader :client, :code_challenge, :code_challenge_method, :missing_param,
20
20
  :redirect_uri, :resource_owner, :response_type, :state,
@@ -47,7 +47,7 @@ module Doorkeeper
47
47
  end
48
48
 
49
49
  def error_response
50
- if error == :invalid_request
50
+ if error == Errors::InvalidRequest
51
51
  OAuth::InvalidRequestResponse.from_request(
52
52
  self,
53
53
  response_on_fragment: response_on_fragment?,
@@ -5,11 +5,11 @@ module Doorkeeper
5
5
  class RefreshTokenRequest < BaseRequest
6
6
  include OAuth::Helpers
7
7
 
8
- validate :token_presence, error: :invalid_request
9
- validate :token, error: :invalid_grant
10
- validate :client, error: :invalid_client
11
- validate :client_match, error: :invalid_grant
12
- validate :scope, error: :invalid_scope
8
+ validate :token_presence, error: Errors::InvalidRequest
9
+ validate :token, error: Errors::InvalidGrant
10
+ validate :client, error: Errors::InvalidClient
11
+ validate :client_match, error: Errors::InvalidGrant
12
+ validate :scope, error: Errors::InvalidScope
13
13
 
14
14
  attr_reader :access_token, :client, :credentials, :refresh_token
15
15
  attr_reader :missing_param
@@ -6,6 +6,8 @@ module Doorkeeper
6
6
  #
7
7
  # @see https://datatracker.ietf.org/doc/html/rfc7662
8
8
  class TokenIntrospection
9
+ attr_reader :error
10
+
9
11
  def initialize(server, token)
10
12
  @server = server
11
13
  @token = token
@@ -20,12 +22,12 @@ module Doorkeeper
20
22
  def error_response
21
23
  return if @error.blank?
22
24
 
23
- if @error == :invalid_token
25
+ if @error == Errors::InvalidToken
24
26
  OAuth::InvalidTokenResponse.from_access_token(authorized_token)
25
- elsif @error == :invalid_request
27
+ elsif @error == Errors::InvalidRequest
26
28
  OAuth::InvalidRequestResponse.from_request(self)
27
29
  else
28
- OAuth::ErrorResponse.new(name: @error)
30
+ OAuth::ErrorResponse.from_request(self)
29
31
  end
30
32
  end
31
33
 
@@ -36,7 +38,7 @@ module Doorkeeper
36
38
  private
37
39
 
38
40
  attr_reader :server, :token
39
- attr_reader :error, :invalid_request_reason
41
+ attr_reader :invalid_request_reason
40
42
 
41
43
  # If the protected resource uses OAuth 2.0 client credentials to
42
44
  # authenticate to the introspection endpoint and its credentials are
@@ -58,7 +60,7 @@ module Doorkeeper
58
60
  def authorize!
59
61
  # Requested client authorization
60
62
  if server.credentials
61
- @error = :invalid_client unless authorized_client
63
+ @error = Errors::InvalidClient unless authorized_client
62
64
  elsif authorized_token
63
65
  # Requested bearer token authorization
64
66
  #
@@ -69,9 +71,9 @@ module Doorkeeper
69
71
  # HTTP 401 code as described in Section 3 of OAuth 2.0 Bearer Token
70
72
  # Usage [RFC6750].
71
73
  #
72
- @error = :invalid_token unless valid_authorized_token?
74
+ @error = Errors::InvalidToken unless valid_authorized_token?
73
75
  else
74
- @error = :invalid_request
76
+ @error = Errors::InvalidRequest
75
77
  @invalid_request_reason = :request_not_authorized
76
78
  end
77
79
  end
@@ -17,7 +17,7 @@ module Doorkeeper
17
17
  end
18
18
 
19
19
  def deny
20
- pre_auth.error = :access_denied
20
+ pre_auth.error = Errors::AccessDenied
21
21
  pre_auth.error_response
22
22
  end
23
23
  end
@@ -22,7 +22,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
22
22
 
23
23
  validates :name, :secret, :uid, presence: true
24
24
  validates :uid, uniqueness: { case_sensitive: true }
25
- validates :redirect_uri, "doorkeeper/redirect_uri": true
25
+ validates_with Doorkeeper::RedirectUriValidator, attributes: [:redirect_uri]
26
26
  validates :confidential, inclusion: { in: [true, false] }
27
27
 
28
28
  validate :scopes_match_configured, if: :enforce_scopes?
@@ -5,7 +5,7 @@ module Doorkeeper
5
5
  # Semantic versioning
6
6
  MAJOR = 5
7
7
  MINOR = 6
8
- TINY = 6
8
+ TINY = 8
9
9
  PRE = nil
10
10
 
11
11
  # Full version number
@@ -312,6 +312,12 @@ Doorkeeper.configure do
312
312
  # Doorkeeper::Errors::TokenRevoked, Doorkeeper::Errors::TokenUnknown
313
313
  #
314
314
  # handle_auth_errors :raise
315
+ #
316
+ # If you want to redirect back to the client application in accordance with
317
+ # https://datatracker.ietf.org/doc/html/rfc6749#section-4.1.2.1, you can set
318
+ # +handle_auth_errors+ to :redirect
319
+ #
320
+ # handle_auth_errors :redirect
315
321
 
316
322
  # Customize token introspection response.
317
323
  # Allows to add your own fields to default one that are required by the OAuth spec
@@ -385,7 +391,7 @@ Doorkeeper.configure do
385
391
  # true in case resource owner authorized for the specific application or false in other
386
392
  # cases.
387
393
  #
388
- # Be default all Resource Owners are authorized to any Client (application).
394
+ # By default all Resource Owners are authorized to any Client (application).
389
395
  #
390
396
  # authorize_resource_owner_for_client do |client, resource_owner|
391
397
  # resource_owner.admin? || client.owners_allowlist.include?(resource_owner)
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.6
4
+ version: 5.6.8
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-03-29 00:00:00.000000000 Z
14
+ date: 2023-12-01 00:00:00.000000000 Z
15
15
  dependencies:
16
16
  - !ruby/object:Gem::Dependency
17
17
  name: railties