doorkeeper 5.1.2 → 5.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (272) hide show
  1. checksums.yaml +4 -4
  2. data/{NEWS.md → CHANGELOG.md} +314 -27
  3. data/README.md +39 -22
  4. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  5. data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
  6. data/app/controllers/doorkeeper/applications_controller.rb +5 -4
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +76 -25
  8. data/app/controllers/doorkeeper/authorized_applications_controller.rb +5 -5
  9. data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
  10. data/app/controllers/doorkeeper/tokens_controller.rb +99 -28
  11. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  12. data/app/views/doorkeeper/applications/_form.html.erb +1 -7
  13. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  14. data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
  15. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  16. data/app/views/doorkeeper/authorizations/new.html.erb +16 -14
  17. data/config/locales/en.yml +16 -3
  18. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  19. data/lib/doorkeeper/config/option.rb +20 -2
  20. data/lib/doorkeeper/config/validations.rb +53 -0
  21. data/lib/doorkeeper/config.rb +300 -136
  22. data/lib/doorkeeper/engine.rb +10 -3
  23. data/lib/doorkeeper/errors.rb +13 -18
  24. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  25. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  26. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  27. data/lib/doorkeeper/grant_flow.rb +45 -0
  28. data/lib/doorkeeper/grape/helpers.rb +7 -3
  29. data/lib/doorkeeper/helpers/controller.rb +36 -11
  30. data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
  31. data/lib/doorkeeper/models/access_token_mixin.rb +195 -52
  32. data/lib/doorkeeper/models/application_mixin.rb +8 -7
  33. data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
  34. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  35. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  36. data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
  37. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  38. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  39. data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
  40. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  41. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  42. data/lib/doorkeeper/oauth/authorization/code.rb +31 -14
  43. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  44. data/lib/doorkeeper/oauth/authorization/token.rb +30 -19
  45. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  46. data/lib/doorkeeper/oauth/authorization_code_request.rb +51 -22
  47. data/lib/doorkeeper/oauth/base_request.rb +21 -22
  48. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  49. data/lib/doorkeeper/oauth/client.rb +8 -9
  50. data/lib/doorkeeper/oauth/client_credentials/creator.rb +42 -5
  51. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
  52. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +14 -5
  53. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  54. data/lib/doorkeeper/oauth/code_request.rb +6 -12
  55. data/lib/doorkeeper/oauth/code_response.rb +24 -14
  56. data/lib/doorkeeper/oauth/error.rb +1 -1
  57. data/lib/doorkeeper/oauth/error_response.rb +11 -13
  58. data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
  59. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
  60. data/lib/doorkeeper/oauth/helpers/unique_token.rb +10 -7
  61. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +19 -23
  62. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  63. data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
  64. data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
  65. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  66. data/lib/doorkeeper/oauth/password_access_token_request.rb +34 -11
  67. data/lib/doorkeeper/oauth/pre_authorization.rb +114 -44
  68. data/lib/doorkeeper/oauth/refresh_token_request.rb +54 -34
  69. data/lib/doorkeeper/oauth/token.rb +6 -7
  70. data/lib/doorkeeper/oauth/token_introspection.rb +28 -22
  71. data/lib/doorkeeper/oauth/token_request.rb +6 -20
  72. data/lib/doorkeeper/oauth/token_response.rb +2 -3
  73. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  74. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  75. data/lib/doorkeeper/orm/active_record/application.rb +5 -149
  76. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +63 -0
  77. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +77 -0
  78. data/lib/doorkeeper/orm/active_record/mixins/application.rb +210 -0
  79. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  80. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +5 -2
  81. data/lib/doorkeeper/orm/active_record.rb +29 -22
  82. data/lib/doorkeeper/rails/helpers.rb +4 -4
  83. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  84. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  85. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  86. data/lib/doorkeeper/rails/routes.rb +28 -27
  87. data/lib/doorkeeper/rake/db.rake +6 -6
  88. data/lib/doorkeeper/request/authorization_code.rb +5 -3
  89. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  90. data/lib/doorkeeper/request/password.rb +3 -2
  91. data/lib/doorkeeper/request/refresh_token.rb +5 -4
  92. data/lib/doorkeeper/request/strategy.rb +2 -2
  93. data/lib/doorkeeper/request.rb +49 -17
  94. data/lib/doorkeeper/server.rb +7 -11
  95. data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
  96. data/lib/doorkeeper/version.rb +2 -6
  97. data/lib/doorkeeper.rb +183 -80
  98. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  99. data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
  100. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  101. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  102. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  103. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +7 -7
  104. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  105. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  106. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  107. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  108. data/lib/generators/doorkeeper/templates/initializer.rb +230 -50
  109. data/lib/generators/doorkeeper/templates/migration.rb.erb +31 -9
  110. metadata +61 -327
  111. data/.coveralls.yml +0 -1
  112. data/.github/ISSUE_TEMPLATE.md +0 -25
  113. data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
  114. data/.gitignore +0 -20
  115. data/.gitlab-ci.yml +0 -16
  116. data/.hound.yml +0 -3
  117. data/.rspec +0 -1
  118. data/.rubocop.yml +0 -50
  119. data/.travis.yml +0 -35
  120. data/Appraisals +0 -40
  121. data/CODE_OF_CONDUCT.md +0 -46
  122. data/CONTRIBUTING.md +0 -47
  123. data/Dangerfile +0 -67
  124. data/Gemfile +0 -24
  125. data/RELEASING.md +0 -10
  126. data/Rakefile +0 -28
  127. data/SECURITY.md +0 -15
  128. data/UPGRADE.md +0 -2
  129. data/app/validators/redirect_uri_validator.rb +0 -50
  130. data/bin/console +0 -16
  131. data/doorkeeper.gemspec +0 -34
  132. data/gemfiles/rails_5_0.gemfile +0 -17
  133. data/gemfiles/rails_5_1.gemfile +0 -17
  134. data/gemfiles/rails_5_2.gemfile +0 -17
  135. data/gemfiles/rails_6_0.gemfile +0 -17
  136. data/gemfiles/rails_master.gemfile +0 -17
  137. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  138. data/spec/controllers/applications_controller_spec.rb +0 -180
  139. data/spec/controllers/authorizations_controller_spec.rb +0 -527
  140. data/spec/controllers/protected_resources_controller_spec.rb +0 -353
  141. data/spec/controllers/token_info_controller_spec.rb +0 -50
  142. data/spec/controllers/tokens_controller_spec.rb +0 -330
  143. data/spec/dummy/Rakefile +0 -9
  144. data/spec/dummy/app/assets/config/manifest.js +0 -2
  145. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  146. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  147. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  148. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  149. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  150. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  151. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  152. data/spec/dummy/app/models/user.rb +0 -7
  153. data/spec/dummy/app/views/home/index.html.erb +0 -0
  154. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  155. data/spec/dummy/config/application.rb +0 -47
  156. data/spec/dummy/config/boot.rb +0 -7
  157. data/spec/dummy/config/database.yml +0 -15
  158. data/spec/dummy/config/environment.rb +0 -5
  159. data/spec/dummy/config/environments/development.rb +0 -31
  160. data/spec/dummy/config/environments/production.rb +0 -64
  161. data/spec/dummy/config/environments/test.rb +0 -45
  162. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  163. data/spec/dummy/config/initializers/doorkeeper.rb +0 -121
  164. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  165. data/spec/dummy/config/initializers/session_store.rb +0 -10
  166. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  167. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  168. data/spec/dummy/config/routes.rb +0 -13
  169. data/spec/dummy/config.ru +0 -6
  170. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  171. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  172. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  173. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  174. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  175. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  176. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  177. data/spec/dummy/db/schema.rb +0 -68
  178. data/spec/dummy/public/404.html +0 -26
  179. data/spec/dummy/public/422.html +0 -26
  180. data/spec/dummy/public/500.html +0 -26
  181. data/spec/dummy/public/favicon.ico +0 -0
  182. data/spec/dummy/script/rails +0 -9
  183. data/spec/factories.rb +0 -30
  184. data/spec/generators/application_owner_generator_spec.rb +0 -28
  185. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  186. data/spec/generators/install_generator_spec.rb +0 -36
  187. data/spec/generators/migration_generator_spec.rb +0 -28
  188. data/spec/generators/pkce_generator_spec.rb +0 -28
  189. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  190. data/spec/generators/templates/routes.rb +0 -4
  191. data/spec/generators/views_generator_spec.rb +0 -29
  192. data/spec/grape/grape_integration_spec.rb +0 -137
  193. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  194. data/spec/lib/config_spec.rb +0 -697
  195. data/spec/lib/doorkeeper_spec.rb +0 -27
  196. data/spec/lib/models/expirable_spec.rb +0 -61
  197. data/spec/lib/models/reusable_spec.rb +0 -40
  198. data/spec/lib/models/revocable_spec.rb +0 -59
  199. data/spec/lib/models/scopes_spec.rb +0 -53
  200. data/spec/lib/models/secret_storable_spec.rb +0 -135
  201. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  202. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -156
  203. data/spec/lib/oauth/base_request_spec.rb +0 -205
  204. data/spec/lib/oauth/base_response_spec.rb +0 -47
  205. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  206. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -94
  207. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  208. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  209. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
  210. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
  211. data/spec/lib/oauth/client_spec.rb +0 -38
  212. data/spec/lib/oauth/code_request_spec.rb +0 -47
  213. data/spec/lib/oauth/code_response_spec.rb +0 -36
  214. data/spec/lib/oauth/error_response_spec.rb +0 -66
  215. data/spec/lib/oauth/error_spec.rb +0 -23
  216. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
  217. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
  218. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  219. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -247
  220. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
  221. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
  222. data/spec/lib/oauth/pre_authorization_spec.rb +0 -215
  223. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  224. data/spec/lib/oauth/scopes_spec.rb +0 -148
  225. data/spec/lib/oauth/token_request_spec.rb +0 -150
  226. data/spec/lib/oauth/token_response_spec.rb +0 -86
  227. data/spec/lib/oauth/token_spec.rb +0 -158
  228. data/spec/lib/request/strategy_spec.rb +0 -54
  229. data/spec/lib/secret_storing/base_spec.rb +0 -60
  230. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  231. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  232. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  233. data/spec/lib/server_spec.rb +0 -61
  234. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  235. data/spec/models/doorkeeper/access_grant_spec.rb +0 -144
  236. data/spec/models/doorkeeper/access_token_spec.rb +0 -591
  237. data/spec/models/doorkeeper/application_spec.rb +0 -472
  238. data/spec/requests/applications/applications_request_spec.rb +0 -259
  239. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  240. data/spec/requests/endpoints/authorization_spec.rb +0 -73
  241. data/spec/requests/endpoints/token_spec.rb +0 -75
  242. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -78
  243. data/spec/requests/flows/authorization_code_spec.rb +0 -447
  244. data/spec/requests/flows/client_credentials_spec.rb +0 -128
  245. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -34
  246. data/spec/requests/flows/implicit_grant_spec.rb +0 -90
  247. data/spec/requests/flows/password_spec.rb +0 -259
  248. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  249. data/spec/requests/flows/revoke_token_spec.rb +0 -143
  250. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  251. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  252. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  253. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  254. data/spec/routing/default_routes_spec.rb +0 -41
  255. data/spec/routing/scoped_routes_spec.rb +0 -47
  256. data/spec/spec_helper.rb +0 -57
  257. data/spec/spec_helper_integration.rb +0 -4
  258. data/spec/support/dependencies/factory_bot.rb +0 -4
  259. data/spec/support/doorkeeper_rspec.rb +0 -22
  260. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  261. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  262. data/spec/support/helpers/config_helper.rb +0 -11
  263. data/spec/support/helpers/model_helper.rb +0 -78
  264. data/spec/support/helpers/request_spec_helper.rb +0 -98
  265. data/spec/support/helpers/url_helper.rb +0 -62
  266. data/spec/support/http_method_shim.rb +0 -29
  267. data/spec/support/orm/active_record.rb +0 -5
  268. data/spec/support/shared/controllers_shared_context.rb +0 -123
  269. data/spec/support/shared/hashing_shared_context.rb +0 -36
  270. data/spec/support/shared/models_shared_examples.rb +0 -54
  271. data/spec/validators/redirect_uri_validator_spec.rb +0 -158
  272. data/spec/version/version_spec.rb +0 -17
@@ -1,7 +1,8 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  Doorkeeper.configure do
4
- # Change the ORM that doorkeeper will use (needs plugins)
4
+ # Change the ORM that doorkeeper will use (requires ORM extensions installed).
5
+ # Check the list of supported ORMs here: https://github.com/doorkeeper-gem/doorkeeper#orms
5
6
  orm :active_record
6
7
 
7
8
  # This block will be called to check whether the resource owner is authenticated or not.
@@ -9,7 +10,7 @@ Doorkeeper.configure do
9
10
  raise "Please configure doorkeeper resource_owner_authenticator block located in #{__FILE__}"
10
11
  # Put your resource owner authentication logic here.
11
12
  # Example implementation:
12
- # User.find_by_id(session[:user_id]) || redirect_to(new_user_session_url)
13
+ # User.find_by(id: session[:user_id]) || redirect_to(new_user_session_url)
13
14
  end
14
15
 
15
16
  # If you didn't skip applications controller from Doorkeeper routes in your application routes.rb
@@ -28,6 +29,52 @@ Doorkeeper.configure do
28
29
  # end
29
30
  # end
30
31
 
32
+ # You can use your own model classes if you need to extend (or even override) default
33
+ # Doorkeeper models such as `Application`, `AccessToken` and `AccessGrant.
34
+ #
35
+ # Be default Doorkeeper ActiveRecord ORM uses it's own classes:
36
+ #
37
+ # access_token_class "Doorkeeper::AccessToken"
38
+ # access_grant_class "Doorkeeper::AccessGrant"
39
+ # application_class "Doorkeeper::Application"
40
+ #
41
+ # Don't forget to include Doorkeeper ORM mixins into your custom models:
42
+ #
43
+ # * ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken - for access token
44
+ # * ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant - for access grant
45
+ # * ::Doorkeeper::Orm::ActiveRecord::Mixins::Application - for application (OAuth2 clients)
46
+ #
47
+ # For example:
48
+ #
49
+ # access_token_class "MyAccessToken"
50
+ #
51
+ # class MyAccessToken < ApplicationRecord
52
+ # include ::Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken
53
+ #
54
+ # self.table_name = "hey_i_wanna_my_name"
55
+ #
56
+ # def destroy_me!
57
+ # destroy
58
+ # end
59
+ # end
60
+
61
+ # Enables polymorphic Resource Owner association for Access Tokens and Access Grants.
62
+ # By default this option is disabled.
63
+ #
64
+ # Make sure you properly setup you database and have all the required columns (run
65
+ # `bundle exec rails generate doorkeeper:enable_polymorphic_resource_owner` and execute Rails
66
+ # migrations).
67
+ #
68
+ # If this option enabled, Doorkeeper will store not only Resource Owner primary key
69
+ # value, but also it's type (class name). See "Polymorphic Associations" section of
70
+ # Rails guides: https://guides.rubyonrails.org/association_basics.html#polymorphic-associations
71
+ #
72
+ # [NOTE] If you apply this option on already existing project don't forget to manually
73
+ # update `resource_owner_type` column in the database and fix migration template as it will
74
+ # set NOT NULL constraint for Access Grants table.
75
+ #
76
+ # use_polymorphic_resource_owner
77
+
31
78
  # If you are planning to use Doorkeeper in Rails 5 API-only application, then you might
32
79
  # want to use API mode that will skip all the views management and change the way how
33
80
  # Doorkeeper responds to a requests.
@@ -39,53 +86,64 @@ Doorkeeper.configure do
39
86
  #
40
87
  # enforce_content_type
41
88
 
42
- # Authorization Code expiration time (default 10 minutes).
89
+ # Authorization Code expiration time (default: 10 minutes).
43
90
  #
44
91
  # authorization_code_expires_in 10.minutes
45
92
 
46
- # Access token expiration time (default 2 hours).
47
- # If you want to disable expiration, set this to nil.
93
+ # Access token expiration time (default: 2 hours).
94
+ # If you want to disable expiration, set this to `nil`.
48
95
  #
49
96
  # access_token_expires_in 2.hours
50
97
 
51
98
  # Assign custom TTL for access tokens. Will be used instead of access_token_expires_in
52
99
  # option if defined. In case the block returns `nil` value Doorkeeper fallbacks to
53
- # `access_token_expires_in` configuration option value. If you really need to issue a
100
+ # +access_token_expires_in+ configuration option value. If you really need to issue a
54
101
  # non-expiring access token (which is not recommended) then you need to return
55
102
  # Float::INFINITY from this block.
56
103
  #
57
104
  # `context` has the following properties available:
58
105
  #
59
- # `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
60
- # `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
61
- # `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
106
+ # * `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
107
+ # * `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
108
+ # * `scopes` - the requested scopes (see Doorkeeper::OAuth::Scopes)
109
+ # * `resource_owner` - authorized resource owner instance (if present)
62
110
  #
63
111
  # custom_access_token_expires_in do |context|
64
- # context.client.application.additional_settings.implicit_oauth_expiration
112
+ # context.client.additional_settings.implicit_oauth_expiration
65
113
  # end
66
114
 
67
115
  # Use a custom class for generating the access token.
68
- # See https://github.com/doorkeeper-gem/doorkeeper#custom-access-token-generator
116
+ # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
69
117
  #
70
118
  # access_token_generator '::Doorkeeper::JWT'
71
119
 
72
- # The controller Doorkeeper::ApplicationController inherits from.
73
- # Defaults to ActionController::Base.
74
- # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-base-controller
120
+ # The controller +Doorkeeper::ApplicationController+ inherits from.
121
+ # Defaults to +ActionController::Base+ unless +api_only+ is set, which changes the default to
122
+ # +ActionController::API+. The return value of this option must be a stringified class name.
123
+ # See https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
75
124
  #
76
125
  # base_controller 'ApplicationController'
77
126
 
78
127
  # Reuse access token for the same resource owner within an application (disabled by default).
79
128
  #
80
- # This option protects your application from creating new tokens before old valid one becomes
81
- # expired so your database doesn't bloat. Keep in mind that when this option is `on` Doorkeeper
82
- # doesn't updates existing token expiration time, it will create a new token instead.
129
+ # This option protects your application from creating new tokens before old **valid** one becomes
130
+ # expired so your database doesn't bloat. Keep in mind that when this option is enabled Doorkeeper
131
+ # doesn't update existing token expiration time, it will create a new token instead if no active matching
132
+ # token found for the application, resources owner and/or set of scopes.
83
133
  # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
84
134
  #
85
135
  # You can not enable this option together with +hash_token_secrets+.
86
136
  #
87
137
  # reuse_access_token
88
138
 
139
+ # In case you enabled `reuse_access_token` option Doorkeeper will try to find matching
140
+ # token using `matching_token_for` Access Token API that searches for valid records
141
+ # in batches in order not to pollute the memory with all the database records. By default
142
+ # Doorkeeper uses batch size of 10 000 records. You can increase or decrease this value
143
+ # depending on your needs and server capabilities.
144
+ #
145
+ # token_lookup_batch_size 10_000
146
+
89
147
  # Set a limit for token_reuse if using reuse_access_token option
90
148
  #
91
149
  # This option limits token_reusability to some extent.
@@ -96,13 +154,22 @@ Doorkeeper.configure do
96
154
  #
97
155
  # token_reuse_limit 100
98
156
 
157
+ # Only allow one valid access token obtained via client credentials
158
+ # per client. If a new access token is obtained before the old one
159
+ # expired, the old one gets revoked (disabled by default)
160
+ #
161
+ # When enabling this option, make sure that you do not expect multiple processes
162
+ # using the same credentials at the same time (e.g. web servers spanning
163
+ # multiple machines and/or processes).
164
+ #
165
+ # revoke_previous_client_credentials_token
166
+
99
167
  # Hash access and refresh tokens before persisting them.
100
168
  # This will disable the possibility to use +reuse_access_token+
101
169
  # since plain values can no longer be retrieved.
102
170
  #
103
171
  # Note: If you are already a user of doorkeeper and have existing tokens
104
- # in your installation, they will be invalid without enabling the additional
105
- # setting `fallback_to_plain_secrets` below.
172
+ # in your installation, they will be invalid without adding 'fallback: :plain'.
106
173
  #
107
174
  # hash_token_secrets
108
175
  # By default, token secrets will be hashed using the
@@ -128,21 +195,22 @@ Doorkeeper.configure do
128
195
  #
129
196
  # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt'
130
197
 
131
- # When the above option is enabled,
132
- # and a hashed token or secret is not found,
133
- # you can allow to fall back to another strategy.
134
- # For users upgrading doorkeeper and wishing to enable hashing,
135
- # you will probably want to enable the fallback to plain tokens.
198
+ # When the above option is enabled, and a hashed token or secret is not found,
199
+ # you can allow to fall back to another strategy. For users upgrading
200
+ # doorkeeper and wishing to enable hashing, you will probably want to enable
201
+ # the fallback to plain tokens.
136
202
  #
137
203
  # This will ensure that old access tokens and secrets
138
204
  # will remain valid even if the hashing above is enabled.
139
205
  #
140
- # fallback_to_plain_secrets
206
+ # This can be done by adding 'fallback: plain', e.g. :
207
+ #
208
+ # hash_application_secrets using: '::Doorkeeper::SecretStoring::BCrypt', fallback: :plain
141
209
 
142
210
  # Issue access tokens with refresh token (disabled by default), you may also
143
211
  # pass a block which accepts `context` to customize when to give a refresh
144
- # token or not. Similar to `custom_access_token_expires_in`, `context` has
145
- # the properties:
212
+ # token or not. Similar to +custom_access_token_expires_in+, `context` has
213
+ # the following properties:
146
214
  #
147
215
  # `client` - the OAuth client application (see Doorkeeper::OAuth::Client)
148
216
  # `grant_type` - the grant type of the request (see Doorkeeper::OAuth)
@@ -151,7 +219,7 @@ Doorkeeper.configure do
151
219
  # use_refresh_token
152
220
 
153
221
  # Provide support for an owner to be assigned to each registered application (disabled by default)
154
- # Optional parameter confirmation: true (default false) if you want to enforce ownership of
222
+ # Optional parameter confirmation: true (default: false) if you want to enforce ownership of
155
223
  # a registered application
156
224
  # NOTE: you must also run the rails g doorkeeper:application_owner generator
157
225
  # to provide the necessary support
@@ -160,22 +228,22 @@ Doorkeeper.configure do
160
228
 
161
229
  # Define access token scopes for your provider
162
230
  # For more information go to
163
- # https://github.com/doorkeeper-gem/doorkeeper/wiki/Using-Scopes
231
+ # https://doorkeeper.gitbook.io/guides/ruby-on-rails/scopes
164
232
  #
165
233
  # default_scopes :public
166
234
  # optional_scopes :write, :update
167
235
 
168
- # Define scopes_by_grant_type to restrict only certain scopes for grant_type
236
+ # Allows to restrict only certain scopes for grant_type.
169
237
  # By default, all the scopes will be available for all the grant types.
170
238
  #
171
239
  # Keys to this hash should be the name of grant_type and
172
240
  # values should be the array of scopes for that grant type.
173
- # Note: scopes should be from configured_scopes(i.e. deafult or optional)
241
+ # Note: scopes should be from configured_scopes (i.e. default or optional)
174
242
  #
175
243
  # scopes_by_grant_type password: [:write], client_credentials: [:update]
176
244
 
177
245
  # Forbids creating/updating applications with arbitrary scopes that are
178
- # not in configuration, i.e. `default_scopes` or `optional_scopes`.
246
+ # not in configuration, i.e. +default_scopes+ or +optional_scopes+.
179
247
  # (disabled by default)
180
248
  #
181
249
  # enforce_configured_scopes
@@ -196,15 +264,6 @@ Doorkeeper.configure do
196
264
  #
197
265
  # access_token_methods :from_bearer_authorization, :from_access_token_param, :from_bearer_param
198
266
 
199
- # Change the native redirect uri for client apps
200
- # When clients register with the following redirect uri, they won't be redirected to
201
- # any server and the authorizationcode will be displayed within the provider
202
- # The value can be any string. Use nil to disable this feature. When disabled, clients
203
- # must providea valid URL
204
- # (Similar behaviour: https://developers.google.com/accounts/docs/OAuth2InstalledApp#choosingredirecturi)
205
- #
206
- # native_redirect_uri 'urn:ietf:wg:oauth:2.0:oob'
207
-
208
267
  # Forces the usage of the HTTPS protocol in non-native redirect uris (enabled
209
268
  # by default in non-development environments). OAuth2 delegates security in
210
269
  # communication to the HTTPS protocol so it is wise to keep this enabled.
@@ -218,7 +277,7 @@ Doorkeeper.configure do
218
277
  # force_ssl_in_redirect_uri { |uri| uri.host != 'localhost' }
219
278
 
220
279
  # Specify what redirect URI's you want to block during Application creation.
221
- # Any redirect URI is whitelisted by default.
280
+ # Any redirect URI is allowed by default.
222
281
  #
223
282
  # You can use this option in order to forbid URI's with 'javascript' scheme
224
283
  # for example.
@@ -246,7 +305,7 @@ Doorkeeper.configure do
246
305
  # is invalid, expired, revoked or has invalid scopes.
247
306
  #
248
307
  # If you want to render error response yourself (i.e. rescue exceptions),
249
- # set handle_auth_errors to `:raise` and rescue Doorkeeper::Errors::InvalidToken
308
+ # set +handle_auth_errors+ to `:raise` and rescue Doorkeeper::Errors::InvalidToken
250
309
  # or following specific errors:
251
310
  #
252
311
  # Doorkeeper::Errors::TokenForbidden, Doorkeeper::Errors::TokenExpired,
@@ -285,11 +344,70 @@ Doorkeeper.configure do
285
344
  #
286
345
  # implicit and password grant flows have risks that you should understand
287
346
  # before enabling:
288
- # http://tools.ietf.org/html/rfc6819#section-4.4.2
289
- # http://tools.ietf.org/html/rfc6819#section-4.4.3
347
+ # https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.2
348
+ # https://datatracker.ietf.org/doc/html/rfc6819#section-4.4.3
290
349
  #
291
350
  # grant_flows %w[authorization_code client_credentials]
292
351
 
352
+ # Allows to customize OAuth grant flows that +each+ application support.
353
+ # You can configure a custom block (or use a class respond to `#call`) that must
354
+ # return `true` in case Application instance supports requested OAuth grant flow
355
+ # during the authorization request to the server. This configuration +doesn't+
356
+ # set flows per application, it only allows to check if application supports
357
+ # specific grant flow.
358
+ #
359
+ # For example you can add an additional database column to `oauth_applications` table,
360
+ # say `t.array :grant_flows, default: []`, and store allowed grant flows that can
361
+ # be used with this application there. Then when authorization requested Doorkeeper
362
+ # will call this block to check if specific Application (passed with client_id and/or
363
+ # client_secret) is allowed to perform the request for the specific grant type
364
+ # (authorization, password, client_credentials, etc).
365
+ #
366
+ # Example of the block:
367
+ #
368
+ # ->(flow, client) { client.grant_flows.include?(flow) }
369
+ #
370
+ # In case this option invocation result is `false`, Doorkeeper server returns
371
+ # :unauthorized_client error and stops the request.
372
+ #
373
+ # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
374
+ # @return [Boolean] `true` if allow or `false` if forbid the request
375
+ #
376
+ # allow_grant_flow_for_client do |grant_flow, client|
377
+ # # `grant_flows` is an Array column with grant
378
+ # # flows that application supports
379
+ #
380
+ # client.grant_flows.include?(grant_flow)
381
+ # end
382
+
383
+ # If you need arbitrary Resource Owner-Client authorization you can enable this option
384
+ # and implement the check your need. Config option must respond to #call and return
385
+ # true in case resource owner authorized for the specific application or false in other
386
+ # cases.
387
+ #
388
+ # Be default all Resource Owners are authorized to any Client (application).
389
+ #
390
+ # authorize_resource_owner_for_client do |client, resource_owner|
391
+ # resource_owner.admin? || client.owners_allowlist.include?(resource_owner)
392
+ # end
393
+
394
+ # Allows additional data fields to be sent while granting access to an application,
395
+ # and for this additional data to be included in subsequently generated access tokens.
396
+ # The 'authorizations/new' page will need to be overridden to include this additional data
397
+ # in the request params when granting access. The access grant and access token models
398
+ # will both need to respond to these additional data fields, and have a database column
399
+ # to store them in.
400
+ #
401
+ # Example:
402
+ # You have a multi-tenanted platform and want to be able to grant access to a specific
403
+ # tenant, rather than all the tenants a user has access to. You can use this config
404
+ # option to specify that a ':tenant_id' will be passed when authorizing. This tenant_id
405
+ # will be included in the access tokens. When a request is made with one of these access
406
+ # tokens, you can check that the requested data belongs to the specified tenant.
407
+ #
408
+ # Default value is an empty Array: []
409
+ # custom_access_token_attributes [:tenant_id]
410
+
293
411
  # Hook into the strategies' request & response life-cycle in case your
294
412
  # application needs advanced customization or logging:
295
413
  #
@@ -302,17 +420,25 @@ Doorkeeper.configure do
302
420
  # end
303
421
 
304
422
  # Hook into Authorization flow in order to implement Single Sign Out
305
- # or add any other functionality.
423
+ # or add any other functionality. Inside the block you have an access
424
+ # to `controller` (authorizations controller instance) and `context`
425
+ # (Doorkeeper::OAuth::Hooks::Context instance) which provides pre auth
426
+ # or auth objects with issued token based on hook type (before or after).
306
427
  #
307
- # before_successful_authorization do |controller|
308
- # Rails.logger.info(params.inspect)
428
+ # before_successful_authorization do |controller, context|
429
+ # Rails.logger.info(controller.request.params.inspect)
430
+ #
431
+ # Rails.logger.info(context.pre_auth.inspect)
309
432
  # end
310
433
  #
311
- # after_successful_authorization do |controller|
434
+ # after_successful_authorization do |controller, context|
312
435
  # controller.session[:logout_urls] <<
313
436
  # Doorkeeper::Application
314
437
  # .find_by(controller.request.params.slice(:redirect_uri))
315
438
  # .logout_uri
439
+ #
440
+ # Rails.logger.info(context.auth.inspect)
441
+ # Rails.logger.info(context.issued_token)
316
442
  # end
317
443
 
318
444
  # Under some circumstances you might want to have applications auto-approved,
@@ -323,7 +449,61 @@ Doorkeeper.configure do
323
449
  # client.superapp? or resource_owner.admin?
324
450
  # end
325
451
 
326
- # WWW-Authenticate Realm (default "Doorkeeper").
452
+ # Configure custom constraints for the Token Introspection request.
453
+ # By default this configuration option allows to introspect a token by another
454
+ # token of the same application, OR to introspect the token that belongs to
455
+ # authorized client (from authenticated client) OR when token doesn't
456
+ # belong to any client (public token). Otherwise requester has no access to the
457
+ # introspection and it will return response as stated in the RFC.
458
+ #
459
+ # Block arguments:
460
+ #
461
+ # @param token [Doorkeeper::AccessToken]
462
+ # token to be introspected
463
+ #
464
+ # @param authorized_client [Doorkeeper::Application]
465
+ # authorized client (if request is authorized using Basic auth with
466
+ # Client Credentials for example)
467
+ #
468
+ # @param authorized_token [Doorkeeper::AccessToken]
469
+ # Bearer token used to authorize the request
470
+ #
471
+ # In case the block returns `nil` or `false` introspection responses with 401 status code
472
+ # when using authorized token to introspect, or you'll get 200 with { "active": false } body
473
+ # when using authorized client to introspect as stated in the
474
+ # RFC 7662 section 2.2. Introspection Response.
475
+ #
476
+ # Using with caution:
477
+ # Keep in mind that these three parameters pass to block can be nil as following case:
478
+ # `authorized_client` is nil if and only if `authorized_token` is present, and vice versa.
479
+ # `token` will be nil if and only if `authorized_token` is present.
480
+ # So remember to use `&` or check if it is present before calling method on
481
+ # them to make sure you doesn't get NoMethodError exception.
482
+ #
483
+ # You can define your custom check:
484
+ #
485
+ # allow_token_introspection do |token, authorized_client, authorized_token|
486
+ # if authorized_token
487
+ # # customize: require `introspection` scope
488
+ # authorized_token.application == token&.application ||
489
+ # authorized_token.scopes.include?("introspection")
490
+ # elsif token.application
491
+ # # `protected_resource` is a new database boolean column, for example
492
+ # authorized_client == token.application || authorized_client.protected_resource?
493
+ # else
494
+ # # public token (when token.application is nil, token doesn't belong to any application)
495
+ # true
496
+ # end
497
+ # end
498
+ #
499
+ # Or you can completely disable any token introspection:
500
+ #
501
+ # allow_token_introspection false
502
+ #
503
+ # If you need to block the request at all, then configure your routes.rb or web-server
504
+ # like nginx to forbid the request.
505
+
506
+ # WWW-Authenticate Realm (default: "Doorkeeper").
327
507
  #
328
508
  # realm "Doorkeeper"
329
509
  end
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
2
4
  def change
3
5
  create_table :oauth_applications do |t|
@@ -22,9 +24,9 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
22
24
  t.string :token, null: false
23
25
  t.integer :expires_in, null: false
24
26
  t.text :redirect_uri, null: false
27
+ t.string :scopes, null: false, default: ''
25
28
  t.datetime :created_at, null: false
26
29
  t.datetime :revoked_at
27
- t.string :scopes
28
30
  end
29
31
 
30
32
  add_index :oauth_access_grants, :token, unique: true
@@ -36,6 +38,9 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
36
38
 
37
39
  create_table :oauth_access_tokens do |t|
38
40
  t.references :resource_owner, index: true
41
+
42
+ # Remove `null: false` if you are planning to use Password
43
+ # Credentials Grant flow that doesn't require an application.
39
44
  t.references :application, null: false
40
45
 
41
46
  # If you use a custom token generator you may need to change this column
@@ -48,21 +53,38 @@ class CreateDoorkeeperTables < ActiveRecord::Migration<%= migration_version %>
48
53
 
49
54
  t.string :refresh_token
50
55
  t.integer :expires_in
51
- t.datetime :revoked_at
52
- t.datetime :created_at, null: false
53
56
  t.string :scopes
57
+ t.datetime :created_at, null: false
58
+ t.datetime :revoked_at
54
59
 
55
- # If there is a previous_refresh_token column,
60
+ # The authorization server MAY issue a new refresh token, in which case
61
+ # *the client MUST discard the old refresh token* and replace it with the
62
+ # new refresh token. The authorization server MAY revoke the old
63
+ # refresh token after issuing a new refresh token to the client.
64
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-6
65
+ #
66
+ # Doorkeeper implementation: if there is a `previous_refresh_token` column,
56
67
  # refresh tokens will be revoked after a related access token is used.
57
- # If there is no previous_refresh_token column,
58
- # previous tokens are revoked as soon as a new access token is created.
59
- # Comment out this line if you'd rather have refresh tokens
60
- # instantly revoked.
68
+ # If there is no `previous_refresh_token` column, previous tokens are
69
+ # revoked as soon as a new access token is created.
70
+ #
71
+ # Comment out this line if you want refresh tokens to be instantly
72
+ # revoked after use.
61
73
  t.string :previous_refresh_token, null: false, default: ""
62
74
  end
63
75
 
64
76
  add_index :oauth_access_tokens, :token, unique: true
65
- add_index :oauth_access_tokens, :refresh_token, unique: true
77
+
78
+ # See https://github.com/doorkeeper-gem/doorkeeper/issues/1592
79
+ if ActiveRecord::Base.connection.adapter_name == "SQLServer"
80
+ execute <<~SQL.squish
81
+ CREATE UNIQUE NONCLUSTERED INDEX index_oauth_access_tokens_on_refresh_token ON oauth_access_tokens(refresh_token)
82
+ WHERE refresh_token IS NOT NULL
83
+ SQL
84
+ else
85
+ add_index :oauth_access_tokens, :refresh_token, unique: true
86
+ end
87
+
66
88
  add_foreign_key(
67
89
  :oauth_access_tokens,
68
90
  :oauth_applications,