super-smart-kit 0.0.1

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