doorkeeper 5.2.2 → 5.5.4
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of doorkeeper might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/CHANGELOG.md +198 -3
- data/README.md +28 -20
- data/app/controllers/doorkeeper/application_controller.rb +3 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
- data/app/controllers/doorkeeper/applications_controller.rb +7 -8
- data/app/controllers/doorkeeper/authorizations_controller.rb +48 -18
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +6 -6
- data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +70 -25
- data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
- data/app/views/doorkeeper/applications/_form.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +35 -14
- data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +2 -0
- data/config/locales/en.yml +9 -2
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +26 -14
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +214 -122
- data/lib/doorkeeper/engine.rb +1 -1
- data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
- data/lib/doorkeeper/grant_flow/flow.rb +44 -0
- data/lib/doorkeeper/grant_flow/registry.rb +50 -0
- data/lib/doorkeeper/grant_flow.rb +45 -0
- data/lib/doorkeeper/grape/helpers.rb +2 -2
- data/lib/doorkeeper/helpers/controller.rb +18 -12
- data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
- data/lib/doorkeeper/models/access_token_mixin.rb +157 -55
- data/lib/doorkeeper/models/application_mixin.rb +8 -7
- data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
- data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
- data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
- data/lib/doorkeeper/oauth/authorization/code.rb +22 -9
- data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/token.rb +23 -18
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +30 -20
- data/lib/doorkeeper/oauth/base_request.rb +19 -23
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
- data/lib/doorkeeper/oauth/client.rb +8 -9
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +38 -12
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +7 -5
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +4 -4
- data/lib/doorkeeper/oauth/code_response.rb +24 -14
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +10 -11
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +10 -7
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -19
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
- data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
- data/lib/doorkeeper/oauth/password_access_token_request.rb +28 -10
- data/lib/doorkeeper/oauth/pre_authorization.rb +73 -37
- data/lib/doorkeeper/oauth/refresh_token_request.rb +35 -26
- data/lib/doorkeeper/oauth/token.rb +6 -7
- data/lib/doorkeeper/oauth/token_introspection.rb +12 -16
- data/lib/doorkeeper/oauth/token_request.rb +3 -3
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
- data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
- data/lib/doorkeeper/orm/active_record/application.rb +5 -95
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +60 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +199 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +8 -3
- data/lib/doorkeeper/orm/active_record.rb +5 -7
- data/lib/doorkeeper/rails/helpers.rb +4 -4
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/rails/routes.rb +17 -25
- data/lib/doorkeeper/rake/db.rake +6 -6
- data/lib/doorkeeper/rake/setup.rake +5 -0
- data/lib/doorkeeper/request/authorization_code.rb +3 -3
- data/lib/doorkeeper/request/client_credentials.rb +2 -2
- data/lib/doorkeeper/request/password.rb +3 -2
- data/lib/doorkeeper/request/refresh_token.rb +5 -4
- data/lib/doorkeeper/request/strategy.rb +2 -2
- data/lib/doorkeeper/request.rb +49 -12
- data/lib/doorkeeper/server.rb +5 -5
- data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
- data/lib/doorkeeper/version.rb +2 -6
- data/lib/doorkeeper.rb +112 -81
- data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/migration_generator.rb +1 -1
- data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +99 -14
- data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
- metadata +37 -306
- data/Appraisals +0 -40
- data/CODE_OF_CONDUCT.md +0 -46
- data/CONTRIBUTING.md +0 -49
- data/Dangerfile +0 -67
- data/Dockerfile +0 -29
- data/Gemfile +0 -25
- data/NEWS.md +0 -1
- data/RELEASING.md +0 -11
- data/Rakefile +0 -28
- data/SECURITY.md +0 -15
- data/UPGRADE.md +0 -2
- data/bin/console +0 -16
- data/doorkeeper.gemspec +0 -42
- data/gemfiles/rails_5_0.gemfile +0 -18
- data/gemfiles/rails_5_1.gemfile +0 -18
- data/gemfiles/rails_5_2.gemfile +0 -18
- data/gemfiles/rails_6_0.gemfile +0 -18
- data/gemfiles/rails_master.gemfile +0 -18
- data/spec/controllers/application_metal_controller_spec.rb +0 -64
- data/spec/controllers/applications_controller_spec.rb +0 -273
- data/spec/controllers/authorizations_controller_spec.rb +0 -608
- data/spec/controllers/protected_resources_controller_spec.rb +0 -353
- data/spec/controllers/token_info_controller_spec.rb +0 -50
- data/spec/controllers/tokens_controller_spec.rb +0 -498
- data/spec/dummy/Rakefile +0 -9
- data/spec/dummy/app/assets/config/manifest.js +0 -2
- data/spec/dummy/app/controllers/application_controller.rb +0 -5
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
- data/spec/dummy/app/controllers/home_controller.rb +0 -18
- data/spec/dummy/app/controllers/metal_controller.rb +0 -13
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
- data/spec/dummy/app/helpers/application_helper.rb +0 -7
- data/spec/dummy/app/models/user.rb +0 -7
- data/spec/dummy/app/views/home/index.html.erb +0 -0
- data/spec/dummy/app/views/layouts/application.html.erb +0 -14
- data/spec/dummy/config/application.rb +0 -49
- data/spec/dummy/config/boot.rb +0 -7
- data/spec/dummy/config/database.yml +0 -15
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -31
- data/spec/dummy/config/environments/production.rb +0 -64
- data/spec/dummy/config/environments/test.rb +0 -45
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
- data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
- data/spec/dummy/config/initializers/secret_token.rb +0 -10
- data/spec/dummy/config/initializers/session_store.rb +0 -10
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
- data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -13
- data/spec/dummy/config.ru +0 -6
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
- data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
- data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
- data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
- data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
- data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
- data/spec/dummy/db/schema.rb +0 -68
- data/spec/dummy/public/404.html +0 -26
- data/spec/dummy/public/422.html +0 -26
- data/spec/dummy/public/500.html +0 -26
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/dummy/script/rails +0 -9
- data/spec/factories.rb +0 -30
- data/spec/generators/application_owner_generator_spec.rb +0 -28
- data/spec/generators/confidential_applications_generator_spec.rb +0 -29
- data/spec/generators/install_generator_spec.rb +0 -36
- data/spec/generators/migration_generator_spec.rb +0 -28
- data/spec/generators/pkce_generator_spec.rb +0 -28
- data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
- data/spec/generators/templates/routes.rb +0 -4
- data/spec/generators/views_generator_spec.rb +0 -29
- data/spec/grape/grape_integration_spec.rb +0 -137
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
- data/spec/lib/config_spec.rb +0 -739
- data/spec/lib/doorkeeper_spec.rb +0 -27
- data/spec/lib/models/expirable_spec.rb +0 -61
- data/spec/lib/models/reusable_spec.rb +0 -40
- data/spec/lib/models/revocable_spec.rb +0 -59
- data/spec/lib/models/scopes_spec.rb +0 -53
- data/spec/lib/models/secret_storable_spec.rb +0 -135
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -168
- data/spec/lib/oauth/base_request_spec.rb +0 -222
- data/spec/lib/oauth/base_response_spec.rb +0 -47
- data/spec/lib/oauth/client/credentials_spec.rb +0 -90
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -97
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
- data/spec/lib/oauth/client_spec.rb +0 -38
- data/spec/lib/oauth/code_request_spec.rb +0 -46
- data/spec/lib/oauth/code_response_spec.rb +0 -36
- data/spec/lib/oauth/error_response_spec.rb +0 -66
- data/spec/lib/oauth/error_spec.rb +0 -23
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
- data/spec/lib/oauth/invalid_request_response_spec.rb +0 -75
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -225
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -178
- data/spec/lib/oauth/scopes_spec.rb +0 -148
- data/spec/lib/oauth/token_request_spec.rb +0 -153
- data/spec/lib/oauth/token_response_spec.rb +0 -86
- data/spec/lib/oauth/token_spec.rb +0 -158
- data/spec/lib/request/strategy_spec.rb +0 -54
- data/spec/lib/secret_storing/base_spec.rb +0 -60
- data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
- data/spec/lib/secret_storing/plain_spec.rb +0 -44
- data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
- data/spec/lib/server_spec.rb +0 -49
- data/spec/lib/stale_records_cleaner_spec.rb +0 -89
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -163
- data/spec/models/doorkeeper/access_token_spec.rb +0 -622
- data/spec/models/doorkeeper/application_spec.rb +0 -377
- data/spec/requests/applications/applications_request_spec.rb +0 -259
- data/spec/requests/applications/authorized_applications_spec.rb +0 -32
- data/spec/requests/endpoints/authorization_spec.rb +0 -89
- data/spec/requests/endpoints/token_spec.rb +0 -75
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
- data/spec/requests/flows/authorization_code_spec.rb +0 -513
- data/spec/requests/flows/client_credentials_spec.rb +0 -166
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
- data/spec/requests/flows/implicit_grant_spec.rb +0 -91
- data/spec/requests/flows/password_spec.rb +0 -296
- data/spec/requests/flows/refresh_token_spec.rb +0 -233
- data/spec/requests/flows/revoke_token_spec.rb +0 -151
- data/spec/requests/flows/skip_authorization_spec.rb +0 -66
- data/spec/requests/protected_resources/metal_spec.rb +0 -16
- data/spec/requests/protected_resources/private_api_spec.rb +0 -83
- data/spec/routing/custom_controller_routes_spec.rb +0 -133
- data/spec/routing/default_routes_spec.rb +0 -41
- data/spec/routing/scoped_routes_spec.rb +0 -47
- data/spec/spec_helper.rb +0 -57
- data/spec/spec_helper_integration.rb +0 -4
- data/spec/support/dependencies/factory_bot.rb +0 -4
- data/spec/support/doorkeeper_rspec.rb +0 -22
- data/spec/support/helpers/access_token_request_helper.rb +0 -13
- data/spec/support/helpers/authorization_request_helper.rb +0 -43
- data/spec/support/helpers/config_helper.rb +0 -11
- data/spec/support/helpers/model_helper.rb +0 -78
- data/spec/support/helpers/request_spec_helper.rb +0 -110
- data/spec/support/helpers/url_helper.rb +0 -62
- data/spec/support/http_method_shim.rb +0 -29
- data/spec/support/orm/active_record.rb +0 -5
- data/spec/support/shared/controllers_shared_context.rb +0 -123
- data/spec/support/shared/hashing_shared_context.rb +0 -36
- data/spec/support/shared/models_shared_examples.rb +0 -54
- data/spec/validators/redirect_uri_validator_spec.rb +0 -183
- data/spec/version/version_spec.rb +0 -17
data/lib/doorkeeper/config.rb
CHANGED
@@ -1,60 +1,66 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
+
require "doorkeeper/config/abstract_builder"
|
3
4
|
require "doorkeeper/config/option"
|
5
|
+
require "doorkeeper/config/validations"
|
4
6
|
|
5
7
|
module Doorkeeper
|
8
|
+
# Defines a MissingConfiguration error for a missing Doorkeeper configuration
|
9
|
+
#
|
6
10
|
class MissingConfiguration < StandardError
|
7
|
-
# Defines a MissingConfiguration error for a missing Doorkeeper
|
8
|
-
# configuration
|
9
11
|
def initialize
|
10
12
|
super("Configuration for doorkeeper missing. Do you have doorkeeper initializer?")
|
11
13
|
end
|
12
14
|
end
|
13
15
|
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
16
|
+
# Doorkeeper option DSL could be reused in extensions to build their own
|
17
|
+
# configurations. To use the Option DSL gems need to define `builder_class` method
|
18
|
+
# that returns configuration Builder class. This exception raises when they don't
|
19
|
+
# define it.
|
20
|
+
#
|
21
|
+
class MissingConfigurationBuilderClass < StandardError; end
|
22
|
+
|
23
|
+
class << self
|
24
|
+
def configure(&block)
|
25
|
+
@config = Config::Builder.new(&block).build
|
26
|
+
setup_orm_adapter
|
27
|
+
setup_orm_models
|
28
|
+
setup_application_owner if @config.enable_application_owner?
|
29
|
+
@config
|
30
|
+
end
|
21
31
|
|
22
|
-
|
23
|
-
|
24
|
-
|
32
|
+
# @return [Doorkeeper::Config] configuration instance
|
33
|
+
#
|
34
|
+
def configuration
|
35
|
+
@config || (raise MissingConfiguration)
|
36
|
+
end
|
25
37
|
|
26
|
-
|
27
|
-
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
28
|
-
rescue NameError => e
|
29
|
-
raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
|
30
|
-
[doorkeeper] ORM adapter not found (#{configuration.orm}), or there was an error
|
31
|
-
trying to load it.
|
38
|
+
alias config configuration
|
32
39
|
|
33
|
-
|
34
|
-
doorkeeper.
|
35
|
-
|
36
|
-
|
40
|
+
def setup_orm_adapter
|
41
|
+
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
42
|
+
rescue NameError => e
|
43
|
+
raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
|
44
|
+
[DOORKEEPER] ORM adapter not found (#{configuration.orm}), or there was an error
|
45
|
+
trying to load it.
|
37
46
|
|
38
|
-
|
39
|
-
|
40
|
-
|
47
|
+
You probably need to add the related gem for this adapter to work with
|
48
|
+
doorkeeper.
|
49
|
+
ERROR_MSG
|
50
|
+
end
|
51
|
+
|
52
|
+
def setup_orm_models
|
53
|
+
@orm_adapter.initialize_models!
|
54
|
+
end
|
41
55
|
|
42
|
-
|
43
|
-
|
56
|
+
def setup_application_owner
|
57
|
+
@orm_adapter.initialize_application_owner!
|
58
|
+
end
|
44
59
|
end
|
45
60
|
|
46
61
|
class Config
|
47
|
-
|
48
|
-
|
49
|
-
@config = Config.new
|
50
|
-
instance_eval(&block)
|
51
|
-
end
|
52
|
-
|
53
|
-
def build
|
54
|
-
@config.validate
|
55
|
-
@config
|
56
|
-
end
|
57
|
-
|
62
|
+
# Default Doorkeeper configuration builder
|
63
|
+
class Builder < AbstractBuilder
|
58
64
|
# Provide support for an owner to be assigned to each registered
|
59
65
|
# application (disabled by default)
|
60
66
|
# Optional parameter confirmation: true (default false) if you want
|
@@ -120,7 +126,7 @@ module Doorkeeper
|
|
120
126
|
def use_refresh_token(enabled = true, &block)
|
121
127
|
@config.instance_variable_set(
|
122
128
|
:@refresh_token_enabled,
|
123
|
-
block || enabled
|
129
|
+
block || enabled,
|
124
130
|
)
|
125
131
|
end
|
126
132
|
|
@@ -131,13 +137,12 @@ module Doorkeeper
|
|
131
137
|
@config.instance_variable_set(:@reuse_access_token, true)
|
132
138
|
end
|
133
139
|
|
134
|
-
#
|
135
|
-
#
|
136
|
-
#
|
137
|
-
#
|
138
|
-
|
139
|
-
|
140
|
-
@config.instance_variable_set(:@token_reuse_limit, percentage)
|
140
|
+
# TODO: maybe make it more generic for other flows too?
|
141
|
+
# Only allow one valid access token obtained via client credentials
|
142
|
+
# per client. If a new access token is obtained before the old one
|
143
|
+
# expired, the old one gets revoked (disabled by default)
|
144
|
+
def revoke_previous_client_credentials_token
|
145
|
+
@config.instance_variable_set(:@revoke_previous_client_credentials_token, true)
|
141
146
|
end
|
142
147
|
|
143
148
|
# Use an API mode for applications generated with --api argument
|
@@ -146,6 +151,12 @@ module Doorkeeper
|
|
146
151
|
@config.instance_variable_set(:@api_only, true)
|
147
152
|
end
|
148
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
|
+
|
149
160
|
# Forbids creating/updating applications with arbitrary scopes that are
|
150
161
|
# not in configuration, i.e. `default_scopes` or `optional_scopes`.
|
151
162
|
# (disabled by default)
|
@@ -195,8 +206,7 @@ module Doorkeeper
|
|
195
206
|
def configure_secrets_for(type, using:, fallback:)
|
196
207
|
raise ArgumentError, "Invalid type #{type}" if %i[application token].exclude?(type)
|
197
208
|
|
198
|
-
@config.instance_variable_set(:"@#{type}_secret_strategy",
|
199
|
-
using.constantize)
|
209
|
+
@config.instance_variable_set(:"@#{type}_secret_strategy", using.constantize)
|
200
210
|
|
201
211
|
if fallback.nil?
|
202
212
|
return
|
@@ -204,18 +214,21 @@ module Doorkeeper
|
|
204
214
|
fallback = "::Doorkeeper::SecretStoring::Plain"
|
205
215
|
end
|
206
216
|
|
207
|
-
@config.instance_variable_set(:"@#{type}_secret_fallback_strategy",
|
208
|
-
fallback.constantize)
|
217
|
+
@config.instance_variable_set(:"@#{type}_secret_fallback_strategy", fallback.constantize)
|
209
218
|
end
|
210
219
|
end
|
211
220
|
|
221
|
+
# Replace with `default: Builder` when we drop support of Rails < 5.2
|
222
|
+
mattr_reader(:builder_class) { Builder }
|
223
|
+
|
212
224
|
extend Option
|
225
|
+
include Validations
|
213
226
|
|
214
227
|
option :resource_owner_authenticator,
|
215
228
|
as: :authenticate_resource_owner,
|
216
229
|
default: (lambda do |_routes|
|
217
230
|
::Rails.logger.warn(
|
218
|
-
I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured")
|
231
|
+
I18n.t("doorkeeper.errors.messages.resource_owner_authenticator_not_configured"),
|
219
232
|
)
|
220
233
|
|
221
234
|
nil
|
@@ -225,7 +238,7 @@ module Doorkeeper
|
|
225
238
|
as: :authenticate_admin,
|
226
239
|
default: (lambda do |_routes|
|
227
240
|
::Rails.logger.warn(
|
228
|
-
I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured")
|
241
|
+
I18n.t("doorkeeper.errors.messages.admin_authenticator_not_configured"),
|
229
242
|
)
|
230
243
|
|
231
244
|
head :forbidden
|
@@ -234,15 +247,15 @@ module Doorkeeper
|
|
234
247
|
option :resource_owner_from_credentials,
|
235
248
|
default: (lambda do |_routes|
|
236
249
|
::Rails.logger.warn(
|
237
|
-
I18n.t("doorkeeper.errors.messages.credential_flow_not_configured")
|
250
|
+
I18n.t("doorkeeper.errors.messages.credential_flow_not_configured"),
|
238
251
|
)
|
239
252
|
|
240
253
|
nil
|
241
254
|
end)
|
242
255
|
|
243
256
|
# Hooks for authorization
|
244
|
-
option :before_successful_authorization, default: ->(_context) {}
|
245
|
-
option :after_successful_authorization, default: ->(_context) {}
|
257
|
+
option :before_successful_authorization, default: ->(_controller, _context = nil) {}
|
258
|
+
option :after_successful_authorization, default: ->(_controller, _context = nil) {}
|
246
259
|
# Hooks for strategies responses
|
247
260
|
option :before_successful_strategy_response, default: ->(_request) {}
|
248
261
|
option :after_successful_strategy_response, default: ->(_request, _response) {}
|
@@ -255,9 +268,38 @@ module Doorkeeper
|
|
255
268
|
option :authorization_code_expires_in, default: 600
|
256
269
|
option :orm, default: :active_record
|
257
270
|
option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob", deprecated: true
|
258
|
-
option :active_record_options, default: {}
|
259
271
|
option :grant_flows, default: %w[authorization_code client_credentials]
|
260
272
|
option :handle_auth_errors, default: :render
|
273
|
+
option :token_lookup_batch_size, default: 10_000
|
274
|
+
# Sets the token_reuse_limit
|
275
|
+
# It will be used only when reuse_access_token option in enabled
|
276
|
+
# By default it will be 100
|
277
|
+
# It will be used for token reusablity to some threshold percentage
|
278
|
+
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
|
279
|
+
option :token_reuse_limit, default: 100
|
280
|
+
|
281
|
+
# Don't require client authentication for password grants. If client credentials
|
282
|
+
# are present they will still be validated, and the grant rejected if the credentials
|
283
|
+
# are invalid.
|
284
|
+
#
|
285
|
+
# This is discouraged. Spec says that password grants always require a client.
|
286
|
+
#
|
287
|
+
# See https://github.com/doorkeeper-gem/doorkeeper/issues/1412#issuecomment-632750422
|
288
|
+
# and https://github.com/doorkeeper-gem/doorkeeper/pull/1420
|
289
|
+
#
|
290
|
+
# Since many applications use this unsafe behavior in the wild, this is kept as a
|
291
|
+
# not-recommended option. You should be aware that you are not following the OAuth
|
292
|
+
# spec, and understand the security implications of doing so.
|
293
|
+
option :skip_client_authentication_for_password_grant,
|
294
|
+
default: false
|
295
|
+
|
296
|
+
option :active_record_options,
|
297
|
+
default: {},
|
298
|
+
deprecated: { message: "Customize Doorkeeper models instead" }
|
299
|
+
|
300
|
+
# Hook to allow arbitrary user-client authorization
|
301
|
+
option :authorize_resource_owner_for_client,
|
302
|
+
default: ->(_client, _resource_owner) { true }
|
261
303
|
|
262
304
|
# Allows to customize OAuth grant flows that +each+ application support.
|
263
305
|
# You can configure a custom block (or use a class respond to `#call`) that must
|
@@ -332,7 +374,7 @@ module Doorkeeper
|
|
332
374
|
|
333
375
|
# The controller Doorkeeper::ApplicationController inherits from.
|
334
376
|
# Defaults to ActionController::Base.
|
335
|
-
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-
|
377
|
+
# https://doorkeeper.gitbook.io/guides/configuration/other-configurations#custom-controllers
|
336
378
|
#
|
337
379
|
# @param base_controller [String] the name of the base controller
|
338
380
|
option :base_controller,
|
@@ -347,6 +389,15 @@ module Doorkeeper
|
|
347
389
|
option :base_metal_controller,
|
348
390
|
default: "ActionController::API"
|
349
391
|
|
392
|
+
option :access_token_class,
|
393
|
+
default: "Doorkeeper::AccessToken"
|
394
|
+
|
395
|
+
option :access_grant_class,
|
396
|
+
default: "Doorkeeper::AccessGrant"
|
397
|
+
|
398
|
+
option :application_class,
|
399
|
+
default: "Doorkeeper::Application"
|
400
|
+
|
350
401
|
# Allows to set blank redirect URIs for Applications in case
|
351
402
|
# server configured to use URI-less grant flows.
|
352
403
|
#
|
@@ -386,17 +437,32 @@ module Doorkeeper
|
|
386
437
|
end
|
387
438
|
end)
|
388
439
|
|
389
|
-
attr_reader :
|
390
|
-
:enforce_content_type,
|
391
|
-
:reuse_access_token,
|
440
|
+
attr_reader :reuse_access_token,
|
392
441
|
:token_secret_fallback_strategy,
|
393
442
|
:application_secret_fallback_strategy
|
394
443
|
|
395
|
-
#
|
396
|
-
|
397
|
-
|
398
|
-
|
399
|
-
|
444
|
+
# Doorkeeper Access Token model class.
|
445
|
+
#
|
446
|
+
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
447
|
+
#
|
448
|
+
def access_token_model
|
449
|
+
@access_token_model ||= access_token_class.constantize
|
450
|
+
end
|
451
|
+
|
452
|
+
# Doorkeeper Access Grant model class.
|
453
|
+
#
|
454
|
+
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
455
|
+
#
|
456
|
+
def access_grant_model
|
457
|
+
@access_grant_model ||= access_grant_class.constantize
|
458
|
+
end
|
459
|
+
|
460
|
+
# Doorkeeper Application model class.
|
461
|
+
#
|
462
|
+
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
463
|
+
#
|
464
|
+
def application_model
|
465
|
+
@application_model ||= application_class.constantize
|
400
466
|
end
|
401
467
|
|
402
468
|
def api_only
|
@@ -415,10 +481,6 @@ module Doorkeeper
|
|
415
481
|
end
|
416
482
|
end
|
417
483
|
|
418
|
-
def token_reuse_limit
|
419
|
-
@token_reuse_limit ||= 100
|
420
|
-
end
|
421
|
-
|
422
484
|
def resolve_controller(name)
|
423
485
|
config_option = public_send(:"#{name}_controller")
|
424
486
|
controller_name = if config_option.respond_to?(:call)
|
@@ -430,6 +492,10 @@ module Doorkeeper
|
|
430
492
|
controller_name.constantize
|
431
493
|
end
|
432
494
|
|
495
|
+
def revoke_previous_client_credentials_token?
|
496
|
+
option_set? :revoke_previous_client_credentials_token
|
497
|
+
end
|
498
|
+
|
433
499
|
def enforce_configured_scopes?
|
434
500
|
option_set? :enforce_configured_scopes
|
435
501
|
end
|
@@ -438,6 +504,10 @@ module Doorkeeper
|
|
438
504
|
option_set? :enable_application_owner
|
439
505
|
end
|
440
506
|
|
507
|
+
def polymorphic_resource_owner?
|
508
|
+
option_set? :polymorphic_resource_owner
|
509
|
+
end
|
510
|
+
|
441
511
|
def confirm_application_owner?
|
442
512
|
option_set? :confirm_application_owner
|
443
513
|
end
|
@@ -446,6 +516,10 @@ module Doorkeeper
|
|
446
516
|
handle_auth_errors == :raise
|
447
517
|
end
|
448
518
|
|
519
|
+
def application_secret_hashed?
|
520
|
+
instance_variable_defined?(:"@application_secret_strategy")
|
521
|
+
end
|
522
|
+
|
449
523
|
def token_secret_strategy
|
450
524
|
@token_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
|
451
525
|
end
|
@@ -482,12 +556,77 @@ module Doorkeeper
|
|
482
556
|
]
|
483
557
|
end
|
484
558
|
|
559
|
+
def enabled_grant_flows
|
560
|
+
@enabled_grant_flows ||= calculate_grant_flows.map { |name| Doorkeeper::GrantFlow.get(name) }.compact
|
561
|
+
end
|
562
|
+
|
563
|
+
def authorization_response_flows
|
564
|
+
@authorization_response_flows ||= enabled_grant_flows.select(&:handles_response_type?) +
|
565
|
+
deprecated_authorization_flows
|
566
|
+
end
|
567
|
+
|
568
|
+
def token_grant_flows
|
569
|
+
@token_grant_flows ||= calculate_token_grant_flows
|
570
|
+
end
|
571
|
+
|
485
572
|
def authorization_response_types
|
486
|
-
|
573
|
+
authorization_response_flows.map(&:response_type_matches)
|
487
574
|
end
|
488
575
|
|
489
576
|
def token_grant_types
|
490
|
-
|
577
|
+
token_grant_flows.map(&:grant_type_matches)
|
578
|
+
end
|
579
|
+
|
580
|
+
# [NOTE]: deprecated and will be removed soon
|
581
|
+
def deprecated_token_grant_types_resolver
|
582
|
+
@deprecated_token_grant_types ||= calculate_token_grant_types
|
583
|
+
end
|
584
|
+
|
585
|
+
# [NOTE]: deprecated and will be removed soon
|
586
|
+
def deprecated_authorization_flows
|
587
|
+
response_types = calculate_authorization_response_types
|
588
|
+
|
589
|
+
if response_types.any?
|
590
|
+
::Kernel.warn <<~WARNING
|
591
|
+
Please, don't patch Doorkeeper::Config#calculate_authorization_response_types method.
|
592
|
+
Register your custom grant flows using the public API:
|
593
|
+
`Doorkeeper::GrantFlow.register(grant_flow_name, **options)`.
|
594
|
+
WARNING
|
595
|
+
end
|
596
|
+
|
597
|
+
response_types.map do |response_type|
|
598
|
+
Doorkeeper::GrantFlow::FallbackFlow.new(response_type, response_type_matches: response_type)
|
599
|
+
end
|
600
|
+
end
|
601
|
+
|
602
|
+
# [NOTE]: deprecated and will be removed soon
|
603
|
+
def calculate_authorization_response_types
|
604
|
+
[]
|
605
|
+
end
|
606
|
+
|
607
|
+
# [NOTE]: deprecated and will be removed soon
|
608
|
+
def calculate_token_grant_types
|
609
|
+
types = grant_flows - ["implicit"]
|
610
|
+
types << "refresh_token" if refresh_token_enabled?
|
611
|
+
types
|
612
|
+
end
|
613
|
+
|
614
|
+
# Calculates grant flows configured by the user in Doorkeeper
|
615
|
+
# configuration considering registered aliases that is exposed
|
616
|
+
# to single or multiple other flows.
|
617
|
+
#
|
618
|
+
def calculate_grant_flows
|
619
|
+
configured_flows = grant_flows.map(&:to_s)
|
620
|
+
aliases = Doorkeeper::GrantFlow.aliases.keys.map(&:to_s)
|
621
|
+
|
622
|
+
flows = configured_flows - aliases
|
623
|
+
aliases.each do |flow_alias|
|
624
|
+
next unless configured_flows.include?(flow_alias)
|
625
|
+
|
626
|
+
flows.concat(Doorkeeper::GrantFlow.expand_alias(flow_alias))
|
627
|
+
end
|
628
|
+
|
629
|
+
flows.flatten.uniq
|
491
630
|
end
|
492
631
|
|
493
632
|
def allow_blank_redirect_uri?(application = nil)
|
@@ -516,57 +655,10 @@ module Doorkeeper
|
|
516
655
|
!!(defined?(var) && var)
|
517
656
|
end
|
518
657
|
|
519
|
-
|
520
|
-
|
521
|
-
|
522
|
-
|
523
|
-
types = []
|
524
|
-
types << "code" if grant_flows.include? "authorization_code"
|
525
|
-
types << "token" if grant_flows.include? "implicit"
|
526
|
-
types
|
527
|
-
end
|
528
|
-
|
529
|
-
# Determines what values are acceptable for 'grant_type' param token
|
530
|
-
# request endpoint, and return them in array.
|
531
|
-
#
|
532
|
-
def calculate_token_grant_types
|
533
|
-
types = grant_flows - ["implicit"]
|
534
|
-
types << "refresh_token" if refresh_token_enabled?
|
535
|
-
types
|
536
|
-
end
|
537
|
-
|
538
|
-
# Determine whether +reuse_access_token+ and a non-restorable
|
539
|
-
# +token_secret_strategy+ have both been activated.
|
540
|
-
#
|
541
|
-
# In that case, disable reuse_access_token value and warn the user.
|
542
|
-
def validate_reuse_access_token_value
|
543
|
-
strategy = token_secret_strategy
|
544
|
-
return if !reuse_access_token || strategy.allows_restoring_secrets?
|
545
|
-
|
546
|
-
::Rails.logger.warn(
|
547
|
-
"You have configured both reuse_access_token " \
|
548
|
-
"AND strategy strategy '#{strategy}' that cannot restore tokens. " \
|
549
|
-
"This combination is unsupported. reuse_access_token will be disabled"
|
550
|
-
)
|
551
|
-
@reuse_access_token = false
|
552
|
-
end
|
553
|
-
|
554
|
-
# Validate that the provided strategies are valid for
|
555
|
-
# tokens and applications
|
556
|
-
def validate_secret_strategies
|
557
|
-
token_secret_strategy.validate_for :token
|
558
|
-
application_secret_strategy.validate_for :application
|
559
|
-
end
|
560
|
-
|
561
|
-
def validate_token_reuse_limit
|
562
|
-
return if !reuse_access_token ||
|
563
|
-
(token_reuse_limit > 0 && token_reuse_limit <= 100)
|
564
|
-
|
565
|
-
::Rails.logger.warn(
|
566
|
-
"You have configured an invalid value for token_reuse_limit option. " \
|
567
|
-
"It will be set to default 100"
|
568
|
-
)
|
569
|
-
@token_reuse_limit = 100
|
658
|
+
def calculate_token_grant_flows
|
659
|
+
flows = enabled_grant_flows.select(&:handles_grant_type?)
|
660
|
+
flows << Doorkeeper::GrantFlow.get("refresh_token") if refresh_token_enabled?
|
661
|
+
flows
|
570
662
|
end
|
571
663
|
end
|
572
664
|
end
|
data/lib/doorkeeper/engine.rb
CHANGED
@@ -4,7 +4,7 @@ module Doorkeeper
|
|
4
4
|
class Engine < Rails::Engine
|
5
5
|
initializer "doorkeeper.params.filter" do |app|
|
6
6
|
parameters = %w[client_secret code authentication_token access_token refresh_token]
|
7
|
-
app.config.filter_parameters << /^(#{Regexp.union
|
7
|
+
app.config.filter_parameters << /^(#{Regexp.union(parameters)})$/
|
8
8
|
end
|
9
9
|
|
10
10
|
initializer "doorkeeper.routes" do
|
@@ -0,0 +1,44 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module GrantFlow
|
5
|
+
class Flow
|
6
|
+
attr_reader :name, :grant_type_matches, :grant_type_strategy,
|
7
|
+
:response_type_matches, :response_type_strategy,
|
8
|
+
:response_mode_matches
|
9
|
+
|
10
|
+
def initialize(name, **options)
|
11
|
+
@name = name
|
12
|
+
@grant_type_matches = options[:grant_type_matches]
|
13
|
+
@grant_type_strategy = options[:grant_type_strategy]
|
14
|
+
@response_type_matches = options[:response_type_matches]
|
15
|
+
@response_type_strategy = options[:response_type_strategy]
|
16
|
+
@response_mode_matches = options[:response_mode_matches]
|
17
|
+
end
|
18
|
+
|
19
|
+
def handles_grant_type?
|
20
|
+
grant_type_matches.present?
|
21
|
+
end
|
22
|
+
|
23
|
+
def handles_response_type?
|
24
|
+
response_type_matches.present?
|
25
|
+
end
|
26
|
+
|
27
|
+
def matches_grant_type?(value)
|
28
|
+
grant_type_matches === value
|
29
|
+
end
|
30
|
+
|
31
|
+
def matches_response_type?(value)
|
32
|
+
response_type_matches === value
|
33
|
+
end
|
34
|
+
|
35
|
+
def default_response_mode
|
36
|
+
response_mode_matches[0]
|
37
|
+
end
|
38
|
+
|
39
|
+
def matches_response_mode?(value)
|
40
|
+
response_mode_matches.include?(value)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
@@ -0,0 +1,50 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module GrantFlow
|
5
|
+
module Registry
|
6
|
+
mattr_accessor :flows
|
7
|
+
self.flows = {}
|
8
|
+
|
9
|
+
mattr_accessor :aliases
|
10
|
+
self.aliases = {}
|
11
|
+
|
12
|
+
# Allows to register custom OAuth grant flow so that Doorkeeper
|
13
|
+
# could recognize and process it.
|
14
|
+
#
|
15
|
+
def register(name_or_flow, **options)
|
16
|
+
unless name_or_flow.is_a?(Doorkeeper::GrantFlow::Flow)
|
17
|
+
name_or_flow = Flow.new(name_or_flow, **options)
|
18
|
+
end
|
19
|
+
|
20
|
+
flow_key = name_or_flow.name.to_sym
|
21
|
+
|
22
|
+
if flows.key?(flow_key)
|
23
|
+
::Kernel.warn <<~WARNING
|
24
|
+
[DOORKEEPER] '#{flow_key}' grant flow already registered and will be overridden
|
25
|
+
in #{caller(1..1).first}
|
26
|
+
WARNING
|
27
|
+
end
|
28
|
+
|
29
|
+
flows[flow_key] = name_or_flow
|
30
|
+
end
|
31
|
+
|
32
|
+
# Allows to register aliases that could be used in `grant_flows`
|
33
|
+
# configuration option. It is possible to have aliases like 1:1 or
|
34
|
+
# 1:N, i.e. "implicit_oidc" => ['token', 'id_token', 'id_token token'].
|
35
|
+
#
|
36
|
+
def register_alias(alias_name, **options)
|
37
|
+
aliases[alias_name.to_sym] = Array.wrap(options.fetch(:as))
|
38
|
+
end
|
39
|
+
|
40
|
+
def expand_alias(alias_name)
|
41
|
+
aliases.fetch(alias_name.to_sym, [])
|
42
|
+
end
|
43
|
+
|
44
|
+
# [NOTE]: make it to use #fetch after removing fallbacks
|
45
|
+
def get(name)
|
46
|
+
flows[name.to_sym]
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "doorkeeper/grant_flow/flow"
|
4
|
+
require "doorkeeper/grant_flow/fallback_flow"
|
5
|
+
require "doorkeeper/grant_flow/registry"
|
6
|
+
|
7
|
+
module Doorkeeper
|
8
|
+
module GrantFlow
|
9
|
+
extend Registry
|
10
|
+
|
11
|
+
register(
|
12
|
+
:implicit,
|
13
|
+
response_type_matches: "token",
|
14
|
+
response_mode_matches: %w[fragment form_post],
|
15
|
+
response_type_strategy: Doorkeeper::Request::Token,
|
16
|
+
)
|
17
|
+
|
18
|
+
register(
|
19
|
+
:authorization_code,
|
20
|
+
response_type_matches: "code",
|
21
|
+
response_mode_matches: %w[query fragment form_post],
|
22
|
+
response_type_strategy: Doorkeeper::Request::Code,
|
23
|
+
grant_type_matches: "authorization_code",
|
24
|
+
grant_type_strategy: Doorkeeper::Request::AuthorizationCode,
|
25
|
+
)
|
26
|
+
|
27
|
+
register(
|
28
|
+
:client_credentials,
|
29
|
+
grant_type_matches: "client_credentials",
|
30
|
+
grant_type_strategy: Doorkeeper::Request::ClientCredentials,
|
31
|
+
)
|
32
|
+
|
33
|
+
register(
|
34
|
+
:password,
|
35
|
+
grant_type_matches: "password",
|
36
|
+
grant_type_strategy: Doorkeeper::Request::Password,
|
37
|
+
)
|
38
|
+
|
39
|
+
register(
|
40
|
+
:refresh_token,
|
41
|
+
grant_type_matches: "refresh_token",
|
42
|
+
grant_type_strategy: Doorkeeper::Request::RefreshToken,
|
43
|
+
)
|
44
|
+
end
|
45
|
+
end
|
@@ -18,7 +18,7 @@ module Doorkeeper
|
|
18
18
|
|
19
19
|
scopes = if endpoint_scopes
|
20
20
|
Doorkeeper::OAuth::Scopes.from_array(endpoint_scopes)
|
21
|
-
elsif scopes
|
21
|
+
elsif scopes.present?
|
22
22
|
Doorkeeper::OAuth::Scopes.from_array(scopes)
|
23
23
|
end
|
24
24
|
|
@@ -39,7 +39,7 @@ module Doorkeeper
|
|
39
39
|
def doorkeeper_token
|
40
40
|
@doorkeeper_token ||= OAuth::Token.authenticate(
|
41
41
|
decorated_request,
|
42
|
-
*Doorkeeper.
|
42
|
+
*Doorkeeper.config.access_token_methods,
|
43
43
|
)
|
44
44
|
end
|
45
45
|
|