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.

Potentially problematic release.


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

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