doorkeeper 5.3.0 → 5.4.0
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/CHANGELOG.md +97 -1
- data/README.md +6 -4
- data/app/controllers/doorkeeper/applications_controller.rb +7 -7
- data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
- data/app/controllers/doorkeeper/authorized_applications_controller.rb +3 -3
- data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
- data/app/views/doorkeeper/applications/_form.html.erb +1 -1
- data/app/views/doorkeeper/applications/show.html.erb +19 -2
- data/config/locales/en.yml +3 -1
- data/lib/doorkeeper/config/abstract_builder.rb +28 -0
- data/lib/doorkeeper/config/option.rb +28 -14
- data/lib/doorkeeper/config.rb +65 -35
- data/lib/doorkeeper/engine.rb +1 -1
- data/lib/doorkeeper/grape/helpers.rb +1 -1
- data/lib/doorkeeper/helpers/controller.rb +4 -4
- data/lib/doorkeeper/models/access_grant_mixin.rb +20 -16
- data/lib/doorkeeper/models/access_token_mixin.rb +110 -46
- data/lib/doorkeeper/models/application_mixin.rb +5 -4
- data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
- data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
- 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 +15 -6
- data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
- data/lib/doorkeeper/oauth/authorization/token.rb +8 -12
- data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
- data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
- data/lib/doorkeeper/oauth/base_request.rb +11 -19
- data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
- data/lib/doorkeeper/oauth/client.rb +1 -1
- data/lib/doorkeeper/oauth/client_credentials/creator.rb +26 -8
- data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
- data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
- data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
- data/lib/doorkeeper/oauth/code_request.rb +3 -3
- data/lib/doorkeeper/oauth/code_response.rb +6 -2
- data/lib/doorkeeper/oauth/error_response.rb +2 -4
- data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
- data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
- data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
- data/lib/doorkeeper/oauth/password_access_token_request.rb +4 -6
- data/lib/doorkeeper/oauth/pre_authorization.rb +36 -30
- data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
- data/lib/doorkeeper/oauth/token.rb +5 -6
- data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
- data/lib/doorkeeper/oauth/token_request.rb +3 -3
- data/lib/doorkeeper/oauth/token_response.rb +1 -1
- data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
- data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
- data/lib/doorkeeper/orm/active_record/mixins/application.rb +69 -10
- data/lib/doorkeeper/orm/active_record.rb +10 -2
- 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 +13 -17
- data/lib/doorkeeper/request/refresh_token.rb +2 -1
- data/lib/doorkeeper/request/strategy.rb +2 -2
- data/lib/doorkeeper/server.rb +4 -4
- data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
- data/lib/doorkeeper/version.rb +1 -1
- data/lib/doorkeeper.rb +106 -79
- data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
- data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
- data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
- 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 +47 -3
- data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
- metadata +12 -295
- 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 -274
- data/spec/controllers/authorizations_controller_spec.rb +0 -608
- data/spec/controllers/protected_resources_controller_spec.rb +0 -361
- 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 -794
- 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 -170
- data/spec/lib/oauth/base_request_spec.rb +0 -224
- data/spec/lib/oauth/base_response_spec.rb +0 -45
- data/spec/lib/oauth/client/credentials_spec.rb +0 -90
- data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
- 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 -27
- data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
- 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 -32
- data/spec/lib/oauth/error_response_spec.rb +0 -64
- data/spec/lib/oauth/error_spec.rb +0 -21
- data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
- data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
- 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 -73
- data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
- data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
- data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
- data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
- data/spec/lib/oauth/scopes_spec.rb +0 -146
- data/spec/lib/oauth/token_request_spec.rb +0 -157
- data/spec/lib/oauth/token_response_spec.rb +0 -84
- data/spec/lib/oauth/token_spec.rb +0 -156
- 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 -161
- data/spec/models/doorkeeper/access_token_spec.rb +0 -622
- data/spec/models/doorkeeper/application_spec.rb +0 -404
- 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 -91
- 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 -525
- 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 -316
- data/spec/requests/flows/refresh_token_spec.rb +0 -233
- data/spec/requests/flows/revoke_token_spec.rb +0 -157
- 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 -54
- 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/orm/active_record.rb +0 -5
- data/spec/support/shared/controllers_shared_context.rb +0 -133
- data/spec/support/shared/hashing_shared_context.rb +0 -36
- data/spec/support/shared/models_shared_examples.rb +0 -54
- data/spec/validators/redirect_uri_validator_spec.rb +0 -183
- data/spec/version/version_spec.rb +0 -17
data/lib/doorkeeper/config.rb
CHANGED
|
@@ -1,16 +1,24 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
3
|
require "doorkeeper/config/option"
|
|
4
|
+
require "doorkeeper/config/abstract_builder"
|
|
4
5
|
|
|
5
6
|
module Doorkeeper
|
|
7
|
+
# Defines a MissingConfiguration error for a missing Doorkeeper configuration
|
|
8
|
+
#
|
|
6
9
|
class MissingConfiguration < StandardError
|
|
7
|
-
# Defines a MissingConfiguration error for a missing Doorkeeper
|
|
8
|
-
# configuration
|
|
9
10
|
def initialize
|
|
10
11
|
super("Configuration for doorkeeper missing. Do you have doorkeeper initializer?")
|
|
11
12
|
end
|
|
12
13
|
end
|
|
13
14
|
|
|
15
|
+
# Doorkeeper option DSL could be reused in extensions to build their own
|
|
16
|
+
# configurations. To use the Option DSL gems need to define `builder_class` method
|
|
17
|
+
# that returns configuration Builder class. This exception raises when they don't
|
|
18
|
+
# define it.
|
|
19
|
+
#
|
|
20
|
+
class MissingConfigurationBuilderClass < StandardError; end
|
|
21
|
+
|
|
14
22
|
class << self
|
|
15
23
|
def configure(&block)
|
|
16
24
|
@config = Config::Builder.new(&block).build
|
|
@@ -30,7 +38,7 @@ module Doorkeeper
|
|
|
30
38
|
@orm_adapter = "doorkeeper/orm/#{configuration.orm}".classify.constantize
|
|
31
39
|
rescue NameError => e
|
|
32
40
|
raise e, "ORM adapter not found (#{configuration.orm})", <<-ERROR_MSG.strip_heredoc
|
|
33
|
-
[
|
|
41
|
+
[DOORKEEPER] ORM adapter not found (#{configuration.orm}), or there was an error
|
|
34
42
|
trying to load it.
|
|
35
43
|
|
|
36
44
|
You probably need to add the related gem for this adapter to work with
|
|
@@ -48,17 +56,8 @@ module Doorkeeper
|
|
|
48
56
|
end
|
|
49
57
|
|
|
50
58
|
class Config
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
@config = Config.new
|
|
54
|
-
instance_eval(&block)
|
|
55
|
-
end
|
|
56
|
-
|
|
57
|
-
def build
|
|
58
|
-
@config.validate
|
|
59
|
-
@config
|
|
60
|
-
end
|
|
61
|
-
|
|
59
|
+
# Default Doorkeeper configuration builder
|
|
60
|
+
class Builder < AbstractBuilder
|
|
62
61
|
# Provide support for an owner to be assigned to each registered
|
|
63
62
|
# application (disabled by default)
|
|
64
63
|
# Optional parameter confirmation: true (default false) if you want
|
|
@@ -135,15 +134,6 @@ module Doorkeeper
|
|
|
135
134
|
@config.instance_variable_set(:@reuse_access_token, true)
|
|
136
135
|
end
|
|
137
136
|
|
|
138
|
-
# Sets the token_reuse_limit
|
|
139
|
-
# It will be used only when reuse_access_token option in enabled
|
|
140
|
-
# By default it will be 100
|
|
141
|
-
# It will be used for token reusablity to some threshold percentage
|
|
142
|
-
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
|
|
143
|
-
def token_reuse_limit(percentage)
|
|
144
|
-
@config.instance_variable_set(:@token_reuse_limit, percentage)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
137
|
# TODO: maybe make it more generic for other flows too?
|
|
148
138
|
# Only allow one valid access token obtained via client credentials
|
|
149
139
|
# per client. If a new access token is obtained before the old one
|
|
@@ -158,6 +148,12 @@ module Doorkeeper
|
|
|
158
148
|
@config.instance_variable_set(:@api_only, true)
|
|
159
149
|
end
|
|
160
150
|
|
|
151
|
+
# Enables polymorphic Resource Owner association for Access Grant and
|
|
152
|
+
# Access Token models. Requires additional database columns to be setup.
|
|
153
|
+
def use_polymorphic_resource_owner
|
|
154
|
+
@config.instance_variable_set(:@polymorphic_resource_owner, true)
|
|
155
|
+
end
|
|
156
|
+
|
|
161
157
|
# Forbids creating/updating applications with arbitrary scopes that are
|
|
162
158
|
# not in configuration, i.e. `default_scopes` or `optional_scopes`.
|
|
163
159
|
# (disabled by default)
|
|
@@ -219,6 +215,9 @@ module Doorkeeper
|
|
|
219
215
|
end
|
|
220
216
|
end
|
|
221
217
|
|
|
218
|
+
# Replace with `default: Builder` when we drop support of Rails < 5.2
|
|
219
|
+
mattr_reader(:builder_class) { Builder }
|
|
220
|
+
|
|
222
221
|
extend Option
|
|
223
222
|
|
|
224
223
|
option :resource_owner_authenticator,
|
|
@@ -251,8 +250,8 @@ module Doorkeeper
|
|
|
251
250
|
end)
|
|
252
251
|
|
|
253
252
|
# Hooks for authorization
|
|
254
|
-
option :before_successful_authorization, default: ->(_context) {}
|
|
255
|
-
option :after_successful_authorization, default: ->(_context) {}
|
|
253
|
+
option :before_successful_authorization, default: ->(_controller, _context = nil) {}
|
|
254
|
+
option :after_successful_authorization, default: ->(_controller, _context = nil) {}
|
|
256
255
|
# Hooks for strategies responses
|
|
257
256
|
option :before_successful_strategy_response, default: ->(_request) {}
|
|
258
257
|
option :after_successful_strategy_response, default: ->(_request, _response) {}
|
|
@@ -265,9 +264,24 @@ module Doorkeeper
|
|
|
265
264
|
option :authorization_code_expires_in, default: 600
|
|
266
265
|
option :orm, default: :active_record
|
|
267
266
|
option :native_redirect_uri, default: "urn:ietf:wg:oauth:2.0:oob", deprecated: true
|
|
268
|
-
option :active_record_options, default: {}
|
|
269
267
|
option :grant_flows, default: %w[authorization_code client_credentials]
|
|
270
268
|
option :handle_auth_errors, default: :render
|
|
269
|
+
option :token_lookup_batch_size, default: 10_000
|
|
270
|
+
|
|
271
|
+
# Sets the token_reuse_limit
|
|
272
|
+
# It will be used only when reuse_access_token option in enabled
|
|
273
|
+
# By default it will be 100
|
|
274
|
+
# It will be used for token reusablity to some threshold percentage
|
|
275
|
+
# Rationale: https://github.com/doorkeeper-gem/doorkeeper/issues/1189
|
|
276
|
+
option :token_reuse_limit, default: 100
|
|
277
|
+
|
|
278
|
+
option :active_record_options,
|
|
279
|
+
default: {},
|
|
280
|
+
deprecated: { message: "Customize Doorkeeper models instead" }
|
|
281
|
+
|
|
282
|
+
# Hook to allow arbitrary user-client authorization
|
|
283
|
+
option :authorize_resource_owner_for_client,
|
|
284
|
+
default: ->(_client, _resource_owner) { true }
|
|
271
285
|
|
|
272
286
|
# Allows to customize OAuth grant flows that +each+ application support.
|
|
273
287
|
# You can configure a custom block (or use a class respond to `#call`) that must
|
|
@@ -410,20 +424,32 @@ module Doorkeeper
|
|
|
410
424
|
:application_secret_fallback_strategy
|
|
411
425
|
|
|
412
426
|
# Return the valid subset of this configuration
|
|
413
|
-
def validate
|
|
427
|
+
def validate!
|
|
414
428
|
validate_reuse_access_token_value
|
|
415
429
|
validate_token_reuse_limit
|
|
416
430
|
validate_secret_strategies
|
|
417
431
|
end
|
|
418
432
|
|
|
433
|
+
# Doorkeeper Access Token model class.
|
|
434
|
+
#
|
|
435
|
+
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
|
436
|
+
#
|
|
419
437
|
def access_token_model
|
|
420
438
|
@access_token_model ||= access_token_class.constantize
|
|
421
439
|
end
|
|
422
440
|
|
|
441
|
+
# Doorkeeper Access Grant model class.
|
|
442
|
+
#
|
|
443
|
+
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
|
444
|
+
#
|
|
423
445
|
def access_grant_model
|
|
424
446
|
@access_grant_model ||= access_grant_class.constantize
|
|
425
447
|
end
|
|
426
448
|
|
|
449
|
+
# Doorkeeper Application model class.
|
|
450
|
+
#
|
|
451
|
+
# @return [ActiveRecord::Base, Mongoid::Document, Sequel::Model]
|
|
452
|
+
#
|
|
427
453
|
def application_model
|
|
428
454
|
@application_model ||= application_class.constantize
|
|
429
455
|
end
|
|
@@ -444,14 +470,6 @@ module Doorkeeper
|
|
|
444
470
|
end
|
|
445
471
|
end
|
|
446
472
|
|
|
447
|
-
def token_reuse_limit
|
|
448
|
-
@token_reuse_limit ||= 100
|
|
449
|
-
end
|
|
450
|
-
|
|
451
|
-
def revoke_previous_client_credentials_token
|
|
452
|
-
@revoke_previous_client_credentials_token || false
|
|
453
|
-
end
|
|
454
|
-
|
|
455
473
|
def resolve_controller(name)
|
|
456
474
|
config_option = public_send(:"#{name}_controller")
|
|
457
475
|
controller_name = if config_option.respond_to?(:call)
|
|
@@ -463,6 +481,10 @@ module Doorkeeper
|
|
|
463
481
|
controller_name.constantize
|
|
464
482
|
end
|
|
465
483
|
|
|
484
|
+
def revoke_previous_client_credentials_token?
|
|
485
|
+
option_set? :revoke_previous_client_credentials_token
|
|
486
|
+
end
|
|
487
|
+
|
|
466
488
|
def enforce_configured_scopes?
|
|
467
489
|
option_set? :enforce_configured_scopes
|
|
468
490
|
end
|
|
@@ -471,6 +493,10 @@ module Doorkeeper
|
|
|
471
493
|
option_set? :enable_application_owner
|
|
472
494
|
end
|
|
473
495
|
|
|
496
|
+
def polymorphic_resource_owner?
|
|
497
|
+
option_set? :polymorphic_resource_owner
|
|
498
|
+
end
|
|
499
|
+
|
|
474
500
|
def confirm_application_owner?
|
|
475
501
|
option_set? :confirm_application_owner
|
|
476
502
|
end
|
|
@@ -479,6 +505,10 @@ module Doorkeeper
|
|
|
479
505
|
handle_auth_errors == :raise
|
|
480
506
|
end
|
|
481
507
|
|
|
508
|
+
def application_secret_hashed?
|
|
509
|
+
instance_variable_defined?(:"@application_secret_strategy")
|
|
510
|
+
end
|
|
511
|
+
|
|
482
512
|
def token_secret_strategy
|
|
483
513
|
@token_secret_strategy ||= ::Doorkeeper::SecretStoring::Plain
|
|
484
514
|
end
|
data/lib/doorkeeper/engine.rb
CHANGED
|
@@ -4,7 +4,7 @@ module Doorkeeper
|
|
|
4
4
|
class Engine < Rails::Engine
|
|
5
5
|
initializer "doorkeeper.params.filter" do |app|
|
|
6
6
|
parameters = %w[client_secret code authentication_token access_token refresh_token]
|
|
7
|
-
app.config.filter_parameters << /^(#{Regexp.union
|
|
7
|
+
app.config.filter_parameters << /^(#{Regexp.union(parameters)})$/
|
|
8
8
|
end
|
|
9
9
|
|
|
10
10
|
initializer "doorkeeper.routes" do
|
|
@@ -36,7 +36,7 @@ module Doorkeeper
|
|
|
36
36
|
|
|
37
37
|
# :doc:
|
|
38
38
|
def doorkeeper_token
|
|
39
|
-
@doorkeeper_token ||= OAuth::Token.authenticate
|
|
39
|
+
@doorkeeper_token ||= OAuth::Token.authenticate(request, *config_methods)
|
|
40
40
|
end
|
|
41
41
|
|
|
42
42
|
def config_methods
|
|
@@ -58,10 +58,10 @@ module Doorkeeper
|
|
|
58
58
|
end
|
|
59
59
|
|
|
60
60
|
def handle_token_exception(exception)
|
|
61
|
-
error = get_error_response_from_exception
|
|
62
|
-
headers.merge!
|
|
61
|
+
error = get_error_response_from_exception(exception)
|
|
62
|
+
headers.merge!(error.headers)
|
|
63
63
|
self.response_body = error.body.to_json
|
|
64
|
-
self.status
|
|
64
|
+
self.status = error.status
|
|
65
65
|
end
|
|
66
66
|
|
|
67
67
|
def skip_authorization?
|
|
@@ -11,14 +11,11 @@ module Doorkeeper
|
|
|
11
11
|
include Models::Orderable
|
|
12
12
|
include Models::SecretStorable
|
|
13
13
|
include Models::Scopes
|
|
14
|
+
include Models::ResourceOwnerable
|
|
14
15
|
|
|
15
|
-
#
|
|
16
|
+
# Never uses PKCE if PKCE migrations were not generated
|
|
16
17
|
def uses_pkce?
|
|
17
|
-
pkce_supported? && code_challenge.present?
|
|
18
|
-
end
|
|
19
|
-
|
|
20
|
-
def pkce_supported?
|
|
21
|
-
respond_to? :code_challenge
|
|
18
|
+
self.class.pkce_supported? && code_challenge.present?
|
|
22
19
|
end
|
|
23
20
|
|
|
24
21
|
module ClassMethods
|
|
@@ -27,8 +24,8 @@ module Doorkeeper
|
|
|
27
24
|
#
|
|
28
25
|
# @param token [#to_s] token value (any object that responds to `#to_s`)
|
|
29
26
|
#
|
|
30
|
-
# @return [Doorkeeper::AccessGrant, nil]
|
|
31
|
-
# if there is no record with such token
|
|
27
|
+
# @return [Doorkeeper::AccessGrant, nil]
|
|
28
|
+
# AccessGrant object or nil if there is no record with such token
|
|
32
29
|
#
|
|
33
30
|
def by_token(token)
|
|
34
31
|
find_by_plaintext_token(:token, token)
|
|
@@ -39,15 +36,16 @@ module Doorkeeper
|
|
|
39
36
|
#
|
|
40
37
|
# @param application_id [Integer]
|
|
41
38
|
# ID of the Application
|
|
42
|
-
# @param resource_owner [ActiveRecord::Base]
|
|
43
|
-
# instance of the Resource Owner model
|
|
39
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
40
|
+
# instance of the Resource Owner model or it's ID
|
|
44
41
|
#
|
|
45
42
|
def revoke_all_for(application_id, resource_owner, clock = Time)
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
43
|
+
by_resource_owner(resource_owner)
|
|
44
|
+
.where(
|
|
45
|
+
application_id: application_id,
|
|
46
|
+
revoked_at: nil,
|
|
47
|
+
)
|
|
48
|
+
.update_all(revoked_at: clock.now.utc)
|
|
51
49
|
end
|
|
52
50
|
|
|
53
51
|
# Implements PKCE code_challenge encoding without base64 padding as described in the spec.
|
|
@@ -96,12 +94,15 @@ module Doorkeeper
|
|
|
96
94
|
end
|
|
97
95
|
|
|
98
96
|
def pkce_supported?
|
|
99
|
-
|
|
97
|
+
column_names.include?("code_challenge")
|
|
100
98
|
end
|
|
101
99
|
|
|
102
100
|
##
|
|
103
101
|
# Determines the secret storing transformer
|
|
104
102
|
# Unless configured otherwise, uses the plain secret strategy
|
|
103
|
+
#
|
|
104
|
+
# @return [Doorkeeper::SecretStoring::Base]
|
|
105
|
+
#
|
|
105
106
|
def secret_strategy
|
|
106
107
|
::Doorkeeper.config.token_secret_strategy
|
|
107
108
|
end
|
|
@@ -109,6 +110,9 @@ module Doorkeeper
|
|
|
109
110
|
##
|
|
110
111
|
# Determine the fallback storing strategy
|
|
111
112
|
# Unless configured, there will be no fallback
|
|
113
|
+
#
|
|
114
|
+
# @return [Doorkeeper::SecretStoring::Base]
|
|
115
|
+
#
|
|
112
116
|
def fallback_secret_strategy
|
|
113
117
|
::Doorkeeper.config.token_secret_fallback_strategy
|
|
114
118
|
end
|
|
@@ -12,6 +12,7 @@ module Doorkeeper
|
|
|
12
12
|
include Models::Orderable
|
|
13
13
|
include Models::SecretStorable
|
|
14
14
|
include Models::Scopes
|
|
15
|
+
include Models::ResourceOwnerable
|
|
15
16
|
|
|
16
17
|
module ClassMethods
|
|
17
18
|
# Returns an instance of the Doorkeeper::AccessToken with
|
|
@@ -60,15 +61,16 @@ module Doorkeeper
|
|
|
60
61
|
#
|
|
61
62
|
# @param application_id [Integer]
|
|
62
63
|
# ID of the Application
|
|
63
|
-
# @param resource_owner [ActiveRecord::Base]
|
|
64
|
-
# instance of the Resource Owner model
|
|
64
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
65
|
+
# instance of the Resource Owner model or it's ID
|
|
65
66
|
#
|
|
66
67
|
def revoke_all_for(application_id, resource_owner, clock = Time)
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
68
|
+
by_resource_owner(resource_owner)
|
|
69
|
+
.where(
|
|
70
|
+
application_id: application_id,
|
|
71
|
+
revoked_at: nil,
|
|
72
|
+
)
|
|
73
|
+
.update_all(revoked_at: clock.now.utc)
|
|
72
74
|
end
|
|
73
75
|
|
|
74
76
|
# Looking for not revoked Access Token with a matching set of scopes
|
|
@@ -76,7 +78,7 @@ module Doorkeeper
|
|
|
76
78
|
#
|
|
77
79
|
# @param application [Doorkeeper::Application]
|
|
78
80
|
# Application instance
|
|
79
|
-
# @param
|
|
81
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
80
82
|
# Resource Owner model instance or it's ID
|
|
81
83
|
# @param scopes [String, Doorkeeper::OAuth::Scopes]
|
|
82
84
|
# set of scopes
|
|
@@ -84,14 +86,8 @@ module Doorkeeper
|
|
|
84
86
|
# @return [Doorkeeper::AccessToken, nil] Access Token instance or
|
|
85
87
|
# nil if matching record was not found
|
|
86
88
|
#
|
|
87
|
-
def matching_token_for(application,
|
|
88
|
-
|
|
89
|
-
resource_owner_or_id.id
|
|
90
|
-
else
|
|
91
|
-
resource_owner_or_id
|
|
92
|
-
end
|
|
93
|
-
|
|
94
|
-
tokens = authorized_tokens_for(application.try(:id), resource_owner_id)
|
|
89
|
+
def matching_token_for(application, resource_owner, scopes)
|
|
90
|
+
tokens = authorized_tokens_for(application&.id, resource_owner)
|
|
95
91
|
find_matching_token(tokens, application, scopes)
|
|
96
92
|
end
|
|
97
93
|
|
|
@@ -126,10 +122,11 @@ module Doorkeeper
|
|
|
126
122
|
return nil unless relation
|
|
127
123
|
|
|
128
124
|
matching_tokens = []
|
|
125
|
+
batch_size = Doorkeeper.configuration.token_lookup_batch_size
|
|
129
126
|
|
|
130
|
-
find_access_token_in_batches(relation) do |batch|
|
|
127
|
+
find_access_token_in_batches(relation, batch_size: batch_size) do |batch|
|
|
131
128
|
tokens = batch.select do |token|
|
|
132
|
-
scopes_match?(token.scopes, scopes, application
|
|
129
|
+
scopes_match?(token.scopes, scopes, application&.scopes)
|
|
133
130
|
end
|
|
134
131
|
|
|
135
132
|
matching_tokens.concat(tokens)
|
|
@@ -169,47 +166,79 @@ module Doorkeeper
|
|
|
169
166
|
#
|
|
170
167
|
# @param application [Doorkeeper::Application]
|
|
171
168
|
# Application instance
|
|
172
|
-
# @param
|
|
169
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
173
170
|
# Resource Owner model instance or it's ID
|
|
174
171
|
# @param scopes [#to_s]
|
|
175
172
|
# set of scopes (any object that responds to `#to_s`)
|
|
176
|
-
# @param
|
|
173
|
+
# @param token_attributes [Hash]
|
|
174
|
+
# Additional attributes to use when creating a token
|
|
175
|
+
# @option token_attributes [Integer] :expires_in
|
|
177
176
|
# token lifetime in seconds
|
|
178
|
-
# @
|
|
177
|
+
# @option token_attributes [Boolean] :use_refresh_token
|
|
179
178
|
# whether to use the refresh token
|
|
180
179
|
#
|
|
181
180
|
# @return [Doorkeeper::AccessToken] existing record or a new one
|
|
182
181
|
#
|
|
183
|
-
def find_or_create_for(application
|
|
182
|
+
def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes)
|
|
184
183
|
if Doorkeeper.config.reuse_access_token
|
|
185
|
-
access_token = matching_token_for(application,
|
|
184
|
+
access_token = matching_token_for(application, resource_owner, scopes)
|
|
186
185
|
|
|
187
186
|
return access_token if access_token&.reusable?
|
|
188
187
|
end
|
|
189
188
|
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
scopes: scopes
|
|
194
|
-
|
|
195
|
-
use_refresh_token: use_refresh_token,
|
|
189
|
+
create_for(
|
|
190
|
+
application: application,
|
|
191
|
+
resource_owner: resource_owner,
|
|
192
|
+
scopes: scopes,
|
|
193
|
+
**token_attributes,
|
|
196
194
|
)
|
|
197
195
|
end
|
|
198
196
|
|
|
197
|
+
# Creates a not expired AccessToken record with a matching set of
|
|
198
|
+
# scopes that belongs to specific Application and Resource Owner.
|
|
199
|
+
#
|
|
200
|
+
# @param application [Doorkeeper::Application]
|
|
201
|
+
# Application instance
|
|
202
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
203
|
+
# Resource Owner model instance or it's ID
|
|
204
|
+
# @param scopes [#to_s]
|
|
205
|
+
# set of scopes (any object that responds to `#to_s`)
|
|
206
|
+
# @param token_attributes [Hash]
|
|
207
|
+
# Additional attributes to use when creating a token
|
|
208
|
+
# @option token_attributes [Integer] :expires_in
|
|
209
|
+
# token lifetime in seconds
|
|
210
|
+
# @option token_attributes [Boolean] :use_refresh_token
|
|
211
|
+
# whether to use the refresh token
|
|
212
|
+
#
|
|
213
|
+
# @return [Doorkeeper::AccessToken] new access token
|
|
214
|
+
#
|
|
215
|
+
def create_for(application:, resource_owner:, scopes:, **token_attributes)
|
|
216
|
+
token_attributes[:application_id] = application&.id
|
|
217
|
+
token_attributes[:scopes] = scopes.to_s
|
|
218
|
+
|
|
219
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
|
220
|
+
token_attributes[:resource_owner] = resource_owner
|
|
221
|
+
else
|
|
222
|
+
token_attributes[:resource_owner_id] = resource_owner_id_for(resource_owner)
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
create!(token_attributes)
|
|
226
|
+
end
|
|
227
|
+
|
|
199
228
|
# Looking for not revoked Access Token records that belongs to specific
|
|
200
229
|
# Application and Resource Owner.
|
|
201
230
|
#
|
|
202
231
|
# @param application_id [Integer]
|
|
203
232
|
# ID of the Application model instance
|
|
204
|
-
# @param
|
|
205
|
-
#
|
|
233
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
234
|
+
# Resource Owner model instance or it's ID
|
|
206
235
|
#
|
|
207
|
-
# @return [
|
|
236
|
+
# @return [ActiveRecord::Relation]
|
|
237
|
+
# collection of matching AccessToken objects
|
|
208
238
|
#
|
|
209
|
-
def authorized_tokens_for(application_id,
|
|
210
|
-
where(
|
|
239
|
+
def authorized_tokens_for(application_id, resource_owner)
|
|
240
|
+
by_resource_owner(resource_owner).where(
|
|
211
241
|
application_id: application_id,
|
|
212
|
-
resource_owner_id: resource_owner_id,
|
|
213
242
|
revoked_at: nil,
|
|
214
243
|
)
|
|
215
244
|
end
|
|
@@ -219,20 +248,24 @@ module Doorkeeper
|
|
|
219
248
|
#
|
|
220
249
|
# @param application_id [Integer]
|
|
221
250
|
# ID of the Application model instance
|
|
222
|
-
# @param
|
|
251
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
223
252
|
# ID of the Resource Owner model instance
|
|
224
253
|
#
|
|
225
254
|
# @return [Doorkeeper::AccessToken, nil] matching AccessToken object or
|
|
226
255
|
# nil if nothing was found
|
|
227
256
|
#
|
|
228
|
-
def last_authorized_token_for(application_id,
|
|
229
|
-
authorized_tokens_for(application_id,
|
|
230
|
-
.ordered_by(:created_at, :desc)
|
|
257
|
+
def last_authorized_token_for(application_id, resource_owner)
|
|
258
|
+
authorized_tokens_for(application_id, resource_owner)
|
|
259
|
+
.ordered_by(:created_at, :desc)
|
|
260
|
+
.first
|
|
231
261
|
end
|
|
232
262
|
|
|
233
263
|
##
|
|
234
264
|
# Determines the secret storing transformer
|
|
235
265
|
# Unless configured otherwise, uses the plain secret strategy
|
|
266
|
+
#
|
|
267
|
+
# @return [Doorkeeper::SecretStoring::Base]
|
|
268
|
+
#
|
|
236
269
|
def secret_strategy
|
|
237
270
|
::Doorkeeper.config.token_secret_strategy
|
|
238
271
|
end
|
|
@@ -268,7 +301,11 @@ module Doorkeeper
|
|
|
268
301
|
expires_in: expires_in_seconds,
|
|
269
302
|
application: { uid: application.try(:uid) },
|
|
270
303
|
created_at: created_at.to_i,
|
|
271
|
-
}
|
|
304
|
+
}.tap do |json|
|
|
305
|
+
if Doorkeeper.configuration.polymorphic_resource_owner?
|
|
306
|
+
json[:resource_owner_type] = resource_owner_type
|
|
307
|
+
end
|
|
308
|
+
end
|
|
272
309
|
end
|
|
273
310
|
|
|
274
311
|
# Indicates whether the token instance have the same credential
|
|
@@ -280,7 +317,22 @@ module Doorkeeper
|
|
|
280
317
|
#
|
|
281
318
|
def same_credential?(access_token)
|
|
282
319
|
application_id == access_token.application_id &&
|
|
320
|
+
same_resource_owner?(access_token)
|
|
321
|
+
end
|
|
322
|
+
|
|
323
|
+
# Indicates whether the token instance have the same credential
|
|
324
|
+
# as the other Access Token.
|
|
325
|
+
#
|
|
326
|
+
# @param access_token [Doorkeeper::AccessToken] other token
|
|
327
|
+
#
|
|
328
|
+
# @return [Boolean] true if credentials are same of false in other cases
|
|
329
|
+
#
|
|
330
|
+
def same_resource_owner?(access_token)
|
|
331
|
+
if Doorkeeper.configuration.polymorphic_resource_owner?
|
|
332
|
+
resource_owner == access_token.resource_owner
|
|
333
|
+
else
|
|
283
334
|
resource_owner_id == access_token.resource_owner_id
|
|
335
|
+
end
|
|
284
336
|
end
|
|
285
337
|
|
|
286
338
|
# Indicates if token is acceptable for specific scopes.
|
|
@@ -325,7 +377,7 @@ module Doorkeeper
|
|
|
325
377
|
return unless self.class.refresh_token_revoked_on_use?
|
|
326
378
|
|
|
327
379
|
old_refresh_token&.revoke
|
|
328
|
-
|
|
380
|
+
update_column(:previous_refresh_token, "")
|
|
329
381
|
end
|
|
330
382
|
|
|
331
383
|
private
|
|
@@ -362,16 +414,28 @@ module Doorkeeper
|
|
|
362
414
|
def generate_token
|
|
363
415
|
self.created_at ||= Time.now.utc
|
|
364
416
|
|
|
365
|
-
@raw_token = token_generator.generate(
|
|
417
|
+
@raw_token = token_generator.generate(attributes_for_token_generator)
|
|
418
|
+
secret_strategy.store_secret(self, :token, @raw_token)
|
|
419
|
+
@raw_token
|
|
420
|
+
end
|
|
421
|
+
|
|
422
|
+
# Set of attributes that would be passed to token generator to
|
|
423
|
+
# generate unique token based on them.
|
|
424
|
+
#
|
|
425
|
+
# @return [Hash] set of attributes
|
|
426
|
+
#
|
|
427
|
+
def attributes_for_token_generator
|
|
428
|
+
{
|
|
366
429
|
resource_owner_id: resource_owner_id,
|
|
367
430
|
scopes: scopes,
|
|
368
431
|
application: application,
|
|
369
432
|
expires_in: expires_in,
|
|
370
433
|
created_at: created_at,
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
434
|
+
}.tap do |attributes|
|
|
435
|
+
if Doorkeeper.config.polymorphic_resource_owner?
|
|
436
|
+
attributes[:resource_owner] = resource_owner
|
|
437
|
+
end
|
|
438
|
+
end
|
|
375
439
|
end
|
|
376
440
|
|
|
377
441
|
def token_generator
|
|
@@ -20,8 +20,8 @@ module Doorkeeper
|
|
|
20
20
|
# @param uid [#to_s] UID (any object that responds to `#to_s`)
|
|
21
21
|
# @param secret [#to_s] secret (any object that responds to `#to_s`)
|
|
22
22
|
#
|
|
23
|
-
# @return [Doorkeeper::Application, nil]
|
|
24
|
-
# if there is no record with such credentials
|
|
23
|
+
# @return [Doorkeeper::Application, nil]
|
|
24
|
+
# Application instance or nil if there is no record with such credentials
|
|
25
25
|
#
|
|
26
26
|
def by_uid_and_secret(uid, secret)
|
|
27
27
|
app = by_uid(uid)
|
|
@@ -60,9 +60,10 @@ module Doorkeeper
|
|
|
60
60
|
|
|
61
61
|
# Set an application's valid redirect URIs.
|
|
62
62
|
#
|
|
63
|
-
# @param uris [String, Array] Newline-separated string or array the URI(s)
|
|
63
|
+
# @param uris [String, Array<String>] Newline-separated string or array the URI(s)
|
|
64
|
+
#
|
|
65
|
+
# @return [String] The redirect URI(s) separated by newlines.
|
|
64
66
|
#
|
|
65
|
-
# @return [String] The redirect URI(s) seperated by newlines.
|
|
66
67
|
def redirect_uri=(uris)
|
|
67
68
|
super(uris.is_a?(Array) ? uris.join("\n") : uris)
|
|
68
69
|
end
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
module Doorkeeper
|
|
4
|
+
module Models
|
|
5
|
+
module ResourceOwnerable
|
|
6
|
+
extend ActiveSupport::Concern
|
|
7
|
+
|
|
8
|
+
module ClassMethods
|
|
9
|
+
# Searches for record by Resource Owner considering Doorkeeper
|
|
10
|
+
# configuration for resource owner association.
|
|
11
|
+
#
|
|
12
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
13
|
+
# resource owner
|
|
14
|
+
#
|
|
15
|
+
# @return [Doorkeeper::AccessGrant, Doorkeeper::AccessToken]
|
|
16
|
+
# collection of records
|
|
17
|
+
#
|
|
18
|
+
def by_resource_owner(resource_owner)
|
|
19
|
+
if Doorkeeper.configuration.polymorphic_resource_owner?
|
|
20
|
+
where(resource_owner: resource_owner)
|
|
21
|
+
else
|
|
22
|
+
where(resource_owner_id: resource_owner_id_for(resource_owner))
|
|
23
|
+
end
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
protected
|
|
27
|
+
|
|
28
|
+
# Backward compatible way to retrieve resource owner itself (if
|
|
29
|
+
# polymorphic association enabled) or just it's ID.
|
|
30
|
+
#
|
|
31
|
+
# @param resource_owner [ActiveRecord::Base, Integer]
|
|
32
|
+
# resource owner
|
|
33
|
+
#
|
|
34
|
+
# @return [ActiveRecord::Base, Integer]
|
|
35
|
+
# instance of Resource Owner or it's ID
|
|
36
|
+
#
|
|
37
|
+
def resource_owner_id_for(resource_owner)
|
|
38
|
+
if resource_owner.respond_to?(:to_key)
|
|
39
|
+
resource_owner.id
|
|
40
|
+
else
|
|
41
|
+
resource_owner
|
|
42
|
+
end
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
end
|
|
46
|
+
end
|
|
47
|
+
end
|