doorkeeper 5.5.4 → 5.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +111 -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 +28 -6
  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 +4 -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 +32 -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 +36 -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 +31 -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/routes.rb +12 -3
  47. data/lib/doorkeeper/rake/setup.rake +0 -5
  48. data/lib/doorkeeper/revocable_tokens/revocable_access_token.rb +21 -0
  49. data/lib/doorkeeper/revocable_tokens/revocable_refresh_token.rb +21 -0
  50. data/lib/doorkeeper/version.rb +2 -2
  51. data/lib/doorkeeper.rb +78 -5
  52. data/lib/generators/doorkeeper/remove_applications_secret_not_null_constraint_generator.rb +33 -0
  53. data/lib/generators/doorkeeper/templates/initializer.rb +44 -6
  54. data/lib/generators/doorkeeper/templates/migration.rb.erb +15 -4
  55. data/lib/generators/doorkeeper/templates/remove_applications_secret_not_null_constraint.rb.erb +7 -0
  56. metadata +28 -21
@@ -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
@@ -29,12 +29,17 @@ module Doorkeeper
29
29
  grant.lock!
30
30
  raise Errors::InvalidGrantReuse if grant.revoked?
31
31
 
32
+ if Doorkeeper.config.revoke_previous_authorization_code_token?
33
+ revoke_previous_tokens(grant.application, resource_owner)
34
+ end
35
+
32
36
  grant.revoke
33
37
 
34
38
  find_or_create_access_token(
35
- grant.application,
39
+ client,
36
40
  resource_owner,
37
41
  grant.scopes,
42
+ custom_token_attributes_with_data,
38
43
  server,
39
44
  )
40
45
  end
@@ -54,12 +59,19 @@ module Doorkeeper
54
59
  Doorkeeper.config.access_grant_model.pkce_supported?
55
60
  end
56
61
 
62
+ def confidential?
63
+ client&.confidential
64
+ end
65
+
57
66
  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
67
+ @missing_param =
68
+ if grant&.uses_pkce? && code_verifier.blank?
69
+ :code_verifier
70
+ elsif !confidential? && Doorkeeper.config.force_pkce? && code_verifier.blank?
71
+ :code_verifier
72
+ elsif redirect_uri.blank?
73
+ :redirect_uri
74
+ end
63
75
 
64
76
  @missing_param.nil?
65
77
  end
@@ -97,7 +109,19 @@ module Doorkeeper
97
109
  end
98
110
 
99
111
  def generate_code_challenge(code_verifier)
100
- server_config.access_grant_model.generate_code_challenge(code_verifier)
112
+ Doorkeeper.config.access_grant_model.generate_code_challenge(code_verifier)
113
+ end
114
+
115
+ def custom_token_attributes_with_data
116
+ grant
117
+ .attributes
118
+ .with_indifferent_access
119
+ .slice(*Doorkeeper.config.custom_access_token_attributes)
120
+ .symbolize_keys
121
+ end
122
+
123
+ def revoke_previous_tokens(application, resource_owner)
124
+ Doorkeeper.config.access_token_model.revoke_all_for(application.id, resource_owner)
101
125
  end
102
126
  end
103
127
  end
@@ -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)
@@ -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,
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
@@ -58,7 +59,8 @@ module Doorkeeper
58
59
  client_scopes = @client&.scopes
59
60
  return default_scopes if client_scopes.blank?
60
61
 
61
- default_scopes & client_scopes
62
+ # Avoid using Scope#& for dynamic scopes
63
+ client_scopes.allowed(default_scopes)
62
64
  end
63
65
  end
64
66
  end
@@ -5,7 +5,7 @@ module Doorkeeper
5
5
  class Client
6
6
  attr_reader :application
7
7
 
8
- delegate :id, :name, :uid, :redirect_uri, :scopes, to: :@application
8
+ delegate :id, :name, :uid, :redirect_uri, :scopes, :confidential, to: :@application
9
9
 
10
10
  def initialize(application)
11
11
  @application = application
@@ -8,13 +8,14 @@ module Doorkeeper
8
8
  existing_token = nil
9
9
 
10
10
  if lookup_existing_token?
11
- existing_token = find_existing_token_for(client, scopes)
12
- return existing_token if server_config.reuse_access_token && existing_token&.reusable?
11
+ existing_token = find_active_existing_token_for(client, scopes, attributes)
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
- server_config.access_token_model.find_or_create_for(
17
- application: client,
16
+ application = client.is_a?(Doorkeeper.config.application_model) ? client : client&.application
17
+ Doorkeeper.config.access_token_model.create_for(
18
+ application: application,
18
19
  resource_owner: nil,
19
20
  scopes: scopes,
20
21
  **attributes,
@@ -25,7 +26,7 @@ module Doorkeeper
25
26
  private
26
27
 
27
28
  def with_revocation(existing_token:)
28
- if existing_token && server_config.revoke_previous_client_credentials_token?
29
+ if existing_token && Doorkeeper.config.revoke_previous_client_credentials_token?
29
30
  existing_token.with_lock do
30
31
  raise Errors::DoorkeeperError, :invalid_token_reuse if existing_token.revoked?
31
32
 
@@ -39,16 +40,15 @@ module Doorkeeper
39
40
  end
40
41
 
41
42
  def lookup_existing_token?
42
- server_config.reuse_access_token ||
43
- server_config.revoke_previous_client_credentials_token?
43
+ Doorkeeper.config.reuse_access_token ||
44
+ Doorkeeper.config.revoke_previous_client_credentials_token?
44
45
  end
45
46
 
46
- def find_existing_token_for(client, scopes)
47
- server_config.access_token_model.matching_token_for(client, nil, scopes)
48
- end
49
-
50
- def server_config
51
- Doorkeeper.config
47
+ def find_active_existing_token_for(client, scopes, attributes)
48
+ custom_attributes = Doorkeeper.config.access_token_model.
49
+ extract_custom_attributes(attributes).presence
50
+ Doorkeeper.config.access_token_model.matching_token_for(
51
+ client, nil, scopes, custom_attributes: custom_attributes, include_expired: false)
52
52
  end
53
53
  end
54
54
  end
@@ -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
@@ -35,13 +35,12 @@ module Doorkeeper
35
35
  end
36
36
 
37
37
  def validate_scopes
38
- return true if @request.scopes.blank?
39
-
40
38
  application_scopes = if @client.present?
41
39
  @client.application.scopes
42
40
  else
43
41
  ""
44
42
  end
43
+ return true if @request.scopes.blank? && application_scopes.blank?
45
44
 
46
45
  ScopeChecker.valid?(
47
46
  scope_str: @request.scopes.to_s,
@@ -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
@@ -2,13 +2,14 @@
2
2
 
3
3
  module Doorkeeper
4
4
  module OAuth
5
- Error = Struct.new(:name, :state) do
5
+ Error = Struct.new(:name, :state, :translate_options) do
6
6
  def description
7
- I18n.translate(
8
- name,
7
+ options = (translate_options || {}).merge(
9
8
  scope: %i[doorkeeper errors messages],
10
9
  default: :server_error,
11
10
  )
11
+
12
+ I18n.translate(name, **options)
12
13
  end
13
14
  end
14
15
  end
@@ -10,17 +10,32 @@ module Doorkeeper
10
10
  def self.from_request(request, attributes = {})
11
11
  new(
12
12
  attributes.merge(
13
- name: request.error,
13
+ name: error_name_for(request.error),
14
+ exception_class: exception_class_for(request.error),
15
+ translate_options: request.error.try(:translate_options),
14
16
  state: request.try(:state),
15
17
  redirect_uri: request.try(:redirect_uri),
16
18
  ),
17
19
  )
18
20
  end
19
21
 
22
+ def self.error_name_for(error)
23
+ error.respond_to?(:name_for_response) ? error.name_for_response : error
24
+ end
25
+
26
+ def self.exception_class_for(error)
27
+ return error if error.respond_to?(:name_for_response)
28
+
29
+ "Doorkeeper::Errors::#{error.to_s.classify}".safe_constantize
30
+ end
31
+
32
+ private_class_method :error_name_for, :exception_class_for
33
+
20
34
  delegate :name, :description, :state, to: :@error
21
35
 
22
36
  def initialize(attributes = {})
23
- @error = OAuth::Error.new(*attributes.values_at(:name, :state))
37
+ @error = OAuth::Error.new(*attributes.values_at(:name, :state, :translate_options))
38
+ @exception_class = attributes[:exception_class]
24
39
  @redirect_uri = attributes[:redirect_uri]
25
40
  @response_on_fragment = attributes[:response_on_fragment]
26
41
  end
@@ -55,8 +70,7 @@ module Doorkeeper
55
70
 
56
71
  def headers
57
72
  {
58
- "Cache-Control" => "no-store",
59
- "Pragma" => "no-cache",
73
+ "Cache-Control" => "no-store, no-cache",
60
74
  "Content-Type" => "application/json; charset=utf-8",
61
75
  "WWW-Authenticate" => authenticate_info,
62
76
  }
@@ -73,6 +87,7 @@ module Doorkeeper
73
87
  end
74
88
 
75
89
  def exception_class
90
+ return @exception_class if @exception_class
76
91
  raise NotImplementedError, "error response must define #exception_class"
77
92
  end
78
93
 
@@ -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
 
@@ -61,9 +61,9 @@ module Doorkeeper
61
61
  end
62
62
 
63
63
  def self.valid_scheme?(uri)
64
- return false if uri.scheme.nil?
64
+ return false if uri.scheme.blank?
65
65
 
66
- %w[localhost].include?(uri.scheme) == false
66
+ %w[localhost].exclude?(uri.scheme)
67
67
  end
68
68
 
69
69
  def self.hypertext_scheme?(uri)
@@ -71,7 +71,7 @@ module Doorkeeper
71
71
  end
72
72
 
73
73
  def self.iff_host?(uri)
74
- !(hypertext_scheme?(uri) && uri.host.nil?)
74
+ !(hypertext_scheme?(uri) && uri.host.blank?)
75
75
  end
76
76
 
77
77
  def self.oob_uri?(uri)
@@ -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
 
@@ -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
@@ -5,32 +5,34 @@ 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, error: Errors::InvalidCodeChallenge
18
+ validate :code_challenge_method, error: Errors::InvalidCodeChallengeMethod
18
19
 
19
20
  attr_reader :client, :code_challenge, :code_challenge_method, :missing_param,
20
21
  :redirect_uri, :resource_owner, :response_type, :state,
21
- :authorization_response_flow, :response_mode
22
+ :authorization_response_flow, :response_mode, :custom_access_token_attributes
22
23
 
23
24
  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]
25
+ @server = server
26
+ @client_id = parameters[:client_id]
27
+ @response_type = parameters[:response_type]
28
+ @response_mode = parameters[:response_mode]
29
+ @redirect_uri = parameters[:redirect_uri]
30
+ @scope = parameters[:scope]
31
+ @state = parameters[:state]
32
+ @code_challenge = parameters[:code_challenge]
32
33
  @code_challenge_method = parameters[:code_challenge_method]
33
- @resource_owner = resource_owner
34
+ @resource_owner = resource_owner
35
+ @custom_access_token_attributes = parameters.slice(*Doorkeeper.config.custom_access_token_attributes).to_h
34
36
  end
35
37
 
36
38
  def authorizable?
@@ -46,7 +48,7 @@ module Doorkeeper
46
48
  end
47
49
 
48
50
  def error_response
49
- if error == :invalid_request
51
+ if error == Errors::InvalidRequest
50
52
  OAuth::InvalidRequestResponse.from_request(
51
53
  self,
52
54
  response_on_fragment: response_on_fragment?,
@@ -73,7 +75,7 @@ module Doorkeeper
73
75
  if client_scopes.blank?
74
76
  server.default_scopes.to_s
75
77
  else
76
- (server.default_scopes & client_scopes).to_s
78
+ server.default_scopes.allowed(client_scopes).to_s
77
79
  end
78
80
  end
79
81
 
@@ -142,11 +144,17 @@ module Doorkeeper
142
144
  )
143
145
  end
144
146
 
147
+ def validate_code_challenge
148
+ return true unless Doorkeeper.config.force_pkce?
149
+ return true if client.confidential
150
+ code_challenge.present?
151
+ end
152
+
145
153
  def validate_code_challenge_method
146
154
  return true unless Doorkeeper.config.access_grant_model.pkce_supported?
147
155
 
148
156
  code_challenge.blank? ||
149
- (code_challenge_method.present? && code_challenge_method =~ /^plain$|^S256$/)
157
+ (code_challenge_method.present? && Doorkeeper.config.pkce_code_challenge_methods_supported.include?(code_challenge_method))
150
158
  end
151
159
 
152
160
  def 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
@@ -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