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
@@ -9,7 +9,7 @@ module Doorkeeper
|
|
9
9
|
# @param clock [Time] time object
|
10
10
|
#
|
11
11
|
def revoke(clock = Time)
|
12
|
-
update_attribute
|
12
|
+
update_attribute(:revoked_at, clock.now.utc)
|
13
13
|
end
|
14
14
|
|
15
15
|
# Indicates whether the object has been revoked.
|
@@ -19,33 +19,6 @@ module Doorkeeper
|
|
19
19
|
def revoked?
|
20
20
|
!!(revoked_at && revoked_at <= Time.now.utc)
|
21
21
|
end
|
22
|
-
|
23
|
-
# Revokes token with `:refresh_token` equal to `:previous_refresh_token`
|
24
|
-
# and clears `:previous_refresh_token` attribute.
|
25
|
-
#
|
26
|
-
def revoke_previous_refresh_token!
|
27
|
-
return unless refresh_token_revoked_on_use?
|
28
|
-
|
29
|
-
old_refresh_token&.revoke
|
30
|
-
update_attribute :previous_refresh_token, ""
|
31
|
-
end
|
32
|
-
|
33
|
-
private
|
34
|
-
|
35
|
-
# Searches for Access Token record with `:refresh_token` equal to
|
36
|
-
# `:previous_refresh_token` value.
|
37
|
-
#
|
38
|
-
# @return [Doorkeeper::AccessToken, nil]
|
39
|
-
# Access Token record or nil if nothing found
|
40
|
-
#
|
41
|
-
def old_refresh_token
|
42
|
-
@old_refresh_token ||=
|
43
|
-
AccessToken.by_refresh_token(previous_refresh_token)
|
44
|
-
end
|
45
|
-
|
46
|
-
def refresh_token_revoked_on_use?
|
47
|
-
AccessToken.refresh_token_revoked_on_use?
|
48
|
-
end
|
49
22
|
end
|
50
23
|
end
|
51
24
|
end
|
@@ -8,7 +8,11 @@ module Doorkeeper
|
|
8
8
|
end
|
9
9
|
|
10
10
|
def scopes=(value)
|
11
|
-
|
11
|
+
if value.is_a?(Array)
|
12
|
+
super(Doorkeeper::OAuth::Scopes.from_array(value).to_s)
|
13
|
+
else
|
14
|
+
super(Doorkeeper::OAuth::Scopes.from_string(value.to_s).to_s)
|
15
|
+
end
|
12
16
|
end
|
13
17
|
|
14
18
|
def scopes_string
|
@@ -25,9 +25,7 @@ module Doorkeeper
|
|
25
25
|
# @return [Boolean]
|
26
26
|
# Whether input matches secret as per the secret strategy
|
27
27
|
#
|
28
|
-
|
29
|
-
secret_strategy.secret_matches?(input, secret)
|
30
|
-
end
|
28
|
+
delegate :secret_matches?, to: :secret_strategy
|
31
29
|
|
32
30
|
# Returns an instance of the Doorkeeper::AccessToken with
|
33
31
|
# specific token value.
|
@@ -4,35 +4,48 @@ module Doorkeeper
|
|
4
4
|
module OAuth
|
5
5
|
module Authorization
|
6
6
|
class Code
|
7
|
-
|
7
|
+
attr_reader :pre_auth, :resource_owner, :token
|
8
8
|
|
9
9
|
def initialize(pre_auth, resource_owner)
|
10
10
|
@pre_auth = pre_auth
|
11
11
|
@resource_owner = resource_owner
|
12
12
|
end
|
13
13
|
|
14
|
-
def issue_token
|
15
|
-
@token
|
14
|
+
def issue_token!
|
15
|
+
return @token if defined?(@token)
|
16
|
+
|
17
|
+
@token = Doorkeeper.config.access_grant_model.create!(access_grant_attributes)
|
16
18
|
end
|
17
19
|
|
18
20
|
def oob_redirect
|
19
21
|
{ action: :show, code: token.plaintext_token }
|
20
22
|
end
|
21
23
|
|
24
|
+
def access_grant?
|
25
|
+
true
|
26
|
+
end
|
27
|
+
|
22
28
|
private
|
23
29
|
|
24
30
|
def authorization_code_expires_in
|
25
|
-
Doorkeeper.
|
31
|
+
Doorkeeper.config.authorization_code_expires_in
|
26
32
|
end
|
27
33
|
|
28
34
|
def access_grant_attributes
|
29
|
-
|
35
|
+
attributes = {
|
30
36
|
application_id: pre_auth.client.id,
|
31
|
-
resource_owner_id: resource_owner.id,
|
32
37
|
expires_in: authorization_code_expires_in,
|
33
38
|
redirect_uri: pre_auth.redirect_uri,
|
34
|
-
scopes: pre_auth.scopes.to_s
|
35
|
-
|
39
|
+
scopes: pre_auth.scopes.to_s,
|
40
|
+
}
|
41
|
+
|
42
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
43
|
+
attributes[:resource_owner] = resource_owner
|
44
|
+
else
|
45
|
+
attributes[:resource_owner_id] = resource_owner.id
|
46
|
+
end
|
47
|
+
|
48
|
+
pkce_attributes.merge(attributes)
|
36
49
|
end
|
37
50
|
|
38
51
|
def pkce_attributes
|
@@ -47,7 +60,7 @@ module Doorkeeper
|
|
47
60
|
# Ensures firstly, if migration with additional PKCE columns was
|
48
61
|
# generated and migrated
|
49
62
|
def pkce_supported?
|
50
|
-
Doorkeeper
|
63
|
+
Doorkeeper.config.access_grant_model.pkce_supported?
|
51
64
|
end
|
52
65
|
end
|
53
66
|
end
|
@@ -4,12 +4,12 @@ module Doorkeeper
|
|
4
4
|
module OAuth
|
5
5
|
module Authorization
|
6
6
|
class Context
|
7
|
-
attr_reader :client, :grant_type, :scopes
|
7
|
+
attr_reader :client, :grant_type, :resource_owner, :scopes
|
8
8
|
|
9
|
-
def initialize(
|
10
|
-
|
11
|
-
|
12
|
-
|
9
|
+
def initialize(**attributes)
|
10
|
+
attributes.each do |name, value|
|
11
|
+
instance_variable_set(:"@#{name}", value) if respond_to?(name)
|
12
|
+
end
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
@@ -4,10 +4,10 @@ module Doorkeeper
|
|
4
4
|
module OAuth
|
5
5
|
module Authorization
|
6
6
|
class Token
|
7
|
-
|
7
|
+
attr_reader :pre_auth, :resource_owner, :token
|
8
8
|
|
9
9
|
class << self
|
10
|
-
def build_context(pre_auth_or_oauth_client, grant_type, scopes)
|
10
|
+
def build_context(pre_auth_or_oauth_client, grant_type, scopes, resource_owner)
|
11
11
|
oauth_client = if pre_auth_or_oauth_client.respond_to?(:application)
|
12
12
|
pre_auth_or_oauth_client.application
|
13
13
|
elsif pre_auth_or_oauth_client.respond_to?(:client)
|
@@ -17,9 +17,10 @@ module Doorkeeper
|
|
17
17
|
end
|
18
18
|
|
19
19
|
Doorkeeper::OAuth::Authorization::Context.new(
|
20
|
-
oauth_client,
|
21
|
-
grant_type,
|
22
|
-
scopes
|
20
|
+
client: oauth_client,
|
21
|
+
grant_type: grant_type,
|
22
|
+
scopes: scopes,
|
23
|
+
resource_owner: resource_owner,
|
23
24
|
)
|
24
25
|
end
|
25
26
|
|
@@ -35,7 +36,7 @@ module Doorkeeper
|
|
35
36
|
end
|
36
37
|
|
37
38
|
def refresh_token_enabled?(server, context)
|
38
|
-
if server.refresh_token_enabled?.respond_to?
|
39
|
+
if server.refresh_token_enabled?.respond_to?(:call)
|
39
40
|
server.refresh_token_enabled?.call(context)
|
40
41
|
else
|
41
42
|
!!server.refresh_token_enabled?
|
@@ -48,18 +49,22 @@ module Doorkeeper
|
|
48
49
|
@resource_owner = resource_owner
|
49
50
|
end
|
50
51
|
|
51
|
-
def issue_token
|
52
|
+
def issue_token!
|
53
|
+
return @token if defined?(@token)
|
54
|
+
|
52
55
|
context = self.class.build_context(
|
53
56
|
pre_auth.client,
|
54
57
|
Doorkeeper::OAuth::IMPLICIT,
|
55
|
-
pre_auth.scopes
|
56
|
-
)
|
57
|
-
@token ||= AccessToken.find_or_create_for(
|
58
|
-
pre_auth.client,
|
59
|
-
resource_owner.id,
|
60
58
|
pre_auth.scopes,
|
61
|
-
|
62
|
-
|
59
|
+
resource_owner,
|
60
|
+
)
|
61
|
+
|
62
|
+
@token = Doorkeeper.config.access_token_model.find_or_create_for(
|
63
|
+
application: pre_auth.client,
|
64
|
+
resource_owner: resource_owner,
|
65
|
+
scopes: pre_auth.scopes,
|
66
|
+
expires_in: self.class.access_token_expires_in(Doorkeeper.config, context),
|
67
|
+
use_refresh_token: false,
|
63
68
|
)
|
64
69
|
end
|
65
70
|
|
@@ -71,12 +76,12 @@ module Doorkeeper
|
|
71
76
|
}
|
72
77
|
end
|
73
78
|
|
74
|
-
|
75
|
-
|
76
|
-
def configuration
|
77
|
-
Doorkeeper.configuration
|
79
|
+
def access_token?
|
80
|
+
true
|
78
81
|
end
|
79
82
|
|
83
|
+
private
|
84
|
+
|
80
85
|
def controller
|
81
86
|
@controller ||= begin
|
82
87
|
mapping = Doorkeeper::Rails::Routes.mapping[:token_info] || {}
|
@@ -8,9 +8,9 @@ module Doorkeeper
|
|
8
8
|
class URIBuilder
|
9
9
|
class << self
|
10
10
|
def uri_with_query(url, parameters = {})
|
11
|
-
uri
|
11
|
+
uri = URI.parse(url)
|
12
12
|
original_query = Rack::Utils.parse_query(uri.query)
|
13
|
-
uri.query
|
13
|
+
uri.query = build_query(original_query.merge(parameters))
|
14
14
|
uri.to_s
|
15
15
|
end
|
16
16
|
|
@@ -23,8 +23,8 @@ module Doorkeeper
|
|
23
23
|
private
|
24
24
|
|
25
25
|
def build_query(parameters = {})
|
26
|
-
parameters
|
27
|
-
Rack::Utils.build_query
|
26
|
+
parameters.reject! { |_, value| value.blank? }
|
27
|
+
Rack::Utils.build_query(parameters)
|
28
28
|
end
|
29
29
|
end
|
30
30
|
end
|
@@ -3,17 +3,15 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class AuthorizationCodeRequest < BaseRequest
|
6
|
-
validate :pkce_support, error: :invalid_request
|
7
6
|
validate :params, error: :invalid_request
|
8
7
|
validate :client, error: :invalid_client
|
9
8
|
validate :grant, error: :invalid_grant
|
10
|
-
# @see https://
|
9
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
11
10
|
validate :redirect_uri, error: :invalid_grant
|
12
11
|
validate :code_verifier, error: :invalid_grant
|
13
12
|
|
14
|
-
|
15
|
-
|
16
|
-
attr_reader :invalid_request_reason, :missing_param
|
13
|
+
attr_reader :grant, :client, :redirect_uri, :access_token, :code_verifier,
|
14
|
+
:invalid_request_reason, :missing_param
|
17
15
|
|
18
16
|
def initialize(server, grant, client, parameters = {})
|
19
17
|
@server = server
|
@@ -32,20 +30,28 @@ module Doorkeeper
|
|
32
30
|
raise Errors::InvalidGrantReuse if grant.revoked?
|
33
31
|
|
34
32
|
grant.revoke
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
33
|
+
|
34
|
+
find_or_create_access_token(
|
35
|
+
grant.application,
|
36
|
+
resource_owner,
|
37
|
+
grant.scopes,
|
38
|
+
server,
|
39
|
+
)
|
39
40
|
end
|
41
|
+
|
40
42
|
super
|
41
43
|
end
|
42
44
|
|
43
|
-
def
|
44
|
-
|
45
|
-
|
46
|
-
|
45
|
+
def resource_owner
|
46
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
47
|
+
grant.resource_owner
|
48
|
+
else
|
49
|
+
grant.resource_owner_id
|
50
|
+
end
|
51
|
+
end
|
47
52
|
|
48
|
-
|
53
|
+
def pkce_supported?
|
54
|
+
Doorkeeper.config.access_grant_model.pkce_supported?
|
49
55
|
end
|
50
56
|
|
51
57
|
def validate_params
|
@@ -71,24 +77,28 @@ module Doorkeeper
|
|
71
77
|
def validate_redirect_uri
|
72
78
|
Helpers::URIChecker.valid_for_authorization?(
|
73
79
|
redirect_uri,
|
74
|
-
grant.redirect_uri
|
80
|
+
grant.redirect_uri,
|
75
81
|
)
|
76
82
|
end
|
77
83
|
|
78
|
-
# if either side (server or client) request
|
79
|
-
# against the DB - if
|
84
|
+
# if either side (server or client) request PKCE, check the verifier
|
85
|
+
# against the DB - if PKCE is supported
|
80
86
|
def validate_code_verifier
|
81
|
-
return true unless
|
82
|
-
return
|
87
|
+
return true unless pkce_supported?
|
88
|
+
return grant.code_challenge.blank? if code_verifier.blank?
|
83
89
|
|
84
90
|
if grant.code_challenge_method == "S256"
|
85
|
-
grant.code_challenge ==
|
91
|
+
grant.code_challenge == generate_code_challenge(code_verifier)
|
86
92
|
elsif grant.code_challenge_method == "plain"
|
87
93
|
grant.code_challenge == code_verifier
|
88
94
|
else
|
89
95
|
false
|
90
96
|
end
|
91
97
|
end
|
98
|
+
|
99
|
+
def generate_code_challenge(code_verifier)
|
100
|
+
server_config.access_grant_model.generate_code_challenge(code_verifier)
|
101
|
+
end
|
92
102
|
end
|
93
103
|
end
|
94
104
|
end
|
@@ -5,11 +5,11 @@ module Doorkeeper
|
|
5
5
|
class BaseRequest
|
6
6
|
include Validations
|
7
7
|
|
8
|
-
attr_reader :grant_type
|
8
|
+
attr_reader :grant_type, :server
|
9
9
|
|
10
|
-
|
11
|
-
validate
|
10
|
+
delegate :default_scopes, to: :server
|
12
11
|
|
12
|
+
def authorize
|
13
13
|
if valid?
|
14
14
|
before_successful_response
|
15
15
|
@response = TokenResponse.new(access_token)
|
@@ -26,31 +26,27 @@ module Doorkeeper
|
|
26
26
|
@scopes ||= build_scopes
|
27
27
|
end
|
28
28
|
|
29
|
-
def
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
def find_or_create_access_token(client, resource_owner_id, scopes, server)
|
38
|
-
context = Authorization::Token.build_context(client, grant_type, scopes)
|
39
|
-
@access_token = AccessToken.find_or_create_for(
|
40
|
-
client,
|
41
|
-
resource_owner_id,
|
42
|
-
scopes,
|
43
|
-
Authorization::Token.access_token_expires_in(server, context),
|
44
|
-
Authorization::Token.refresh_token_enabled?(server, context)
|
29
|
+
def find_or_create_access_token(client, resource_owner, scopes, server)
|
30
|
+
context = Authorization::Token.build_context(client, grant_type, scopes, resource_owner)
|
31
|
+
@access_token = server_config.access_token_model.find_or_create_for(
|
32
|
+
application: client,
|
33
|
+
resource_owner: resource_owner,
|
34
|
+
scopes: scopes,
|
35
|
+
expires_in: Authorization::Token.access_token_expires_in(server, context),
|
36
|
+
use_refresh_token: Authorization::Token.refresh_token_enabled?(server, context),
|
45
37
|
)
|
46
38
|
end
|
47
39
|
|
48
40
|
def before_successful_response
|
49
|
-
|
41
|
+
server_config.before_successful_strategy_response.call(self)
|
50
42
|
end
|
51
43
|
|
52
44
|
def after_successful_response
|
53
|
-
|
45
|
+
server_config.after_successful_strategy_response.call(self, @response)
|
46
|
+
end
|
47
|
+
|
48
|
+
def server_config
|
49
|
+
Doorkeeper.config
|
54
50
|
end
|
55
51
|
|
56
52
|
private
|
@@ -59,10 +55,10 @@ module Doorkeeper
|
|
59
55
|
if @original_scopes.present?
|
60
56
|
OAuth::Scopes.from_string(@original_scopes)
|
61
57
|
else
|
62
|
-
client_scopes = @client
|
58
|
+
client_scopes = @client&.scopes
|
63
59
|
return default_scopes if client_scopes.blank?
|
64
60
|
|
65
|
-
default_scopes &
|
61
|
+
default_scopes & client_scopes
|
66
62
|
end
|
67
63
|
end
|
68
64
|
end
|
@@ -9,7 +9,7 @@ module Doorkeeper
|
|
9
9
|
credentials_methods.inject(nil) do |_, method|
|
10
10
|
method = self.method(method) if method.is_a?(Symbol)
|
11
11
|
credentials = Credentials.new(*method.call(request))
|
12
|
-
break credentials
|
12
|
+
break credentials if credentials.present?
|
13
13
|
end
|
14
14
|
end
|
15
15
|
|
@@ -27,9 +27,7 @@ module Doorkeeper
|
|
27
27
|
|
28
28
|
# Public clients may have their secret blank, but "credentials" are
|
29
29
|
# still present
|
30
|
-
|
31
|
-
uid.blank?
|
32
|
-
end
|
30
|
+
delegate :blank?, to: :uid
|
33
31
|
end
|
34
32
|
end
|
35
33
|
end
|
@@ -3,7 +3,7 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class Client
|
6
|
-
|
6
|
+
attr_reader :application
|
7
7
|
|
8
8
|
delegate :id, :name, :uid, :redirect_uri, :scopes, to: :@application
|
9
9
|
|
@@ -11,18 +11,17 @@ module Doorkeeper
|
|
11
11
|
@application = application
|
12
12
|
end
|
13
13
|
|
14
|
-
def self.find(uid, method =
|
15
|
-
|
16
|
-
|
17
|
-
|
14
|
+
def self.find(uid, method = Doorkeeper.config.application_model.method(:by_uid))
|
15
|
+
return unless (application = method.call(uid))
|
16
|
+
|
17
|
+
new(application)
|
18
18
|
end
|
19
19
|
|
20
|
-
def self.authenticate(credentials, method =
|
20
|
+
def self.authenticate(credentials, method = Doorkeeper.config.application_model.method(:by_uid_and_secret))
|
21
21
|
return if credentials.blank?
|
22
|
+
return unless (application = method.call(credentials.uid, credentials.secret))
|
22
23
|
|
23
|
-
|
24
|
-
new(application)
|
25
|
-
end
|
24
|
+
new(application)
|
26
25
|
end
|
27
26
|
end
|
28
27
|
end
|
@@ -2,27 +2,53 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
|
-
|
5
|
+
module ClientCredentials
|
6
6
|
class Creator
|
7
7
|
def call(client, scopes, attributes = {})
|
8
|
-
existing_token =
|
8
|
+
existing_token = nil
|
9
9
|
|
10
|
-
if
|
11
|
-
|
10
|
+
if lookup_existing_token?
|
11
|
+
existing_token = find_existing_token_for(client, scopes)
|
12
|
+
return existing_token if server_config.reuse_access_token && existing_token&.reusable?
|
12
13
|
end
|
13
14
|
|
14
|
-
existing_token
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
15
|
+
with_revocation(existing_token: existing_token) do
|
16
|
+
server_config.access_token_model.find_or_create_for(
|
17
|
+
application: client,
|
18
|
+
resource_owner: nil,
|
19
|
+
scopes: scopes,
|
20
|
+
**attributes,
|
21
|
+
)
|
22
|
+
end
|
20
23
|
end
|
21
24
|
|
22
25
|
private
|
23
26
|
|
24
|
-
def
|
25
|
-
|
27
|
+
def with_revocation(existing_token:)
|
28
|
+
if existing_token && server_config.revoke_previous_client_credentials_token?
|
29
|
+
existing_token.with_lock do
|
30
|
+
raise Errors::DoorkeeperError, :invalid_token_reuse if existing_token.revoked?
|
31
|
+
|
32
|
+
existing_token.revoke
|
33
|
+
|
34
|
+
yield
|
35
|
+
end
|
36
|
+
else
|
37
|
+
yield
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def lookup_existing_token?
|
42
|
+
server_config.reuse_access_token ||
|
43
|
+
server_config.revoke_previous_client_credentials_token?
|
44
|
+
end
|
45
|
+
|
46
|
+
def find_existing_token_for(client, scopes)
|
47
|
+
server_config.access_token_model.matching_token_for(client, nil, scopes)
|
48
|
+
end
|
49
|
+
|
50
|
+
def server_config
|
51
|
+
Doorkeeper.config
|
26
52
|
end
|
27
53
|
end
|
28
54
|
end
|
@@ -2,23 +2,24 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
|
-
|
5
|
+
module ClientCredentials
|
6
6
|
class Issuer
|
7
|
-
|
7
|
+
attr_reader :token, :validator, :error
|
8
8
|
|
9
|
-
def initialize(server,
|
9
|
+
def initialize(server, validator)
|
10
10
|
@server = server
|
11
|
-
@
|
11
|
+
@validator = validator
|
12
12
|
end
|
13
13
|
|
14
14
|
def create(client, scopes, creator = Creator.new)
|
15
|
-
if
|
15
|
+
if validator.valid?
|
16
16
|
@token = create_token(client, scopes, creator)
|
17
17
|
@error = :server_error unless @token
|
18
18
|
else
|
19
19
|
@token = false
|
20
|
-
@error =
|
20
|
+
@error = validator.error
|
21
21
|
end
|
22
|
+
|
22
23
|
@token
|
23
24
|
end
|
24
25
|
|
@@ -28,7 +29,8 @@ module Doorkeeper
|
|
28
29
|
context = Authorization::Token.build_context(
|
29
30
|
client,
|
30
31
|
Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
31
|
-
scopes
|
32
|
+
scopes,
|
33
|
+
nil,
|
32
34
|
)
|
33
35
|
ttl = Authorization::Token.access_token_expires_in(@server, context)
|
34
36
|
|
@@ -36,7 +38,7 @@ module Doorkeeper
|
|
36
38
|
client,
|
37
39
|
scopes,
|
38
40
|
use_refresh_token: false,
|
39
|
-
expires_in: ttl
|
41
|
+
expires_in: ttl,
|
40
42
|
)
|
41
43
|
end
|
42
44
|
end
|
@@ -2,8 +2,8 @@
|
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
|
-
|
6
|
-
class
|
5
|
+
module ClientCredentials
|
6
|
+
class Validator
|
7
7
|
include Validations
|
8
8
|
include OAuth::Helpers
|
9
9
|
|
@@ -26,9 +26,11 @@ module Doorkeeper
|
|
26
26
|
end
|
27
27
|
|
28
28
|
def validate_client_supports_grant_flow
|
29
|
-
|
29
|
+
return if @client.blank?
|
30
|
+
|
31
|
+
Doorkeeper.config.allow_grant_flow_for_client?(
|
30
32
|
Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
31
|
-
@client
|
33
|
+
@client.application,
|
32
34
|
)
|
33
35
|
end
|
34
36
|
|
@@ -45,7 +47,7 @@ module Doorkeeper
|
|
45
47
|
scope_str: @request.scopes.to_s,
|
46
48
|
server_scopes: @server.scopes,
|
47
49
|
app_scopes: application_scopes,
|
48
|
-
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS
|
50
|
+
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
49
51
|
)
|
50
52
|
end
|
51
53
|
end
|
@@ -3,18 +3,12 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class ClientCredentialsRequest < BaseRequest
|
6
|
-
|
7
|
-
attr_reader :response
|
8
|
-
attr_writer :issuer
|
6
|
+
attr_reader :client, :original_scopes, :response
|
9
7
|
|
10
8
|
alias error_response response
|
11
9
|
|
12
10
|
delegate :error, to: :issuer
|
13
11
|
|
14
|
-
def issuer
|
15
|
-
@issuer ||= Issuer.new(server, Validation.new(server, self))
|
16
|
-
end
|
17
|
-
|
18
12
|
def initialize(server, client, parameters = {})
|
19
13
|
@client = client
|
20
14
|
@server = server
|
@@ -26,6 +20,13 @@ module Doorkeeper
|
|
26
20
|
issuer.token
|
27
21
|
end
|
28
22
|
|
23
|
+
def issuer
|
24
|
+
@issuer ||= ClientCredentials::Issuer.new(
|
25
|
+
server,
|
26
|
+
ClientCredentials::Validator.new(server, self),
|
27
|
+
)
|
28
|
+
end
|
29
|
+
|
29
30
|
private
|
30
31
|
|
31
32
|
def valid?
|