doorkeeper 5.3.3 → 5.5.0.rc2

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 (233) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +125 -7
  3. data/README.md +6 -4
  4. data/app/controllers/doorkeeper/applications_controller.rb +4 -4
  5. data/app/controllers/doorkeeper/authorizations_controller.rb +46 -16
  6. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  7. data/app/controllers/doorkeeper/tokens_controller.rb +67 -22
  8. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  9. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  10. data/app/views/doorkeeper/authorizations/form_post.html.erb +11 -0
  11. data/config/locales/en.yml +6 -2
  12. data/lib/doorkeeper.rb +111 -79
  13. data/lib/doorkeeper/config.rb +148 -94
  14. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  15. data/lib/doorkeeper/config/option.rb +26 -14
  16. data/lib/doorkeeper/config/validations.rb +53 -0
  17. data/lib/doorkeeper/engine.rb +1 -1
  18. data/lib/doorkeeper/grant_flow.rb +45 -0
  19. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  20. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  21. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  22. data/lib/doorkeeper/grape/helpers.rb +1 -1
  23. data/lib/doorkeeper/helpers/controller.rb +8 -4
  24. data/lib/doorkeeper/models/access_grant_mixin.rb +21 -18
  25. data/lib/doorkeeper/models/access_token_mixin.rb +110 -47
  26. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  27. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  28. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  29. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  30. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  31. data/lib/doorkeeper/oauth/authorization/code.rb +19 -6
  32. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  33. data/lib/doorkeeper/oauth/authorization/token.rb +18 -16
  34. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  35. data/lib/doorkeeper/oauth/authorization_code_request.rb +17 -14
  36. data/lib/doorkeeper/oauth/base_request.rb +12 -20
  37. data/lib/doorkeeper/oauth/client.rb +1 -1
  38. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  39. data/lib/doorkeeper/oauth/client_credentials/creator.rb +27 -8
  40. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +4 -2
  41. data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
  42. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  43. data/lib/doorkeeper/oauth/code_request.rb +3 -3
  44. data/lib/doorkeeper/oauth/code_response.rb +22 -12
  45. data/lib/doorkeeper/oauth/error_response.rb +6 -7
  46. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +2 -8
  47. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  48. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  49. data/lib/doorkeeper/oauth/password_access_token_request.rb +24 -7
  50. data/lib/doorkeeper/oauth/pre_authorization.rb +63 -32
  51. data/lib/doorkeeper/oauth/refresh_token_request.rb +31 -22
  52. data/lib/doorkeeper/oauth/token.rb +5 -6
  53. data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
  54. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  55. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  56. data/lib/doorkeeper/orm/active_record.rb +14 -7
  57. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
  58. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
  59. data/lib/doorkeeper/orm/active_record/mixins/application.rb +6 -3
  60. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +5 -0
  61. data/lib/doorkeeper/rails/routes.rb +14 -20
  62. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  63. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  64. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  65. data/lib/doorkeeper/request.rb +49 -12
  66. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  67. data/lib/doorkeeper/request/strategy.rb +2 -2
  68. data/lib/doorkeeper/server.rb +4 -4
  69. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  70. data/lib/doorkeeper/version.rb +3 -7
  71. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  72. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  73. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  74. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  75. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  76. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  77. data/lib/generators/doorkeeper/templates/initializer.rb +48 -10
  78. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  79. metadata +30 -300
  80. data/Appraisals +0 -40
  81. data/CODE_OF_CONDUCT.md +0 -46
  82. data/CONTRIBUTING.md +0 -49
  83. data/Dangerfile +0 -67
  84. data/Dockerfile +0 -29
  85. data/Gemfile +0 -25
  86. data/NEWS.md +0 -1
  87. data/RELEASING.md +0 -11
  88. data/Rakefile +0 -28
  89. data/SECURITY.md +0 -15
  90. data/UPGRADE.md +0 -2
  91. data/bin/console +0 -16
  92. data/doorkeeper.gemspec +0 -42
  93. data/gemfiles/rails_5_0.gemfile +0 -18
  94. data/gemfiles/rails_5_1.gemfile +0 -18
  95. data/gemfiles/rails_5_2.gemfile +0 -18
  96. data/gemfiles/rails_6_0.gemfile +0 -18
  97. data/gemfiles/rails_master.gemfile +0 -18
  98. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  99. data/spec/controllers/applications_controller_spec.rb +0 -274
  100. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  101. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  102. data/spec/controllers/token_info_controller_spec.rb +0 -50
  103. data/spec/controllers/tokens_controller_spec.rb +0 -498
  104. data/spec/dummy/Rakefile +0 -9
  105. data/spec/dummy/app/assets/config/manifest.js +0 -2
  106. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  107. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  108. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  109. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  110. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  111. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  112. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  113. data/spec/dummy/app/models/user.rb +0 -7
  114. data/spec/dummy/app/views/home/index.html.erb +0 -0
  115. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  116. data/spec/dummy/config.ru +0 -6
  117. data/spec/dummy/config/application.rb +0 -49
  118. data/spec/dummy/config/boot.rb +0 -7
  119. data/spec/dummy/config/database.yml +0 -15
  120. data/spec/dummy/config/environment.rb +0 -5
  121. data/spec/dummy/config/environments/development.rb +0 -31
  122. data/spec/dummy/config/environments/production.rb +0 -64
  123. data/spec/dummy/config/environments/test.rb +0 -45
  124. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  125. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  126. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  127. data/spec/dummy/config/initializers/session_store.rb +0 -10
  128. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  129. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  130. data/spec/dummy/config/routes.rb +0 -13
  131. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  132. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  133. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  134. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  135. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  136. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  137. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  138. data/spec/dummy/db/schema.rb +0 -68
  139. data/spec/dummy/public/404.html +0 -26
  140. data/spec/dummy/public/422.html +0 -26
  141. data/spec/dummy/public/500.html +0 -26
  142. data/spec/dummy/public/favicon.ico +0 -0
  143. data/spec/dummy/script/rails +0 -9
  144. data/spec/factories.rb +0 -30
  145. data/spec/generators/application_owner_generator_spec.rb +0 -28
  146. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  147. data/spec/generators/install_generator_spec.rb +0 -36
  148. data/spec/generators/migration_generator_spec.rb +0 -28
  149. data/spec/generators/pkce_generator_spec.rb +0 -28
  150. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  151. data/spec/generators/templates/routes.rb +0 -4
  152. data/spec/generators/views_generator_spec.rb +0 -29
  153. data/spec/grape/grape_integration_spec.rb +0 -137
  154. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  155. data/spec/lib/config_spec.rb +0 -809
  156. data/spec/lib/doorkeeper_spec.rb +0 -27
  157. data/spec/lib/models/expirable_spec.rb +0 -61
  158. data/spec/lib/models/reusable_spec.rb +0 -40
  159. data/spec/lib/models/revocable_spec.rb +0 -59
  160. data/spec/lib/models/scopes_spec.rb +0 -53
  161. data/spec/lib/models/secret_storable_spec.rb +0 -135
  162. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  163. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
  164. data/spec/lib/oauth/base_request_spec.rb +0 -224
  165. data/spec/lib/oauth/base_response_spec.rb +0 -45
  166. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  167. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
  168. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  169. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  170. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  171. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
  172. data/spec/lib/oauth/client_spec.rb +0 -38
  173. data/spec/lib/oauth/code_request_spec.rb +0 -46
  174. data/spec/lib/oauth/code_response_spec.rb +0 -32
  175. data/spec/lib/oauth/error_response_spec.rb +0 -64
  176. data/spec/lib/oauth/error_spec.rb +0 -21
  177. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  178. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  179. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  180. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  181. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  182. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  183. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
  184. data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
  185. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  186. data/spec/lib/oauth/scopes_spec.rb +0 -146
  187. data/spec/lib/oauth/token_request_spec.rb +0 -157
  188. data/spec/lib/oauth/token_response_spec.rb +0 -84
  189. data/spec/lib/oauth/token_spec.rb +0 -156
  190. data/spec/lib/request/strategy_spec.rb +0 -54
  191. data/spec/lib/secret_storing/base_spec.rb +0 -60
  192. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  193. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  194. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  195. data/spec/lib/server_spec.rb +0 -49
  196. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  197. data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
  198. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  199. data/spec/models/doorkeeper/application_spec.rb +0 -482
  200. data/spec/requests/applications/applications_request_spec.rb +0 -259
  201. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  202. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  203. data/spec/requests/endpoints/token_spec.rb +0 -75
  204. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  205. data/spec/requests/flows/authorization_code_spec.rb +0 -525
  206. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  207. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  208. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  209. data/spec/requests/flows/password_spec.rb +0 -316
  210. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  211. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  212. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  213. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  214. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  215. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  216. data/spec/routing/default_routes_spec.rb +0 -41
  217. data/spec/routing/scoped_routes_spec.rb +0 -47
  218. data/spec/spec_helper.rb +0 -54
  219. data/spec/spec_helper_integration.rb +0 -4
  220. data/spec/support/dependencies/factory_bot.rb +0 -4
  221. data/spec/support/doorkeeper_rspec.rb +0 -22
  222. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  223. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  224. data/spec/support/helpers/config_helper.rb +0 -11
  225. data/spec/support/helpers/model_helper.rb +0 -78
  226. data/spec/support/helpers/request_spec_helper.rb +0 -110
  227. data/spec/support/helpers/url_helper.rb +0 -62
  228. data/spec/support/orm/active_record.rb +0 -5
  229. data/spec/support/shared/controllers_shared_context.rb +0 -133
  230. data/spec/support/shared/hashing_shared_context.rb +0 -36
  231. data/spec/support/shared/models_shared_examples.rb +0 -54
  232. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  233. data/spec/version/version_spec.rb +0 -17
@@ -1,4 +1,4 @@
1
- <%= form_for application, url: doorkeeper_submit_path(application), html: { role: 'form' } do |f| %>
1
+ <%= form_for application, url: doorkeeper_submit_path(application), as: :doorkeeper_application, html: { role: 'form' } do |f| %>
2
2
  <% if application.errors.any? %>
3
3
  <div class="alert alert-danger" data-alert><p><%= t('doorkeeper.applications.form.error') %></p></div>
4
4
  <% end %>
@@ -8,28 +8,49 @@
8
8
  <p><code class="bg-light" id="application_id"><%= @application.uid %></code></p>
9
9
 
10
10
  <h4><%= t('.secret') %>:</h4>
11
- <p><code class="bg-light" id="secret"><%= flash[:application_secret].presence || @application.plaintext_secret %></code></p>
11
+ <p>
12
+ <code class="bg-light" id="secret">
13
+ <% secret = flash[:application_secret].presence || @application.plaintext_secret %>
14
+ <% if secret.blank? && Doorkeeper.config.application_secret_hashed? %>
15
+ <span class="bg-light font-italic text-uppercase text-muted"><%= t('.secret_hashed') %></span>
16
+ <% else %>
17
+ <%= secret %>
18
+ <% end %>
19
+ </code>
20
+ </p>
12
21
 
13
22
  <h4><%= t('.scopes') %>:</h4>
14
- <p><code class="bg-light" id="scopes"><%= @application.scopes.presence || raw('&nbsp;') %></code></p>
23
+ <p>
24
+ <code class="bg-light" id="scopes">
25
+ <% if @application.scopes.present? %>
26
+ <%= @application.scopes %>
27
+ <% else %>
28
+ <span class="bg-light font-italic text-uppercase text-muted"><%= t('.not_defined') %></span>
29
+ <% end %>
30
+ </code>
31
+ </p>
15
32
 
16
33
  <h4><%= t('.confidential') %>:</h4>
17
34
  <p><code class="bg-light" id="confidential"><%= @application.confidential? %></code></p>
18
35
 
19
36
  <h4><%= t('.callback_urls') %>:</h4>
20
37
 
21
- <table>
22
- <% @application.redirect_uri.split.each do |uri| %>
23
- <tr>
24
- <td>
25
- <code class="bg-light"><%= uri %></code>
26
- </td>
27
- <td>
28
- <%= link_to t('doorkeeper.applications.buttons.authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code', scope: @application.scopes), class: 'btn btn-success', target: '_blank' %>
29
- </td>
30
- </tr>
31
- <% end %>
32
- </table>
38
+ <% if @application.redirect_uri.present? %>
39
+ <table>
40
+ <% @application.redirect_uri.split.each do |uri| %>
41
+ <tr>
42
+ <td>
43
+ <code class="bg-light"><%= uri %></code>
44
+ </td>
45
+ <td>
46
+ <%= link_to t('doorkeeper.applications.buttons.authorize'), oauth_authorization_path(client_id: @application.uid, redirect_uri: uri, response_type: 'code', scope: @application.scopes), class: 'btn btn-success', target: '_blank' %>
47
+ </td>
48
+ </tr>
49
+ <% end %>
50
+ </table>
51
+ <% else %>
52
+ <span class="bg-light font-italic text-uppercase text-muted"><%= t('.not_defined') %></span>
53
+ <% end %>
33
54
  </div>
34
55
 
35
56
  <div class="col-md-4">
@@ -0,0 +1,11 @@
1
+ <header class="page-header">
2
+ <h1><%= t('.title') %></h1>
3
+ </header>
4
+
5
+ <main role="main" onload="document.forms[0].submit()">
6
+ <%= form_tag @pre_auth.redirect_uri, method: :post do %>
7
+ <% @authorize_response.body.each do |key, value| %>
8
+ <%= hidden_field_tag key, value %>
9
+ <% end %>
10
+ <% end %>
11
+ </main>
@@ -51,12 +51,14 @@ en:
51
51
  title: 'New Application'
52
52
  show:
53
53
  title: 'Application: %{name}'
54
- application_id: 'Application UID'
54
+ application_id: 'UID'
55
55
  secret: 'Secret'
56
+ secret_hashed: 'Secret hashed'
56
57
  scopes: 'Scopes'
57
58
  confidential: 'Confidential'
58
59
  callback_urls: 'Callback urls'
59
60
  actions: 'Actions'
61
+ not_defined: 'Not defined'
60
62
 
61
63
  authorizations:
62
64
  buttons:
@@ -70,6 +72,8 @@ en:
70
72
  able_to: 'This application will be able to'
71
73
  show:
72
74
  title: 'Authorization code'
75
+ form_post:
76
+ title: 'Submit this form'
73
77
 
74
78
  authorized_applications:
75
79
  confirmations:
@@ -91,7 +95,6 @@ en:
91
95
  invalid_request:
92
96
  unknown: 'The request is missing a required parameter, includes an unsupported parameter value, or is otherwise malformed.'
93
97
  missing_param: 'Missing required parameter: %{value}.'
94
- not_support_pkce: 'Invalid code_verifier parameter. Server does not support pkce.'
95
98
  request_not_authorized: 'Request need to be authorized. Required parameter for authorizing request is missing or invalid.'
96
99
  invalid_redirect_uri: "The requested redirect uri is malformed or doesn't match client redirect URI."
97
100
  unauthorized_client: 'The client is not authorized to perform this request using this method.'
@@ -108,6 +111,7 @@ en:
108
111
 
109
112
  # Access grant errors
110
113
  unsupported_response_type: 'The authorization server does not support this response type.'
114
+ unsupported_response_mode: 'The authorization server does not support this response mode.'
111
115
 
112
116
  # Access token errors
113
117
  invalid_client: 'Client authentication failed due to unknown client, no client authentication included, or unsupported authentication method.'
@@ -1,90 +1,122 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require "doorkeeper/version"
4
- require "doorkeeper/engine"
5
3
  require "doorkeeper/config"
6
-
7
- require "doorkeeper/request/strategy"
8
- require "doorkeeper/request/authorization_code"
9
- require "doorkeeper/request/client_credentials"
10
- require "doorkeeper/request/code"
11
- require "doorkeeper/request/password"
12
- require "doorkeeper/request/refresh_token"
13
- require "doorkeeper/request/token"
14
-
15
- require "doorkeeper/errors"
16
- require "doorkeeper/server"
17
- require "doorkeeper/request"
18
- require "doorkeeper/validations"
19
-
20
- require "doorkeeper/oauth/authorization/code"
21
- require "doorkeeper/oauth/authorization/context"
22
- require "doorkeeper/oauth/authorization/token"
23
- require "doorkeeper/oauth/authorization/uri_builder"
24
- require "doorkeeper/oauth/helpers/scope_checker"
25
- require "doorkeeper/oauth/helpers/uri_checker"
26
- require "doorkeeper/oauth/helpers/unique_token"
27
-
28
- require "doorkeeper/oauth"
29
- require "doorkeeper/oauth/scopes"
30
- require "doorkeeper/oauth/error"
31
- require "doorkeeper/oauth/base_response"
32
- require "doorkeeper/oauth/code_response"
33
- require "doorkeeper/oauth/token_response"
34
- require "doorkeeper/oauth/error_response"
35
- require "doorkeeper/oauth/pre_authorization"
36
- require "doorkeeper/oauth/base_request"
37
- require "doorkeeper/oauth/authorization_code_request"
38
- require "doorkeeper/oauth/refresh_token_request"
39
- require "doorkeeper/oauth/password_access_token_request"
40
-
41
- require "doorkeeper/oauth/client_credentials/validator"
42
- require "doorkeeper/oauth/client_credentials/creator"
43
- require "doorkeeper/oauth/client_credentials/issuer"
44
- require "doorkeeper/oauth/client/credentials"
45
-
46
- require "doorkeeper/oauth/client_credentials_request"
47
- require "doorkeeper/oauth/code_request"
48
- require "doorkeeper/oauth/token_request"
49
- require "doorkeeper/oauth/client"
50
- require "doorkeeper/oauth/token"
51
- require "doorkeeper/oauth/token_introspection"
52
- require "doorkeeper/oauth/invalid_token_response"
53
- require "doorkeeper/oauth/forbidden_token_response"
54
- require "doorkeeper/oauth/invalid_request_response"
55
- require "doorkeeper/oauth/nonstandard"
56
-
57
- require "doorkeeper/secret_storing/base"
58
- require "doorkeeper/secret_storing/plain"
59
- require "doorkeeper/secret_storing/sha256_hash"
60
- require "doorkeeper/secret_storing/bcrypt"
61
-
62
- require "doorkeeper/models/concerns/orderable"
63
- require "doorkeeper/models/concerns/scopes"
64
- require "doorkeeper/models/concerns/expirable"
65
- require "doorkeeper/models/concerns/reusable"
66
- require "doorkeeper/models/concerns/revocable"
67
- require "doorkeeper/models/concerns/accessible"
68
- require "doorkeeper/models/concerns/secret_storable"
69
-
70
- require "doorkeeper/models/access_grant_mixin"
71
- require "doorkeeper/models/access_token_mixin"
72
- require "doorkeeper/models/application_mixin"
73
-
74
- require "doorkeeper/helpers/controller"
75
-
76
- require "doorkeeper/rails/routes"
77
- require "doorkeeper/rails/helpers"
78
-
79
- require "doorkeeper/rake"
80
- require "doorkeeper/stale_records_cleaner"
81
-
82
- require "doorkeeper/orm/active_record"
4
+ require "doorkeeper/engine"
83
5
 
84
6
  # Main Doorkeeper namespace.
85
7
  #
86
8
  module Doorkeeper
9
+ autoload :Errors, "doorkeeper/errors"
10
+ autoload :GrantFlow, "doorkeeper/grant_flow"
11
+ autoload :OAuth, "doorkeeper/oauth"
12
+ autoload :Rake, "doorkeeper/rake"
13
+ autoload :Request, "doorkeeper/request"
14
+ autoload :Server, "doorkeeper/server"
15
+ autoload :StaleRecordsCleaner, "doorkeeper/stale_records_cleaner"
16
+ autoload :Validations, "doorkeeper/validations"
17
+ autoload :VERSION, "doorkeeper/version"
18
+
19
+ autoload :AccessGrantMixin, "doorkeeper/models/access_grant_mixin"
20
+ autoload :AccessTokenMixin, "doorkeeper/models/access_token_mixin"
21
+ autoload :ApplicationMixin, "doorkeeper/models/application_mixin"
22
+
23
+ module Helpers
24
+ autoload :Controller, "doorkeeper/helpers/controller"
25
+ end
26
+
27
+ module Request
28
+ autoload :Strategy, "doorkeeper/request/strategy"
29
+ autoload :AuthorizationCode, "doorkeeper/request/authorization_code"
30
+ autoload :ClientCredentials, "doorkeeper/request/client_credentials"
31
+ autoload :Code, "doorkeeper/request/code"
32
+ autoload :Password, "doorkeeper/request/password"
33
+ autoload :RefreshToken, "doorkeeper/request/refresh_token"
34
+ autoload :Token, "doorkeeper/request/token"
35
+ end
36
+
37
+ module OAuth
38
+ autoload :BaseRequest, "doorkeeper/oauth/base_request"
39
+ autoload :AuthorizationCodeRequest, "doorkeeper/oauth/authorization_code_request"
40
+ autoload :BaseResponse, "doorkeeper/oauth/base_response"
41
+ autoload :CodeResponse, "doorkeeper/oauth/code_response"
42
+ autoload :Client, "doorkeeper/oauth/client"
43
+ autoload :ClientCredentialsRequest, "doorkeeper/oauth/client_credentials_request"
44
+ autoload :CodeRequest, "doorkeeper/oauth/code_request"
45
+ autoload :ErrorResponse, "doorkeeper/oauth/error_response"
46
+ autoload :Error, "doorkeeper/oauth/error"
47
+ autoload :InvalidTokenResponse, "doorkeeper/oauth/invalid_token_response"
48
+ autoload :InvalidRequestResponse, "doorkeeper/oauth/invalid_request_response"
49
+ autoload :ForbiddenTokenResponse, "doorkeeper/oauth/forbidden_token_response"
50
+ autoload :NonStandard, "doorkeeper/oauth/nonstandard"
51
+ autoload :PasswordAccessTokenRequest, "doorkeeper/oauth/password_access_token_request"
52
+ autoload :PreAuthorization, "doorkeeper/oauth/pre_authorization"
53
+ autoload :RefreshTokenRequest, "doorkeeper/oauth/refresh_token_request"
54
+ autoload :Scopes, "doorkeeper/oauth/scopes"
55
+ autoload :Token, "doorkeeper/oauth/token"
56
+ autoload :TokenIntrospection, "doorkeeper/oauth/token_introspection"
57
+ autoload :TokenRequest, "doorkeeper/oauth/token_request"
58
+ autoload :TokenResponse, "doorkeeper/oauth/token_response"
59
+
60
+ module Authorization
61
+ autoload :Code, "doorkeeper/oauth/authorization/code"
62
+ autoload :Context, "doorkeeper/oauth/authorization/context"
63
+ autoload :Token, "doorkeeper/oauth/authorization/token"
64
+ autoload :URIBuilder, "doorkeeper/oauth/authorization/uri_builder"
65
+ end
66
+
67
+ class Client
68
+ autoload :Credentials, "doorkeeper/oauth/client/credentials"
69
+ end
70
+
71
+ module ClientCredentials
72
+ autoload :Validator, "doorkeeper/oauth/client_credentials/validator"
73
+ autoload :Creator, "doorkeeper/oauth/client_credentials/creator"
74
+ autoload :Issuer, "doorkeeper/oauth/client_credentials/issuer"
75
+ end
76
+
77
+ module Helpers
78
+ autoload :ScopeChecker, "doorkeeper/oauth/helpers/scope_checker"
79
+ autoload :URIChecker, "doorkeeper/oauth/helpers/uri_checker"
80
+ autoload :UniqueToken, "doorkeeper/oauth/helpers/unique_token"
81
+ end
82
+
83
+ module Hooks
84
+ autoload :Context, "doorkeeper/oauth/hooks/context"
85
+ end
86
+ end
87
+
88
+ module Models
89
+ autoload :Accessible, "doorkeeper/models/concerns/accessible"
90
+ autoload :Expirable, "doorkeeper/models/concerns/expirable"
91
+ autoload :Orderable, "doorkeeper/models/concerns/orderable"
92
+ autoload :Scopes, "doorkeeper/models/concerns/scopes"
93
+ autoload :Reusable, "doorkeeper/models/concerns/reusable"
94
+ autoload :ResourceOwnerable, "doorkeeper/models/concerns/resource_ownerable"
95
+ autoload :Revocable, "doorkeeper/models/concerns/revocable"
96
+ autoload :SecretStorable, "doorkeeper/models/concerns/secret_storable"
97
+ end
98
+
99
+ module Orm
100
+ autoload :ActiveRecord, "doorkeeper/orm/active_record"
101
+ end
102
+
103
+ module Rails
104
+ autoload :Helpers, "doorkeeper/rails/helpers"
105
+ autoload :Routes, "doorkeeper/rails/routes"
106
+ end
107
+
108
+ module SecretStoring
109
+ autoload :Base, "doorkeeper/secret_storing/base"
110
+ autoload :Plain, "doorkeeper/secret_storing/plain"
111
+ autoload :Sha256Hash, "doorkeeper/secret_storing/sha256_hash"
112
+ autoload :BCrypt, "doorkeeper/secret_storing/bcrypt"
113
+ end
114
+
87
115
  def self.authenticate(request, methods = Doorkeeper.config.access_token_methods)
88
116
  OAuth::Token.authenticate(request, *methods)
89
117
  end
118
+
119
+ def self.gem_version
120
+ ::Gem::Version.new(::Doorkeeper::VERSION::STRING)
121
+ end
90
122
  end
@@ -1,16 +1,25 @@
1
1
  # frozen_string_literal: true
2
2
 
3
+ require "doorkeeper/config/abstract_builder"
3
4
  require "doorkeeper/config/option"
5
+ require "doorkeeper/config/validations"
4
6
 
5
7
  module Doorkeeper
8
+ # Defines a MissingConfiguration error for a missing Doorkeeper configuration
9
+ #
6
10
  class MissingConfiguration < StandardError
7
- # Defines a MissingConfiguration error for a missing Doorkeeper
8
- # configuration
9
11
  def initialize
10
12
  super("Configuration for doorkeeper missing. Do you have doorkeeper initializer?")
11
13
  end
12
14
  end
13
15
 
16
+ # Doorkeeper option DSL could be reused in extensions to build their own
17
+ # configurations. To use the Option DSL gems need to define `builder_class` method
18
+ # that returns configuration Builder class. This exception raises when they don't
19
+ # define it.
20
+ #
21
+ class MissingConfigurationBuilderClass < StandardError; end
22
+
14
23
  class << self
15
24
  def configure(&block)
16
25
  @config = Config::Builder.new(&block).build
@@ -20,6 +29,8 @@ module Doorkeeper
20
29
  @config
21
30
  end
22
31
 
32
+ # @return [Doorkeeper::Config] configuration instance
33
+ #
23
34
  def configuration
24
35
  @config || (raise MissingConfiguration)
25
36
  end
@@ -30,7 +41,7 @@ module Doorkeeper
30
41
  @orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
31
42
  rescue NameError => e
32
43
  raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
33
- [doorkeeper] ORM adapter not found (#{configuration.orm}), or there was an error
44
+ [DOORKEEPER] ORM adapter not found (#{configuration.orm}), or there was an error
34
45
  trying to load it.
35
46
 
36
47
  You probably need to add the related gem for this adapter to work with
@@ -48,17 +59,8 @@ module Doorkeeper
48
59
  end
49
60
 
50
61
  class Config
51
- class Builder
52
- def initialize(&block)
53
- @config = Config.new
54
- instance_eval(&block)
55
- end
56
-
57
- def build
58
- @config.validate
59
- @config
60
- end
61
-
62
+ # Default Doorkeeper configuration builder
63
+ class Builder < AbstractBuilder
62
64
  # Provide support for an owner to be assigned to each registered
63
65
  # application (disabled by default)
64
66
  # Optional parameter confirmation: true (default false) if you want
@@ -135,15 +137,6 @@ module Doorkeeper
135
137
  @config.instance_variable_set(:@reuse_access_token, true)
136
138
  end
137
139
 
138
- # Sets the token_reuse_limit
139
- # It will be used only when reuse_access_token option in enabled
140
- # By default it will be 100
141
- # It will be used for token reusablity to some threshold percentage
142
- # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
143
- def token_reuse_limit(percentage)
144
- @config.instance_variable_set(:@token_reuse_limit, percentage)
145
- end
146
-
147
140
  # TODO: maybe make it more generic for other flows too?
148
141
  # Only allow one valid access token obtained via client credentials
149
142
  # per client. If a new access token is obtained before the old one
@@ -158,6 +151,12 @@ module Doorkeeper
158
151
  @config.instance_variable_set(:@api_only, true)
159
152
  end
160
153
 
154
+ # Enables polymorphic Resource Owner association for Access Grant and
155
+ # Access Token models. Requires additional database columns to be setup.
156
+ def use_polymorphic_resource_owner
157
+ @config.instance_variable_set(:@polymorphic_resource_owner, true)
158
+ end
159
+
161
160
  # Forbids creating/updating applications with arbitrary scopes that are
162
161
  # not in configuration, i.e. `default_scopes` or `optional_scopes`.
163
162
  # (disabled by default)
@@ -219,7 +218,11 @@ module Doorkeeper
219
218
  end
220
219
  end
221
220
 
221
+ # Replace with `default: Builder` when we drop support of Rails < 5.2
222
+ mattr_reader(:builder_class) { Builder }
223
+
222
224
  extend Option
225
+ include Validations
223
226
 
224
227
  option :resource_owner_authenticator,
225
228
  as: :authenticate_resource_owner,
@@ -251,8 +254,8 @@ module Doorkeeper
251
254
  end)
252
255
 
253
256
  # Hooks for authorization
254
- option :before_successful_authorization, default: ->(_context) {}
255
- option :after_successful_authorization, default: ->(_context) {}
257
+ option :before_successful_authorization, default: ->(_controller, _context = nil) {}
258
+ option :after_successful_authorization, default: ->(_controller, _context = nil) {}
256
259
  # Hooks for strategies responses
257
260
  option :before_successful_strategy_response, default: ->(_request) {}
258
261
  option :after_successful_strategy_response, default: ->(_request, _response) {}
@@ -265,10 +268,34 @@ module Doorkeeper
265
268
  option :authorization_code_expires_in, default: 600
266
269
  option :orm, default: :active_record
267
270
  option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob", deprecated: true
268
- option :active_record_options, default: {}
269
271
  option :grant_flows, default: %w[authorization_code client_credentials]
270
272
  option :handle_auth_errors, default: :render
271
273
  option :token_lookup_batch_size, default: 10_000
274
+ # Sets the token_reuse_limit
275
+ # It will be used only when reuse_access_token option in enabled
276
+ # By default it will be 100
277
+ # It will be used for token reusablity to some threshold percentage
278
+ # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
279
+ option :token_reuse_limit, default: 100
280
+
281
+ # This is discouraged. Spec says that password grants always require a client.
282
+ #
283
+ # See https://github.com/doorkeeper-gem/doorkeeper/issues/1412#issuecomment-632750422
284
+ # and https://github.com/doorkeeper-gem/doorkeeper/pull/1420
285
+ #
286
+ # Since many applications use this unsafe behavior in the wild, this is kept as a
287
+ # not-recommended option. You should be aware that you are not following the OAuth
288
+ # spec, and understand the security implications of doing so.
289
+ option :skip_client_authentication_for_password_grant,
290
+ default: false
291
+
292
+ option :active_record_options,
293
+ default: {},
294
+ deprecated: { message: "Customize Doorkeeper models instead" }
295
+
296
+ # Hook to allow arbitrary user-client authorization
297
+ option :authorize_resource_owner_for_client,
298
+ default: ->(_client, _resource_owner) { true }
272
299
 
273
300
  # Allows to customize OAuth grant flows that +each+ application support.
274
301
  # You can configure a custom block (or use a class respond to `#call`) that must
@@ -410,21 +437,26 @@ module Doorkeeper
410
437
  :token_secret_fallback_strategy,
411
438
  :application_secret_fallback_strategy
412
439
 
413
- # Return the valid subset of this configuration
414
- def validate
415
- validate_reuse_access_token_value
416
- validate_token_reuse_limit
417
- validate_secret_strategies
418
- end
419
-
440
+ # Doorkeeper Access Token model class.
441
+ #
442
+ # @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
443
+ #
420
444
  def access_token_model
421
445
  @access_token_model ||= access_token_class.constantize
422
446
  end
423
447
 
448
+ # Doorkeeper Access Grant model class.
449
+ #
450
+ # @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
451
+ #
424
452
  def access_grant_model
425
453
  @access_grant_model ||= access_grant_class.constantize
426
454
  end
427
455
 
456
+ # Doorkeeper Application model class.
457
+ #
458
+ # @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
459
+ #
428
460
  def application_model
429
461
  @application_model ||= application_class.constantize
430
462
  end
@@ -445,14 +477,6 @@ module Doorkeeper
445
477
  end
446
478
  end
447
479
 
448
- def token_reuse_limit
449
- @token_reuse_limit ||= 100
450
- end
451
-
452
- def revoke_previous_client_credentials_token
453
- @revoke_previous_client_credentials_token || false
454
- end
455
-
456
480
  def resolve_controller(name)
457
481
  config_option = public_send(:"#{name}_controller")
458
482
  controller_name = if config_option.respond_to?(:call)
@@ -464,6 +488,10 @@ module Doorkeeper
464
488
  controller_name.constantize
465
489
  end
466
490
 
491
+ def revoke_previous_client_credentials_token?
492
+ option_set? :revoke_previous_client_credentials_token
493
+ end
494
+
467
495
  def enforce_configured_scopes?
468
496
  option_set? :enforce_configured_scopes
469
497
  end
@@ -472,6 +500,10 @@ module Doorkeeper
472
500
  option_set? :enable_application_owner
473
501
  end
474
502
 
503
+ def polymorphic_resource_owner?
504
+ option_set? :polymorphic_resource_owner
505
+ end
506
+
475
507
  def confirm_application_owner?
476
508
  option_set? :confirm_application_owner
477
509
  end
@@ -480,6 +512,10 @@ module Doorkeeper
480
512
  handle_auth_errors == :raise
481
513
  end
482
514
 
515
+ def application_secret_hashed?
516
+ instance_variable_defined?(:"@application_secret_strategy")
517
+ end
518
+
483
519
  def token_secret_strategy
484
520
  @token_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
485
521
  end
@@ -516,12 +552,77 @@ module Doorkeeper
516
552
  ]
517
553
  end
518
554
 
555
+ def enabled_grant_flows
556
+ @enabled_grant_flows ||= calculate_grant_flows.map { |name| Doorkeeper::GrantFlow.get(name) }.compact
557
+ end
558
+
559
+ def authorization_response_flows
560
+ @authorization_response_flows ||= enabled_grant_flows.select(&:handles_response_type?) +
561
+ deprecated_authorization_flows
562
+ end
563
+
564
+ def token_grant_flows
565
+ @token_grant_flows ||= calculate_token_grant_flows
566
+ end
567
+
519
568
  def authorization_response_types
520
- @authorization_response_types ||= calculate_authorization_response_types.freeze
569
+ authorization_response_flows.map(&:response_type_matches)
521
570
  end
522
571
 
523
572
  def token_grant_types
524
- @token_grant_types ||= calculate_token_grant_types.freeze
573
+ token_grant_flows.map(&:grant_type_matches)
574
+ end
575
+
576
+ # [NOTE]: deprecated and will be removed soon
577
+ def deprecated_token_grant_types_resolver
578
+ @deprecated_token_grant_types ||= calculate_token_grant_types
579
+ end
580
+
581
+ # [NOTE]: deprecated and will be removed soon
582
+ def deprecated_authorization_flows
583
+ response_types = calculate_authorization_response_types
584
+
585
+ if response_types.any?
586
+ ::Kernel.warn <<~WARNING
587
+ Please, don't patch Doorkeeper::Config#calculate_authorization_response_types method.
588
+ Register your custom grant flows using the public API:
589
+ `Doorkeeper::GrantFlow.register(grant_flow_name, **options)`.
590
+ WARNING
591
+ end
592
+
593
+ response_types.map do |response_type|
594
+ Doorkeeper::GrantFlow::FallbackFlow.new(response_type, response_type_matches: response_type)
595
+ end
596
+ end
597
+
598
+ # [NOTE]: deprecated and will be removed soon
599
+ def calculate_authorization_response_types
600
+ []
601
+ end
602
+
603
+ # [NOTE]: deprecated and will be removed soon
604
+ def calculate_token_grant_types
605
+ types = grant_flows - ["implicit"]
606
+ types << "refresh_token" if refresh_token_enabled?
607
+ types
608
+ end
609
+
610
+ # Calculates grant flows configured by the user in Doorkeeper
611
+ # configuration considering registered aliases that is exposed
612
+ # to single or multiple other flows.
613
+ #
614
+ def calculate_grant_flows
615
+ configured_flows = grant_flows.map(&:to_s)
616
+ aliases = Doorkeeper::GrantFlow.aliases.keys.map(&:to_s)
617
+
618
+ flows = configured_flows - aliases
619
+ aliases.each do |flow_alias|
620
+ next unless configured_flows.include?(flow_alias)
621
+
622
+ flows.concat(Doorkeeper::GrantFlow.expand_alias(flow_alias))
623
+ end
624
+
625
+ flows.flatten.uniq
525
626
  end
526
627
 
527
628
  def allow_blank_redirect_uri?(application = nil)
@@ -550,57 +651,10 @@ module Doorkeeper
550
651
  !!(defined?(var) && var)
551
652
  end
552
653
 
553
- # Determines what values are acceptable for 'response_type' param in
554
- # authorization request endpoint, and return them as an array of strings.
555
- #
556
- def calculate_authorization_response_types
557
- types = []
558
- types << "code" if grant_flows.include? "authorization_code"
559
- types << "token" if grant_flows.include? "implicit"
560
- types
561
- end
562
-
563
- # Determines what values are acceptable for 'grant_type' param token
564
- # request endpoint, and return them in array.
565
- #
566
- def calculate_token_grant_types
567
- types = grant_flows - ["implicit"]
568
- types << "refresh_token" if refresh_token_enabled?
569
- types
570
- end
571
-
572
- # Determine whether +reuse_access_token+ and a non-restorable
573
- # +token_secret_strategy+ have both been activated.
574
- #
575
- # In that case, disable reuse_access_token value and warn the user.
576
- def validate_reuse_access_token_value
577
- strategy = token_secret_strategy
578
- return if !reuse_access_token || strategy.allows_restoring_secrets?
579
-
580
- ::Rails.logger.warn(
581
- "You have configured both reuse_access_token " \
582
- "AND strategy strategy '#{strategy}' that cannot restore tokens. " \
583
- "This combination is unsupported. reuse_access_token will be disabled",
584
- )
585
- @reuse_access_token = false
586
- end
587
-
588
- # Validate that the provided strategies are valid for
589
- # tokens and applications
590
- def validate_secret_strategies
591
- token_secret_strategy.validate_for :token
592
- application_secret_strategy.validate_for :application
593
- end
594
-
595
- def validate_token_reuse_limit
596
- return if !reuse_access_token ||
597
- (token_reuse_limit > 0 && token_reuse_limit <= 100)
598
-
599
- ::Rails.logger.warn(
600
- "You have configured an invalid value for token_reuse_limit option. " \
601
- "It will be set to default 100",
602
- )
603
- @token_reuse_limit = 100
654
+ def calculate_token_grant_flows
655
+ flows = enabled_grant_flows.select(&:handles_grant_type?)
656
+ flows << Doorkeeper::GrantFlow.get("refresh_token") if refresh_token_enabled?
657
+ flows
604
658
  end
605
659
  end
606
660
  end