doorkeeper 5.1.2 → 5.6.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/{NEWS.md → CHANGELOG.md} +314 -27
- data/README.md +39 -22
- data/app/controllers/doorkeeper/application_controller.rb +3 -2
- data/app/controllers/doorkeeper/application_metal_controller.rb +3 -2
- data/app/controllers/doorkeeper/applications_controller.rb +5 -4
- data/app/controllers/doorkeeper/authorizations_controller.rb +76 -25
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +5 -5
- data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
- data/app/controllers/doorkeeper/tokens_controller.rb +99 -28
- data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
- data/app/views/doorkeeper/applications/_form.html.erb +1 -7
- data/app/views/doorkeeper/applications/show.html.erb +35 -14
- data/app/views/doorkeeper/authorizations/error.html.erb +3 -1
- data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +16 -14
- data/config/locales/en.yml +16 -3
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +20 -2
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +300 -136
- data/lib/doorkeeper/engine.rb +10 -3
- data/lib/doorkeeper/errors.rb +13 -18
- 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 +7 -3
- data/lib/doorkeeper/helpers/controller.rb +36 -11
- data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
- data/lib/doorkeeper/models/access_token_mixin.rb +195 -52
- data/lib/doorkeeper/models/application_mixin.rb +8 -7
- data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
- data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
- data/lib/doorkeeper/models/concerns/polymorphic_resource_owner.rb +30 -0
- 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 +31 -14
- data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
- data/lib/doorkeeper/oauth/authorization/token.rb +30 -19
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +51 -22
- data/lib/doorkeeper/oauth/base_request.rb +21 -22
- 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 +42 -5
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
- data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +14 -5
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +6 -12
- data/lib/doorkeeper/oauth/code_response.rb +24 -14
- data/lib/doorkeeper/oauth/error.rb +1 -1
- data/lib/doorkeeper/oauth/error_response.rb +11 -13
- 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 +19 -23
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_request_response.rb +43 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +34 -11
- data/lib/doorkeeper/oauth/pre_authorization.rb +114 -44
- data/lib/doorkeeper/oauth/refresh_token_request.rb +54 -34
- data/lib/doorkeeper/oauth/token.rb +6 -7
- data/lib/doorkeeper/oauth/token_introspection.rb +28 -22
- data/lib/doorkeeper/oauth/token_request.rb +6 -20
- data/lib/doorkeeper/oauth/token_response.rb +2 -3
- 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 -149
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +63 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +77 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +210 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +5 -2
- data/lib/doorkeeper/orm/active_record.rb +29 -22
- 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 +28 -27
- data/lib/doorkeeper/rake/db.rake +6 -6
- data/lib/doorkeeper/request/authorization_code.rb +5 -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 -17
- data/lib/doorkeeper/server.rb +7 -11
- data/lib/doorkeeper/stale_records_cleaner.rb +6 -2
- data/lib/doorkeeper/version.rb +2 -6
- data/lib/doorkeeper.rb +183 -80
- 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 +7 -7
- 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 +230 -50
- data/lib/generators/doorkeeper/templates/migration.rb.erb +31 -9
- metadata +61 -327
- data/.coveralls.yml +0 -1
- data/.github/ISSUE_TEMPLATE.md +0 -25
- data/.github/PULL_REQUEST_TEMPLATE.md +0 -17
- data/.gitignore +0 -20
- data/.gitlab-ci.yml +0 -16
- data/.hound.yml +0 -3
- data/.rspec +0 -1
- data/.rubocop.yml +0 -50
- data/.travis.yml +0 -35
- data/Appraisals +0 -40
- data/CODE_OF_CONDUCT.md +0 -46
- data/CONTRIBUTING.md +0 -47
- data/Dangerfile +0 -67
- data/Gemfile +0 -24
- data/RELEASING.md +0 -10
- data/Rakefile +0 -28
- data/SECURITY.md +0 -15
- data/UPGRADE.md +0 -2
- data/app/validators/redirect_uri_validator.rb +0 -50
- data/bin/console +0 -16
- data/doorkeeper.gemspec +0 -34
- data/gemfiles/rails_5_0.gemfile +0 -17
- data/gemfiles/rails_5_1.gemfile +0 -17
- data/gemfiles/rails_5_2.gemfile +0 -17
- data/gemfiles/rails_6_0.gemfile +0 -17
- data/gemfiles/rails_master.gemfile +0 -17
- data/spec/controllers/application_metal_controller_spec.rb +0 -64
- data/spec/controllers/applications_controller_spec.rb +0 -180
- data/spec/controllers/authorizations_controller_spec.rb +0 -527
- 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 -330
- 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 -47
- 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 -121
- 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 -697
- 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 -156
- data/spec/lib/oauth/base_request_spec.rb +0 -205
- 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 -94
- 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 -47
- 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 -247
- 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 -215
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
- data/spec/lib/oauth/scopes_spec.rb +0 -148
- data/spec/lib/oauth/token_request_spec.rb +0 -150
- 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 -61
- data/spec/lib/stale_records_cleaner_spec.rb +0 -89
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -144
- data/spec/models/doorkeeper/access_token_spec.rb +0 -591
- data/spec/models/doorkeeper/application_spec.rb +0 -472
- 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 -73
- data/spec/requests/endpoints/token_spec.rb +0 -75
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -78
- data/spec/requests/flows/authorization_code_spec.rb +0 -447
- data/spec/requests/flows/client_credentials_spec.rb +0 -128
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -34
- data/spec/requests/flows/implicit_grant_spec.rb +0 -90
- data/spec/requests/flows/password_spec.rb +0 -259
- data/spec/requests/flows/refresh_token_spec.rb +0 -233
- data/spec/requests/flows/revoke_token_spec.rb +0 -143
- 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 -98
- 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 -158
- data/spec/version/version_spec.rb +0 -17
@@ -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,37 +4,54 @@ 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
|
-
def
|
20
|
+
def oob_redirect
|
19
21
|
{ action: :show, code: token.plaintext_token }
|
20
22
|
end
|
21
23
|
|
22
|
-
def
|
23
|
-
|
24
|
+
def access_grant?
|
25
|
+
true
|
24
26
|
end
|
25
27
|
|
26
28
|
private
|
27
29
|
|
28
30
|
def authorization_code_expires_in
|
29
|
-
|
31
|
+
Doorkeeper.config.authorization_code_expires_in
|
30
32
|
end
|
31
33
|
|
32
34
|
def access_grant_attributes
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
35
|
+
attributes = {
|
36
|
+
application_id: pre_auth.client.id,
|
37
|
+
expires_in: authorization_code_expires_in,
|
38
|
+
redirect_uri: pre_auth.redirect_uri,
|
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).merge(custom_attributes)
|
49
|
+
end
|
50
|
+
|
51
|
+
def custom_attributes
|
52
|
+
# Custom access token attributes are saved into the access grant,
|
53
|
+
# and then included in subsequently generated access tokens.
|
54
|
+
@pre_auth.custom_access_token_attributes.to_h.with_indifferent_access
|
38
55
|
end
|
39
56
|
|
40
57
|
def pkce_attributes
|
@@ -46,10 +63,10 @@ module Doorkeeper
|
|
46
63
|
}
|
47
64
|
end
|
48
65
|
|
49
|
-
#
|
66
|
+
# Ensures firstly, if migration with additional PKCE columns was
|
50
67
|
# generated and migrated
|
51
68
|
def pkce_supported?
|
52
|
-
Doorkeeper
|
69
|
+
Doorkeeper.config.access_grant_model.pkce_supported?
|
53
70
|
end
|
54
71
|
end
|
55
72
|
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,22 +49,32 @@ 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
|
-
false
|
59
|
+
resource_owner,
|
63
60
|
)
|
61
|
+
|
62
|
+
@token = Doorkeeper.config.access_token_model.find_or_create_for(
|
63
|
+
application: application,
|
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,
|
68
|
+
)
|
69
|
+
end
|
70
|
+
|
71
|
+
def application
|
72
|
+
return unless pre_auth.client
|
73
|
+
|
74
|
+
pre_auth.client.is_a?(Doorkeeper.config.application_model) ? pre_auth.client : pre_auth.client.application
|
64
75
|
end
|
65
76
|
|
66
|
-
def
|
77
|
+
def oob_redirect
|
67
78
|
{
|
68
79
|
controller: controller,
|
69
80
|
action: :show,
|
@@ -71,12 +82,12 @@ module Doorkeeper
|
|
71
82
|
}
|
72
83
|
end
|
73
84
|
|
74
|
-
|
75
|
-
|
76
|
-
def configuration
|
77
|
-
Doorkeeper.configuration
|
85
|
+
def access_token?
|
86
|
+
true
|
78
87
|
end
|
79
88
|
|
89
|
+
private
|
90
|
+
|
80
91
|
def controller
|
81
92
|
@controller ||= begin
|
82
93
|
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,15 +3,15 @@
|
|
3
3
|
module Doorkeeper
|
4
4
|
module OAuth
|
5
5
|
class AuthorizationCodeRequest < BaseRequest
|
6
|
-
validate :
|
6
|
+
validate :params, error: :invalid_request
|
7
7
|
validate :client, error: :invalid_client
|
8
8
|
validate :grant, error: :invalid_grant
|
9
|
-
# @see https://
|
9
|
+
# @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2
|
10
10
|
validate :redirect_uri, error: :invalid_grant
|
11
11
|
validate :code_verifier, error: :invalid_grant
|
12
12
|
|
13
|
-
|
14
|
-
|
13
|
+
attr_reader :grant, :client, :redirect_uri, :access_token, :code_verifier,
|
14
|
+
:invalid_request_reason, :missing_param
|
15
15
|
|
16
16
|
def initialize(server, grant, client, parameters = {})
|
17
17
|
@server = server
|
@@ -24,29 +24,46 @@ module Doorkeeper
|
|
24
24
|
|
25
25
|
private
|
26
26
|
|
27
|
-
def client_by_uid(parameters)
|
28
|
-
Doorkeeper::Application.by_uid(parameters[:client_id])
|
29
|
-
end
|
30
|
-
|
31
27
|
def before_successful_response
|
32
28
|
grant.transaction do
|
33
29
|
grant.lock!
|
34
30
|
raise Errors::InvalidGrantReuse if grant.revoked?
|
35
31
|
|
36
32
|
grant.revoke
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
33
|
+
|
34
|
+
find_or_create_access_token(
|
35
|
+
grant.application,
|
36
|
+
resource_owner,
|
37
|
+
grant.scopes,
|
38
|
+
custom_token_attributes_with_data,
|
39
|
+
server,
|
40
|
+
)
|
41
41
|
end
|
42
|
+
|
42
43
|
super
|
43
44
|
end
|
44
45
|
|
45
|
-
def
|
46
|
-
|
47
|
-
|
46
|
+
def resource_owner
|
47
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
48
|
+
grant.resource_owner
|
49
|
+
else
|
50
|
+
grant.resource_owner_id
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def pkce_supported?
|
55
|
+
Doorkeeper.config.access_grant_model.pkce_supported?
|
56
|
+
end
|
57
|
+
|
58
|
+
def validate_params
|
59
|
+
@missing_param =
|
60
|
+
if grant&.uses_pkce? && code_verifier.blank?
|
61
|
+
:code_verifier
|
62
|
+
elsif redirect_uri.blank?
|
63
|
+
:redirect_uri
|
64
|
+
end
|
48
65
|
|
49
|
-
|
66
|
+
@missing_param.nil?
|
50
67
|
end
|
51
68
|
|
52
69
|
def validate_client
|
@@ -62,24 +79,36 @@ module Doorkeeper
|
|
62
79
|
def validate_redirect_uri
|
63
80
|
Helpers::URIChecker.valid_for_authorization?(
|
64
81
|
redirect_uri,
|
65
|
-
grant.redirect_uri
|
82
|
+
grant.redirect_uri,
|
66
83
|
)
|
67
84
|
end
|
68
85
|
|
69
|
-
# if either side (server or client) request
|
70
|
-
# against the DB - if
|
86
|
+
# if either side (server or client) request PKCE, check the verifier
|
87
|
+
# against the DB - if PKCE is supported
|
71
88
|
def validate_code_verifier
|
72
|
-
return true unless
|
73
|
-
return
|
89
|
+
return true unless pkce_supported?
|
90
|
+
return grant.code_challenge.blank? if code_verifier.blank?
|
74
91
|
|
75
92
|
if grant.code_challenge_method == "S256"
|
76
|
-
grant.code_challenge ==
|
93
|
+
grant.code_challenge == generate_code_challenge(code_verifier)
|
77
94
|
elsif grant.code_challenge_method == "plain"
|
78
95
|
grant.code_challenge == code_verifier
|
79
96
|
else
|
80
97
|
false
|
81
98
|
end
|
82
99
|
end
|
100
|
+
|
101
|
+
def generate_code_challenge(code_verifier)
|
102
|
+
Doorkeeper.config.access_grant_model.generate_code_challenge(code_verifier)
|
103
|
+
end
|
104
|
+
|
105
|
+
def custom_token_attributes_with_data
|
106
|
+
grant
|
107
|
+
.attributes
|
108
|
+
.with_indifferent_access
|
109
|
+
.slice(*Doorkeeper.config.custom_access_token_attributes)
|
110
|
+
.symbolize_keys
|
111
|
+
end
|
83
112
|
end
|
84
113
|
end
|
85
114
|
end
|
@@ -5,16 +5,18 @@ 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)
|
16
16
|
after_successful_response
|
17
17
|
@response
|
18
|
+
elsif error == :invalid_request
|
19
|
+
@response = InvalidRequestResponse.from_request(self)
|
18
20
|
else
|
19
21
|
@response = ErrorResponse.from_request(self)
|
20
22
|
end
|
@@ -24,31 +26,28 @@ module Doorkeeper
|
|
24
26
|
@scopes ||= build_scopes
|
25
27
|
end
|
26
28
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
29
|
+
def find_or_create_access_token(client, resource_owner, scopes, custom_attributes, server)
|
30
|
+
context = Authorization::Token.build_context(client, grant_type, scopes, resource_owner)
|
31
|
+
application = client.is_a?(Doorkeeper.config.application_model) ? client : client&.application
|
30
32
|
|
31
|
-
|
32
|
-
|
33
|
-
|
33
|
+
token_attributes = {
|
34
|
+
application: application,
|
35
|
+
resource_owner: resource_owner,
|
36
|
+
scopes: scopes,
|
37
|
+
expires_in: Authorization::Token.access_token_expires_in(server, context),
|
38
|
+
use_refresh_token: Authorization::Token.refresh_token_enabled?(server, context),
|
39
|
+
}
|
34
40
|
|
35
|
-
|
36
|
-
|
37
|
-
@access_token = AccessToken.find_or_create_for(
|
38
|
-
client,
|
39
|
-
resource_owner_id,
|
40
|
-
scopes,
|
41
|
-
Authorization::Token.access_token_expires_in(server, context),
|
42
|
-
Authorization::Token.refresh_token_enabled?(server, context)
|
43
|
-
)
|
41
|
+
@access_token =
|
42
|
+
Doorkeeper.config.access_token_model.find_or_create_for(**token_attributes.merge(custom_attributes))
|
44
43
|
end
|
45
44
|
|
46
45
|
def before_successful_response
|
47
|
-
Doorkeeper.
|
46
|
+
Doorkeeper.config.before_successful_strategy_response.call(self)
|
48
47
|
end
|
49
48
|
|
50
49
|
def after_successful_response
|
51
|
-
Doorkeeper.
|
50
|
+
Doorkeeper.config.after_successful_strategy_response.call(self, @response)
|
52
51
|
end
|
53
52
|
|
54
53
|
private
|
@@ -57,10 +56,10 @@ module Doorkeeper
|
|
57
56
|
if @original_scopes.present?
|
58
57
|
OAuth::Scopes.from_string(@original_scopes)
|
59
58
|
else
|
60
|
-
client_scopes = @client
|
59
|
+
client_scopes = @client&.scopes
|
61
60
|
return default_scopes if client_scopes.blank?
|
62
61
|
|
63
|
-
default_scopes &
|
62
|
+
default_scopes & client_scopes
|
64
63
|
end
|
65
64
|
end
|
66
65
|
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,13 +2,50 @@
|
|
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
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
8
|
+
existing_token = nil
|
9
|
+
|
10
|
+
if lookup_existing_token?
|
11
|
+
existing_token = find_active_existing_token_for(client, scopes)
|
12
|
+
return existing_token if Doorkeeper.config.reuse_access_token && existing_token&.reusable?
|
13
|
+
end
|
14
|
+
|
15
|
+
with_revocation(existing_token: existing_token) do
|
16
|
+
application = client.is_a?(Doorkeeper.config.application_model) ? client : client&.application
|
17
|
+
Doorkeeper.config.access_token_model.create_for(
|
18
|
+
application: application,
|
19
|
+
resource_owner: nil,
|
20
|
+
scopes: scopes,
|
21
|
+
**attributes,
|
22
|
+
)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
private
|
27
|
+
|
28
|
+
def with_revocation(existing_token:)
|
29
|
+
if existing_token && Doorkeeper.config.revoke_previous_client_credentials_token?
|
30
|
+
existing_token.with_lock do
|
31
|
+
raise Errors::DoorkeeperError, :invalid_token_reuse if existing_token.revoked?
|
32
|
+
|
33
|
+
existing_token.revoke
|
34
|
+
|
35
|
+
yield
|
36
|
+
end
|
37
|
+
else
|
38
|
+
yield
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
def lookup_existing_token?
|
43
|
+
Doorkeeper.config.reuse_access_token ||
|
44
|
+
Doorkeeper.config.revoke_previous_client_credentials_token?
|
45
|
+
end
|
46
|
+
|
47
|
+
def find_active_existing_token_for(client, scopes)
|
48
|
+
Doorkeeper.config.access_token_model.matching_token_for(client, nil, scopes, include_expired: false)
|
12
49
|
end
|
13
50
|
end
|
14
51
|
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,12 +2,13 @@
|
|
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
|
|
10
10
|
validate :client, error: :invalid_client
|
11
|
+
validate :client_supports_grant_flow, error: :unauthorized_client
|
11
12
|
validate :scopes, error: :invalid_scope
|
12
13
|
|
13
14
|
def initialize(server, request)
|
@@ -24,20 +25,28 @@ module Doorkeeper
|
|
24
25
|
@client.present?
|
25
26
|
end
|
26
27
|
|
27
|
-
def
|
28
|
-
return
|
28
|
+
def validate_client_supports_grant_flow
|
29
|
+
return if @client.blank?
|
29
30
|
|
31
|
+
Doorkeeper.config.allow_grant_flow_for_client?(
|
32
|
+
Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
33
|
+
@client.application,
|
34
|
+
)
|
35
|
+
end
|
36
|
+
|
37
|
+
def validate_scopes
|
30
38
|
application_scopes = if @client.present?
|
31
39
|
@client.application.scopes
|
32
40
|
else
|
33
41
|
""
|
34
42
|
end
|
43
|
+
return true if @request.scopes.blank? && application_scopes.blank?
|
35
44
|
|
36
45
|
ScopeChecker.valid?(
|
37
46
|
scope_str: @request.scopes.to_s,
|
38
47
|
server_scopes: @server.scopes,
|
39
48
|
app_scopes: application_scopes,
|
40
|
-
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS
|
49
|
+
grant_type: Doorkeeper::OAuth::CLIENT_CREDENTIALS,
|
41
50
|
)
|
42
51
|
end
|
43
52
|
end
|