doorkeeper 3.1.0 → 5.6.2
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 +5 -5
- data/CHANGELOG.md +1079 -0
- data/README.md +114 -326
- data/app/assets/stylesheets/doorkeeper/admin/application.css +2 -2
- data/app/controllers/doorkeeper/application_controller.rb +7 -6
- data/app/controllers/doorkeeper/application_metal_controller.rb +9 -12
- data/app/controllers/doorkeeper/applications_controller.rb +66 -21
- data/app/controllers/doorkeeper/authorizations_controller.rb +100 -18
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +23 -4
- data/app/controllers/doorkeeper/token_info_controller.rb +16 -4
- data/app/controllers/doorkeeper/tokens_controller.rb +138 -22
- data/app/helpers/doorkeeper/dashboard_helper.rb +15 -9
- data/app/views/doorkeeper/applications/_delete_form.html.erb +4 -3
- data/app/views/doorkeeper/applications/_form.html.erb +33 -21
- data/app/views/doorkeeper/applications/edit.html.erb +1 -1
- data/app/views/doorkeeper/applications/index.html.erb +18 -6
- data/app/views/doorkeeper/applications/new.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +40 -16
- data/app/views/doorkeeper/authorizations/error.html.erb +1 -1
- data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
- data/app/views/doorkeeper/authorizations/new.html.erb +17 -11
- data/app/views/doorkeeper/authorized_applications/_delete_form.html.erb +1 -2
- data/app/views/doorkeeper/authorized_applications/index.html.erb +0 -1
- data/app/views/layouts/doorkeeper/admin.html.erb +16 -14
- data/config/locales/en.yml +37 -9
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +82 -0
- data/lib/doorkeeper/config/validations.rb +53 -0
- data/lib/doorkeeper/config.rb +602 -142
- data/lib/doorkeeper/engine.rb +22 -7
- data/lib/doorkeeper/errors.rb +37 -10
- 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/authorization_decorator.rb +6 -4
- data/lib/doorkeeper/grape/helpers.rb +24 -12
- data/lib/doorkeeper/helpers/controller.rb +49 -27
- data/lib/doorkeeper/models/access_grant_mixin.rb +99 -16
- data/lib/doorkeeper/models/access_token_mixin.rb +386 -77
- data/lib/doorkeeper/models/application_mixin.rb +73 -30
- data/lib/doorkeeper/models/concerns/accessible.rb +6 -0
- data/lib/doorkeeper/models/concerns/expirable.rb +20 -6
- data/lib/doorkeeper/models/concerns/expiration_time_sql_math.rb +88 -0
- data/lib/doorkeeper/models/concerns/orderable.rb +15 -0
- data/lib/doorkeeper/models/concerns/ownership.rb +4 -2
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/reusable.rb +19 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +13 -2
- data/lib/doorkeeper/models/concerns/scopes.rb +12 -2
- data/lib/doorkeeper/models/concerns/secret_storable.rb +106 -0
- data/lib/doorkeeper/oauth/authorization/code.rb +48 -12
- data/lib/doorkeeper/oauth/authorization/context.rb +17 -0
- data/lib/doorkeeper/oauth/authorization/token.rb +72 -28
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +22 -18
- data/lib/doorkeeper/oauth/authorization_code_request.rb +64 -14
- data/lib/doorkeeper/oauth/base_request.rb +66 -0
- data/lib/doorkeeper/oauth/base_response.rb +31 -0
- data/lib/doorkeeper/oauth/client/credentials.rb +23 -10
- data/lib/doorkeeper/oauth/client.rb +10 -12
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +48 -4
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +17 -9
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +55 -0
- data/lib/doorkeeper/oauth/client_credentials_request.rb +14 -15
- data/lib/doorkeeper/oauth/code_request.rb +8 -12
- data/lib/doorkeeper/oauth/code_response.rb +31 -19
- data/lib/doorkeeper/oauth/error.rb +5 -3
- data/lib/doorkeeper/oauth/error_response.rb +41 -20
- data/lib/doorkeeper/oauth/forbidden_token_response.rb +11 -3
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +24 -19
- data/lib/doorkeeper/oauth/helpers/unique_token.rb +20 -3
- data/lib/doorkeeper/oauth/helpers/uri_checker.rb +55 -4
- 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 +31 -5
- data/lib/doorkeeper/oauth/nonstandard.rb +39 -0
- data/lib/doorkeeper/oauth/password_access_token_request.rb +46 -18
- data/lib/doorkeeper/oauth/pre_authorization.rb +135 -26
- data/lib/doorkeeper/oauth/refresh_token_request.rb +67 -30
- data/lib/doorkeeper/oauth/scopes.rb +26 -12
- data/lib/doorkeeper/oauth/token.rb +28 -25
- data/lib/doorkeeper/oauth/token_introspection.rb +202 -0
- data/lib/doorkeeper/oauth/token_request.rb +8 -21
- data/lib/doorkeeper/oauth/token_response.rb +14 -10
- data/lib/doorkeeper/oauth.rb +13 -0
- data/lib/doorkeeper/orm/active_record/access_grant.rb +6 -4
- data/lib/doorkeeper/orm/active_record/access_token.rb +5 -17
- data/lib/doorkeeper/orm/active_record/application.rb +6 -20
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +81 -0
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +214 -0
- data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +66 -0
- data/lib/doorkeeper/orm/active_record/stale_records_cleaner.rb +33 -0
- data/lib/doorkeeper/orm/active_record.rb +36 -26
- data/lib/doorkeeper/rails/helpers.rb +14 -15
- data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
- data/lib/doorkeeper/rails/routes/mapper.rb +4 -2
- data/lib/doorkeeper/rails/routes/mapping.rb +10 -8
- data/lib/doorkeeper/rails/routes/registry.rb +45 -0
- data/lib/doorkeeper/rails/routes.rb +45 -28
- data/lib/doorkeeper/rake/db.rake +40 -0
- data/lib/doorkeeper/rake/setup.rake +6 -0
- data/lib/doorkeeper/rake.rb +14 -0
- data/lib/doorkeeper/request/authorization_code.rb +12 -4
- data/lib/doorkeeper/request/client_credentials.rb +3 -3
- data/lib/doorkeeper/request/code.rb +1 -1
- data/lib/doorkeeper/request/password.rb +5 -4
- data/lib/doorkeeper/request/refresh_token.rb +6 -5
- data/lib/doorkeeper/request/strategy.rb +4 -2
- data/lib/doorkeeper/request/token.rb +1 -1
- data/lib/doorkeeper/request.rb +62 -29
- data/lib/doorkeeper/secret_storing/base.rb +64 -0
- data/lib/doorkeeper/secret_storing/bcrypt.rb +60 -0
- data/lib/doorkeeper/secret_storing/plain.rb +33 -0
- data/lib/doorkeeper/secret_storing/sha256_hash.rb +26 -0
- data/lib/doorkeeper/server.rb +9 -19
- data/lib/doorkeeper/stale_records_cleaner.rb +24 -0
- data/lib/doorkeeper/validations.rb +5 -2
- data/lib/doorkeeper/version.rb +12 -1
- data/lib/doorkeeper.rb +112 -56
- data/lib/generators/doorkeeper/application_owner_generator.rb +28 -13
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +33 -0
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/install_generator.rb +19 -9
- data/lib/generators/doorkeeper/migration_generator.rb +27 -10
- data/lib/generators/doorkeeper/pkce_generator.rb +33 -0
- data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +41 -0
- data/lib/generators/doorkeeper/templates/add_confidential_to_applications.rb.erb +13 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +9 -0
- data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +13 -0
- data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +8 -0
- data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
- data/lib/generators/doorkeeper/templates/initializer.rb +417 -32
- data/lib/generators/doorkeeper/templates/migration.rb.erb +88 -0
- data/lib/generators/doorkeeper/views_generator.rb +8 -4
- data/vendor/assets/stylesheets/doorkeeper/bootstrap.min.css +4 -5
- metadata +163 -280
- data/.gitignore +0 -14
- data/.hound.yml +0 -13
- data/.rspec +0 -1
- data/.travis.yml +0 -22
- data/CONTRIBUTING.md +0 -45
- data/Gemfile +0 -10
- data/NEWS.md +0 -525
- data/RELEASING.md +0 -17
- data/Rakefile +0 -20
- data/app/validators/redirect_uri_validator.rb +0 -34
- data/doorkeeper.gemspec +0 -27
- data/lib/doorkeeper/oauth/client/methods.rb +0 -18
- data/lib/doorkeeper/oauth/client_credentials/validation.rb +0 -45
- data/lib/doorkeeper/oauth/request_concern.rb +0 -48
- data/lib/generators/doorkeeper/application_scopes_generator.rb +0 -34
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb +0 -7
- data/lib/generators/doorkeeper/templates/add_scopes_to_oauth_applications.rb +0 -5
- data/lib/generators/doorkeeper/templates/migration.rb +0 -50
- data/spec/controllers/applications_controller_spec.rb +0 -58
- data/spec/controllers/authorizations_controller_spec.rb +0 -203
- data/spec/controllers/protected_resources_controller_spec.rb +0 -271
- data/spec/controllers/token_info_controller_spec.rb +0 -52
- data/spec/controllers/tokens_controller_spec.rb +0 -88
- data/spec/dummy/Rakefile +0 -7
- data/spec/dummy/app/controllers/application_controller.rb +0 -3
- data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -7
- data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -12
- data/spec/dummy/app/controllers/home_controller.rb +0 -17
- data/spec/dummy/app/controllers/metal_controller.rb +0 -11
- data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -11
- data/spec/dummy/app/helpers/application_helper.rb +0 -5
- data/spec/dummy/app/models/user.rb +0 -9
- 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 -57
- data/spec/dummy/config/boot.rb +0 -9
- data/spec/dummy/config/database.yml +0 -15
- data/spec/dummy/config/environment.rb +0 -5
- data/spec/dummy/config/environments/development.rb +0 -29
- data/spec/dummy/config/environments/production.rb +0 -62
- data/spec/dummy/config/environments/test.rb +0 -55
- data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -7
- data/spec/dummy/config/initializers/doorkeeper.rb +0 -96
- data/spec/dummy/config/initializers/secret_token.rb +0 -9
- data/spec/dummy/config/initializers/session_store.rb +0 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +0 -14
- data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
- data/spec/dummy/config/routes.rb +0 -52
- data/spec/dummy/config.ru +0 -4
- data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -9
- data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -5
- data/spec/dummy/db/migrate/20130902165751_create_doorkeeper_tables.rb +0 -41
- data/spec/dummy/db/migrate/20130902175349_add_owner_to_application.rb +0 -7
- data/spec/dummy/db/migrate/20141209001746_add_scopes_to_oauth_applications.rb +0 -5
- data/spec/dummy/db/schema.rb +0 -66
- 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 -6
- data/spec/factories.rb +0 -26
- data/spec/generators/application_owner_generator_spec.rb +0 -22
- data/spec/generators/install_generator_spec.rb +0 -31
- data/spec/generators/migration_generator_spec.rb +0 -20
- data/spec/generators/templates/routes.rb +0 -3
- data/spec/generators/views_generator_spec.rb +0 -27
- data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -24
- data/spec/lib/config_spec.rb +0 -317
- data/spec/lib/doorkeeper_spec.rb +0 -28
- data/spec/lib/models/expirable_spec.rb +0 -51
- data/spec/lib/models/revocable_spec.rb +0 -36
- data/spec/lib/models/scopes_spec.rb +0 -43
- data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -42
- data/spec/lib/oauth/authorization_code_request_spec.rb +0 -80
- data/spec/lib/oauth/client/credentials_spec.rb +0 -47
- data/spec/lib/oauth/client/methods_spec.rb +0 -54
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -44
- data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -86
- data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -54
- data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -104
- data/spec/lib/oauth/client_spec.rb +0 -39
- data/spec/lib/oauth/code_request_spec.rb +0 -45
- data/spec/lib/oauth/error_response_spec.rb +0 -61
- data/spec/lib/oauth/error_spec.rb +0 -23
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -23
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -64
- data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -20
- data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -104
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -28
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -90
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -155
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -123
- data/spec/lib/oauth/scopes_spec.rb +0 -123
- data/spec/lib/oauth/token_request_spec.rb +0 -98
- data/spec/lib/oauth/token_response_spec.rb +0 -85
- data/spec/lib/oauth/token_spec.rb +0 -109
- data/spec/lib/request/strategy_spec.rb +0 -53
- data/spec/lib/server_spec.rb +0 -52
- data/spec/models/doorkeeper/access_grant_spec.rb +0 -36
- data/spec/models/doorkeeper/access_token_spec.rb +0 -350
- data/spec/models/doorkeeper/application_spec.rb +0 -187
- data/spec/requests/applications/applications_request_spec.rb +0 -94
- data/spec/requests/applications/authorized_applications_spec.rb +0 -30
- data/spec/requests/endpoints/authorization_spec.rb +0 -72
- data/spec/requests/endpoints/token_spec.rb +0 -64
- data/spec/requests/flows/authorization_code_errors_spec.rb +0 -66
- data/spec/requests/flows/authorization_code_spec.rb +0 -156
- data/spec/requests/flows/client_credentials_spec.rb +0 -58
- data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -32
- data/spec/requests/flows/implicit_grant_spec.rb +0 -61
- data/spec/requests/flows/password_spec.rb +0 -94
- data/spec/requests/flows/refresh_token_spec.rb +0 -104
- data/spec/requests/flows/revoke_token_spec.rb +0 -143
- data/spec/requests/flows/skip_authorization_spec.rb +0 -59
- data/spec/requests/protected_resources/metal_spec.rb +0 -14
- data/spec/requests/protected_resources/private_api_spec.rb +0 -81
- data/spec/routing/custom_controller_routes_spec.rb +0 -71
- data/spec/routing/default_routes_spec.rb +0 -35
- data/spec/routing/scoped_routes_spec.rb +0 -31
- data/spec/spec_helper.rb +0 -2
- data/spec/spec_helper_integration.rb +0 -56
- data/spec/support/dependencies/factory_girl.rb +0 -2
- data/spec/support/helpers/access_token_request_helper.rb +0 -11
- data/spec/support/helpers/authorization_request_helper.rb +0 -41
- data/spec/support/helpers/config_helper.rb +0 -9
- data/spec/support/helpers/model_helper.rb +0 -45
- data/spec/support/helpers/request_spec_helper.rb +0 -76
- data/spec/support/helpers/url_helper.rb +0 -55
- data/spec/support/orm/active_record.rb +0 -3
- data/spec/support/shared/controllers_shared_context.rb +0 -60
- data/spec/support/shared/models_shared_examples.rb +0 -52
- data/spec/validators/redirect_uri_validator_spec.rb +0 -78
@@ -1,32 +1,42 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require "doorkeeper/rails/routes/mapping"
|
4
|
+
require "doorkeeper/rails/routes/mapper"
|
5
|
+
require "doorkeeper/rails/routes/abstract_router"
|
6
|
+
require "doorkeeper/rails/routes/registry"
|
3
7
|
|
4
8
|
module Doorkeeper
|
5
9
|
module Rails
|
6
|
-
class Routes
|
10
|
+
class Routes # :nodoc:
|
7
11
|
module Helper
|
8
|
-
# TODO: options hash is not being used
|
9
12
|
def use_doorkeeper(options = {}, &block)
|
10
13
|
Doorkeeper::Rails::Routes.new(self, &block).generate_routes!(options)
|
11
14
|
end
|
12
15
|
end
|
13
16
|
|
14
|
-
|
15
|
-
|
17
|
+
include AbstractRouter
|
18
|
+
extend Registry
|
19
|
+
|
20
|
+
mattr_reader :mapping do
|
21
|
+
{}
|
16
22
|
end
|
17
23
|
|
18
|
-
|
24
|
+
def self.install!
|
25
|
+
ActionDispatch::Routing::Mapper.include Doorkeeper::Rails::Routes::Helper
|
19
26
|
|
20
|
-
|
21
|
-
|
27
|
+
registered_routes.each(&:install!)
|
28
|
+
end
|
29
|
+
|
30
|
+
def initialize(routes, mapper = Mapper.new, &block)
|
31
|
+
super
|
22
32
|
end
|
23
33
|
|
24
34
|
def generate_routes!(options)
|
25
|
-
|
26
|
-
routes.scope options[:scope] || 'oauth', as: 'oauth' do
|
35
|
+
routes.scope options[:scope] || "oauth", as: "oauth" do
|
27
36
|
map_route(:authorizations, :authorization_routes)
|
28
37
|
map_route(:tokens, :token_routes)
|
29
38
|
map_route(:tokens, :revoke_routes)
|
39
|
+
map_route(:tokens, :introspect_routes) unless Doorkeeper.config.allow_token_introspection.is_a?(FalseClass)
|
30
40
|
map_route(:applications, :application_routes)
|
31
41
|
map_route(:authorized_applications, :authorized_applications_routes)
|
32
42
|
map_route(:token_info, :token_info_routes)
|
@@ -35,21 +45,15 @@ module Doorkeeper
|
|
35
45
|
|
36
46
|
private
|
37
47
|
|
38
|
-
def map_route(name, method)
|
39
|
-
unless @mapping.skipped?(name)
|
40
|
-
send method, @mapping[name]
|
41
|
-
end
|
42
|
-
end
|
43
|
-
|
44
48
|
def authorization_routes(mapping)
|
45
49
|
routes.resource(
|
46
50
|
:authorization,
|
47
|
-
path:
|
48
|
-
only: [
|
51
|
+
path: "authorize",
|
52
|
+
only: %i[create destroy],
|
49
53
|
as: mapping[:as],
|
50
|
-
controller: mapping[:controllers]
|
54
|
+
controller: mapping[:controllers],
|
51
55
|
) do
|
52
|
-
routes.get
|
56
|
+
routes.get native_authorization_code_route, action: :show, on: :member
|
53
57
|
routes.get '/', action: :new, on: :member
|
54
58
|
end
|
55
59
|
end
|
@@ -57,31 +61,44 @@ module Doorkeeper
|
|
57
61
|
def token_routes(mapping)
|
58
62
|
routes.resource(
|
59
63
|
:token,
|
60
|
-
path:
|
64
|
+
path: "token",
|
61
65
|
only: [:create], as: mapping[:as],
|
62
|
-
controller: mapping[:controllers]
|
66
|
+
controller: mapping[:controllers],
|
63
67
|
)
|
64
68
|
end
|
65
69
|
|
66
70
|
def revoke_routes(mapping)
|
67
|
-
routes.post
|
71
|
+
routes.post "revoke", controller: mapping[:controllers], action: :revoke
|
72
|
+
end
|
73
|
+
|
74
|
+
def introspect_routes(mapping)
|
75
|
+
routes.post "introspect", controller: mapping[:controllers], action: :introspect
|
68
76
|
end
|
69
77
|
|
70
78
|
def token_info_routes(mapping)
|
71
79
|
routes.resource(
|
72
80
|
:token_info,
|
73
|
-
path:
|
81
|
+
path: "token/info",
|
74
82
|
only: [:show], as: mapping[:as],
|
75
|
-
controller: mapping[:controllers]
|
83
|
+
controller: mapping[:controllers],
|
76
84
|
)
|
77
85
|
end
|
78
86
|
|
79
87
|
def application_routes(mapping)
|
80
|
-
routes.resources :doorkeeper_applications,
|
88
|
+
routes.resources :doorkeeper_applications,
|
89
|
+
controller: mapping[:controllers],
|
90
|
+
as: :applications,
|
91
|
+
path: "applications"
|
81
92
|
end
|
82
93
|
|
83
94
|
def authorized_applications_routes(mapping)
|
84
|
-
routes.resources :authorized_applications,
|
95
|
+
routes.resources :authorized_applications,
|
96
|
+
only: %i[index destroy],
|
97
|
+
controller: mapping[:controllers]
|
98
|
+
end
|
99
|
+
|
100
|
+
def native_authorization_code_route
|
101
|
+
Doorkeeper.configuration.native_authorization_code_route
|
85
102
|
end
|
86
103
|
end
|
87
104
|
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
namespace :doorkeeper do
|
4
|
+
namespace :db do
|
5
|
+
desc "Removes stale data from doorkeeper related database tables"
|
6
|
+
task cleanup: [
|
7
|
+
"doorkeeper:db:cleanup:revoked_tokens",
|
8
|
+
"doorkeeper:db:cleanup:expired_tokens",
|
9
|
+
"doorkeeper:db:cleanup:revoked_grants",
|
10
|
+
"doorkeeper:db:cleanup:expired_grants",
|
11
|
+
]
|
12
|
+
|
13
|
+
namespace :cleanup do
|
14
|
+
desc "Removes stale access tokens"
|
15
|
+
task revoked_tokens: "doorkeeper:setup" do
|
16
|
+
cleaner = Doorkeeper::StaleRecordsCleaner.new(Doorkeeper.config.access_token_model)
|
17
|
+
cleaner.clean_revoked
|
18
|
+
end
|
19
|
+
|
20
|
+
desc "Removes expired (TTL passed) access tokens"
|
21
|
+
task expired_tokens: "doorkeeper:setup" do
|
22
|
+
expirable_tokens = Doorkeeper.config.access_token_model.where(refresh_token: nil)
|
23
|
+
cleaner = Doorkeeper::StaleRecordsCleaner.new(expirable_tokens)
|
24
|
+
cleaner.clean_expired(Doorkeeper.config.access_token_expires_in)
|
25
|
+
end
|
26
|
+
|
27
|
+
desc "Removes stale access grants"
|
28
|
+
task revoked_grants: "doorkeeper:setup" do
|
29
|
+
cleaner = Doorkeeper::StaleRecordsCleaner.new(Doorkeeper.config.access_grant_model)
|
30
|
+
cleaner.clean_revoked
|
31
|
+
end
|
32
|
+
|
33
|
+
desc "Removes expired (TTL passed) access grants"
|
34
|
+
task expired_grants: "doorkeeper:setup" do
|
35
|
+
cleaner = Doorkeeper::StaleRecordsCleaner.new(Doorkeeper.config.access_grant_model)
|
36
|
+
cleaner.clean_expired(Doorkeeper.config.authorization_code_expires_in)
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -1,18 +1,26 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module Request
|
5
5
|
class AuthorizationCode < Strategy
|
6
|
-
delegate :
|
6
|
+
delegate :client, :parameters, to: :server
|
7
7
|
|
8
8
|
def request
|
9
9
|
@request ||= OAuth::AuthorizationCodeRequest.new(
|
10
|
-
Doorkeeper.
|
10
|
+
Doorkeeper.config,
|
11
11
|
grant,
|
12
12
|
client,
|
13
|
-
parameters
|
13
|
+
parameters,
|
14
14
|
)
|
15
15
|
end
|
16
|
+
|
17
|
+
private
|
18
|
+
|
19
|
+
def grant
|
20
|
+
raise Errors::MissingRequiredParameter, :code if parameters[:code].blank?
|
21
|
+
|
22
|
+
Doorkeeper.config.access_grant_model.by_token(parameters[:code])
|
23
|
+
end
|
16
24
|
end
|
17
25
|
end
|
18
26
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module Request
|
@@ -7,9 +7,9 @@ module Doorkeeper
|
|
7
7
|
|
8
8
|
def request
|
9
9
|
@request ||= OAuth::ClientCredentialsRequest.new(
|
10
|
-
Doorkeeper.
|
10
|
+
Doorkeeper.config,
|
11
11
|
client,
|
12
|
-
parameters
|
12
|
+
parameters,
|
13
13
|
)
|
14
14
|
end
|
15
15
|
end
|
@@ -1,16 +1,17 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module Request
|
5
5
|
class Password < Strategy
|
6
|
-
delegate :credentials, :resource_owner, :parameters, to: :server
|
6
|
+
delegate :credentials, :resource_owner, :parameters, :client, to: :server
|
7
7
|
|
8
8
|
def request
|
9
9
|
@request ||= OAuth::PasswordAccessTokenRequest.new(
|
10
|
-
Doorkeeper.
|
10
|
+
Doorkeeper.config,
|
11
|
+
client,
|
11
12
|
credentials,
|
12
13
|
resource_owner,
|
13
|
-
parameters
|
14
|
+
parameters,
|
14
15
|
)
|
15
16
|
end
|
16
17
|
end
|
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
# frozen_string_literal: true
|
2
2
|
|
3
3
|
module Doorkeeper
|
4
4
|
module Request
|
@@ -6,14 +6,15 @@ module Doorkeeper
|
|
6
6
|
delegate :credentials, :parameters, to: :server
|
7
7
|
|
8
8
|
def refresh_token
|
9
|
-
|
9
|
+
Doorkeeper.config.access_token_model.by_refresh_token(parameters[:refresh_token])
|
10
10
|
end
|
11
11
|
|
12
12
|
def request
|
13
13
|
@request ||= OAuth::RefreshTokenRequest.new(
|
14
|
-
Doorkeeper.
|
15
|
-
refresh_token,
|
16
|
-
|
14
|
+
Doorkeeper.config,
|
15
|
+
refresh_token,
|
16
|
+
credentials,
|
17
|
+
parameters,
|
17
18
|
)
|
18
19
|
end
|
19
20
|
end
|
@@ -1,12 +1,14 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
module Request
|
3
5
|
class Strategy
|
4
|
-
|
6
|
+
attr_reader :server
|
5
7
|
|
6
8
|
delegate :authorize, to: :request
|
7
9
|
|
8
10
|
def initialize(server)
|
9
|
-
|
11
|
+
@server = server
|
10
12
|
end
|
11
13
|
|
12
14
|
def request
|
data/lib/doorkeeper/request.rb
CHANGED
@@ -1,40 +1,73 @@
|
|
1
|
-
|
2
|
-
require 'doorkeeper/request/client_credentials'
|
3
|
-
require 'doorkeeper/request/code'
|
4
|
-
require 'doorkeeper/request/password'
|
5
|
-
require 'doorkeeper/request/refresh_token'
|
6
|
-
require 'doorkeeper/request/token'
|
1
|
+
# frozen_string_literal: true
|
7
2
|
|
8
3
|
module Doorkeeper
|
9
4
|
module Request
|
10
|
-
|
5
|
+
class << self
|
6
|
+
def authorization_strategy(response_type)
|
7
|
+
grant_flow = authorization_flows.detect do |flow|
|
8
|
+
flow.matches_response_type?(response_type)
|
9
|
+
end
|
11
10
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
11
|
+
if grant_flow
|
12
|
+
grant_flow.response_type_strategy
|
13
|
+
else
|
14
|
+
# [NOTE]: this will be removed in a newer versions of Doorkeeper.
|
15
|
+
# For retro-compatibility only
|
16
|
+
build_fallback_strategy_class(response_type)
|
17
|
+
end
|
18
|
+
end
|
17
19
|
|
18
|
-
|
19
|
-
|
20
|
-
rescue NameError
|
21
|
-
raise Errors::InvalidTokenStrategy
|
22
|
-
end
|
20
|
+
def token_strategy(grant_type)
|
21
|
+
raise Errors::MissingRequiredParameter, :grant_type if grant_type.blank?
|
23
22
|
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
"Doorkeeper::Request::#{grant_or_request_type.to_s.camelize}".constantize
|
28
|
-
end
|
23
|
+
grant_flow = token_flows.detect do |flow|
|
24
|
+
flow.matches_grant_type?(grant_type)
|
25
|
+
end
|
29
26
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
27
|
+
if grant_flow
|
28
|
+
grant_flow.grant_type_strategy
|
29
|
+
else
|
30
|
+
# [NOTE]: this will be removed in a newer versions of Doorkeeper.
|
31
|
+
# For retro-compatibility only
|
32
|
+
raise Errors::InvalidTokenStrategy unless available.include?(grant_type.to_s)
|
33
|
+
|
34
|
+
strategy_class = build_fallback_strategy_class(grant_type)
|
35
|
+
raise Errors::InvalidTokenStrategy unless strategy_class
|
36
|
+
|
37
|
+
strategy_class
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
private
|
42
|
+
|
43
|
+
def authorization_flows
|
44
|
+
Doorkeeper.configuration.authorization_response_flows
|
45
|
+
end
|
46
|
+
|
47
|
+
def token_flows
|
48
|
+
Doorkeeper.configuration.token_grant_flows
|
49
|
+
end
|
50
|
+
|
51
|
+
# [NOTE]: this will be removed in a newer versions of Doorkeeper.
|
52
|
+
# For retro-compatibility only
|
53
|
+
def available
|
54
|
+
Doorkeeper.config.deprecated_token_grant_types_resolver
|
55
|
+
end
|
56
|
+
|
57
|
+
def build_fallback_strategy_class(grant_or_request_type)
|
58
|
+
strategy_class_name = grant_or_request_type.to_s.tr(" ", "_").camelize
|
59
|
+
fallback_strategy = "Doorkeeper::Request::#{strategy_class_name}".constantize
|
60
|
+
|
61
|
+
::Kernel.warn <<~WARNING
|
62
|
+
[DOORKEEPER] #{fallback_strategy} found using fallback, it must be
|
63
|
+
registered using `Doorkeeper::GrantFlow.register(grant_flow_name, **options)`.
|
64
|
+
This functionality will be removed in a newer versions of Doorkeeper.
|
65
|
+
WARNING
|
34
66
|
|
35
|
-
|
36
|
-
|
67
|
+
fallback_strategy
|
68
|
+
rescue NameError
|
69
|
+
raise Errors::InvalidTokenStrategy
|
70
|
+
end
|
37
71
|
end
|
38
|
-
private_class_method :token_grant_types
|
39
72
|
end
|
40
73
|
end
|
@@ -0,0 +1,64 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module SecretStoring
|
5
|
+
##
|
6
|
+
# Base class for secret storing, including common helpers
|
7
|
+
class Base
|
8
|
+
##
|
9
|
+
# Return the value to be stored by the database
|
10
|
+
# used for looking up a database value.
|
11
|
+
# @param plain_secret The plain secret input / generated
|
12
|
+
def self.transform_secret(_plain_secret)
|
13
|
+
raise NotImplementedError
|
14
|
+
end
|
15
|
+
|
16
|
+
##
|
17
|
+
# Transform and store the given secret attribute => value
|
18
|
+
# pair used for safely storing the attribute
|
19
|
+
# @param resource The model instance being modified
|
20
|
+
# @param attribute The secret attribute
|
21
|
+
# @param plain_secret The plain secret input / generated
|
22
|
+
def self.store_secret(resource, attribute, plain_secret)
|
23
|
+
transformed_value = transform_secret(plain_secret)
|
24
|
+
resource.public_send(:"#{attribute}=", transformed_value)
|
25
|
+
|
26
|
+
transformed_value
|
27
|
+
end
|
28
|
+
|
29
|
+
##
|
30
|
+
# Return the restored value from the database
|
31
|
+
# @param resource The resource instance to act on
|
32
|
+
# @param attribute The secret attribute to restore
|
33
|
+
# as retrieved from the database.
|
34
|
+
def self.restore_secret(_resource, _attribute)
|
35
|
+
raise NotImplementedError
|
36
|
+
end
|
37
|
+
|
38
|
+
##
|
39
|
+
# Determines whether this strategy supports restoring
|
40
|
+
# secrets from the database. This allows detecting users
|
41
|
+
# trying to use a non-restorable strategy with +reuse_access_tokens+.
|
42
|
+
def self.allows_restoring_secrets?
|
43
|
+
false
|
44
|
+
end
|
45
|
+
|
46
|
+
##
|
47
|
+
# Determines what secrets this strategy is applicable for
|
48
|
+
def self.validate_for(model)
|
49
|
+
valid = %i[token application]
|
50
|
+
return true if valid.include?(model.to_sym)
|
51
|
+
|
52
|
+
raise ArgumentError, "'#{name}' can not be used for #{model}."
|
53
|
+
end
|
54
|
+
|
55
|
+
##
|
56
|
+
# Securely compare the given +input+ value with a +stored+ value
|
57
|
+
# processed by +transform_secret+.
|
58
|
+
def self.secret_matches?(input, stored)
|
59
|
+
transformed_input = transform_secret(input)
|
60
|
+
ActiveSupport::SecurityUtils.secure_compare transformed_input, stored
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module SecretStoring
|
5
|
+
##
|
6
|
+
# Plain text secret storing, which is the default
|
7
|
+
# but also provides fallback lookup if
|
8
|
+
# other secret storing mechanisms are enabled.
|
9
|
+
class BCrypt < Base
|
10
|
+
##
|
11
|
+
# Return the value to be stored by the database
|
12
|
+
# @param plain_secret The plain secret input / generated
|
13
|
+
def self.transform_secret(plain_secret)
|
14
|
+
::BCrypt::Password.create(plain_secret.to_s)
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Securely compare the given +input+ value with a +stored+ value
|
19
|
+
# processed by +transform_secret+.
|
20
|
+
def self.secret_matches?(input, stored)
|
21
|
+
::BCrypt::Password.new(stored.to_s) == input.to_s
|
22
|
+
rescue ::BCrypt::Errors::InvalidHash
|
23
|
+
false
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Determines whether this strategy supports restoring
|
28
|
+
# secrets from the database. This allows detecting users
|
29
|
+
# trying to use a non-restorable strategy with +reuse_access_tokens+.
|
30
|
+
def self.allows_restoring_secrets?
|
31
|
+
false
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Determines what secrets this strategy is applicable for
|
36
|
+
def self.validate_for(model)
|
37
|
+
unless model.to_sym == :application
|
38
|
+
raise ArgumentError,
|
39
|
+
"'#{name}' can only be used for storing application secrets."
|
40
|
+
end
|
41
|
+
|
42
|
+
unless bcrypt_present?
|
43
|
+
raise ArgumentError,
|
44
|
+
"'#{name}' requires the 'bcrypt' gem being loaded."
|
45
|
+
end
|
46
|
+
|
47
|
+
true
|
48
|
+
end
|
49
|
+
|
50
|
+
##
|
51
|
+
# Test if we can require the BCrypt gem
|
52
|
+
def self.bcrypt_present?
|
53
|
+
require "bcrypt"
|
54
|
+
true
|
55
|
+
rescue LoadError
|
56
|
+
false
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module SecretStoring
|
5
|
+
##
|
6
|
+
# Plain text secret storing, which is the default
|
7
|
+
# but also provides fallback lookup if
|
8
|
+
# other secret storing mechanisms are enabled.
|
9
|
+
class Plain < Base
|
10
|
+
##
|
11
|
+
# Return the value to be stored by the database
|
12
|
+
# @param plain_secret The plain secret input / generated
|
13
|
+
def self.transform_secret(plain_secret)
|
14
|
+
plain_secret
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Return the restored value from the database
|
19
|
+
# @param resource The resource instance to act on
|
20
|
+
# @param attribute The secret attribute to restore
|
21
|
+
# as retrieved from the database.
|
22
|
+
def self.restore_secret(resource, attribute)
|
23
|
+
resource.public_send(attribute)
|
24
|
+
end
|
25
|
+
|
26
|
+
##
|
27
|
+
# Plain values obviously allow restoring
|
28
|
+
def self.allows_restoring_secrets?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Doorkeeper
|
4
|
+
module SecretStoring
|
5
|
+
##
|
6
|
+
# Plain text secret storing, which is the default
|
7
|
+
# but also provides fallback lookup if
|
8
|
+
# other secret storing mechanisms are enabled.
|
9
|
+
class Sha256Hash < Base
|
10
|
+
##
|
11
|
+
# Return the value to be stored by the database
|
12
|
+
# @param plain_secret The plain secret input / generated
|
13
|
+
def self.transform_secret(plain_secret)
|
14
|
+
::Digest::SHA256.hexdigest plain_secret
|
15
|
+
end
|
16
|
+
|
17
|
+
##
|
18
|
+
# Determines whether this strategy supports restoring
|
19
|
+
# secrets from the database. This allows detecting users
|
20
|
+
# trying to use a non-restorable strategy with +reuse_access_tokens+.
|
21
|
+
def self.allows_restoring_secrets?
|
22
|
+
false
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/doorkeeper/server.rb
CHANGED
@@ -1,19 +1,21 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
module Doorkeeper
|
2
4
|
class Server
|
3
|
-
|
5
|
+
attr_reader :context
|
4
6
|
|
5
|
-
def initialize(context
|
7
|
+
def initialize(context)
|
6
8
|
@context = context
|
7
9
|
end
|
8
10
|
|
9
11
|
def authorization_request(strategy)
|
10
|
-
klass = Request.authorization_strategy
|
11
|
-
klass.new
|
12
|
+
klass = Request.authorization_strategy(strategy)
|
13
|
+
klass.new(self)
|
12
14
|
end
|
13
15
|
|
14
16
|
def token_request(strategy)
|
15
|
-
klass = Request.token_strategy
|
16
|
-
klass.new
|
17
|
+
klass = Request.token_strategy(strategy)
|
18
|
+
klass.new(self)
|
17
19
|
end
|
18
20
|
|
19
21
|
# TODO: context should be the request
|
@@ -25,29 +27,17 @@ module Doorkeeper
|
|
25
27
|
@client ||= OAuth::Client.authenticate(credentials)
|
26
28
|
end
|
27
29
|
|
28
|
-
def client_via_uid
|
29
|
-
@client_via_uid ||= OAuth::Client.find(parameters[:client_id])
|
30
|
-
end
|
31
|
-
|
32
30
|
def current_resource_owner
|
33
31
|
context.send :current_resource_owner
|
34
32
|
end
|
35
33
|
|
36
|
-
def current_refresh_token
|
37
|
-
AccessToken.by_refresh_token(parameters[:refresh_token])
|
38
|
-
end
|
39
|
-
|
40
|
-
def grant
|
41
|
-
AccessGrant.by_token(parameters[:code])
|
42
|
-
end
|
43
|
-
|
44
34
|
# TODO: Use configuration and evaluate proper context on block
|
45
35
|
def resource_owner
|
46
36
|
context.send :resource_owner_from_credentials
|
47
37
|
end
|
48
38
|
|
49
39
|
def credentials
|
50
|
-
methods = Doorkeeper.
|
40
|
+
methods = Doorkeeper.config.client_credentials_methods
|
51
41
|
@credentials ||= OAuth::Client::Credentials.from_request(context.request, *methods)
|
52
42
|
end
|
53
43
|
end
|