doorkeeper 5.2.0.rc2 → 5.2.0.rc3

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (59) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +1 -1
  3. data/CHANGELOG.md +15 -2
  4. data/Gemfile +1 -1
  5. data/README.md +9 -1
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +1 -1
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +11 -9
  8. data/config/locales/en.yml +5 -1
  9. data/doorkeeper.gemspec +8 -0
  10. data/gemfiles/rails_6_0.gemfile +1 -1
  11. data/lib/doorkeeper.rb +1 -0
  12. data/lib/doorkeeper/config.rb +41 -2
  13. data/lib/doorkeeper/errors.rb +13 -18
  14. data/lib/doorkeeper/helpers/controller.rb +6 -2
  15. data/lib/doorkeeper/oauth/authorization/code.rb +1 -5
  16. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -9
  17. data/lib/doorkeeper/oauth/base_request.rb +2 -0
  18. data/lib/doorkeeper/oauth/client_credentials/validation.rb +8 -0
  19. data/lib/doorkeeper/oauth/code_request.rb +5 -11
  20. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  21. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -2
  22. data/lib/doorkeeper/oauth/pre_authorization.rb +70 -37
  23. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -2
  24. data/lib/doorkeeper/oauth/token_introspection.rb +4 -1
  25. data/lib/doorkeeper/oauth/token_request.rb +4 -18
  26. data/lib/doorkeeper/orm/active_record.rb +2 -2
  27. data/lib/doorkeeper/orm/active_record/application.rb +1 -1
  28. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +61 -0
  29. data/lib/doorkeeper/request.rb +6 -11
  30. data/lib/doorkeeper/request/authorization_code.rb +2 -0
  31. data/lib/doorkeeper/server.rb +2 -6
  32. data/lib/doorkeeper/version.rb +1 -1
  33. data/lib/generators/doorkeeper/templates/initializer.rb +33 -2
  34. data/lib/generators/doorkeeper/templates/migration.rb.erb +1 -1
  35. data/spec/controllers/authorizations_controller_spec.rb +127 -61
  36. data/spec/controllers/protected_resources_controller_spec.rb +3 -3
  37. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +1 -1
  38. data/spec/lib/config_spec.rb +17 -0
  39. data/spec/lib/oauth/authorization_code_request_spec.rb +11 -1
  40. data/spec/lib/oauth/base_request_spec.rb +33 -16
  41. data/spec/lib/oauth/code_request_spec.rb +27 -28
  42. data/spec/lib/oauth/invalid_request_response_spec.rb +75 -0
  43. data/spec/lib/oauth/pre_authorization_spec.rb +80 -55
  44. data/spec/lib/oauth/refresh_token_request_spec.rb +1 -0
  45. data/spec/lib/oauth/token_request_spec.rb +20 -17
  46. data/spec/lib/server_spec.rb +0 -12
  47. data/spec/requests/endpoints/authorization_spec.rb +21 -5
  48. data/spec/requests/endpoints/token_spec.rb +1 -1
  49. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -0
  50. data/spec/requests/flows/authorization_code_spec.rb +77 -23
  51. data/spec/requests/flows/client_credentials_spec.rb +38 -0
  52. data/spec/requests/flows/implicit_grant_errors_spec.rb +22 -10
  53. data/spec/requests/flows/implicit_grant_spec.rb +9 -8
  54. data/spec/requests/flows/password_spec.rb +37 -0
  55. data/spec/requests/flows/refresh_token_spec.rb +1 -1
  56. data/spec/support/helpers/request_spec_helper.rb +14 -2
  57. data/spec/validators/redirect_uri_validator_spec.rb +1 -1
  58. metadata +12 -4
  59. data/app/validators/redirect_uri_validator.rb +0 -60
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 30363aebde1b255fb64b8df11e5d9b1c80f0d896ebb970908f764a8a5fd17fdf
4
- data.tar.gz: 129cddd18b7ea164da1387d8a3fef5c40b4be96eca9f141ebb0167a318f28a07
3
+ metadata.gz: 79deafb0a48421ccce39ffc81a5c78e89c02d53d3759dfd8ec1cc18a8fee9eb1
4
+ data.tar.gz: 4d31a738a4955f1e7c323aa972a487b85d6050f05d2ceb4f4b8197925371ef1d
5
5
  SHA512:
6
- metadata.gz: 48f707ac0ee598c6987cf396cc168f57975abe8fbf78ce0479733e1b7fdf35ef6abcd73474f0141c72eee1b08ce8a9f0cf46d866f974c0feea8ae9609cb36d07
7
- data.tar.gz: 79c4aa3fdae50be283f3ef78c544554ad5d50d8395d6f6970a41c73a0d46d427b859dd07e38685120d0df9b1016567a3a34b79d882b9b23d6bb470a19c95ecd8
6
+ metadata.gz: 58fb6a412cb9b9a3e7c89c1aa93edc98380673ff71bd0c0797bb32a1ad89806370c41b3a40ca98f113af922e681deef696f90233bd098fdee30b149cce927e0d
7
+ data.tar.gz: e32e2d2cdc45a38ca98fcf27bc1a6657077de7cb0a738d07627dd51d5c2237287e736fff3833d1a154346be46286e6ea87b4a16d0e2c4637e58f4d79bce2a45b
data/Appraisals CHANGED
@@ -16,7 +16,7 @@ appraise "rails-5-2" do
16
16
  end
17
17
 
18
18
  appraise "rails-6-0" do
19
- gem "rails", "~> 6.0.0.beta3"
19
+ gem "rails", "~> 6.0.0.rc2"
20
20
  gem "sqlite3", "~> 1.4", platform: %i[ruby mswin mingw x64_mingw]
21
21
 
22
22
  # TODO: Remove when rspec-rails 4.0 released
@@ -7,7 +7,20 @@ User-visible changes worth mentioning.
7
7
 
8
8
  ## master
9
9
 
10
- - [#PR ID] Add your description here
10
+ - [#PR ID] Add your description here.
11
+
12
+ ## 5.2.0.rc3
13
+
14
+ - [#1298] Slice strong params so doesn't error with Rails forms.
15
+ - [#1300] Limiting access to attributes of pre_authorization.
16
+ - [#1296] Adding client_id to strong parameters.
17
+ - [#1293] Move ar specific redirect uri validator to ar orm directory.
18
+ - [#1288] Allow to pass attributes to the `Doorkeeper::OAuth::PreAuthorization#as_json` method to customize
19
+ the PreAuthorization response.
20
+ - [#1286] Add ability to customize grant flows per application (OAuth client) (#1245 , #1207)
21
+ - [#1283] Allow to customize base class for `Doorkeeper::ApplicationMetalController` (new configuration
22
+ option called `base_metal_controller` (fix #1273).
23
+ - [#1277] Prevent requested scope be empty on authorization request, handle and add description for invalid request.
11
24
 
12
25
  ## 5.2.0.rc2
13
26
 
@@ -20,7 +33,7 @@ User-visible changes worth mentioning.
20
33
 
21
34
  ## 5.2.0.rc1
22
35
 
23
- - [#1260], [#1261] Improve Token Introspection configuration option (access to tokens, client).
36
+ - [#1260], [#1262] Improve Token Introspection configuration option (access to tokens, client).
24
37
  - [#1257] Add constraint configuration when using client authentication on introspection endpoint.
25
38
  - [#1252] Returning `unauthorized` when the revocation of the token should not be performed due to wrong permissions.
26
39
  - [#1249] Specify case sensitive uniqueness to remove Rails 6 deprecation message
data/Gemfile CHANGED
@@ -5,7 +5,7 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
5
 
6
6
  gemspec
7
7
 
8
- gem "rails", "~> 6.0.0.rc1"
8
+ gem "rails", "~> 6.0.0.rc2"
9
9
 
10
10
  # TODO: Remove when rspec-rails 4.0 released
11
11
  gem "rspec-core", github: "rspec/rspec-core"
data/README.md CHANGED
@@ -21,10 +21,11 @@ Supported features:
21
21
  - [Implicit grant](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.2)
22
22
  - [Resource Owner Password Credentials](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.3)
23
23
  - [Client Credentials](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.4)
24
- - [Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636)
25
24
  - [OAuth 2.0 Token Revocation](http://tools.ietf.org/html/rfc7009)
26
25
  - [OAuth 2.0 Token Introspection](https://tools.ietf.org/html/rfc7662)
27
26
  - [OAuth 2.0 Threat Model and Security Considerations](http://tools.ietf.org/html/rfc6819)
27
+ - [OAuth 2.0 for Native Apps](https://tools.ietf.org/html/draft-ietf-oauth-native-apps-10)
28
+ - [Proof Key for Code Exchange by OAuth Public Clients](https://tools.ietf.org/html/rfc7636)
28
29
 
29
30
  ## Table of Contents
30
31
 
@@ -93,6 +94,7 @@ Doorkeeper supports Active Record by default, but can be configured to work with
93
94
  | MongoDB | [doorkeeper-gem/doorkeeper-mongodb](https://github.com/doorkeeper-gem/doorkeeper-mongodb) |
94
95
  | Sequel | [nbulaj/doorkeeper-sequel](https://github.com/nbulaj/doorkeeper-sequel) |
95
96
  | Couchbase | [acaprojects/doorkeeper-couchbase](https://github.com/acaprojects/doorkeeper-couchbase) |
97
+ | RethinkDB | [aca-labs/doorkeeper-rethinkdb](https://github.com/aca-labs/doorkeeper-rethinkdb) |
96
98
 
97
99
  ## Extensions
98
100
 
@@ -136,6 +138,12 @@ Support this project by becoming a sponsor. Your logo will show up here with a l
136
138
 
137
139
  > If you prefer not to deal with the gory details of OAuth 2, need dedicated customer support & consulting, try the cloud-based SaaS version: [https://oauth.io](https://oauth.io/?utm_source=doorkeeper-gem)
138
140
 
141
+ <br>
142
+
143
+ <a href="https://www.wealthsimple.com/?utm_source=doorkeeper-gem" target="_blank"><img src="https://wealthsimple.s3.amazonaws.com/branding/medium-black.svg"/></a>
144
+
145
+ > Wealthsimple is a financial company on a mission to help everyone achieve financial freedom by providing products and advice that are accessible and affordable. Using smart technology, Wealthsimple takes financial services that are often confusing, opaque and expensive and makes them simple, transparent, and low-cost. See what Investing on Autopilot is all about: [https://www.wealthsimple.com](https://www.wealthsimple.com/?utm_source=doorkeeper-gem)
146
+
139
147
  ## Development
140
148
 
141
149
  To run the local engine server:
@@ -1,7 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Doorkeeper
4
- class ApplicationMetalController < ActionController::API
4
+ class ApplicationMetalController < Doorkeeper.configuration.base_metal_controller.constantize
5
5
  include Helpers::Controller
6
6
 
7
7
  before_action :enforce_content_type,
@@ -12,7 +12,6 @@ module Doorkeeper
12
12
  end
13
13
  end
14
14
 
15
- # TODO: Handle raise invalid authorization
16
15
  def create
17
16
  redirect_or_render authorize_response
18
17
  end
@@ -66,14 +65,16 @@ module Doorkeeper
66
65
  end
67
66
 
68
67
  def pre_auth
69
- @pre_auth ||= OAuth::PreAuthorization.new(Doorkeeper.configuration,
70
- server.client_via_uid,
71
- pre_auth_params)
68
+ @pre_auth ||= OAuth::PreAuthorization.new(Doorkeeper.configuration, pre_auth_params)
72
69
  end
73
70
 
74
71
  def pre_auth_params
75
- params.permit(:response_type, :redirect_uri, :scope, :state,
76
- :code_challenge, :code_challenge_method)
72
+ params.slice(*pre_auth_param_fields).permit(*pre_auth_param_fields)
73
+ end
74
+
75
+ def pre_auth_param_fields
76
+ %i[client_id response_type redirect_uri scope state code_challenge
77
+ code_challenge_method]
77
78
  end
78
79
 
79
80
  def authorization
@@ -86,10 +87,11 @@ module Doorkeeper
86
87
 
87
88
  def authorize_response
88
89
  @authorize_response ||= begin
89
- authorizable = pre_auth.authorizable?
90
- before_successful_authorization if authorizable
90
+ return pre_auth.error_response unless pre_auth.authorizable?
91
+
92
+ before_successful_authorization
91
93
  auth = strategy.authorize
92
- after_successful_authorization if authorizable
94
+ after_successful_authorization
93
95
  auth
94
96
  end
95
97
  end
@@ -88,7 +88,11 @@ en:
88
88
  errors:
89
89
  messages:
90
90
  # Common error messages
91
- invalid_request: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
91
+ invalid_request:
92
+ unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
93
+ missing_param: 'Missing required parameter: #{value}.'
94
+ not_support_pkce: 'Invalid code_verifier parameter. Server does not support pkce.'
95
+ request_not_authorized: 'Request need to be authorized. Required parameter for authorizing request is missing or invalid.'
92
96
  invalid_redirect_uri: "The requested redirect uri is malformed or doesn't match client redirect URI."
93
97
  unauthorized_client: 'The client is not authorized to perform this request using this method.'
94
98
  access_denied: 'The resource owner or authorization server denied the request.'
@@ -18,6 +18,14 @@ Gem::Specification.new do |gem|
18
18
  gem.test_files = `git ls-files -- spec/*`.split("\n")
19
19
  gem.require_paths = ["lib"]
20
20
 
21
+ gem.metadata = {
22
+ "homepage_uri" => "https://github.com/doorkeeper-gem/doorkeeper",
23
+ "changelog_uri" => "https://github.com/doorkeeper-gem/doorkeeper/blob/master/CHANGELOG.md",
24
+ "source_code_uri" => "https://github.com/doorkeeper-gem/doorkeeper",
25
+ "bug_tracker_uri" => "https://github.com/doorkeeper-gem/doorkeeper/issues",
26
+ "documentation_uri" => "https://doorkeeper.gitbook.io/guides/",
27
+ }
28
+
21
29
  gem.add_dependency "railties", ">= 5"
22
30
  gem.required_ruby_version = ">= 2.4"
23
31
 
@@ -2,7 +2,7 @@
2
2
 
3
3
  source "https://rubygems.org"
4
4
 
5
- gem "rails", "~> 6.0.0.rc1"
5
+ gem "rails", "~> 6.0.0.rc2"
6
6
  gem "rspec-core", git: "https://github.com/rspec/rspec-core.git"
7
7
  gem "rspec-expectations", git: "https://github.com/rspec/rspec-expectations.git"
8
8
  gem "rspec-mocks", git: "https://github.com/rspec/rspec-mocks.git"
@@ -52,6 +52,7 @@ require "doorkeeper/oauth/token"
52
52
  require "doorkeeper/oauth/token_introspection"
53
53
  require "doorkeeper/oauth/invalid_token_response"
54
54
  require "doorkeeper/oauth/forbidden_token_response"
55
+ require "doorkeeper/oauth/invalid_request_response"
55
56
  require "doorkeeper/oauth/nonstandard"
56
57
 
57
58
  require "doorkeeper/secret_storing/base"
@@ -259,6 +259,32 @@ module Doorkeeper
259
259
  option :grant_flows, default: %w[authorization_code client_credentials]
260
260
  option :handle_auth_errors, default: :render
261
261
 
262
+ # Allows to customize OAuth grant flows that +each+ application support.
263
+ # You can configure a custom block (or use a class respond to `#call`) that must
264
+ # return `true` in case Application instance supports requested OAuth grant flow
265
+ # during the authorization request to the server. This configuration +doesn't+
266
+ # set flows per application, it only allows to check if application supports
267
+ # specific grant flow.
268
+ #
269
+ # For example you can add an additional database column to `oauth_applications` table,
270
+ # say `t.array :grant_flows, default: []`, and store allowed grant flows that can
271
+ # be used with this application there. Then when authorization requested Doorkeeper
272
+ # will call this block to check if specific Application (passed with client_id and/or
273
+ # client_secret) is allowed to perform the request for the specific grant type
274
+ # (authorization, password, client_credentials, etc).
275
+ #
276
+ # Example of the block:
277
+ #
278
+ # ->(flow, client) { client.grant_flows.include?(flow) }
279
+ #
280
+ # In case this option invocation result is `false`, Doorkeeper server returns
281
+ # :unauthorized_client error and stops the request.
282
+ #
283
+ # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
284
+ # @return [Boolean] `true` if allow or `false` if forbid the request
285
+ #
286
+ option :allow_grant_flow_for_client, default: ->(_grant_flow, _client) { true }
287
+
262
288
  # Allows to forbid specific Application redirect URI's by custom rules.
263
289
  # Doesn't forbid any URI by default.
264
290
  #
@@ -288,7 +314,7 @@ module Doorkeeper
288
314
  option :force_ssl_in_redirect_uri, default: !Rails.env.development?
289
315
 
290
316
  # Use a custom class for generating the access token.
291
- # https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
317
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
292
318
  #
293
319
  # @param access_token_generator [String]
294
320
  # the name of the access token generator class
@@ -306,12 +332,19 @@ module Doorkeeper
306
332
 
307
333
  # The controller Doorkeeper::ApplicationController inherits from.
308
334
  # Defaults to ActionController::Base.
309
- # https://github.com/doorkeeper-gem/doorkeeper#custom-base-controller
335
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-base-controller
310
336
  #
311
337
  # @param base_controller [String] the name of the base controller
312
338
  option :base_controller,
313
339
  default: "ActionController::Base"
314
340
 
341
+ # The controller Doorkeeper::ApplicationMetalController inherits from.
342
+ # Defaults to ActionController::API.
343
+ #
344
+ # @param base_metal_controller [String] the name of the base controller
345
+ option :base_metal_controller,
346
+ default: "ActionController::API"
347
+
315
348
  # Allows to set blank redirect URIs for Applications in case
316
349
  # server configured to use URI-less grant flows.
317
350
  #
@@ -452,6 +485,12 @@ module Doorkeeper
452
485
  end
453
486
  end
454
487
 
488
+ def allow_grant_flow_for_client?(grant_flow, client)
489
+ return true unless option_defined?(:allow_grant_flow_for_client)
490
+
491
+ allow_grant_flow_for_client.call(grant_flow, client)
492
+ end
493
+
455
494
  def option_defined?(name)
456
495
  instance_variable_defined?("@#{name}")
457
496
  end
@@ -8,18 +8,6 @@ module Doorkeeper
8
8
  end
9
9
  end
10
10
 
11
- class InvalidAuthorizationStrategy < DoorkeeperError
12
- def type
13
- :unsupported_response_type
14
- end
15
- end
16
-
17
- class InvalidTokenReuse < DoorkeeperError
18
- def type
19
- :invalid_request
20
- end
21
- end
22
-
23
11
  class InvalidGrantReuse < DoorkeeperError
24
12
  def type
25
13
  :invalid_grant
@@ -32,7 +20,14 @@ module Doorkeeper
32
20
  end
33
21
  end
34
22
 
35
- class MissingRequestStrategy < DoorkeeperError
23
+ class MissingRequiredParameter < DoorkeeperError
24
+ attr_reader :missing_param
25
+
26
+ def initialize(missing_param)
27
+ super
28
+ @missing_param = missing_param
29
+ end
30
+
36
31
  def type
37
32
  :invalid_request
38
33
  end
@@ -50,10 +45,10 @@ module Doorkeeper
50
45
  TokenGeneratorNotFound = Class.new(DoorkeeperError)
51
46
  NoOrmCleaner = Class.new(DoorkeeperError)
52
47
 
53
- InvalidToken = Class.new BaseResponseError
54
- TokenExpired = Class.new InvalidToken
55
- TokenRevoked = Class.new InvalidToken
56
- TokenUnknown = Class.new InvalidToken
57
- TokenForbidden = Class.new InvalidToken
48
+ InvalidToken = Class.new(BaseResponseError)
49
+ TokenExpired = Class.new(InvalidToken)
50
+ TokenRevoked = Class.new(InvalidToken)
51
+ TokenUnknown = Class.new(InvalidToken)
52
+ TokenForbidden = Class.new(InvalidToken)
58
53
  end
59
54
  end
@@ -44,8 +44,12 @@ module Doorkeeper
44
44
  def get_error_response_from_exception(exception)
45
45
  if exception.respond_to?(:response)
46
46
  exception.response
47
+ elsif exception.type == :invalid_request
48
+ OAuth::InvalidRequestResponse.new(name: exception.type,
49
+ state: params[:state],
50
+ missing_param: exception.missing_param)
47
51
  else
48
- OAuth::ErrorResponse.new name: exception.type, state: params[:state]
52
+ OAuth::ErrorResponse.new(name: exception.type, state: params[:state])
49
53
  end
50
54
  end
51
55
 
@@ -58,7 +62,7 @@ module Doorkeeper
58
62
 
59
63
  def skip_authorization?
60
64
  !!instance_exec(
61
- [@server.current_resource_owner, @pre_auth.client],
65
+ [server.current_resource_owner, @pre_auth.client],
62
66
  &Doorkeeper.configuration.skip_authorization
63
67
  )
64
68
  end
@@ -19,14 +19,10 @@ module Doorkeeper
19
19
  { action: :show, code: token.plaintext_token }
20
20
  end
21
21
 
22
- def configuration
23
- Doorkeeper.configuration
24
- end
25
-
26
22
  private
27
23
 
28
24
  def authorization_code_expires_in
29
- configuration.authorization_code_expires_in
25
+ Doorkeeper.configuration.authorization_code_expires_in
30
26
  end
31
27
 
32
28
  def access_grant_attributes
@@ -3,7 +3,8 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class AuthorizationCodeRequest < BaseRequest
6
- validate :attributes, error: :invalid_request
6
+ validate :pkce_support, error: :invalid_request
7
+ validate :params, error: :invalid_request
7
8
  validate :client, error: :invalid_client
8
9
  validate :grant, error: :invalid_grant
9
10
  # @see https://tools.ietf.org/html/rfc6749#section-5.2
@@ -12,6 +13,7 @@ module Doorkeeper
12
13
 
13
14
  attr_accessor :server, :grant, :client, :redirect_uri, :access_token,
14
15
  :code_verifier
16
+ attr_reader :invalid_request_reason, :missing_param
15
17
 
16
18
  def initialize(server, grant, client, parameters = {})
17
19
  @server = server
@@ -24,10 +26,6 @@ module Doorkeeper
24
26
 
25
27
  private
26
28
 
27
- def client_by_uid(parameters)
28
- Doorkeeper::Application.by_uid(parameters[:client_id])
29
- end
30
-
31
29
  def before_successful_response
32
30
  grant.transaction do
33
31
  grant.lock!
@@ -42,11 +40,22 @@ module Doorkeeper
42
40
  super
43
41
  end
44
42
 
45
- def validate_attributes
46
- return false if grant&.uses_pkce? && code_verifier.blank?
47
- return false if grant && !grant.pkce_supported? && !code_verifier.blank?
43
+ def validate_pkce_support
44
+ @invalid_request_reason = :not_support_pkce if grant &&
45
+ !grant.pkce_supported? &&
46
+ code_verifier.present?
47
+
48
+ @invalid_request_reason.nil?
49
+ end
50
+
51
+ def validate_params
52
+ @missing_param = if grant&.uses_pkce? && code_verifier.blank?
53
+ :code_verifier
54
+ elsif redirect_uri.blank?
55
+ :redirect_uri
56
+ end
48
57
 
49
- redirect_uri.present?
58
+ @missing_param.nil?
50
59
  end
51
60
 
52
61
  def validate_client
@@ -15,6 +15,8 @@ module Doorkeeper
15
15
  @response = TokenResponse.new(access_token)
16
16
  after_successful_response
17
17
  @response
18
+ elsif error == :invalid_request
19
+ @response = InvalidRequestResponse.from_request(self)
18
20
  else
19
21
  @response = ErrorResponse.from_request(self)
20
22
  end
@@ -8,6 +8,7 @@ module Doorkeeper
8
8
  include OAuth::Helpers
9
9
 
10
10
  validate :client, error: :invalid_client
11
+ validate :client_supports_grant_flow, error: :unauthorized_client
11
12
  validate :scopes, error: :invalid_scope
12
13
 
13
14
  def initialize(server, request)
@@ -24,6 +25,13 @@ module Doorkeeper
24
25
  @client.present?
25
26
  end
26
27
 
28
+ def validate_client_supports_grant_flow
29
+ Doorkeeper.configuration.allow_grant_flow_for_client?(
30
+ Doorkeeper::OAuth::CLIENT_CREDENTIALS,
31
+ @client
32
+ )
33
+ end
34
+
27
35
  def validate_scopes
28
36
  return true if @request.scopes.blank?
29
37