doorkeeper 5.3.2 → 5.4.0

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.

Files changed (225) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +84 -2
  3. data/README.md +6 -4
  4. data/app/controllers/doorkeeper/applications_controller.rb +4 -4
  5. data/app/controllers/doorkeeper/authorizations_controller.rb +31 -12
  6. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  7. data/app/controllers/doorkeeper/tokens_controller.rb +57 -20
  8. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  9. data/app/views/doorkeeper/applications/show.html.erb +19 -2
  10. data/config/locales/en.yml +3 -1
  11. data/lib/doorkeeper.rb +106 -79
  12. data/lib/doorkeeper/config.rb +64 -35
  13. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  14. data/lib/doorkeeper/config/option.rb +28 -14
  15. data/lib/doorkeeper/engine.rb +1 -1
  16. data/lib/doorkeeper/grape/helpers.rb +1 -1
  17. data/lib/doorkeeper/helpers/controller.rb +4 -4
  18. data/lib/doorkeeper/models/access_grant_mixin.rb +20 -16
  19. data/lib/doorkeeper/models/access_token_mixin.rb +108 -45
  20. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  21. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  22. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  23. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  24. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  25. data/lib/doorkeeper/oauth/authorization/code.rb +15 -6
  26. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  27. data/lib/doorkeeper/oauth/authorization/token.rb +8 -12
  28. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  29. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  30. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  31. data/lib/doorkeeper/oauth/client.rb +1 -1
  32. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  33. data/lib/doorkeeper/oauth/client_credentials/creator.rb +26 -8
  34. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  35. data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
  36. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  37. data/lib/doorkeeper/oauth/code_request.rb +3 -3
  38. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  39. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  40. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  41. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  42. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  43. data/lib/doorkeeper/oauth/password_access_token_request.rb +4 -6
  44. data/lib/doorkeeper/oauth/pre_authorization.rb +36 -30
  45. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  46. data/lib/doorkeeper/oauth/token.rb +5 -6
  47. data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
  48. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  49. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  50. data/lib/doorkeeper/orm/active_record.rb +10 -2
  51. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
  52. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
  53. data/lib/doorkeeper/orm/active_record/mixins/application.rb +20 -16
  54. data/lib/doorkeeper/rails/routes.rb +13 -17
  55. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  56. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  57. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  58. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  59. data/lib/doorkeeper/request/strategy.rb +2 -2
  60. data/lib/doorkeeper/server.rb +4 -4
  61. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  62. data/lib/doorkeeper/version.rb +2 -2
  63. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  64. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  65. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  66. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  67. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  68. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  69. data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
  70. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  71. metadata +12 -295
  72. data/Appraisals +0 -40
  73. data/CODE_OF_CONDUCT.md +0 -46
  74. data/CONTRIBUTING.md +0 -49
  75. data/Dangerfile +0 -67
  76. data/Dockerfile +0 -29
  77. data/Gemfile +0 -25
  78. data/NEWS.md +0 -1
  79. data/RELEASING.md +0 -11
  80. data/Rakefile +0 -28
  81. data/SECURITY.md +0 -15
  82. data/UPGRADE.md +0 -2
  83. data/bin/console +0 -16
  84. data/doorkeeper.gemspec +0 -42
  85. data/gemfiles/rails_5_0.gemfile +0 -18
  86. data/gemfiles/rails_5_1.gemfile +0 -18
  87. data/gemfiles/rails_5_2.gemfile +0 -18
  88. data/gemfiles/rails_6_0.gemfile +0 -18
  89. data/gemfiles/rails_master.gemfile +0 -18
  90. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  91. data/spec/controllers/applications_controller_spec.rb +0 -274
  92. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  93. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  94. data/spec/controllers/token_info_controller_spec.rb +0 -50
  95. data/spec/controllers/tokens_controller_spec.rb +0 -498
  96. data/spec/dummy/Rakefile +0 -9
  97. data/spec/dummy/app/assets/config/manifest.js +0 -2
  98. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  99. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  100. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  101. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  102. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  103. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  104. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  105. data/spec/dummy/app/models/user.rb +0 -7
  106. data/spec/dummy/app/views/home/index.html.erb +0 -0
  107. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  108. data/spec/dummy/config.ru +0 -6
  109. data/spec/dummy/config/application.rb +0 -49
  110. data/spec/dummy/config/boot.rb +0 -7
  111. data/spec/dummy/config/database.yml +0 -15
  112. data/spec/dummy/config/environment.rb +0 -5
  113. data/spec/dummy/config/environments/development.rb +0 -31
  114. data/spec/dummy/config/environments/production.rb +0 -64
  115. data/spec/dummy/config/environments/test.rb +0 -45
  116. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  117. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  118. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  119. data/spec/dummy/config/initializers/session_store.rb +0 -10
  120. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  121. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  122. data/spec/dummy/config/routes.rb +0 -13
  123. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  124. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  125. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  126. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  127. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  128. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  129. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  130. data/spec/dummy/db/schema.rb +0 -68
  131. data/spec/dummy/public/404.html +0 -26
  132. data/spec/dummy/public/422.html +0 -26
  133. data/spec/dummy/public/500.html +0 -26
  134. data/spec/dummy/public/favicon.ico +0 -0
  135. data/spec/dummy/script/rails +0 -9
  136. data/spec/factories.rb +0 -30
  137. data/spec/generators/application_owner_generator_spec.rb +0 -28
  138. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  139. data/spec/generators/install_generator_spec.rb +0 -36
  140. data/spec/generators/migration_generator_spec.rb +0 -28
  141. data/spec/generators/pkce_generator_spec.rb +0 -28
  142. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  143. data/spec/generators/templates/routes.rb +0 -4
  144. data/spec/generators/views_generator_spec.rb +0 -29
  145. data/spec/grape/grape_integration_spec.rb +0 -137
  146. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  147. data/spec/lib/config_spec.rb +0 -809
  148. data/spec/lib/doorkeeper_spec.rb +0 -27
  149. data/spec/lib/models/expirable_spec.rb +0 -61
  150. data/spec/lib/models/reusable_spec.rb +0 -40
  151. data/spec/lib/models/revocable_spec.rb +0 -59
  152. data/spec/lib/models/scopes_spec.rb +0 -53
  153. data/spec/lib/models/secret_storable_spec.rb +0 -135
  154. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  155. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
  156. data/spec/lib/oauth/base_request_spec.rb +0 -224
  157. data/spec/lib/oauth/base_response_spec.rb +0 -45
  158. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  159. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
  160. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  161. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  162. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  163. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
  164. data/spec/lib/oauth/client_spec.rb +0 -38
  165. data/spec/lib/oauth/code_request_spec.rb +0 -46
  166. data/spec/lib/oauth/code_response_spec.rb +0 -32
  167. data/spec/lib/oauth/error_response_spec.rb +0 -64
  168. data/spec/lib/oauth/error_spec.rb +0 -21
  169. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  170. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  171. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  172. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  173. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  174. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  175. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
  176. data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
  177. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  178. data/spec/lib/oauth/scopes_spec.rb +0 -146
  179. data/spec/lib/oauth/token_request_spec.rb +0 -157
  180. data/spec/lib/oauth/token_response_spec.rb +0 -84
  181. data/spec/lib/oauth/token_spec.rb +0 -156
  182. data/spec/lib/request/strategy_spec.rb +0 -54
  183. data/spec/lib/secret_storing/base_spec.rb +0 -60
  184. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  185. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  186. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  187. data/spec/lib/server_spec.rb +0 -49
  188. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  189. data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
  190. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  191. data/spec/models/doorkeeper/application_spec.rb +0 -482
  192. data/spec/requests/applications/applications_request_spec.rb +0 -259
  193. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  194. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  195. data/spec/requests/endpoints/token_spec.rb +0 -75
  196. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  197. data/spec/requests/flows/authorization_code_spec.rb +0 -525
  198. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  199. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  200. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  201. data/spec/requests/flows/password_spec.rb +0 -316
  202. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  203. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  204. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  205. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  206. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  207. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  208. data/spec/routing/default_routes_spec.rb +0 -41
  209. data/spec/routing/scoped_routes_spec.rb +0 -47
  210. data/spec/spec_helper.rb +0 -54
  211. data/spec/spec_helper_integration.rb +0 -4
  212. data/spec/support/dependencies/factory_bot.rb +0 -4
  213. data/spec/support/doorkeeper_rspec.rb +0 -22
  214. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  215. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  216. data/spec/support/helpers/config_helper.rb +0 -11
  217. data/spec/support/helpers/model_helper.rb +0 -78
  218. data/spec/support/helpers/request_spec_helper.rb +0 -110
  219. data/spec/support/helpers/url_helper.rb +0 -62
  220. data/spec/support/orm/active_record.rb +0 -5
  221. data/spec/support/shared/controllers_shared_context.rb +0 -133
  222. data/spec/support/shared/hashing_shared_context.rb +0 -36
  223. data/spec/support/shared/models_shared_examples.rb +0 -54
  224. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  225. data/spec/version/version_spec.rb +0 -17
@@ -36,22 +36,29 @@ module Doorkeeper
36
36
  attribute = options[:as] || name
37
37
  attribute_builder = options[:builder_class]
38
38
 
39
- Builder.instance_eval do
40
- remove_method name if method_defined?(name)
41
- if options[:deprecated]
42
- define_method name do |*_, &_|
43
- Kernel.warn "[DOORKEEPER] #{name} has been deprecated and will soon be removed"
44
- end
45
- else
46
- define_method name do |*args, &block|
47
- value = if attribute_builder
48
- attribute_builder.new(&block).build
49
- else
50
- block || args.first
51
- end
39
+ builder_class.instance_eval do
40
+ if method_defined?(name)
41
+ Kernel.warn "[DOORKEEPER] Option #{name} already defined and will be overridden"
42
+ remove_method name
43
+ end
52
44
 
53
- @config.instance_variable_set(:"@#{attribute}", value)
45
+ define_method name do |*args, &block|
46
+ if (deprecation_opts = options[:deprecated])
47
+ warning = "[DOORKEEPER] #{name} has been deprecated and will soon be removed"
48
+ if deprecation_opts.is_a?(Hash)
49
+ warning = "#{warning}\n#{deprecation_opts.fetch(:message)}"
50
+ end
51
+
52
+ Kernel.warn(warning)
54
53
  end
54
+
55
+ value = if attribute_builder
56
+ attribute_builder.new(&block).build
57
+ else
58
+ block || args.first
59
+ end
60
+
61
+ @config.instance_variable_set(:"@#{attribute}", value)
55
62
  end
56
63
  end
57
64
 
@@ -65,6 +72,13 @@ module Doorkeeper
65
72
 
66
73
  public attribute
67
74
  end
75
+
76
+ def self.extended(base)
77
+ return if base.respond_to?(:builder_class)
78
+
79
+ raise Doorkeeper::MissingConfigurationBuilderClass, "Define `self.builder_class` method " \
80
+ "for #{base} that returns your custom Builder class to use options DSL!"
81
+ end
68
82
  end
69
83
  end
70
84
  end
@@ -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 parameters})$/
7
+ app.config.filter_parameters << /^(#{Regexp.union(parameters)})$/
8
8
  end
9
9
 
10
10
  initializer "doorkeeper.routes" do
@@ -18,7 +18,7 @@ module Doorkeeper
18
18
 
19
19
  scopes = if endpoint_scopes
20
20
  Doorkeeper::OAuth::Scopes.from_array(endpoint_scopes)
21
- elsif scopes && !scopes.empty?
21
+ elsif scopes.present?
22
22
  Doorkeeper::OAuth::Scopes.from_array(scopes)
23
23
  end
24
24
 
@@ -36,7 +36,7 @@ module Doorkeeper
36
36
 
37
37
  # :doc:
38
38
  def doorkeeper_token
39
- @doorkeeper_token ||= OAuth::Token.authenticate request, *config_methods
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 exception
62
- headers.merge! error.headers
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 = error.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
- # never uses pkce, if pkce migrations were not generated
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] AccessGrant object or 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
- where(
47
- application_id: application_id,
48
- resource_owner_id: resource_owner.id,
49
- revoked_at: nil,
50
- ).update_all(revoked_at: clock.now.utc)
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
- new.pkce_supported?
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
- where(
68
- application_id: application_id,
69
- resource_owner_id: resource_owner.id,
70
- revoked_at: nil,
71
- ).update_all(revoked_at: clock.now.utc)
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 resource_owner_or_id [ActiveRecord::Base, Integer]
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, resource_owner_or_id, scopes)
88
- resource_owner_id = if resource_owner_or_id.respond_to?(:to_key)
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
 
@@ -130,7 +126,7 @@ module Doorkeeper
130
126
 
131
127
  find_access_token_in_batches(relation, batch_size: batch_size) do |batch|
132
128
  tokens = batch.select do |token|
133
- scopes_match?(token.scopes, scopes, application.try(:scopes))
129
+ scopes_match?(token.scopes, scopes, application&.scopes)
134
130
  end
135
131
 
136
132
  matching_tokens.concat(tokens)
@@ -170,47 +166,79 @@ module Doorkeeper
170
166
  #
171
167
  # @param application [Doorkeeper::Application]
172
168
  # Application instance
173
- # @param resource_owner_id [ActiveRecord::Base, Integer]
169
+ # @param resource_owner [ActiveRecord::Base, Integer]
174
170
  # Resource Owner model instance or it's ID
175
171
  # @param scopes [#to_s]
176
172
  # set of scopes (any object that responds to `#to_s`)
177
- # @param expires_in [Integer]
173
+ # @param token_attributes [Hash]
174
+ # Additional attributes to use when creating a token
175
+ # @option token_attributes [Integer] :expires_in
178
176
  # token lifetime in seconds
179
- # @param use_refresh_token [Boolean]
177
+ # @option token_attributes [Boolean] :use_refresh_token
180
178
  # whether to use the refresh token
181
179
  #
182
180
  # @return [Doorkeeper::AccessToken] existing record or a new one
183
181
  #
184
- def find_or_create_for(application, resource_owner_id, scopes, expires_in, use_refresh_token)
182
+ def find_or_create_for(application:, resource_owner:, scopes:, **token_attributes)
185
183
  if Doorkeeper.config.reuse_access_token
186
- access_token = matching_token_for(application, resource_owner_id, scopes)
184
+ access_token = matching_token_for(application, resource_owner, scopes)
187
185
 
188
186
  return access_token if access_token&.reusable?
189
187
  end
190
188
 
191
- create!(
192
- application_id: application.try(:id),
193
- resource_owner_id: resource_owner_id,
194
- scopes: scopes.to_s,
195
- expires_in: expires_in,
196
- use_refresh_token: use_refresh_token,
189
+ create_for(
190
+ application: application,
191
+ resource_owner: resource_owner,
192
+ scopes: scopes,
193
+ **token_attributes,
197
194
  )
198
195
  end
199
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
+
200
228
  # Looking for not revoked Access Token records that belongs to specific
201
229
  # Application and Resource Owner.
202
230
  #
203
231
  # @param application_id [Integer]
204
232
  # ID of the Application model instance
205
- # @param resource_owner_id [Integer]
206
- # ID of the Resource Owner model instance
233
+ # @param resource_owner [ActiveRecord::Base, Integer]
234
+ # Resource Owner model instance or it's ID
207
235
  #
208
- # @return [Doorkeeper::AccessToken] array of matching AccessToken objects
236
+ # @return [ActiveRecord::Relation]
237
+ # collection of matching AccessToken objects
209
238
  #
210
- def authorized_tokens_for(application_id, resource_owner_id)
211
- where(
239
+ def authorized_tokens_for(application_id, resource_owner)
240
+ by_resource_owner(resource_owner).where(
212
241
  application_id: application_id,
213
- resource_owner_id: resource_owner_id,
214
242
  revoked_at: nil,
215
243
  )
216
244
  end
@@ -220,20 +248,24 @@ module Doorkeeper
220
248
  #
221
249
  # @param application_id [Integer]
222
250
  # ID of the Application model instance
223
- # @param resource_owner_id [Integer]
251
+ # @param resource_owner [ActiveRecord::Base, Integer]
224
252
  # ID of the Resource Owner model instance
225
253
  #
226
254
  # @return [Doorkeeper::AccessToken, nil] matching AccessToken object or
227
255
  # nil if nothing was found
228
256
  #
229
- def last_authorized_token_for(application_id, resource_owner_id)
230
- authorized_tokens_for(application_id, resource_owner_id)
231
- .ordered_by(:created_at, :desc).first
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
232
261
  end
233
262
 
234
263
  ##
235
264
  # Determines the secret storing transformer
236
265
  # Unless configured otherwise, uses the plain secret strategy
266
+ #
267
+ # @return [Doorkeeper::SecretStoring::Base]
268
+ #
237
269
  def secret_strategy
238
270
  ::Doorkeeper.config.token_secret_strategy
239
271
  end
@@ -269,7 +301,11 @@ module Doorkeeper
269
301
  expires_in: expires_in_seconds,
270
302
  application: { uid: application.try(:uid) },
271
303
  created_at: created_at.to_i,
272
- }
304
+ }.tap do |json|
305
+ if Doorkeeper.configuration.polymorphic_resource_owner?
306
+ json[:resource_owner_type] = resource_owner_type
307
+ end
308
+ end
273
309
  end
274
310
 
275
311
  # Indicates whether the token instance have the same credential
@@ -281,7 +317,22 @@ module Doorkeeper
281
317
  #
282
318
  def same_credential?(access_token)
283
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
284
334
  resource_owner_id == access_token.resource_owner_id
335
+ end
285
336
  end
286
337
 
287
338
  # Indicates if token is acceptable for specific scopes.
@@ -326,7 +377,7 @@ module Doorkeeper
326
377
  return unless self.class.refresh_token_revoked_on_use?
327
378
 
328
379
  old_refresh_token&.revoke
329
- update_attribute :previous_refresh_token, ""
380
+ update_column(:previous_refresh_token, "")
330
381
  end
331
382
 
332
383
  private
@@ -363,16 +414,28 @@ module Doorkeeper
363
414
  def generate_token
364
415
  self.created_at ||= Time.now.utc
365
416
 
366
- @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
+ {
367
429
  resource_owner_id: resource_owner_id,
368
430
  scopes: scopes,
369
431
  application: application,
370
432
  expires_in: expires_in,
371
433
  created_at: created_at,
372
- )
373
-
374
- secret_strategy.store_secret(self, :token, @raw_token)
375
- @raw_token
434
+ }.tap do |attributes|
435
+ if Doorkeeper.config.polymorphic_resource_owner?
436
+ attributes[:resource_owner] = resource_owner
437
+ end
438
+ end
376
439
  end
377
440
 
378
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] Application instance or 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