doorkeeper 4.4.3 → 5.0.0

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 (181) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +1 -0
  3. data/.gitlab-ci.yml +16 -0
  4. data/.travis.yml +2 -0
  5. data/Appraisals +2 -2
  6. data/Gemfile +1 -1
  7. data/NEWS.md +61 -8
  8. data/README.md +92 -9
  9. data/Rakefile +6 -0
  10. data/UPGRADE.md +2 -0
  11. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  12. data/app/controllers/doorkeeper/application_controller.rb +4 -3
  13. data/app/controllers/doorkeeper/application_metal_controller.rb +4 -0
  14. data/app/controllers/doorkeeper/applications_controller.rb +42 -22
  15. data/app/controllers/doorkeeper/authorizations_controller.rb +55 -12
  16. data/app/controllers/doorkeeper/authorized_applications_controller.rb +19 -2
  17. data/app/controllers/doorkeeper/tokens_controller.rb +2 -6
  18. data/app/helpers/doorkeeper/dashboard_helper.rb +7 -7
  19. data/app/validators/redirect_uri_validator.rb +3 -2
  20. data/app/views/doorkeeper/applications/_delete_form.html.erb +3 -1
  21. data/app/views/doorkeeper/applications/_form.html.erb +25 -24
  22. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  23. data/app/views/doorkeeper/applications/index.html.erb +17 -7
  24. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  25. data/app/views/doorkeeper/applications/show.html.erb +6 -6
  26. data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
  27. data/app/views/doorkeeper/authorizations/new.html.erb +4 -0
  28. data/app/views/layouts/doorkeeper/admin.html.erb +15 -15
  29. data/config/locales/en.yml +10 -1
  30. data/doorkeeper.gemspec +18 -20
  31. data/gemfiles/rails_5_2.gemfile +1 -1
  32. data/gemfiles/rails_master.gemfile +4 -1
  33. data/lib/doorkeeper/config.rb +75 -39
  34. data/lib/doorkeeper/engine.rb +4 -0
  35. data/lib/doorkeeper/errors.rb +2 -5
  36. data/lib/doorkeeper/grape/helpers.rb +1 -1
  37. data/lib/doorkeeper/helpers/controller.rb +7 -2
  38. data/lib/doorkeeper/models/access_grant_mixin.rb +71 -0
  39. data/lib/doorkeeper/models/access_token_mixin.rb +39 -22
  40. data/lib/doorkeeper/models/concerns/scopes.rb +1 -1
  41. data/lib/doorkeeper/oauth/authorization/code.rb +31 -8
  42. data/lib/doorkeeper/oauth/authorization/context.rb +15 -0
  43. data/lib/doorkeeper/oauth/authorization/token.rb +36 -14
  44. data/lib/doorkeeper/oauth/authorization_code_request.rb +27 -2
  45. data/lib/doorkeeper/oauth/base_request.rb +20 -9
  46. data/lib/doorkeeper/oauth/client/credentials.rb +1 -1
  47. data/lib/doorkeeper/oauth/client.rb +0 -2
  48. data/lib/doorkeeper/oauth/client_credentials/creator.rb +2 -1
  49. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +6 -3
  50. data/lib/doorkeeper/oauth/client_credentials/validation.rb +4 -6
  51. data/lib/doorkeeper/oauth/client_credentials_request.rb +0 -4
  52. data/lib/doorkeeper/oauth/error_response.rb +11 -3
  53. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +0 -8
  54. data/lib/doorkeeper/oauth/password_access_token_request.rb +7 -4
  55. data/lib/doorkeeper/oauth/pre_authorization.rb +41 -11
  56. data/lib/doorkeeper/oauth/refresh_token_request.rb +6 -1
  57. data/lib/doorkeeper/oauth/scopes.rb +1 -1
  58. data/lib/doorkeeper/oauth/token.rb +5 -2
  59. data/lib/doorkeeper/oauth/token_introspection.rb +2 -2
  60. data/lib/doorkeeper/oauth/token_response.rb +4 -2
  61. data/lib/doorkeeper/oauth.rb +13 -0
  62. data/lib/doorkeeper/orm/active_record/application.rb +22 -14
  63. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +26 -0
  64. data/lib/doorkeeper/orm/active_record.rb +2 -0
  65. data/lib/doorkeeper/rails/helpers.rb +2 -4
  66. data/lib/doorkeeper/rails/routes.rb +14 -6
  67. data/lib/doorkeeper/rake/db.rake +40 -0
  68. data/lib/doorkeeper/rake/setup.rake +6 -0
  69. data/lib/doorkeeper/rake.rb +14 -0
  70. data/lib/doorkeeper/request/authorization_code.rb +0 -2
  71. data/lib/doorkeeper/request/client_credentials.rb +0 -2
  72. data/lib/doorkeeper/request/code.rb +0 -2
  73. data/lib/doorkeeper/request/password.rb +0 -2
  74. data/lib/doorkeeper/request/refresh_token.rb +0 -2
  75. data/lib/doorkeeper/request/token.rb +0 -2
  76. data/lib/doorkeeper/request.rb +28 -35
  77. data/lib/doorkeeper/version.rb +5 -25
  78. data/lib/doorkeeper.rb +19 -17
  79. data/lib/generators/doorkeeper/application_owner_generator.rb +23 -18
  80. data/lib/generators/doorkeeper/confidential_applications_generator.rb +32 -0
  81. data/lib/generators/doorkeeper/install_generator.rb +17 -9
  82. data/lib/generators/doorkeeper/migration_generator.rb +23 -18
  83. data/lib/generators/doorkeeper/pkce_generator.rb +32 -0
  84. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +29 -24
  85. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  86. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +6 -0
  87. data/lib/generators/doorkeeper/templates/initializer.rb +76 -11
  88. data/lib/generators/doorkeeper/views_generator.rb +3 -1
  89. data/spec/controllers/application_metal_controller_spec.rb +50 -0
  90. data/spec/controllers/applications_controller_spec.rb +126 -13
  91. data/spec/controllers/authorizations_controller_spec.rb +277 -47
  92. data/spec/controllers/protected_resources_controller_spec.rb +16 -16
  93. data/spec/controllers/token_info_controller_spec.rb +4 -12
  94. data/spec/controllers/tokens_controller_spec.rb +13 -15
  95. data/spec/dummy/app/assets/config/manifest.js +2 -0
  96. data/spec/dummy/config/environments/test.rb +4 -5
  97. data/spec/dummy/config/initializers/doorkeeper.rb +10 -5
  98. data/spec/dummy/config/initializers/new_framework_defaults.rb +4 -0
  99. data/spec/dummy/config/routes.rb +3 -42
  100. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +6 -0
  101. data/spec/dummy/db/migrate/{20180210183654_add_confidential_to_application.rb → 20180210183654_add_confidential_to_applications.rb} +1 -1
  102. data/spec/dummy/db/schema.rb +36 -36
  103. data/spec/generators/application_owner_generator_spec.rb +1 -1
  104. data/spec/generators/confidential_applications_generator_spec.rb +45 -0
  105. data/spec/generators/install_generator_spec.rb +1 -1
  106. data/spec/generators/migration_generator_spec.rb +1 -1
  107. data/spec/generators/pkce_generator_spec.rb +43 -0
  108. data/spec/generators/previous_refresh_token_generator_spec.rb +1 -1
  109. data/spec/generators/views_generator_spec.rb +1 -1
  110. data/spec/grape/grape_integration_spec.rb +1 -1
  111. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  112. data/spec/lib/config_spec.rb +80 -31
  113. data/spec/lib/doorkeeper_spec.rb +1 -126
  114. data/spec/lib/models/expirable_spec.rb +0 -3
  115. data/spec/lib/models/revocable_spec.rb +0 -2
  116. data/spec/lib/models/scopes_spec.rb +0 -4
  117. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -4
  118. data/spec/lib/oauth/authorization_code_request_spec.rb +9 -2
  119. data/spec/lib/oauth/base_request_spec.rb +40 -2
  120. data/spec/lib/oauth/base_response_spec.rb +1 -1
  121. data/spec/lib/oauth/client/credentials_spec.rb +1 -3
  122. data/spec/lib/oauth/client_credentials/creator_spec.rb +5 -1
  123. data/spec/lib/oauth/client_credentials/issuer_spec.rb +26 -7
  124. data/spec/lib/oauth/client_credentials/validation_spec.rb +2 -3
  125. data/spec/lib/oauth/client_credentials_integration_spec.rb +1 -1
  126. data/spec/lib/oauth/client_credentials_request_spec.rb +3 -5
  127. data/spec/lib/oauth/client_spec.rb +0 -3
  128. data/spec/lib/oauth/code_request_spec.rb +4 -2
  129. data/spec/lib/oauth/error_response_spec.rb +0 -3
  130. data/spec/lib/oauth/error_spec.rb +0 -2
  131. data/spec/lib/oauth/forbidden_token_response_spec.rb +1 -4
  132. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -3
  133. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -1
  134. data/spec/lib/oauth/helpers/uri_checker_spec.rb +5 -7
  135. data/spec/lib/oauth/invalid_token_response_spec.rb +1 -4
  136. data/spec/lib/oauth/password_access_token_request_spec.rb +37 -2
  137. data/spec/lib/oauth/pre_authorization_spec.rb +33 -4
  138. data/spec/lib/oauth/refresh_token_request_spec.rb +11 -7
  139. data/spec/lib/oauth/scopes_spec.rb +0 -3
  140. data/spec/lib/oauth/token_request_spec.rb +4 -5
  141. data/spec/lib/oauth/token_response_spec.rb +0 -1
  142. data/spec/lib/oauth/token_spec.rb +37 -14
  143. data/spec/lib/orm/active_record/stale_records_cleaner_spec.rb +79 -0
  144. data/spec/lib/request/strategy_spec.rb +0 -1
  145. data/spec/lib/server_spec.rb +1 -1
  146. data/spec/models/doorkeeper/access_grant_spec.rb +44 -1
  147. data/spec/models/doorkeeper/access_token_spec.rb +66 -22
  148. data/spec/models/doorkeeper/application_spec.rb +14 -47
  149. data/spec/requests/applications/applications_request_spec.rb +134 -1
  150. data/spec/requests/applications/authorized_applications_spec.rb +1 -1
  151. data/spec/requests/endpoints/authorization_spec.rb +1 -1
  152. data/spec/requests/endpoints/token_spec.rb +7 -5
  153. data/spec/requests/flows/authorization_code_errors_spec.rb +1 -1
  154. data/spec/requests/flows/authorization_code_spec.rb +197 -1
  155. data/spec/requests/flows/client_credentials_spec.rb +46 -6
  156. data/spec/requests/flows/implicit_grant_errors_spec.rb +1 -1
  157. data/spec/requests/flows/implicit_grant_spec.rb +38 -11
  158. data/spec/requests/flows/password_spec.rb +56 -2
  159. data/spec/requests/flows/refresh_token_spec.rb +2 -2
  160. data/spec/requests/flows/revoke_token_spec.rb +11 -11
  161. data/spec/requests/flows/skip_authorization_spec.rb +16 -11
  162. data/spec/requests/protected_resources/metal_spec.rb +1 -1
  163. data/spec/requests/protected_resources/private_api_spec.rb +1 -1
  164. data/spec/routing/custom_controller_routes_spec.rb +59 -7
  165. data/spec/routing/default_routes_spec.rb +2 -2
  166. data/spec/routing/scoped_routes_spec.rb +16 -2
  167. data/spec/spec_helper.rb +54 -3
  168. data/spec/spec_helper_integration.rb +2 -74
  169. data/spec/support/dependencies/{factory_girl.rb → factory_bot.rb} +0 -0
  170. data/spec/support/doorkeeper_rspec.rb +19 -0
  171. data/spec/support/helpers/authorization_request_helper.rb +4 -4
  172. data/spec/support/helpers/request_spec_helper.rb +10 -2
  173. data/spec/support/helpers/url_helper.rb +7 -3
  174. data/spec/support/http_method_shim.rb +12 -16
  175. data/spec/validators/redirect_uri_validator_spec.rb +7 -1
  176. data/spec/version/version_spec.rb +3 -3
  177. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  178. metadata +37 -33
  179. data/lib/generators/doorkeeper/add_client_confidentiality_generator.rb +0 -31
  180. data/lib/generators/doorkeeper/templates/add_confidential_to_application_migration.rb.erb +0 -11
  181. data/spec/controllers/application_metal_controller.rb +0 -10
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 8d8d3550d8406d4abb224c4960d1d6e8a0c4c706
4
- data.tar.gz: b12408cb8b0dc2b14ee69b57798943b5c1bfaa30
3
+ metadata.gz: db3333346ca1b82cd7aa332bb1e43f8d979534c0
4
+ data.tar.gz: 12511ea5d14b0bba28fef47893cc925c9e45ebcd
5
5
  SHA512:
6
- metadata.gz: 0674af950f6070d6457e09f73fc89736b092ae6595e484ca6e67e7f126912ea007509d9249fdc4eb01e66bf981c1e49da33712203d8428d10401a43faabd1cfd
7
- data.tar.gz: e447513c202dfde4c622b898da2a98dff64272193136fe399b890bb97488e7915156a2588caa6de3566db411f4c7dfa89e88be3a8b8d0a76511251f2f980c382
6
+ metadata.gz: a5265ed62b206c4f9f117c3cbc8e6d905840636297a342ea952e5dfced01f7ce4bd6b59fc7efd6a4f0e6558475c566bf59ba4a793ef3f87942cf8935dde061ba
7
+ data.tar.gz: 18d2b90ae8e5f2e6e80f518fe0a251c49ba3187fda34c9213f14c0152f301dfd149d11db14dcd94a69bb8048352f8a945107c572cfb3fa03aeabc6d6383b706c
data/.gitignore CHANGED
@@ -17,3 +17,4 @@ gemfiles/*.lock
17
17
  /doc/
18
18
  /rdoc/
19
19
  coverage
20
+ *.gem
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,16 @@
1
+ dependency_scanning:
2
+ image: docker:stable
3
+ variables:
4
+ DOCKER_DRIVER: overlay2
5
+ allow_failure: true
6
+ services:
7
+ - docker:stable-dind
8
+ script:
9
+ - export SP_VERSION=$(echo "$CI_SERVER_VERSION" | sed 's/^\([0-9]*\)\.\([0-9]*\).*/\1-\2-stable/')
10
+ - docker run
11
+ --env DEP_SCAN_DISABLE_REMOTE_CHECKS="${DEP_SCAN_DISABLE_REMOTE_CHECKS:-false}"
12
+ --volume "$PWD:/code"
13
+ --volume /var/run/docker.sock:/var/run/docker.sock
14
+ "registry.gitlab.com/gitlab-org/security-products/dependency-scanning:$SP_VERSION" /code
15
+ artifacts:
16
+ paths: [gl-dependency-scanning-report.json]
data/.travis.yml CHANGED
@@ -8,6 +8,7 @@ rvm:
8
8
  - 2.3
9
9
  - 2.4
10
10
  - 2.5
11
+ - ruby-2.6.0-preview1
11
12
 
12
13
  before_install:
13
14
  - gem update --system # Need for Ruby 2.5.0. https://github.com/travis-ci/travis-ci/issues/8978
@@ -21,6 +22,7 @@ gemfile:
21
22
  - gemfiles/rails_master.gemfile
22
23
 
23
24
  matrix:
25
+ fast_finish: true
24
26
  exclude:
25
27
  - gemfile: gemfiles/rails_5_0.gemfile
26
28
  rvm: 2.1
data/Appraisals CHANGED
@@ -4,12 +4,12 @@ end
4
4
 
5
5
  appraise "rails-5-0" do
6
6
  gem "rails", "~> 5.0.0"
7
- gem "rspec-rails", "~> 3.5"
7
+ gem "rspec-rails", "~> 3.7"
8
8
  end
9
9
 
10
10
  appraise "rails-5-1" do
11
11
  gem "rails", "~> 5.1.0"
12
- gem "rspec-rails", "~> 3.5"
12
+ gem "rspec-rails", "~> 3.7"
13
13
  end
14
14
 
15
15
  appraise "rails-master" do
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "https://rubygems.org"
2
2
 
3
- gem "rails", "~> 5.1"
3
+ gem "rails", "~> 5.2"
4
4
 
5
5
  gem "appraisal"
6
6
 
data/NEWS.md CHANGED
@@ -1,24 +1,77 @@
1
1
  # News
2
2
 
3
+ See https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions for
4
+ upgrade guides.
5
+
3
6
  User-visible changes worth mentioning.
4
7
 
5
8
  ## master
6
9
 
7
- ## 4.4.3
8
- - [#1143] Adds a config option opt_out_native_route_change to opt out of the
9
- breaking api changed introduced in
10
- https://github.com/doorkeeper-gem/doorkeeper/pull/1003
11
-
10
+ - [#PR ID] Add PR description.
11
+
12
+ ## 5.0.0
13
+
14
+ - [#1127] Change the token_type initials of the Banner Token to uppercase to comply with the RFC6750 specification.
15
+
16
+ ## 5.0.0.rc2
17
+
18
+ - [#1106] Restrict access to AdminController with 'Forbidden 403' if admin_authenticator is not
19
+ configured by developers..
20
+ - [#1108] Simple formating of callback URLs when listing oauth applications
21
+ - [#1116] `AccessGrant`s will now be revoked along with `AccessToken`s when
22
+ hitting the `AuthorizedApplicationController#destroy` route.
23
+ - [#1114] Make token info endpoint's attributes consistent with token creation
24
+ - [#1119] Fix token revocation for OAuth apps using "implicit" grant flow
25
+ - [#1122] Fix AuthorizationsController#new error response to be in JSON format
26
+
27
+ ## 5.0.0.rc1
28
+
29
+ - [#1103] Allow customizing use_refresh_token
30
+ - [#1089] Removed enable_pkce_without_secret configuration option
31
+ - [#1102] Expiration time based on scopes
32
+ - [#1099] All the configuration variables in `Doorkeeper.configuration` now
33
+ always return a non-nil value (`true` or `false`)
34
+ - [#1099] ORM / Query optimization: Do not revoke the refresh token if it is not enabled
35
+ in `doorkeeper.rb`
36
+ - [#996] Expiration Time Base On Grant Type
37
+ - [#997] Allow PKCE authorization_code flow as specified in RFC7636
38
+ - [#907] Fix lookup for matching tokens in certain edge-cases
39
+ - [#992] Add API option to use Doorkeeper without management views for API only
40
+ Rails applications (`api_only`)
41
+ - [#1045] Validate redirect_uri as the native URI when making authorization code requests
42
+ - [#1048] Remove deprecated `Doorkeeper#configured?`, `Doorkeeper#database_installed?`, and
43
+ `Doorkeeper#installed?` method
44
+ - [#1031] Allow public clients to authenticate without `client_secret`. Define an app as
45
+ either public or private/confidential
46
+ - [#1010] Add configuration to enforce configured scopes (`default_scopes` and
47
+ `optional_scopes`) for applications
48
+ - [#1060] Ensure that the native redirect_uri parameter matches with redirect_uri of the client
49
+ - [#1064] Add :before_successful_authorization and :after_successful_authorization hooks
50
+ - [#1069] Upgrade Bootstrap to 4 for Admin
51
+ - [#1068] Add rake task to cleanup databases that can become large over time
52
+ - [#1072] AuthorizationsController: Memoize strategy.authorize_response result to enable
53
+ subclasses to use the response object.
54
+ - [#1075] Call `before_successful_authorization` and `after_successful_authorization` hooks
55
+ on `create` action as well as `new`
56
+ - [#1082] Fix #916: remember routes mapping and use it required places (fix error with
57
+ customized Token Info route).
58
+ - [#1086, #1088] Fix bug with receiving default scopes in the token even if they are
59
+ not present in the application scopes (use scopes intersection).
60
+ - [#1076] Add config to enforce content type to application/x-www-form-urlencoded
61
+ - Fix bug with `force_ssl_in_redirect_uri` when it breaks existing applications with an
62
+ SSL redirect_uri.
63
+
12
64
  ## 4.4.2
13
- - [#1130] Backport fix for native redirect_uri from 5.x.
14
65
 
66
+ - [#1130] Backport fix for native redirect_uri from 5.x.
67
+
15
68
  ## 4.4.1
16
69
 
17
70
  - [#1127] Backport token type to comply with the RFC6750 specification.
18
71
  - [#1125] Backport Quote surround I18n yes/no keys
19
-
72
+
20
73
  ## 4.4.0
21
-
74
+
22
75
  - [#1120] Backport security fix from 5.x for token revocation when using public clients
23
76
 
24
77
  ## 4.3.2
data/README.md CHANGED
@@ -1,14 +1,14 @@
1
- # Doorkeeper - awesome OAuth 2 provider for your Rails app.
1
+ # Doorkeeper awesome OAuth 2 provider for your Rails / Grape app.
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/doorkeeper.svg)](https://rubygems.org/gems/doorkeeper)
4
4
  [![Build Status](https://travis-ci.org/doorkeeper-gem/doorkeeper.svg?branch=master)](https://travis-ci.org/doorkeeper-gem/doorkeeper)
5
- [![Dependency Status](https://gemnasium.com/doorkeeper-gem/doorkeeper.svg?travis)](https://gemnasium.com/doorkeeper-gem/doorkeeper)
6
5
  [![Code Climate](https://codeclimate.com/github/doorkeeper-gem/doorkeeper.svg)](https://codeclimate.com/github/doorkeeper-gem/doorkeeper)
7
6
  [![Coverage Status](https://coveralls.io/repos/github/doorkeeper-gem/doorkeeper/badge.svg?branch=master)](https://coveralls.io/github/doorkeeper-gem/doorkeeper?branch=master)
8
7
  [![Security](https://hakiri.io/github/doorkeeper-gem/doorkeeper/master.svg)](https://hakiri.io/github/doorkeeper-gem/doorkeeper/master)
8
+ [![Reviewed by Hound](https://img.shields.io/badge/Reviewed_by-Hound-8E64B0.svg)](https://houndci.com)
9
9
 
10
- Doorkeeper is a gem that makes it easy to introduce OAuth 2 provider
11
- functionality to your Rails or Grape application.
10
+ Doorkeeper is a gem (Rails engine) that makes it easy to introduce OAuth 2 provider
11
+ functionality to your Ruby on Rails or Grape application.
12
12
 
13
13
  Supported features:
14
14
 
@@ -19,6 +19,7 @@ Supported features:
19
19
  - [Implicit grant](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.2)
20
20
  - [Resource Owner Password Credentials](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.3)
21
21
  - [Client Credentials](http://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-4.4)
22
+ - [Proof Key for Code Exchange](https://tools.ietf.org/html/rfc7636)
22
23
  - [OAuth 2.0 Token Revocation](http://tools.ietf.org/html/rfc7009)
23
24
  - [OAuth 2.0 Token Introspection](https://tools.ietf.org/html/rfc7662)
24
25
 
@@ -27,7 +28,8 @@ Supported features:
27
28
  Please check the documentation for the version of doorkeeper you are using in:
28
29
  https://github.com/doorkeeper-gem/doorkeeper/releases
29
30
 
30
- - See the [wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki)
31
+ - See the [Wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki)
32
+ - See [upgrade guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
31
33
  - For general questions, please post in [Stack Overflow](http://stackoverflow.com/questions/tagged/doorkeeper)
32
34
  - See [SECURITY.md](SECURITY.md) for this project's security disclose
33
35
  policy
@@ -44,9 +46,11 @@ https://github.com/doorkeeper-gem/doorkeeper/releases
44
46
  - [MongoDB](#mongodb)
45
47
  - [Sequel](#sequel)
46
48
  - [Couchbase](#couchbase)
49
+ - [API mode](#api-mode)
47
50
  - [Routes](#routes)
48
51
  - [Authenticating](#authenticating)
49
52
  - [Internationalization (I18n)](#internationalization-i18n)
53
+ - [Rake Tasks](#rake-tasks)
50
54
  - [Protecting resources with OAuth (a.k.a your API endpoint)](#protecting-resources-with-oauth-aka-your-api-endpoint)
51
55
  - [Ruby on Rails controllers](#ruby-on-rails-controllers)
52
56
  - [Grape endpoints](#grape-endpoints)
@@ -103,12 +107,26 @@ for each table that includes a `resource_owner_id` column:
103
107
  add_foreign_key :table_name, :users, column: :resource_owner_id
104
108
  ```
105
109
 
110
+ If you want to enable [PKCE flow] for mobile apps, you need to generate another
111
+ migration:
112
+
113
+ [PKCE flow]: https://tools.ietf.org/html/rfc7636
114
+
115
+ ```sh
116
+ rails generate doorkeeper:pkce
117
+ ```
118
+
106
119
  Then run migrations:
107
120
 
108
121
  ```sh
109
122
  rake db:migrate
110
123
  ```
111
124
 
125
+ Ensure to use non-confidential apps for pkce. PKCE is created, because
126
+ you cannot trust its apps' secret. So whatever app needs pkce: it means, it cannot
127
+ be a confidential app by design.
128
+
129
+
112
130
  Remember to add associations to your model so the related records are deleted.
113
131
  If you don't do this an `ActiveRecord::InvalidForeignKey`-error will be raised
114
132
  when you try to destroy a model with related access grants or access tokens.
@@ -146,6 +164,24 @@ Use [doorkeeper-couchbase] extension if you are using Couchbase database.
146
164
 
147
165
  [doorkeeper-couchbase]: https://github.com/acaprojects/doorkeeper-couchbase
148
166
 
167
+ ### API mode
168
+
169
+ By default Doorkeeper uses full Rails stack to provide all the OAuth 2 functionality
170
+ with additional features like administration area for managing applications. By the
171
+ way, starting from Doorkeeper 5 you can use API mode for your [API only Rails 5 applications](http://edgeguides.rubyonrails.org/api_app.html).
172
+ All you need is just to configure the gem to work in desired mode:
173
+
174
+ ``` ruby
175
+ Doorkeeper.configure do
176
+ # ...
177
+
178
+ api_only
179
+ end
180
+ ```
181
+
182
+ Keep in mind, that in this mode you will not be able to access `Applications` or
183
+ `Authorized Applications` controllers because they will be skipped. CSRF protections (which are otherwise enabled) will be skipped, and all the redirects will be returned as JSON response with corresponding locations.
184
+
149
185
  ### Routes
150
186
 
151
187
  The installation script will also automatically add the Doorkeeper routes into
@@ -198,7 +234,36 @@ You may want to check other ways of authentication
198
234
 
199
235
  ### Internationalization (I18n)
200
236
 
201
- See language files in [the I18n repository](https://github.com/doorkeeper-gem/doorkeeper-i18n).
237
+ Doorkeeper support multiple languages. See language files in
238
+ [the I18n repository](https://github.com/doorkeeper-gem/doorkeeper-i18n).
239
+
240
+ ### Rake Tasks
241
+
242
+ If you are using `rake`, you can load rake tasks provided by this gem, by adding
243
+ the following line to your `Rakefile`:
244
+
245
+ ```ruby
246
+ Doorkeeper::Rake.load_tasks
247
+ ```
248
+
249
+ #### Cleaning up
250
+
251
+ By default Doorkeeper is retaining expired and revoked access tokens and grants.
252
+ This allows to keep an audit log of those records, but it also leads to the
253
+ corresponding tables to grow large over the lifetime of your application.
254
+
255
+ If you are concerned about those tables growing too large,
256
+ you can regularly run the following rake task to remove stale entries
257
+ from the database:
258
+
259
+ ```rake
260
+ rake doorkeeper:db:cleanup
261
+ ```
262
+
263
+ Note that this will remove tokens that are expired according to the configured TTL
264
+ in `Doorkeeper.configuration.access_token_expires_in`. The specific `expires_in`
265
+ value of each access token **is not considered**. The same is true for access
266
+ grants.
202
267
 
203
268
  ## Protecting resources with OAuth (a.k.a your API endpoint)
204
269
 
@@ -210,7 +275,9 @@ protect. For example:
210
275
 
211
276
  ``` ruby
212
277
  class Api::V1::ProductsController < Api::V1::ApiController
213
- before_action :doorkeeper_authorize! # Require access token for all actions
278
+ before_action :doorkeeper_authorize! # Requires access token for all actions
279
+
280
+ # before_action -> { doorkeeper_authorize! :read, :write }
214
281
 
215
282
  # your actions
216
283
  end
@@ -399,6 +466,22 @@ customize the controller used by the list or skip the controller all together.
399
466
  For more information see the page
400
467
  [in the wiki](https://github.com/doorkeeper-gem/doorkeeper/wiki/Customizing-routes).
401
468
 
469
+ By default, everybody can create application with any scopes. However,
470
+ you can enforce users to create applications only with configured scopes
471
+ (`default_scopes` and `optional_scopes` from the Doorkeeper initializer):
472
+
473
+ ```ruby
474
+ # config/initializers/doorkeeper.rb
475
+ Doorkeeper.configure do
476
+ # ...
477
+
478
+ default_scopes :read, :write
479
+ optional_scopes :create, :update
480
+
481
+ enforce_configured_scopes
482
+ end
483
+ ```
484
+
402
485
  ## Other customizations
403
486
 
404
487
  - [Associate users to OAuth applications (ownership)](https://github.com/doorkeeper-gem/doorkeeper/wiki/Associate-users-to-OAuth-applications-%28ownership%29)
@@ -412,7 +495,7 @@ Doorkeeper 4.3.0 it uses [ActiveSupport lazy loading hooks](http://api.rubyonrai
412
495
  to load models. There are [known issue](https://github.com/doorkeeper-gem/doorkeeper/issues/1043)
413
496
  with the `factory_bot_rails` gem (it executes factories building before `ActiveRecord::Base`
414
497
  is initialized using hooks in gem railtie, so you can catch a `uninitialized constant` error).
415
- It is recommended to use pure `factory_bot` gem to solve this problem.
498
+ It is recommended to use pure `factory_bot` gem to solve this problem.
416
499
 
417
500
  ## Upgrading
418
501
 
@@ -429,7 +512,7 @@ To run the local engine server:
429
512
 
430
513
  ```
431
514
  bundle install
432
- bundle exec rails server
515
+ bundle exec rake doorkeeper:server
433
516
  ````
434
517
 
435
518
  By default, it uses the latest Rails version with ActiveRecord. To run the
data/Rakefile CHANGED
@@ -15,6 +15,12 @@ namespace :doorkeeper do
15
15
  cd 'spec/dummy'
16
16
  system 'bundle exec rails g doorkeeper:install --force'
17
17
  end
18
+
19
+ desc 'Runs local test server'
20
+ task :server do
21
+ cd 'spec/dummy'
22
+ system 'bundle exec rails server'
23
+ end
18
24
  end
19
25
 
20
26
  Bundler::GemHelper.install_tasks
data/UPGRADE.md ADDED
@@ -0,0 +1,2 @@
1
+ See [Upgrade Guides](https://github.com/doorkeeper-gem/doorkeeper/wiki/Migration-from-old-versions)
2
+ in the project Wiki.
@@ -5,6 +5,6 @@
5
5
  *= require_tree .
6
6
  */
7
7
 
8
- td {
9
- vertical-align: middle !important;
8
+ .doorkeeper-admin .form-group > .field_with_errors {
9
+ width: 16.66667%;
10
10
  }
@@ -4,8 +4,9 @@ module Doorkeeper
4
4
 
5
5
  include Helpers::Controller
6
6
 
7
- protect_from_forgery with: :exception
8
-
9
- helper 'doorkeeper/dashboard'
7
+ unless Doorkeeper.configuration.api_only
8
+ protect_from_forgery with: :exception
9
+ helper 'doorkeeper/dashboard'
10
+ end
10
11
  end
11
12
  end
@@ -5,6 +5,7 @@ module Doorkeeper
5
5
  AbstractController::Rendering,
6
6
  ActionController::Rendering,
7
7
  ActionController::Renderers::All,
8
+ AbstractController::Callbacks,
8
9
  Helpers::Controller
9
10
  ].freeze
10
11
 
@@ -12,6 +13,9 @@ module Doorkeeper
12
13
  include mod
13
14
  end
14
15
 
16
+ before_action :enforce_content_type,
17
+ if: -> { Doorkeeper.configuration.enforce_content_type }
18
+
15
19
  ActiveSupport.run_load_hooks(:doorkeeper_metal_controller, self)
16
20
  end
17
21
  end
@@ -1,24 +1,25 @@
1
1
  module Doorkeeper
2
2
  class ApplicationsController < Doorkeeper::ApplicationController
3
- layout 'doorkeeper/admin'
3
+ layout 'doorkeeper/admin' unless Doorkeeper.configuration.api_only
4
4
 
5
5
  before_action :authenticate_admin!
6
- before_action :set_application, only: [:show, :edit, :update, :destroy]
6
+ before_action :set_application, only: %i[show edit update destroy]
7
7
 
8
8
  def index
9
- @applications = if Application.respond_to?(:ordered_by)
10
- Application.ordered_by(:created_at)
11
- else
12
- ActiveSupport::Deprecation.warn <<-MSG.squish
13
- Doorkeeper #{Doorkeeper.configuration.orm} extension must implement #ordered_by
14
- method for it's models as it will be used by default in Doorkeeper 5.
15
- MSG
16
-
17
- Application.all
18
- end
9
+ @applications = Application.ordered_by(:created_at)
10
+
11
+ respond_to do |format|
12
+ format.html
13
+ format.json { head :no_content }
14
+ end
19
15
  end
20
16
 
21
- def show; end
17
+ def show
18
+ respond_to do |format|
19
+ format.html
20
+ format.json { render json: @application }
21
+ end
22
+ end
22
23
 
23
24
  def new
24
25
  @application = Application.new
@@ -26,28 +27,47 @@ module Doorkeeper
26
27
 
27
28
  def create
28
29
  @application = Application.new(application_params)
30
+
29
31
  if @application.save
30
- flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :create])
31
- redirect_to oauth_application_url(@application)
32
+ flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications create])
33
+
34
+ respond_to do |format|
35
+ format.html { redirect_to oauth_application_url(@application) }
36
+ format.json { render json: @application }
37
+ end
32
38
  else
33
- render :new
39
+ respond_to do |format|
40
+ format.html { render :new }
41
+ format.json { render json: { errors: @application.errors.full_messages }, status: :unprocessable_entity }
42
+ end
34
43
  end
35
44
  end
36
45
 
37
46
  def edit; end
38
47
 
39
48
  def update
40
- if @application.update_attributes(application_params)
41
- flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :update])
42
- redirect_to oauth_application_url(@application)
49
+ if @application.update(application_params)
50
+ flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications update])
51
+
52
+ respond_to do |format|
53
+ format.html { redirect_to oauth_application_url(@application) }
54
+ format.json { render json: @application }
55
+ end
43
56
  else
44
- render :edit
57
+ respond_to do |format|
58
+ format.html { render :edit }
59
+ format.json { render json: { errors: @application.errors.full_messages }, status: :unprocessable_entity }
60
+ end
45
61
  end
46
62
  end
47
63
 
48
64
  def destroy
49
- flash[:notice] = I18n.t(:notice, scope: [:doorkeeper, :flash, :applications, :destroy]) if @application.destroy
50
- redirect_to oauth_applications_url
65
+ flash[:notice] = I18n.t(:notice, scope: %i[doorkeeper flash applications destroy]) if @application.destroy
66
+
67
+ respond_to do |format|
68
+ format.html { redirect_to oauth_applications_url }
69
+ format.json { head :no_content }
70
+ end
51
71
  end
52
72
 
53
73
  private
@@ -4,20 +4,15 @@ module Doorkeeper
4
4
 
5
5
  def new
6
6
  if pre_auth.authorizable?
7
- if skip_authorization? || matching_token?
8
- auth = authorization.authorize
9
- redirect_to auth.redirect_uri
10
- else
11
- render :new
12
- end
7
+ render_success
13
8
  else
14
- render :error
9
+ render_error
15
10
  end
16
11
  end
17
12
 
18
13
  # TODO: Handle raise invalid authorization
19
14
  def create
20
- redirect_or_render authorization.authorize
15
+ redirect_or_render authorize_response
21
16
  end
22
17
 
23
18
  def destroy
@@ -26,15 +21,45 @@ module Doorkeeper
26
21
 
27
22
  private
28
23
 
24
+ def render_success
25
+ if skip_authorization? || matching_token?
26
+ redirect_or_render authorize_response
27
+ elsif Doorkeeper.configuration.api_only
28
+ render json: pre_auth
29
+ else
30
+ render :new
31
+ end
32
+ end
33
+
34
+ def render_error
35
+ if Doorkeeper.configuration.api_only
36
+ render json: pre_auth.error_response.body,
37
+ status: :bad_request
38
+ else
39
+ render :error
40
+ end
41
+ end
42
+
29
43
  def matching_token?
30
- AccessToken.matching_token_for pre_auth.client,
31
- current_resource_owner.id,
32
- pre_auth.scopes
44
+ token = AccessToken.matching_token_for(
45
+ pre_auth.client,
46
+ current_resource_owner.id,
47
+ pre_auth.scopes
48
+ )
49
+
50
+ token && token.accessible?
33
51
  end
34
52
 
35
53
  def redirect_or_render(auth)
36
54
  if auth.redirectable?
37
- redirect_to auth.redirect_uri
55
+ if Doorkeeper.configuration.api_only
56
+ render(
57
+ json: { status: :redirect, redirect_uri: auth.redirect_uri },
58
+ status: auth.status
59
+ )
60
+ else
61
+ redirect_to auth.redirect_uri
62
+ end
38
63
  else
39
64
  render json: auth.body, status: auth.status
40
65
  end
@@ -53,5 +78,23 @@ module Doorkeeper
53
78
  def strategy
54
79
  @strategy ||= server.authorization_request pre_auth.response_type
55
80
  end
81
+
82
+ def authorize_response
83
+ @authorize_response ||= begin
84
+ authorizable = pre_auth.authorizable?
85
+ before_successful_authorization if authorizable
86
+ auth = strategy.authorize
87
+ after_successful_authorization if authorizable
88
+ auth
89
+ end
90
+ end
91
+
92
+ def after_successful_authorization
93
+ Doorkeeper.configuration.after_successful_authorization.call(self)
94
+ end
95
+
96
+ def before_successful_authorization
97
+ Doorkeeper.configuration.before_successful_authorization.call(self)
98
+ end
56
99
  end
57
100
  end
@@ -4,11 +4,28 @@ module Doorkeeper
4
4
 
5
5
  def index
6
6
  @applications = Application.authorized_for(current_resource_owner)
7
+
8
+ respond_to do |format|
9
+ format.html
10
+ format.json { render json: @applications }
11
+ end
7
12
  end
8
13
 
9
14
  def destroy
10
- AccessToken.revoke_all_for params[:id], current_resource_owner
11
- redirect_to oauth_authorized_applications_url, notice: I18n.t(:notice, scope: [:doorkeeper, :flash, :authorized_applications, :destroy])
15
+ Application.revoke_tokens_and_grants_for(
16
+ params[:id],
17
+ current_resource_owner
18
+ )
19
+
20
+ respond_to do |format|
21
+ format.html do
22
+ redirect_to oauth_authorized_applications_url, notice: I18n.t(
23
+ :notice, scope: %i[doorkeeper flash authorized_applications destroy]
24
+ )
25
+ end
26
+
27
+ format.json { render :no_content }
28
+ end
12
29
  end
13
30
  end
14
31
  end
@@ -17,9 +17,7 @@ module Doorkeeper
17
17
  # Doorkeeper does not use the token_type_hint logic described in the
18
18
  # RFC 7009 due to the refresh token implementation that is a field in
19
19
  # the access token model.
20
- if authorized?
21
- revoke_token
22
- end
20
+ revoke_token if authorized?
23
21
 
24
22
  # The authorization server responds with HTTP status code 200 if the token
25
23
  # has been revoked successfully or if the client submitted an invalid
@@ -71,9 +69,7 @@ module Doorkeeper
71
69
  end
72
70
 
73
71
  def revoke_token
74
- if token.accessible?
75
- token.revoke
76
- end
72
+ token.revoke if token.accessible?
77
73
  end
78
74
 
79
75
  def token