doorkeeper 4.2.0 → 5.6.8

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 (273) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +1119 -0
  3. data/README.md +112 -349
  4. data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +6 -7
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +7 -11
  7. data/app/controllers/doorkeeper/applications_controller.rb +65 -20
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +115 -18
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +22 -3
  10. data/app/controllers/doorkeeper/token_info_controller.rb +16 -4
  11. data/app/controllers/doorkeeper/tokens_controller.rb +118 -38
  12. data/app/helpers/doorkeeper/dashboard_helper.rb +10 -6
  13. data/app/views/doorkeeper/applications/_delete_form.html.erb +4 -3
  14. data/app/views/doorkeeper/applications/_form.html.erb +33 -21
  15. data/app/views/doorkeeper/applications/edit.html.erb +1 -1
  16. data/app/views/doorkeeper/applications/index.html.erb +18 -6
  17. data/app/views/doorkeeper/applications/new.html.erb +1 -1
  18. data/app/views/doorkeeper/applications/show.html.erb +40 -16
  19. data/app/views/doorkeeper/authorizations/error.html.erb +4 -2
  20. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  21. data/app/views/doorkeeper/authorizations/new.html.erb +17 -11
  22. data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
  23. data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
  24. data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
  25. data/config/locales/en.yml +36 -9
  26. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  27. data/lib/doorkeeper/config/option.rb +82 -0
  28. data/lib/doorkeeper/config/validations.rb +53 -0
  29. data/lib/doorkeeper/config.rb +551 -155
  30. data/lib/doorkeeper/engine.rb +19 -6
  31. data/lib/doorkeeper/errors.rb +55 -10
  32. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  33. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  34. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  35. data/lib/doorkeeper/grant_flow.rb +45 -0
  36. data/lib/doorkeeper/grape/authorization_decorator.rb +6 -4
  37. data/lib/doorkeeper/grape/helpers.rb +24 -12
  38. data/lib/doorkeeper/helpers/controller.rb +49 -27
  39. data/lib/doorkeeper/models/access_grant_mixin.rb +100 -21
  40. data/lib/doorkeeper/models/access_token_mixin.rb +383 -75
  41. data/lib/doorkeeper/models/application_mixin.rb +72 -25
  42. data/lib/doorkeeper/models/concerns/accessible.rb +6 -0
  43. data/lib/doorkeeper/models/concerns/expirable.rb +20 -6
  44. data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
  45. data/lib/doorkeeper/models/concerns/orderable.rb +15 -0
  46. data/lib/doorkeeper/models/concerns/ownership.rb +4 -7
  47. data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
  48. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  49. data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
  50. data/lib/doorkeeper/models/concerns/revocable.rb +12 -18
  51. data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
  52. data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
  53. data/lib/doorkeeper/oauth/authorization/code.rb +54 -12
  54. data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
  55. data/lib/doorkeeper/oauth/authorization/token.rb +72 -28
  56. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +22 -18
  57. data/lib/doorkeeper/oauth/authorization_code_request.rb +77 -17
  58. data/lib/doorkeeper/oauth/base_request.rb +67 -0
  59. data/lib/doorkeeper/oauth/base_response.rb +31 -0
  60. data/lib/doorkeeper/oauth/client/credentials.rb +23 -10
  61. data/lib/doorkeeper/oauth/client.rb +10 -12
  62. data/lib/doorkeeper/oauth/client_credentials/creator.rb +44 -4
  63. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +21 -13
  64. data/lib/doorkeeper/oauth/client_credentials/validator.rb +55 -0
  65. data/lib/doorkeeper/oauth/client_credentials_request.rb +20 -16
  66. data/lib/doorkeeper/oauth/code_request.rb +9 -13
  67. data/lib/doorkeeper/oauth/code_response.rb +28 -15
  68. data/lib/doorkeeper/oauth/error.rb +5 -3
  69. data/lib/doorkeeper/oauth/error_response.rb +43 -20
  70. data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
  71. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +23 -18
  72. data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
  73. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +53 -3
  74. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  75. data/lib/doorkeeper/oauth/invalid_request_response.rb +47 -0
  76. data/lib/doorkeeper/oauth/invalid_token_response.rb +31 -5
  77. data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
  78. data/lib/doorkeeper/oauth/password_access_token_request.rb +46 -14
  79. data/lib/doorkeeper/oauth/pre_authorization.rb +138 -28
  80. data/lib/doorkeeper/oauth/refresh_token_request.rb +74 -41
  81. data/lib/doorkeeper/oauth/scopes.rb +26 -12
  82. data/lib/doorkeeper/oauth/token.rb +25 -23
  83. data/lib/doorkeeper/oauth/token_introspection.rb +204 -0
  84. data/lib/doorkeeper/oauth/token_request.rb +9 -22
  85. data/lib/doorkeeper/oauth/token_response.rb +13 -10
  86. data/lib/doorkeeper/oauth.rb +13 -0
  87. data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
  88. data/lib/doorkeeper/orm/active_record/access_token.rb +5 -25
  89. data/lib/doorkeeper/orm/active_record/application.rb +6 -15
  90. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +63 -0
  91. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +77 -0
  92. data/lib/doorkeeper/orm/active_record/mixins/application.rb +210 -0
  93. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
  94. data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +36 -0
  95. data/lib/doorkeeper/orm/active_record.rb +34 -12
  96. data/lib/doorkeeper/rails/helpers.rb +14 -15
  97. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  98. data/lib/doorkeeper/rails/routes/mapper.rb +3 -1
  99. data/lib/doorkeeper/rails/routes/mapping.rb +10 -8
  100. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  101. data/lib/doorkeeper/rails/routes.rb +50 -29
  102. data/lib/doorkeeper/rake/db.rake +40 -0
  103. data/lib/doorkeeper/rake/setup.rake +6 -0
  104. data/lib/doorkeeper/rake.rb +14 -0
  105. data/lib/doorkeeper/request/authorization_code.rb +12 -4
  106. data/lib/doorkeeper/request/client_credentials.rb +3 -3
  107. data/lib/doorkeeper/request/code.rb +1 -1
  108. data/lib/doorkeeper/request/password.rb +5 -14
  109. data/lib/doorkeeper/request/refresh_token.rb +6 -5
  110. data/lib/doorkeeper/request/strategy.rb +4 -2
  111. data/lib/doorkeeper/request/token.rb +1 -1
  112. data/lib/doorkeeper/request.rb +62 -29
  113. data/lib/doorkeeper/secret_storing/base.rb +64 -0
  114. data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
  115. data/lib/doorkeeper/secret_storing/plain.rb +33 -0
  116. data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
  117. data/lib/doorkeeper/server.rb +9 -19
  118. data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
  119. data/lib/doorkeeper/validations.rb +5 -2
  120. data/lib/doorkeeper/version.rb +12 -1
  121. data/lib/doorkeeper.rb +180 -57
  122. data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
  123. data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
  124. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  125. data/lib/generators/doorkeeper/install_generator.rb +19 -9
  126. data/lib/generators/doorkeeper/migration_generator.rb +27 -10
  127. data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
  128. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +31 -19
  129. data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
  130. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
  131. data/lib/generators/doorkeeper/templates/{add_previous_refresh_token_to_access_tokens.rb → add_previous_refresh_token_to_access_tokens.rb.erb} +3 -1
  132. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
  133. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  134. data/lib/generators/doorkeeper/templates/initializer.rb +436 -33
  135. data/lib/generators/doorkeeper/templates/migration.rb.erb +98 -0
  136. data/lib/generators/doorkeeper/views_generator.rb +8 -4
  137. data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
  138. metadata +129 -281
  139. data/.gitignore +0 -14
  140. data/.hound.yml +0 -13
  141. data/.rspec +0 -1
  142. data/.travis.yml +0 -20
  143. data/CONTRIBUTING.md +0 -47
  144. data/Gemfile +0 -14
  145. data/NEWS.md +0 -593
  146. data/RELEASING.md +0 -17
  147. data/Rakefile +0 -20
  148. data/app/validators/redirect_uri_validator.rb +0 -34
  149. data/doorkeeper.gemspec +0 -28
  150. data/lib/doorkeeper/oauth/client/methods.rb +0 -18
  151. data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
  152. data/lib/doorkeeper/oauth/request_concern.rb +0 -48
  153. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
  154. data/lib/generators/doorkeeper/templates/migration.rb +0 -68
  155. data/spec/controllers/application_metal_controller.rb +0 -10
  156. data/spec/controllers/applications_controller_spec.rb +0 -58
  157. data/spec/controllers/authorizations_controller_spec.rb +0 -189
  158. data/spec/controllers/protected_resources_controller_spec.rb +0 -300
  159. data/spec/controllers/token_info_controller_spec.rb +0 -52
  160. data/spec/controllers/tokens_controller_spec.rb +0 -88
  161. data/spec/dummy/Rakefile +0 -7
  162. data/spec/dummy/app/controllers/application_controller.rb +0 -3
  163. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
  164. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
  165. data/spec/dummy/app/controllers/home_controller.rb +0 -17
  166. data/spec/dummy/app/controllers/metal_controller.rb +0 -11
  167. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
  168. data/spec/dummy/app/helpers/application_helper.rb +0 -5
  169. data/spec/dummy/app/models/user.rb +0 -5
  170. data/spec/dummy/app/views/home/index.html.erb +0 -0
  171. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  172. data/spec/dummy/config/application.rb +0 -23
  173. data/spec/dummy/config/boot.rb +0 -9
  174. data/spec/dummy/config/database.yml +0 -15
  175. data/spec/dummy/config/environment.rb +0 -5
  176. data/spec/dummy/config/environments/development.rb +0 -29
  177. data/spec/dummy/config/environments/production.rb +0 -62
  178. data/spec/dummy/config/environments/test.rb +0 -44
  179. data/spec/dummy/config/initializers/active_record_belongs_to_required_by_default.rb +0 -6
  180. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
  181. data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
  182. data/spec/dummy/config/initializers/secret_token.rb +0 -9
  183. data/spec/dummy/config/initializers/session_store.rb +0 -8
  184. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
  185. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  186. data/spec/dummy/config/routes.rb +0 -52
  187. data/spec/dummy/config.ru +0 -4
  188. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
  189. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
  190. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -60
  191. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -7
  192. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -11
  193. data/spec/dummy/db/schema.rb +0 -67
  194. data/spec/dummy/public/404.html +0 -26
  195. data/spec/dummy/public/422.html +0 -26
  196. data/spec/dummy/public/500.html +0 -26
  197. data/spec/dummy/public/favicon.ico +0 -0
  198. data/spec/dummy/script/rails +0 -6
  199. data/spec/factories.rb +0 -28
  200. data/spec/generators/application_owner_generator_spec.rb +0 -22
  201. data/spec/generators/install_generator_spec.rb +0 -31
  202. data/spec/generators/migration_generator_spec.rb +0 -20
  203. data/spec/generators/templates/routes.rb +0 -3
  204. data/spec/generators/views_generator_spec.rb +0 -27
  205. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
  206. data/spec/lib/config_spec.rb +0 -334
  207. data/spec/lib/doorkeeper_spec.rb +0 -28
  208. data/spec/lib/models/expirable_spec.rb +0 -51
  209. data/spec/lib/models/revocable_spec.rb +0 -59
  210. data/spec/lib/models/scopes_spec.rb +0 -43
  211. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -42
  212. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
  213. data/spec/lib/oauth/client/credentials_spec.rb +0 -47
  214. data/spec/lib/oauth/client/methods_spec.rb +0 -54
  215. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
  216. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
  217. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
  218. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  219. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
  220. data/spec/lib/oauth/client_spec.rb +0 -39
  221. data/spec/lib/oauth/code_request_spec.rb +0 -45
  222. data/spec/lib/oauth/code_response_spec.rb +0 -34
  223. data/spec/lib/oauth/error_response_spec.rb +0 -61
  224. data/spec/lib/oauth/error_spec.rb +0 -23
  225. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
  226. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
  227. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
  228. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -104
  229. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -28
  230. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -90
  231. data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
  232. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -154
  233. data/spec/lib/oauth/scopes_spec.rb +0 -122
  234. data/spec/lib/oauth/token_request_spec.rb +0 -98
  235. data/spec/lib/oauth/token_response_spec.rb +0 -85
  236. data/spec/lib/oauth/token_spec.rb +0 -116
  237. data/spec/lib/request/strategy_spec.rb +0 -53
  238. data/spec/lib/server_spec.rb +0 -52
  239. data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
  240. data/spec/models/doorkeeper/access_token_spec.rb +0 -394
  241. data/spec/models/doorkeeper/application_spec.rb +0 -179
  242. data/spec/requests/applications/applications_request_spec.rb +0 -94
  243. data/spec/requests/applications/authorized_applications_spec.rb +0 -30
  244. data/spec/requests/endpoints/authorization_spec.rb +0 -72
  245. data/spec/requests/endpoints/token_spec.rb +0 -64
  246. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -66
  247. data/spec/requests/flows/authorization_code_spec.rb +0 -156
  248. data/spec/requests/flows/client_credentials_spec.rb +0 -58
  249. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
  250. data/spec/requests/flows/implicit_grant_spec.rb +0 -61
  251. data/spec/requests/flows/password_spec.rb +0 -115
  252. data/spec/requests/flows/refresh_token_spec.rb +0 -174
  253. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  254. data/spec/requests/flows/skip_authorization_spec.rb +0 -59
  255. data/spec/requests/protected_resources/metal_spec.rb +0 -14
  256. data/spec/requests/protected_resources/private_api_spec.rb +0 -81
  257. data/spec/routing/custom_controller_routes_spec.rb +0 -71
  258. data/spec/routing/default_routes_spec.rb +0 -35
  259. data/spec/routing/scoped_routes_spec.rb +0 -31
  260. data/spec/spec_helper.rb +0 -2
  261. data/spec/spec_helper_integration.rb +0 -59
  262. data/spec/support/dependencies/factory_girl.rb +0 -2
  263. data/spec/support/helpers/access_token_request_helper.rb +0 -11
  264. data/spec/support/helpers/authorization_request_helper.rb +0 -41
  265. data/spec/support/helpers/config_helper.rb +0 -9
  266. data/spec/support/helpers/model_helper.rb +0 -67
  267. data/spec/support/helpers/request_spec_helper.rb +0 -76
  268. data/spec/support/helpers/url_helper.rb +0 -55
  269. data/spec/support/http_method_shim.rb +0 -24
  270. data/spec/support/orm/active_record.rb +0 -3
  271. data/spec/support/shared/controllers_shared_context.rb +0 -69
  272. data/spec/support/shared/models_shared_examples.rb +0 -52
  273. data/spec/validators/redirect_uri_validator_spec.rb +0 -78
@@ -1,213 +1,520 @@
1
- module Doorkeeper
2
- class MissingConfiguration < StandardError
3
- def initialize
4
- super('Configuration for doorkeeper missing. Do you have doorkeeper initializer?')
5
- end
6
- end
7
-
8
- def self.configure(&block)
9
- @config = Config::Builder.new(&block).build
10
- setup_orm_adapter
11
- setup_orm_models
12
- setup_application_owner if @config.enable_application_owner?
13
- end
14
-
15
- def self.configuration
16
- @config || (fail MissingConfiguration)
17
- end
18
-
19
- def self.setup_orm_adapter
20
- @orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
21
- rescue NameError => e
22
- fail e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.squish
23
- [doorkeeper] ORM adapter not found (#{configuration.orm}), or there was an error
24
- trying to load it.
25
-
26
- You probably need to add the related gem for this adapter to work with
27
- doorkeeper.
28
- ERROR_MSG
29
- end
30
-
31
- def self.setup_orm_models
32
- @orm_adapter.initialize_models!
33
- end
1
+ # frozen_string_literal: true
34
2
 
35
- def self.setup_application_owner
36
- @orm_adapter.initialize_application_owner!
37
- end
3
+ require "doorkeeper/config/abstract_builder"
4
+ require "doorkeeper/config/option"
5
+ require "doorkeeper/config/validations"
38
6
 
7
+ module Doorkeeper
8
+ # Doorkeeper option DSL could be reused in extensions to build their own
9
+ # configurations. To use the Option DSL gems need to define `builder_class` method
10
+ # that returns configuration Builder class. This exception raises when they don't
11
+ # define it.
12
+ #
39
13
  class Config
40
- class Builder
41
- def initialize(&block)
42
- @config = Config.new
43
- instance_eval(&block)
44
- end
45
-
46
- def build
47
- @config
48
- end
49
-
14
+ # Default Doorkeeper configuration builder
15
+ class Builder < AbstractBuilder
16
+ # Provide support for an owner to be assigned to each registered
17
+ # application (disabled by default)
18
+ # Optional parameter confirmation: true (default false) if you want
19
+ # to enforce ownership of a registered application
20
+ #
21
+ # @param opts [Hash] the options to confirm if an application owner
22
+ # is present
23
+ # @option opts[Boolean] :confirmation (false)
24
+ # Set confirm_application_owner variable
50
25
  def enable_application_owner(opts = {})
51
- @config.instance_variable_set('@enable_application_owner', true)
26
+ @config.instance_variable_set(:@enable_application_owner, true)
52
27
  confirm_application_owner if opts[:confirmation].present? && opts[:confirmation]
53
28
  end
54
29
 
55
30
  def confirm_application_owner
56
- @config.instance_variable_set('@confirm_application_owner', true)
31
+ @config.instance_variable_set(:@confirm_application_owner, true)
57
32
  end
58
33
 
34
+ # Define default access token scopes for your provider
35
+ #
36
+ # @param scopes [Array] Default set of access (OAuth::Scopes.new)
37
+ # token scopes
59
38
  def default_scopes(*scopes)
60
- @config.instance_variable_set('@default_scopes', OAuth::Scopes.from_array(scopes))
39
+ @config.instance_variable_set(:@default_scopes, OAuth::Scopes.from_array(scopes))
61
40
  end
62
41
 
42
+ # Define default access token scopes for your provider
43
+ #
44
+ # @param scopes [Array] Optional set of access (OAuth::Scopes.new)
45
+ # token scopes
63
46
  def optional_scopes(*scopes)
64
- @config.instance_variable_set('@optional_scopes', OAuth::Scopes.from_array(scopes))
47
+ @config.instance_variable_set(:@optional_scopes, OAuth::Scopes.from_array(scopes))
65
48
  end
66
49
 
50
+ # Define scopes_by_grant_type to limit certain scope to certain grant_type
51
+ # @param { Hash } with grant_types as keys.
52
+ # Default set to {} i.e. no limitation on scopes usage
53
+ def scopes_by_grant_type(hash = {})
54
+ @config.instance_variable_set(:@scopes_by_grant_type, hash)
55
+ end
56
+
57
+ # Change the way client credentials are retrieved from the request object.
58
+ # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
59
+ # falls back to the `:client_id` and `:client_secret` params from the
60
+ # `params` object.
61
+ #
62
+ # @param methods [Array] Define client credentials
67
63
  def client_credentials(*methods)
68
- @config.instance_variable_set('@client_credentials', methods)
64
+ @config.instance_variable_set(:@client_credentials_methods, methods)
69
65
  end
70
66
 
67
+ # Change the way access token is authenticated from the request object.
68
+ # By default it retrieves first from the `HTTP_AUTHORIZATION` header, then
69
+ # falls back to the `:access_token` or `:bearer_token` params from the
70
+ # `params` object.
71
+ #
72
+ # @param methods [Array] Define access token methods
71
73
  def access_token_methods(*methods)
72
- @config.instance_variable_set('@access_token_methods', methods)
74
+ @config.instance_variable_set(:@access_token_methods, methods)
73
75
  end
74
76
 
75
- def use_refresh_token
76
- @config.instance_variable_set('@refresh_token_enabled', true)
77
+ # Issue access tokens with refresh token (disabled if not set)
78
+ def use_refresh_token(enabled = true, &block)
79
+ @config.instance_variable_set(
80
+ :@refresh_token_enabled,
81
+ block || enabled,
82
+ )
77
83
  end
78
84
 
79
- def realm(realm)
80
- @config.instance_variable_set('@realm', realm)
85
+ # Reuse access token for the same resource owner within an application
86
+ # (disabled by default)
87
+ # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/383
88
+ def reuse_access_token
89
+ @config.instance_variable_set(:@reuse_access_token, true)
81
90
  end
82
91
 
83
- def reuse_access_token
84
- @config.instance_variable_set("@reuse_access_token", true)
92
+ # Choose to use the url path for native autorization codes
93
+ # Enabling this flag sets the authorization code response route for
94
+ # native redirect uris to oauth/authorize/<code>. The default is
95
+ # oauth/authorize/native?code=<code>.
96
+ # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1143
97
+ def use_url_path_for_native_authorization
98
+ @config.instance_variable_set(:@use_url_path_for_native_authorization, true)
85
99
  end
86
100
 
87
- def force_ssl_in_redirect_uri(boolean)
88
- @config.instance_variable_set("@force_ssl_in_redirect_uri", boolean)
101
+ # TODO: maybe make it more generic for other flows too?
102
+ # Only allow one valid access token obtained via client credentials
103
+ # per client. If a new access token is obtained before the old one
104
+ # expired, the old one gets revoked (disabled by default)
105
+ def revoke_previous_client_credentials_token
106
+ @config.instance_variable_set(:@revoke_previous_client_credentials_token, true)
89
107
  end
90
108
 
91
- def access_token_generator(access_token_generator)
92
- @config.instance_variable_set(
93
- '@access_token_generator', access_token_generator
94
- )
109
+ # Use an API mode for applications generated with --api argument
110
+ # It will skip applications controller, disable forgery protection
111
+ def api_only
112
+ @config.instance_variable_set(:@api_only, true)
95
113
  end
96
114
 
97
- def base_controller(base_controller)
98
- @config.instance_variable_set('@base_controller', base_controller)
115
+ # Enables polymorphic Resource Owner association for Access Grant and
116
+ # Access Token models. Requires additional database columns to be setup.
117
+ def use_polymorphic_resource_owner
118
+ @config.instance_variable_set(:@polymorphic_resource_owner, true)
99
119
  end
100
- end
101
120
 
102
- module Option
103
- # Defines configuration option
104
- #
105
- # When you call option, it defines two methods. One method will take place
106
- # in the +Config+ class and the other method will take place in the
107
- # +Builder+ class.
108
- #
109
- # The +name+ parameter will set both builder method and config attribute.
110
- # If the +:as+ option is defined, the builder method will be the specified
111
- # option while the config attribute will be the +name+ parameter.
112
- #
113
- # If you want to introduce another level of config DSL you can
114
- # define +builder_class+ parameter.
115
- # Builder should take a block as the initializer parameter and respond to function +build+
116
- # that returns the value of the config attribute.
117
- #
118
- # ==== Options
119
- #
120
- # * [:+as+] Set the builder method that goes inside +configure+ block
121
- # * [+:default+] The default value in case no option was set
122
- #
123
- # ==== Examples
121
+ # Forbids creating/updating applications with arbitrary scopes that are
122
+ # not in configuration, i.e. `default_scopes` or `optional_scopes`.
123
+ # (disabled by default)
124
+ def enforce_configured_scopes
125
+ @config.instance_variable_set(:@enforce_configured_scopes, true)
126
+ end
127
+
128
+ # Enforce request content type as the spec requires:
129
+ # disabled by default for backward compatibility.
130
+ def enforce_content_type
131
+ @config.instance_variable_set(:@enforce_content_type, true)
132
+ end
133
+
134
+ # Allow optional hashing of input tokens before persisting them.
135
+ # Will be used for hashing of input token and grants.
124
136
  #
125
- # option :name
126
- # option :name, as: :set_name
127
- # option :name, default: 'My Name'
128
- # option :scopes builder_class: ScopesBuilder
137
+ # @param using
138
+ # Provide a different secret storage implementation class for tokens
139
+ # @param fallback
140
+ # Provide a fallback secret storage implementation class for tokens
141
+ # or use :plain to fallback to plain tokens
142
+ def hash_token_secrets(using: nil, fallback: nil)
143
+ default = "::Doorkeeper::SecretStoring::Sha256Hash"
144
+ configure_secrets_for :token,
145
+ using: using || default,
146
+ fallback: fallback
147
+ end
148
+
149
+ # Allow optional hashing of application secrets before persisting them.
150
+ # Will be used for hashing of input token and grants.
129
151
  #
130
- def option(name, options = {})
131
- attribute = options[:as] || name
132
- attribute_builder = options[:builder_class]
133
-
134
- Builder.instance_eval do
135
- remove_method name if method_defined?(name)
136
- define_method name do |*args, &block|
137
- # TODO: is builder_class option being used?
138
- value = if attribute_builder
139
- attribute_builder.new(&block).build
140
- else
141
- block ? block : args.first
142
- end
143
-
144
- @config.instance_variable_set(:"@#{attribute}", value)
145
- end
146
- end
152
+ # @param using
153
+ # Provide a different secret storage implementation for applications
154
+ # @param fallback
155
+ # Provide a fallback secret storage implementation for applications
156
+ # or use :plain to fallback to plain application secrets
157
+ def hash_application_secrets(using: nil, fallback: nil)
158
+ default = "::Doorkeeper::SecretStoring::Sha256Hash"
159
+ configure_secrets_for :application,
160
+ using: using || default,
161
+ fallback: fallback
162
+ end
147
163
 
148
- define_method attribute do |*_args|
149
- if instance_variable_defined?(:"@#{attribute}")
150
- instance_variable_get(:"@#{attribute}")
151
- else
152
- options[:default]
153
- end
154
- end
164
+ private
155
165
 
156
- public attribute
157
- end
166
+ # Configure the secret storing functionality
167
+ def configure_secrets_for(type, using:, fallback:)
168
+ raise ArgumentError, "Invalid type #{type}" if %i[application token].exclude?(type)
169
+
170
+ @config.instance_variable_set(:"@#{type}_secret_strategy", using.constantize)
171
+
172
+ if fallback.nil?
173
+ return
174
+ elsif fallback.to_sym == :plain
175
+ fallback = "::Doorkeeper::SecretStoring::Plain"
176
+ end
158
177
 
159
- def extended(base)
160
- base.send(:private, :option)
178
+ @config.instance_variable_set(:"@#{type}_secret_fallback_strategy", fallback.constantize)
161
179
  end
162
180
  end
163
181
 
182
+ # Replace with `default: Builder` when we drop support of Rails < 5.2
183
+ mattr_reader(:builder_class) { Builder }
184
+
164
185
  extend Option
186
+ include Validations
165
187
 
166
188
  option :resource_owner_authenticator,
167
189
  as: :authenticate_resource_owner,
168
190
  default: (lambda do |_routes|
169
- logger.warn(I18n.translate('doorkeeper.errors.messages.resource_owner_authenticator_not_configured'))
191
+ ::Rails.logger.warn(
192
+ I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured"),
193
+ )
194
+
170
195
  nil
171
196
  end)
197
+
172
198
  option :admin_authenticator,
173
199
  as: :authenticate_admin,
174
- default: ->(_routes) {}
200
+ default: (lambda do |_routes|
201
+ ::Rails.logger.warn(
202
+ I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured"),
203
+ )
204
+
205
+ head :forbidden
206
+ end)
207
+
175
208
  option :resource_owner_from_credentials,
176
209
  default: (lambda do |_routes|
177
- warn(I18n.translate('doorkeeper.errors.messages.credential_flow_not_configured'))
210
+ ::Rails.logger.warn(
211
+ I18n.t("doorkeeper.errors.messages.credential_flow_not_configured"),
212
+ )
213
+
178
214
  nil
179
215
  end)
180
216
 
217
+ # Hooks for authorization
218
+ option :before_successful_authorization, default: ->(_controller, _context = nil) {}
219
+ option :after_successful_authorization, default: ->(_controller, _context = nil) {}
220
+ # Hooks for strategies responses
221
+ option :before_successful_strategy_response, default: ->(_request) {}
222
+ option :after_successful_strategy_response, default: ->(_request, _response) {}
223
+ # Allows to customize Token Introspection response
224
+ option :custom_introspection_response, default: ->(_token, _context) { {} }
225
+
181
226
  option :skip_authorization, default: ->(_routes) {}
182
227
  option :access_token_expires_in, default: 7200
183
- option :custom_access_token_expires_in, default: ->(_app) { nil }
228
+ option :custom_access_token_expires_in, default: ->(_context) { nil }
184
229
  option :authorization_code_expires_in, default: 600
185
230
  option :orm, default: :active_record
186
- option :native_redirect_uri, default: 'urn:ietf:wg:oauth:2.0:oob'
187
- option :active_record_options, default: {}
188
- option :realm, default: 'Doorkeeper'
231
+ option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob", deprecated: true
232
+ option :grant_flows, default: %w[authorization_code client_credentials]
233
+ option :handle_auth_errors, default: :render
234
+ option :token_lookup_batch_size, default: 10_000
235
+ # Sets the token_reuse_limit
236
+ # It will be used only when reuse_access_token option in enabled
237
+ # By default it will be 100
238
+ # It will be used for token reusablity to some threshold percentage
239
+ # Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
240
+ option :token_reuse_limit, default: 100
241
+
242
+ # Don't require client authentication for password grants. If client credentials
243
+ # are present they will still be validated, and the grant rejected if the credentials
244
+ # are invalid.
245
+ #
246
+ # This is discouraged. Spec says that password grants always require a client.
247
+ #
248
+ # See https://github.com/doorkeeper-gem/doorkeeper/issues/1412#issuecomment-632750422
249
+ # and https://github.com/doorkeeper-gem/doorkeeper/pull/1420
250
+ #
251
+ # Since many applications use this unsafe behavior in the wild, this is kept as a
252
+ # not-recommended option. You should be aware that you are not following the OAuth
253
+ # spec, and understand the security implications of doing so.
254
+ option :skip_client_authentication_for_password_grant,
255
+ default: false
256
+
257
+ # Hook to allow arbitrary user-client authorization
258
+ option :authorize_resource_owner_for_client,
259
+ default: ->(_client, _resource_owner) { true }
260
+
261
+ # Allows to customize OAuth grant flows that +each+ application support.
262
+ # You can configure a custom block (or use a class respond to `#call`) that must
263
+ # return `true` in case Application instance supports requested OAuth grant flow
264
+ # during the authorization request to the server. This configuration +doesn't+
265
+ # set flows per application, it only allows to check if application supports
266
+ # specific grant flow.
267
+ #
268
+ # For example you can add an additional database column to `oauth_applications` table,
269
+ # say `t.array :grant_flows, default: []`, and store allowed grant flows that can
270
+ # be used with this application there. Then when authorization requested Doorkeeper
271
+ # will call this block to check if specific Application (passed with client_id and/or
272
+ # client_secret) is allowed to perform the request for the specific grant type
273
+ # (authorization, password, client_credentials, etc).
274
+ #
275
+ # Example of the block:
276
+ #
277
+ # ->(flow, client) { client.grant_flows.include?(flow) }
278
+ #
279
+ # In case this option invocation result is `false`, Doorkeeper server returns
280
+ # :unauthorized_client error and stops the request.
281
+ #
282
+ # @param allow_grant_flow_for_client [Proc] Block or any object respond to #call
283
+ # @return [Boolean] `true` if allow or `false` if forbid the request
284
+ #
285
+ option :allow_grant_flow_for_client, default: ->(_grant_flow, _client) { true }
286
+
287
+ # Allows to forbid specific Application redirect URI's by custom rules.
288
+ # Doesn't forbid any URI by default.
289
+ #
290
+ # @param forbid_redirect_uri [Proc] Block or any object respond to #call
291
+ #
292
+ option :forbid_redirect_uri, default: ->(_uri) { false }
293
+
294
+ # WWW-Authenticate Realm (default "Doorkeeper").
295
+ #
296
+ # @param realm [String] ("Doorkeeper") Authentication realm
297
+ #
298
+ option :realm, default: "Doorkeeper"
299
+
300
+ # Forces the usage of the HTTPS protocol in non-native redirect uris
301
+ # (enabled by default in non-development environments). OAuth2
302
+ # delegates security in communication to the HTTPS protocol so it is
303
+ # wise to keep this enabled.
304
+ #
305
+ # @param [Boolean] boolean_or_block value for the parameter, true by default in
306
+ # non-development environment
307
+ #
308
+ # @yield [uri] Conditional usage of SSL redirect uris.
309
+ # @yieldparam [URI] Redirect URI
310
+ # @yieldreturn [Boolean] Indicates necessity of usage of the HTTPS protocol
311
+ # in non-native redirect uris
312
+ #
189
313
  option :force_ssl_in_redirect_uri, default: !Rails.env.development?
190
- option :grant_flows, default: %w(authorization_code client_credentials)
314
+
315
+ # Use a custom class for generating the access token.
316
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-access-token-generator
317
+ #
318
+ # @param access_token_generator [String]
319
+ # the name of the access token generator class
320
+ #
191
321
  option :access_token_generator,
192
- default: 'Doorkeeper::OAuth::Helpers::UniqueToken'
322
+ default: "Doorkeeper::OAuth::Helpers::UniqueToken"
323
+
324
+ # Allows additional data to be received when granting access to an Application, and for this
325
+ # additional data to be sent with subsequently generated access tokens. The access grant and
326
+ # access token models will both need to respond to the specified attribute names.
327
+ #
328
+ # @param attributes [Array] The array of custom attribute names to be saved
329
+ #
330
+ option :custom_access_token_attributes,
331
+ default: []
332
+
333
+ # Use a custom class for generating the application secret.
334
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-application-secret-generator
335
+ #
336
+ # @param application_secret_generator [String]
337
+ # the name of the application secret generator class
338
+ #
339
+ option :application_secret_generator,
340
+ default: "Doorkeeper::OAuth::Helpers::UniqueToken"
341
+
342
+ # Default access token generator is a SecureRandom class from Ruby stdlib.
343
+ # This option defines which method will be used to generate a unique token value.
344
+ #
345
+ # @param default_generator_method [Symbol]
346
+ # the method name of the default access token generator
347
+ #
348
+ option :default_generator_method, default: :urlsafe_base64
349
+
350
+ # The controller Doorkeeper::ApplicationController inherits from.
351
+ # Defaults to ActionController::Base.
352
+ # https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
353
+ #
354
+ # @param base_controller [String] the name of the base controller
193
355
  option :base_controller,
194
- default: 'ActionController::Base'
356
+ default: (lambda do
357
+ api_only ? "ActionController::API" : "ActionController::Base"
358
+ end)
195
359
 
196
- attr_reader :reuse_access_token
360
+ # The controller Doorkeeper::ApplicationMetalController inherits from.
361
+ # Defaults to ActionController::API.
362
+ #
363
+ # @param base_metal_controller [String] the name of the base controller
364
+ option :base_metal_controller,
365
+ default: "ActionController::API"
366
+
367
+ option :access_token_class,
368
+ default: "Doorkeeper::AccessToken"
369
+
370
+ option :access_grant_class,
371
+ default: "Doorkeeper::AccessGrant"
372
+
373
+ option :application_class,
374
+ default: "Doorkeeper::Application"
375
+
376
+ # Allows to set blank redirect URIs for Applications in case
377
+ # server configured to use URI-less grant flows.
378
+ #
379
+ option :allow_blank_redirect_uri,
380
+ default: (lambda do |grant_flows, _application|
381
+ grant_flows.exclude?("authorization_code") &&
382
+ grant_flows.exclude?("implicit")
383
+ end)
384
+
385
+ # Configure protection of token introspection request.
386
+ # By default this configuration allows to introspect a token by
387
+ # another token of the same application, or to introspect the token
388
+ # that belongs to authorized client, or access token has been introspected
389
+ # is a public one (doesn't belong to any client)
390
+ #
391
+ # You can define any custom rule you need or just disable token
392
+ # introspection at all.
393
+ #
394
+ # @param token [Doorkeeper::AccessToken]
395
+ # token to be introspected
396
+ #
397
+ # @param authorized_client [Doorkeeper::Application]
398
+ # authorized client (if request is authorized using Basic auth with
399
+ # Client Credentials for example)
400
+ #
401
+ # @param authorized_token [Doorkeeper::AccessToken]
402
+ # Bearer token used to authorize the request
403
+ #
404
+ option :allow_token_introspection,
405
+ default: (lambda do |token, authorized_client, authorized_token|
406
+ if authorized_token
407
+ authorized_token.application == token&.application
408
+ elsif token.application
409
+ authorized_client == token.application
410
+ else
411
+ true
412
+ end
413
+ end)
414
+
415
+ attr_reader :reuse_access_token,
416
+ :token_secret_fallback_strategy,
417
+ :application_secret_fallback_strategy
418
+
419
+ def clear_cache!
420
+ %i[
421
+ application_model
422
+ access_token_model
423
+ access_grant_model
424
+ ].each do |var|
425
+ remove_instance_variable("@#{var}") if instance_variable_defined?("@#{var}")
426
+ end
427
+ end
428
+
429
+ # Doorkeeper Access Token model class.
430
+ #
431
+ # @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
432
+ #
433
+ def access_token_model
434
+ @access_token_model ||= access_token_class.constantize
435
+ end
436
+
437
+ # Doorkeeper Access Grant model class.
438
+ #
439
+ # @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
440
+ #
441
+ def access_grant_model
442
+ @access_grant_model ||= access_grant_class.constantize
443
+ end
444
+
445
+ # Doorkeeper Application model class.
446
+ #
447
+ # @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
448
+ #
449
+ def application_model
450
+ @application_model ||= application_class.constantize
451
+ end
452
+
453
+ def api_only
454
+ @api_only ||= false
455
+ end
456
+
457
+ def enforce_content_type
458
+ @enforce_content_type ||= false
459
+ end
197
460
 
198
461
  def refresh_token_enabled?
199
- @refresh_token_enabled ||= false
200
- !!@refresh_token_enabled
462
+ if defined?(@refresh_token_enabled)
463
+ @refresh_token_enabled
464
+ else
465
+ false
466
+ end
467
+ end
468
+
469
+ def resolve_controller(name)
470
+ config_option = public_send(:"#{name}_controller")
471
+ controller_name = if config_option.respond_to?(:call)
472
+ instance_exec(&config_option)
473
+ else
474
+ config_option
475
+ end
476
+
477
+ controller_name.constantize
478
+ end
479
+
480
+ def revoke_previous_client_credentials_token?
481
+ option_set? :revoke_previous_client_credentials_token
482
+ end
483
+
484
+ def enforce_configured_scopes?
485
+ option_set? :enforce_configured_scopes
201
486
  end
202
487
 
203
488
  def enable_application_owner?
204
- @enable_application_owner ||= false
205
- !!@enable_application_owner
489
+ option_set? :enable_application_owner
490
+ end
491
+
492
+ def polymorphic_resource_owner?
493
+ option_set? :polymorphic_resource_owner
206
494
  end
207
495
 
208
496
  def confirm_application_owner?
209
- @confirm_application_owner ||= false
210
- !!@confirm_application_owner
497
+ option_set? :confirm_application_owner
498
+ end
499
+
500
+ def raise_on_errors?
501
+ handle_auth_errors == :raise
502
+ end
503
+
504
+ def redirect_on_errors?
505
+ handle_auth_errors == :redirect
506
+ end
507
+
508
+ def application_secret_hashed?
509
+ instance_variable_defined?(:"@application_secret_strategy")
510
+ end
511
+
512
+ def token_secret_strategy
513
+ @token_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
514
+ end
515
+
516
+ def application_secret_strategy
517
+ @application_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
211
518
  end
212
519
 
213
520
  def default_scopes
@@ -222,41 +529,130 @@ doorkeeper.
222
529
  @scopes ||= default_scopes + optional_scopes
223
530
  end
224
531
 
532
+ def scopes_by_grant_type
533
+ @scopes_by_grant_type ||= {}
534
+ end
535
+
225
536
  def client_credentials_methods
226
- @client_credentials ||= [:from_basic, :from_params]
537
+ @client_credentials_methods ||= %i[from_basic from_params]
227
538
  end
228
539
 
229
540
  def access_token_methods
230
- @access_token_methods ||= [:from_bearer_authorization, :from_access_token_param, :from_bearer_param]
541
+ @access_token_methods ||= %i[
542
+ from_bearer_authorization
543
+ from_access_token_param
544
+ from_bearer_param
545
+ ]
546
+ end
547
+
548
+ def enabled_grant_flows
549
+ @enabled_grant_flows ||= calculate_grant_flows.map { |name| Doorkeeper::GrantFlow.get(name) }.compact
550
+ end
551
+
552
+ def authorization_response_flows
553
+ @authorization_response_flows ||= enabled_grant_flows.select(&:handles_response_type?) +
554
+ deprecated_authorization_flows
555
+ end
556
+
557
+ def token_grant_flows
558
+ @token_grant_flows ||= calculate_token_grant_flows
231
559
  end
232
560
 
233
561
  def authorization_response_types
234
- @authorization_response_types ||= calculate_authorization_response_types
562
+ authorization_response_flows.map(&:response_type_matches)
235
563
  end
236
564
 
237
565
  def token_grant_types
238
- @token_grant_types ||= calculate_token_grant_types
566
+ token_grant_flows.map(&:grant_type_matches)
239
567
  end
240
568
 
241
- private
569
+ # [NOTE]: deprecated and will be removed soon
570
+ def deprecated_token_grant_types_resolver
571
+ @deprecated_token_grant_types ||= calculate_token_grant_types
572
+ end
573
+
574
+ def native_authorization_code_route
575
+ @use_url_path_for_native_authorization = false unless defined?(@use_url_path_for_native_authorization)
576
+ @use_url_path_for_native_authorization ? '/:code' : '/native'
577
+ end
242
578
 
243
- # Determines what values are acceptable for 'response_type' param in
244
- # authorization request endpoint, and return them as an array of strings.
245
- #
579
+ # [NOTE]: deprecated and will be removed soon
580
+ def deprecated_authorization_flows
581
+ response_types = calculate_authorization_response_types
582
+
583
+ if response_types.any?
584
+ ::Kernel.warn <<~WARNING
585
+ Please, don't patch Doorkeeper::Config#calculate_authorization_response_types method.
586
+ Register your custom grant flows using the public API:
587
+ `Doorkeeper::GrantFlow.register(grant_flow_name, **options)`.
588
+ WARNING
589
+ end
590
+
591
+ response_types.map do |response_type|
592
+ Doorkeeper::GrantFlow::FallbackFlow.new(response_type, response_type_matches: response_type)
593
+ end
594
+ end
595
+
596
+ # [NOTE]: deprecated and will be removed soon
246
597
  def calculate_authorization_response_types
247
- types = []
248
- types << 'code' if grant_flows.include? 'authorization_code'
249
- types << 'token' if grant_flows.include? 'implicit'
250
- types
598
+ []
251
599
  end
252
600
 
253
- # Determines what values are acceptable for 'grant_type' param token
254
- # request endpoint, and return them in array.
255
- #
601
+ # [NOTE]: deprecated and will be removed soon
256
602
  def calculate_token_grant_types
257
- types = grant_flows - ['implicit']
258
- types << 'refresh_token' if refresh_token_enabled?
603
+ types = grant_flows - ["implicit"]
604
+ types << "refresh_token" if refresh_token_enabled?
259
605
  types
260
606
  end
607
+
608
+ # Calculates grant flows configured by the user in Doorkeeper
609
+ # configuration considering registered aliases that is exposed
610
+ # to single or multiple other flows.
611
+ #
612
+ def calculate_grant_flows
613
+ configured_flows = grant_flows.map(&:to_s)
614
+ aliases = Doorkeeper::GrantFlow.aliases.keys.map(&:to_s)
615
+
616
+ flows = configured_flows - aliases
617
+ aliases.each do |flow_alias|
618
+ next unless configured_flows.include?(flow_alias)
619
+
620
+ flows.concat(Doorkeeper::GrantFlow.expand_alias(flow_alias))
621
+ end
622
+
623
+ flows.flatten.uniq
624
+ end
625
+
626
+ def allow_blank_redirect_uri?(application = nil)
627
+ if allow_blank_redirect_uri.respond_to?(:call)
628
+ allow_blank_redirect_uri.call(grant_flows, application)
629
+ else
630
+ allow_blank_redirect_uri
631
+ end
632
+ end
633
+
634
+ def allow_grant_flow_for_client?(grant_flow, client)
635
+ return true unless option_defined?(:allow_grant_flow_for_client)
636
+
637
+ allow_grant_flow_for_client.call(grant_flow, client)
638
+ end
639
+
640
+ def option_defined?(name)
641
+ instance_variable_defined?("@#{name}")
642
+ end
643
+
644
+ private
645
+
646
+ # Helper to read boolearized configuration option
647
+ def option_set?(instance_key)
648
+ var = instance_variable_get("@#{instance_key}")
649
+ !!(defined?(var) && var)
650
+ end
651
+
652
+ def calculate_token_grant_flows
653
+ flows = enabled_grant_flows.select(&:handles_grant_type?)
654
+ flows << Doorkeeper::GrantFlow.get("refresh_token") if refresh_token_enabled?
655
+ flows
656
+ end
261
657
  end
262
658
  end