doorkeeper 5.3.3 → 5.4.0.rc1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (120) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +0 -14
  3. data/CHANGELOG.md +35 -10
  4. data/Dangerfile +7 -7
  5. data/Dockerfile +2 -2
  6. data/Gemfile +9 -9
  7. data/README.md +6 -4
  8. data/app/controllers/doorkeeper/applications_controller.rb +7 -7
  9. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  10. data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
  11. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  12. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  13. data/bin/console +14 -0
  14. data/config/locales/en.yml +3 -1
  15. data/doorkeeper.gemspec +1 -1
  16. data/gemfiles/rails_5_0.gemfile +8 -7
  17. data/gemfiles/rails_5_1.gemfile +8 -7
  18. data/gemfiles/rails_5_2.gemfile +8 -7
  19. data/gemfiles/rails_6_0.gemfile +8 -7
  20. data/gemfiles/rails_master.gemfile +8 -7
  21. data/lib/doorkeeper.rb +106 -79
  22. data/lib/doorkeeper/config.rb +40 -17
  23. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  24. data/lib/doorkeeper/config/option.rb +28 -14
  25. data/lib/doorkeeper/grape/helpers.rb +1 -1
  26. data/lib/doorkeeper/models/access_grant_mixin.rb +9 -11
  27. data/lib/doorkeeper/models/access_token_mixin.rb +100 -41
  28. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  29. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  30. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  31. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  32. data/lib/doorkeeper/oauth/authorization/code.rb +14 -5
  33. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  34. data/lib/doorkeeper/oauth/authorization/token.rb +7 -11
  35. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  36. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  37. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  38. data/lib/doorkeeper/oauth/client.rb +1 -1
  39. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  40. data/lib/doorkeeper/oauth/client_credentials/creator.rb +25 -7
  41. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  42. data/lib/doorkeeper/oauth/client_credentials/validator.rb +1 -1
  43. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  44. data/lib/doorkeeper/oauth/code_request.rb +1 -1
  45. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  46. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  47. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  48. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  49. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  50. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -5
  51. data/lib/doorkeeper/oauth/pre_authorization.rb +32 -27
  52. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  53. data/lib/doorkeeper/oauth/token.rb +1 -1
  54. data/lib/doorkeeper/oauth/token_introspection.rb +3 -3
  55. data/lib/doorkeeper/oauth/token_request.rb +2 -2
  56. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  57. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +7 -2
  58. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +6 -2
  59. data/lib/doorkeeper/orm/active_record/mixins/application.rb +9 -64
  60. data/lib/doorkeeper/rails/routes.rb +13 -17
  61. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  62. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  63. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  64. data/lib/doorkeeper/request/strategy.rb +2 -2
  65. data/lib/doorkeeper/server.rb +3 -3
  66. data/lib/doorkeeper/version.rb +3 -3
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  69. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  70. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  71. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  72. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  73. data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
  74. data/lib/generators/doorkeeper/templates/migration.rb.erb +2 -0
  75. data/spec/controllers/applications_controller_spec.rb +2 -2
  76. data/spec/controllers/authorizations_controller_spec.rb +165 -30
  77. data/spec/controllers/tokens_controller_spec.rb +6 -5
  78. data/spec/dummy/app/helpers/application_helper.rb +1 -1
  79. data/spec/dummy/app/models/user.rb +5 -1
  80. data/spec/dummy/config/application.rb +6 -4
  81. data/spec/dummy/config/boot.rb +4 -4
  82. data/spec/dummy/config/environment.rb +1 -1
  83. data/spec/dummy/config/routes.rb +4 -4
  84. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +2 -2
  85. data/spec/dummy/db/schema.rb +3 -1
  86. data/spec/factories.rb +1 -1
  87. data/spec/generators/enable_polymorphic_resource_owner_generator_spec.rb +47 -0
  88. data/spec/lib/config_spec.rb +15 -11
  89. data/spec/lib/models/revocable_spec.rb +2 -3
  90. data/spec/lib/models/scopes_spec.rb +8 -0
  91. data/spec/lib/oauth/authorization_code_request_spec.rb +25 -15
  92. data/spec/lib/oauth/base_request_spec.rb +6 -20
  93. data/spec/lib/oauth/client_credentials/creator_spec.rb +90 -89
  94. data/spec/lib/oauth/client_credentials/issuer_spec.rb +84 -86
  95. data/spec/lib/oauth/client_credentials/validation_spec.rb +38 -40
  96. data/spec/lib/oauth/client_credentials_request_spec.rb +5 -4
  97. data/spec/lib/oauth/code_request_spec.rb +1 -1
  98. data/spec/lib/oauth/code_response_spec.rb +5 -1
  99. data/spec/lib/oauth/error_response_spec.rb +1 -1
  100. data/spec/lib/oauth/password_access_token_request_spec.rb +24 -13
  101. data/spec/lib/oauth/pre_authorization_spec.rb +13 -18
  102. data/spec/lib/oauth/refresh_token_request_spec.rb +19 -30
  103. data/spec/lib/oauth/token_request_spec.rb +14 -7
  104. data/spec/lib/option_spec.rb +51 -0
  105. data/spec/lib/stale_records_cleaner_spec.rb +18 -5
  106. data/spec/models/doorkeeper/access_grant_spec.rb +18 -4
  107. data/spec/models/doorkeeper/access_token_spec.rb +507 -479
  108. data/spec/models/doorkeeper/application_spec.rb +22 -62
  109. data/spec/requests/endpoints/token_spec.rb +5 -1
  110. data/spec/requests/flows/authorization_code_errors_spec.rb +4 -1
  111. data/spec/requests/flows/authorization_code_spec.rb +6 -1
  112. data/spec/requests/flows/client_credentials_spec.rb +41 -0
  113. data/spec/requests/flows/refresh_token_spec.rb +16 -8
  114. data/spec/requests/flows/revoke_token_spec.rb +143 -104
  115. data/spec/support/helpers/access_token_request_helper.rb +1 -0
  116. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  117. data/spec/support/helpers/config_helper.rb +1 -1
  118. data/spec/support/shared/controllers_shared_context.rb +2 -2
  119. data/spec/support/shared/models_shared_examples.rb +6 -4
  120. metadata +16 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 4d3ed9e21e9d404f1c7f67a48a36a5745d9a5a7aca05b9ae63fbd10c6d170ac1
4
- data.tar.gz: 21ab4db448c9404a7067e8223433a8aa2ecfe955fd3729e7038efafd616c4237
3
+ metadata.gz: 7c9e55b1b52c75ecb1dc18678a2fb5e7683e85859f9a955c27a3197548c2b146
4
+ data.tar.gz: 59f5eafd45d8a85b7f84c7553f1084ed31c8a7ede3b61d00382b8110aea5e63f
5
5
  SHA512:
6
- metadata.gz: a03ea8dbf25bc5d48f2fa92942c73dfefa74978d16229b79f1f6d691e0d591ecdc08be84bc243139a1a4df50091fde2d039f5dcae65a8250477e309a31ad054d
7
- data.tar.gz: 7f6445f2beb910ba6b3cdeebd5d0d265986f49bb400ccccdbd811f7be8e34e5e029e07acfe22330729fe9065169b1807a4c98094abf3d247fe7175a1cd52daf5
6
+ metadata.gz: 1d64979c31b76f5f36671bfdea039da232aefdcb590a5fdf154740bb6968ec939cd5b883e163217431f38c6539017c01eb7d8518302f7b769c8a56857f16eab2
7
+ data.tar.gz: 62e2bae23f51b365d2aab4c8ba10a8efbd5ac860f68b481a2d41b193a5df2576ba08ec4700ab9b8def2a59a4494709dd628c9b9ec7d5a10ddb709ab4466a5ce1
data/Appraisals CHANGED
@@ -18,23 +18,9 @@ end
18
18
  appraise "rails-6-0" do
19
19
  gem "rails", "~> 6.0.0"
20
20
  gem "sqlite3", "~> 1.4", platform: %i[ruby mswin mingw x64_mingw]
21
-
22
- # TODO: Remove when rspec-rails 4.0 released
23
- gem "rspec-core", github: "rspec/rspec-core"
24
- gem "rspec-expectations", github: "rspec/rspec-expectations"
25
- gem "rspec-mocks", github: "rspec/rspec-mocks"
26
- gem "rspec-rails", github: "rspec/rspec-rails", branch: "4-0-maintenance"
27
- gem "rspec-support", github: "rspec/rspec-support"
28
21
  end
29
22
 
30
23
  appraise "rails-master" do
31
24
  gem "rails", git: "https://github.com/rails/rails"
32
25
  gem "sqlite3", "~> 1.4", platform: %i[ruby mswin mingw x64_mingw]
33
-
34
- # TODO: Remove when rspec-rails 4.0 released
35
- gem "rspec-core", github: "rspec/rspec-core"
36
- gem "rspec-expectations", github: "rspec/rspec-expectations"
37
- gem "rspec-mocks", github: "rspec/rspec-mocks"
38
- gem "rspec-rails", github: "rspec/rspec-rails", branch: "4-0-maintenance"
39
- gem "rspec-support", github: "rspec/rspec-support"
40
26
  end
@@ -5,19 +5,41 @@ upgrade guides.
5
5
 
6
6
  User-visible changes worth mentioning.
7
7
 
8
- ## 5.3.3
8
+ ## master
9
9
 
10
- - [#1404] Backport: Make `Doorkeeper::Application#read_attribute_for_serialization` public.
10
+ - [#PR number] Your changes description.
11
11
 
12
- ## 5.3.2
13
-
14
- - [#1371] Backport: add `#as_json` method and attributes serialization restriction for Application model.
15
- Fixes information disclosure vulnerability (CVE-2020-10187).
12
+ ## 5.4.0.rc1
13
+ - [#1366] Sets expiry of token generated using `refresh_token` to that of original token. (Fixes #1364)
14
+ - [#1354] Add `authorize_resource_owner_for_client` option to authorize the calling user to access an application.
15
+ - [#1355] Allow to enable polymorphic Resource Owner association for Access Token & Grant
16
+ models (`use_polymorphic_resource_owner` configuration option).
17
+
18
+ **[IMPORTANT]** Review your custom patches or extensions for Doorkeeper internals if you
19
+ have such - since now Doorkeeper passes Resource Owner instance to every objects and not
20
+ just it's ID. See PR description for details.
21
+
22
+ - [#1356] Remove duplicated scopes from Access Tokens and Grants on attribute assignment.
23
+ - [#1357] Fix `Doorkeeper::OAuth::PreAuthorization#as_json` method causing
24
+ `Stack level too deep` error with AMS (fix #1312).
25
+ - [#1358] Deprecate `active_record_options` configuration option.
26
+ - [#1359] Refactor Doorkeeper configuration options DSL to make it easy to reuse it
27
+ in external extensions.
28
+ - [#1360] Increase `matching_token_for` lookup size to 10 000 and make it configurable.
29
+ - [#1371] Fix controllers to use valid classes in case Doorkeeper has custom models configured.
30
+ - [#1370] Fix revocation response for invalid token and unauthorized requests to conform with RFC 7009 (fixes #1362).
31
+
32
+ **[IMPORTANT]** now fully according to RFC 7009 nobody can do a revocation request without `client_id`
33
+ (for public clients) and `client_secret` (for private clients). Please update your apps to include that
34
+ info in the revocation request payload.
16
35
 
17
- **[IMPORTANT]** you need to re-implement `#as_json` method for Doorkeeper Application model
18
- if you previously used `#to_json` serialization with custom options or attributes or rely on
19
- JSON response from /oauth/applications.json or /oauth/authorized_applications.json. This change
20
- is a breaking change which restricts serialized attributes to a very small set of columns.
36
+ - [#1373] Make Doorkeeper routes mapper reusable in extensions.
37
+ - [#1374] Revoke and issue client credentials token in a transaction with a row lock.
38
+ - [#1384] Add context object with auth/pre_auth and issued_token for authorization hooks.
39
+ - [#1387] Add `AccessToken#create_for` and use in `RefreshTokenRequest`.
40
+ - [#1392] Fix `enable_polymorphic_resource_owner` migration template to have proper index name.
41
+ - [#1393] Improve Applications #show page with more informative data on client secret and scopes.
42
+ - [#1394] Use Ruby `autoload` feature to load Doorkeeper files.
21
43
 
22
44
  ## 5.3.1
23
45
 
@@ -70,6 +92,9 @@ User-visible changes worth mentioning.
70
92
  - [#1298] Slice strong params so doesn't error with Rails forms.
71
93
  - [#1300] Limiting access to attributes of pre_authorization.
72
94
  - [#1296] Adding client_id to strong parameters.
95
+
96
+ **[IMPORTANT]** `Doorkeeper::Server#client_via_uid` was removed.
97
+
73
98
  - [#1293] Move ar specific redirect uri validator to ar orm directory.
74
99
  - [#1288] Allow to pass attributes to the `Doorkeeper::OAuth::PreAuthorization#as_json` method to customize
75
100
  the PreAuthorization response.
data/Dangerfile CHANGED
@@ -1,14 +1,14 @@
1
- CHANGELOG_FILE = 'CHANGELOG.md'
2
- GITHUB_REPO = 'https://github.com/doorkeeper-gem/doorkeeper'
1
+ CHANGELOG_FILE = "CHANGELOG.md"
2
+ GITHUB_REPO = "https://github.com/doorkeeper-gem/doorkeeper"
3
3
 
4
4
  def changelog_changed?
5
5
  git.modified_files.include?(CHANGELOG_FILE) || git.added_files.include?(CHANGELOG_FILE)
6
6
  end
7
7
 
8
8
  def changelog_entry_example
9
- pr_number = github.pr_json['number']
9
+ pr_number = github.pr_json["number"]
10
10
  pr_title = github.pr_title
11
- .sub(/[?.!,;]?$/, '')
11
+ .sub(/[?.!,;]?$/, "")
12
12
  .capitalize
13
13
 
14
14
  "- [##{pr_number}] #{pr_title}."
@@ -31,7 +31,7 @@ end
31
31
  # You've made changes to specs, but no library code has changed?
32
32
  # --------------------------------------------------------------------------------------------------------------------
33
33
  if !has_app_changes && has_spec_changes
34
- message('We really appreciate pull requests that demonstrate issues, even without a fix. That said, the next step is to try and fix the failing tests!', sticky: false)
34
+ message("We really appreciate pull requests that demonstrate issues, even without a fix. That said, the next step is to try and fix the failing tests!", sticky: false)
35
35
  end
36
36
 
37
37
  # Mainly to encourage writing up some reasoning about the PR, rather than
@@ -59,9 +59,9 @@ Here's an example of a #{CHANGELOG_FILE} entry:
59
59
  end
60
60
 
61
61
  if git.commits.any? { |commit| commit.message =~ /^Merge branch '#{github.branch_for_base}'/ }
62
- warn('Please rebase to get rid of the merge commits in this PR')
62
+ warn("Please rebase to get rid of the merge commits in this PR")
63
63
  end
64
64
 
65
65
  if git.commits.length > 1
66
- warn('Please squash all your commits to a single one')
66
+ warn("Please squash all your commits to a single one")
67
67
  end
data/Dockerfile CHANGED
@@ -1,4 +1,4 @@
1
- FROM ruby:2.6.3-alpine3.9
1
+ FROM ruby:2.6.5-alpine
2
2
 
3
3
  RUN apk add --no-cache \
4
4
  ca-certificates \
@@ -14,7 +14,7 @@ ENV LANG en_US.UTF-8
14
14
  ENV LANGUAGE en_US:en
15
15
  ENV LC_ALL en_US.UTF-8
16
16
 
17
- ENV BUNDLER_VERSION 2.0.1
17
+ ENV BUNDLER_VERSION 2.1.4
18
18
  RUN gem install bundler -v ${BUNDLER_VERSION} -i /usr/local/lib/ruby/gems/$(ls /usr/local/lib/ruby/gems) --force
19
19
 
20
20
  WORKDIR /srv
data/Gemfile CHANGED
@@ -5,17 +5,17 @@ git_source(:github) { |repo| "https://github.com/#{repo}.git" }
5
5
 
6
6
  gemspec
7
7
 
8
- gem "rails", "~> 6.0.0"
8
+ gem "rails", "~> 6.0"
9
9
 
10
- # TODO: Remove when rspec-rails 4.0 released
11
- gem "rspec-core", github: "rspec/rspec-core"
12
- gem "rspec-expectations", github: "rspec/rspec-expectations"
13
- gem "rspec-mocks", github: "rspec/rspec-mocks"
14
- gem "rspec-rails", "4.0.0.beta3"
15
- gem "rspec-support", github: "rspec/rspec-support"
10
+ gem "rspec-core"
11
+ gem "rspec-expectations"
12
+ gem "rspec-mocks"
13
+ gem "rspec-rails", "~> 4.0"
14
+ gem "rspec-support"
16
15
 
17
- gem "rubocop", "~> 0.75"
18
- gem "rubocop-performance"
16
+ gem "rubocop", "~> 0.80"
17
+ gem "rubocop-performance", require: false
18
+ gem "rubocop-rails", require: false
19
19
 
20
20
  gem "bcrypt", "~> 3.1", require: false
21
21
 
data/README.md CHANGED
@@ -6,7 +6,7 @@
6
6
  [![Coverage Status](https://coveralls.io/repos/github/doorkeeper-gem/doorkeeper/badge.svg?branch=master)](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=master)
7
7
  [![Security](https://hakiri.io/github/doorkeeper-gem/doorkeeper/master.svg)](https://hakiri.io/github/doorkeeper-gem/doorkeeper/master)
8
8
  [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
9
- [![GuardRails badge](https://badges.production.guardrails.io/doorkeeper-gem/doorkeeper.svg?token=66768ce8f6995814df81f65a2cff40f739f688492704f973e62809e15599bb62)](https://dashboard.guardrails.io/default/gh/doorkeeper-gem/doorkeeper)
9
+ [![GuardRails badge](https://badges.guardrails.io/doorkeeper-gem/doorkeeper.svg?token=66768ce8f6995814df81f65a2cff40f739f688492704f973e62809e15599bb62)](https://dashboard.guardrails.io/default/gh/doorkeeper-gem/doorkeeper)
10
10
  [![Dependabot](https://img.shields.io/badge/dependabot-enabled-success.svg)](https://dependabot.com)
11
11
 
12
12
  Doorkeeper is a gem (Rails engine) that makes it easy to introduce OAuth 2 provider
@@ -113,7 +113,7 @@ These applications show how Doorkeeper works and how to integrate with it. Start
113
113
 
114
114
  | Application | Link |
115
115
  | :--- | :--- |
116
- | oAuth2 Server with Doorkeeper | [doorkeeper-gem/doorkeeper-provider-app](https://github.com/doorkeeper-gem/doorkeeper-provider-app) |
116
+ | OAuth2 Server with Doorkeeper | [doorkeeper-gem/doorkeeper-provider-app](https://github.com/doorkeeper-gem/doorkeeper-provider-app) |
117
117
  | Sinatra Client connected to Provider App | [doorkeeper-gem/doorkeeper-sinatra-client](https://github.com/doorkeeper-gem/doorkeeper-sinatra-client) |
118
118
  | Devise + Omniauth Client | [doorkeeper-gem/doorkeeper-devise-client](https://github.com/doorkeeper-gem/doorkeeper-devise-client) |
119
119
 
@@ -160,6 +160,9 @@ tests with a specific Rails version:
160
160
  BUNDLE_GEMFILE=gemfiles/rails_6_0.gemfile bundle exec rake
161
161
  ```
162
162
 
163
+ You can also experiment with the changes using `bin/console`. It uses in-memory SQLite database and default
164
+ Doorkeeper config, but you can reestablish connection or reconfigure the gem if you need.
165
+
163
166
  ## Contributing
164
167
 
165
168
  Want to contribute and don't know where to start? Check out [features we're
@@ -168,8 +171,7 @@ create [example
168
171
  apps](https://github.com/doorkeeper-gem/doorkeeper/wiki/Example-Applications),
169
172
  integrate the gem with your app and let us know!
170
173
 
171
- Also, check out our [contributing guidelines
172
- page](https://github.com/doorkeeper-gem/doorkeeper/wiki/Contributing).
174
+ Also, check out our [contributing guidelines page](CONTRIBUTING.md).
173
175
 
174
176
  ## Contributors
175
177
 
@@ -8,7 +8,7 @@ module Doorkeeper
8
8
  before_action :set_application, only: %i[show edit update destroy]
9
9
 
10
10
  def index
11
- @applications = Application.ordered_by(:created_at)
11
+ @applications = Doorkeeper.config.application_model.ordered_by(:created_at)
12
12
 
13
13
  respond_to do |format|
14
14
  format.html
@@ -19,16 +19,16 @@ module Doorkeeper
19
19
  def show
20
20
  respond_to do |format|
21
21
  format.html
22
- format.json { render json: @application, as_owner: true }
22
+ format.json { render json: @application }
23
23
  end
24
24
  end
25
25
 
26
26
  def new
27
- @application = Application.new
27
+ @application = Doorkeeper.config.application_model.new
28
28
  end
29
29
 
30
30
  def create
31
- @application = Application.new(application_params)
31
+ @application = Doorkeeper.config.application_model.new(application_params)
32
32
 
33
33
  if @application.save
34
34
  flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications create])
@@ -36,7 +36,7 @@ module Doorkeeper
36
36
 
37
37
  respond_to do |format|
38
38
  format.html { redirect_to oauth_application_url(@application) }
39
- format.json { render json: @application, as_owner: true }
39
+ format.json { render json: @application }
40
40
  end
41
41
  else
42
42
  respond_to do |format|
@@ -58,7 +58,7 @@ module Doorkeeper
58
58
 
59
59
  respond_to do |format|
60
60
  format.html { redirect_to oauth_application_url(@application) }
61
- format.json { render json: @application, as_owner: true }
61
+ format.json { render json: @application }
62
62
  end
63
63
  else
64
64
  respond_to do |format|
@@ -84,7 +84,7 @@ module Doorkeeper
84
84
  private
85
85
 
86
86
  def set_application
87
- @application = Application.find(params[:id])
87
+ @application = Doorkeeper.config.application_model.find(params[:id])
88
88
  end
89
89
 
90
90
  def application_params
@@ -42,9 +42,9 @@ module Doorkeeper
42
42
  end
43
43
 
44
44
  def matching_token?
45
- AccessToken.matching_token_for(
45
+ Doorkeeper.config.access_token_model.matching_token_for(
46
46
  pre_auth.client,
47
- current_resource_owner.id,
47
+ current_resource_owner,
48
48
  pre_auth.scopes,
49
49
  )
50
50
  end
@@ -65,7 +65,11 @@ module Doorkeeper
65
65
  end
66
66
 
67
67
  def pre_auth
68
- @pre_auth ||= OAuth::PreAuthorization.new(Doorkeeper.configuration, pre_auth_params)
68
+ @pre_auth ||= OAuth::PreAuthorization.new(
69
+ Doorkeeper.configuration,
70
+ pre_auth_params,
71
+ current_resource_owner,
72
+ )
69
73
  end
70
74
 
71
75
  def pre_auth_params
@@ -73,8 +77,14 @@ module Doorkeeper
73
77
  end
74
78
 
75
79
  def pre_auth_param_fields
76
- %i[client_id response_type redirect_uri scope state code_challenge
77
- code_challenge_method]
80
+ %i[
81
+ client_id
82
+ code_challenge
83
+ code_challenge_method
84
+ response_type
85
+ redirect_uri
86
+ scope state
87
+ ]
78
88
  end
79
89
 
80
90
  def authorization
@@ -82,26 +92,35 @@ module Doorkeeper
82
92
  end
83
93
 
84
94
  def strategy
85
- @strategy ||= server.authorization_request pre_auth.response_type
95
+ @strategy ||= server.authorization_request(pre_auth.response_type)
86
96
  end
87
97
 
88
98
  def authorize_response
89
99
  @authorize_response ||= begin
90
100
  return pre_auth.error_response unless pre_auth.authorizable?
91
101
 
92
- before_successful_authorization
102
+ context = build_context(pre_auth: pre_auth)
103
+ before_successful_authorization(context)
104
+
93
105
  auth = strategy.authorize
94
- after_successful_authorization
106
+
107
+ context = build_context(auth: auth)
108
+ after_successful_authorization(context)
109
+
95
110
  auth
96
111
  end
97
112
  end
98
113
 
99
- def after_successful_authorization
100
- Doorkeeper.configuration.after_successful_authorization.call(self)
114
+ def build_context(**attributes)
115
+ Doorkeeper::OAuth::Hooks::Context.new(**attributes)
116
+ end
117
+
118
+ def before_successful_authorization(context = nil)
119
+ Doorkeeper.config.before_successful_authorization.call(self, context)
101
120
  end
102
121
 
103
- def before_successful_authorization
104
- Doorkeeper.configuration.before_successful_authorization.call(self)
122
+ def after_successful_authorization(context)
123
+ Doorkeeper.config.after_successful_authorization.call(self, context)
105
124
  end
106
125
  end
107
126
  end
@@ -5,16 +5,16 @@ module Doorkeeper
5
5
  before_action :authenticate_resource_owner!
6
6
 
7
7
  def index
8
- @applications = Application.authorized_for(current_resource_owner)
8
+ @applications = Doorkeeper.config.application_model.authorized_for(current_resource_owner)
9
9
 
10
10
  respond_to do |format|
11
11
  format.html
12
- format.json { render json: @applications, current_resource_owner: current_resource_owner }
12
+ format.json { render json: @applications }
13
13
  end
14
14
  end
15
15
 
16
16
  def destroy
17
- Application.revoke_tokens_and_grants_for(
17
+ Doorkeeper.config.application_model.revoke_tokens_and_grants_for(
18
18
  params[:id],
19
19
  current_resource_owner,
20
20
  )
@@ -12,14 +12,41 @@ module Doorkeeper
12
12
 
13
13
  # OAuth 2.0 Token Revocation - http://tools.ietf.org/html/rfc7009
14
14
  def revoke
15
- # The authorization server, if applicable, first authenticates the client
16
- # and checks its ownership of the provided token.
15
+ # @see 2.1. Revocation Request
17
16
  #
18
- # Doorkeeper does not use the token_type_hint logic described in the
19
- # RFC 7009 due to the refresh token implementation that is a field in
20
- # the access token model.
17
+ # The client constructs the request by including the following
18
+ # parameters using the "application/x-www-form-urlencoded" format in
19
+ # the HTTP request entity-body:
20
+ # token REQUIRED.
21
+ # token_type_hint OPTIONAL.
22
+ #
23
+ # The client also includes its authentication credentials as described
24
+ # in Section 2.3. of [RFC6749].
25
+ #
26
+ # The authorization server first validates the client credentials (in
27
+ # case of a confidential client) and then verifies whether the token
28
+ # was issued to the client making the revocation request.
29
+ unless server.client
30
+ # If this validation [client credentials / token ownership] fails, the request is
31
+ # refused and the client is informed of the error by the authorization server as
32
+ # described below.
33
+ #
34
+ # @see 2.2.1. Error Response
35
+ #
36
+ # The error presentation conforms to the definition in Section 5.2 of [RFC6749].
37
+ render json: revocation_error_response, status: :forbidden
38
+ return
39
+ end
21
40
 
22
- if authorized?
41
+ # The authorization server responds with HTTP status code 200 if the client
42
+ # submitted an invalid token or the token has been revoked successfully.
43
+ if token.blank?
44
+ render json: {}, status: 200
45
+ # The authorization server validates [...] and whether the token
46
+ # was issued to the client making the revocation request. If this
47
+ # validation fails, the request is refused and the client is informed
48
+ # of the error by the authorization server as described below.
49
+ elsif authorized?
23
50
  revoke_token
24
51
  render json: {}, status: 200
25
52
  else
@@ -42,8 +69,12 @@ module Doorkeeper
42
69
  private
43
70
 
44
71
  # OAuth 2.0 Section 2.1 defines two client types, "public" & "confidential".
45
- # Public clients (as per RFC 7009) do not require authentication whereas
46
- # confidential clients must be authenticated for their token revocation.
72
+ # A malicious client may attempt to guess valid tokens on this endpoint
73
+ # by making revocation requests against potential token strings.
74
+ # According to this specification, a client's request must contain a
75
+ # valid client_id, in the case of a public client, or valid client
76
+ # credentials, in the case of a confidential client. The token being
77
+ # revoked must also belong to the requesting client.
47
78
  #
48
79
  # Once a confidential client is authenticated, it must be authorized to
49
80
  # revoke the provided access or refresh token. This ensures one client
@@ -58,15 +89,13 @@ module Doorkeeper
58
89
  # https://tools.ietf.org/html/rfc6749#section-2.1
59
90
  # https://tools.ietf.org/html/rfc7009
60
91
  def authorized?
61
- return unless token.present?
62
-
63
- # Client is confidential, therefore client authentication & authorization
64
- # is required
92
+ # Token belongs to specific client, so we need to check if
93
+ # authenticated client could access it.
65
94
  if token.application_id? && token.application.confidential?
66
95
  # We authorize client by checking token's application
67
96
  server.client && server.client.application == token.application
68
97
  else
69
- # Client is public, authentication unnecessary
98
+ # Token was issued without client, authorization unnecessary
70
99
  true
71
100
  end
72
101
  end
@@ -78,9 +107,12 @@ module Doorkeeper
78
107
  token.revoke if token&.accessible?
79
108
  end
80
109
 
110
+ # Doorkeeper does not use the token_type_hint logic described in the
111
+ # RFC 7009 due to the refresh token implementation that is a field in
112
+ # the access token model.
81
113
  def token
82
- @token ||= AccessToken.by_token(params["token"]) ||
83
- AccessToken.by_refresh_token(params["token"])
114
+ @token ||= Doorkeeper.config.access_token_model.by_token(params["token"]) ||
115
+ Doorkeeper.config.access_token_model.by_refresh_token(params["token"])
84
116
  end
85
117
 
86
118
  def strategy
@@ -91,17 +123,22 @@ module Doorkeeper
91
123
  @authorize_response ||= begin
92
124
  before_successful_authorization
93
125
  auth = strategy.authorize
94
- after_successful_authorization unless auth.is_a?(Doorkeeper::OAuth::ErrorResponse)
126
+ context = build_context(auth: auth)
127
+ after_successful_authorization(context) unless auth.is_a?(Doorkeeper::OAuth::ErrorResponse)
95
128
  auth
96
129
  end
97
130
  end
98
131
 
99
- def after_successful_authorization
100
- Doorkeeper.configuration.after_successful_authorization.call(self)
132
+ def build_context(**attributes)
133
+ Doorkeeper::OAuth::Hooks::Context.new(**attributes)
134
+ end
135
+
136
+ def before_successful_authorization(context = nil)
137
+ Doorkeeper.config.before_successful_authorization.call(self, context)
101
138
  end
102
139
 
103
- def before_successful_authorization
104
- Doorkeeper.configuration.before_successful_authorization.call(self)
140
+ def after_successful_authorization(context)
141
+ Doorkeeper.config.after_successful_authorization.call(self, context)
105
142
  end
106
143
 
107
144
  def revocation_error_response