doorkeeper 5.2.2 → 5.5.4

Sign up to get free protection for your applications and to get access to all the features.

Potentially problematic release.


This version of doorkeeper might be problematic. Click here for more details.

Files changed (260) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +198 -3
  3. data/README.md +28 -20
  4. data/app/controllers/doorkeeper/application_controller.rb +3 -2
  5. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
  6. data/app/controllers/doorkeeper/applications_controller.rb +7 -8
  7. data/app/controllers/doorkeeper/authorizations_controller.rb +48 -18
  8. data/app/controllers/doorkeeper/authorized_applications_controller.rb +6 -6
  9. data/app/controllers/doorkeeper/token_info_controller.rb +12 -2
  10. data/app/controllers/doorkeeper/tokens_controller.rb +70 -25
  11. data/app/helpers/doorkeeper/dashboard_helper.rb +1 -1
  12. data/app/views/doorkeeper/applications/_form.html.erb +1 -1
  13. data/app/views/doorkeeper/applications/show.html.erb +35 -14
  14. data/app/views/doorkeeper/authorizations/form_post.html.erb +15 -0
  15. data/app/views/doorkeeper/authorizations/new.html.erb +2 -0
  16. data/config/locales/en.yml +9 -2
  17. data/lib/doorkeeper/config/abstract_builder.rb +28 -0
  18. data/lib/doorkeeper/config/option.rb +26 -14
  19. data/lib/doorkeeper/config/validations.rb +53 -0
  20. data/lib/doorkeeper/config.rb +214 -122
  21. data/lib/doorkeeper/engine.rb +1 -1
  22. data/lib/doorkeeper/grant_flow/fallback_flow.rb +15 -0
  23. data/lib/doorkeeper/grant_flow/flow.rb +44 -0
  24. data/lib/doorkeeper/grant_flow/registry.rb +50 -0
  25. data/lib/doorkeeper/grant_flow.rb +45 -0
  26. data/lib/doorkeeper/grape/helpers.rb +2 -2
  27. data/lib/doorkeeper/helpers/controller.rb +18 -12
  28. data/lib/doorkeeper/models/access_grant_mixin.rb +23 -19
  29. data/lib/doorkeeper/models/access_token_mixin.rb +157 -55
  30. data/lib/doorkeeper/models/application_mixin.rb +8 -7
  31. data/lib/doorkeeper/models/concerns/expirable.rb +1 -1
  32. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  33. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  34. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  35. data/lib/doorkeeper/models/concerns/revocable.rb +1 -28
  36. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  37. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  38. data/lib/doorkeeper/oauth/authorization/code.rb +22 -9
  39. data/lib/doorkeeper/oauth/authorization/context.rb +5 -5
  40. data/lib/doorkeeper/oauth/authorization/token.rb +23 -18
  41. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  42. data/lib/doorkeeper/oauth/authorization_code_request.rb +30 -20
  43. data/lib/doorkeeper/oauth/base_request.rb +19 -23
  44. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  45. data/lib/doorkeeper/oauth/client.rb +8 -9
  46. data/lib/doorkeeper/oauth/client_credentials/creator.rb +38 -12
  47. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +10 -8
  48. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +7 -5
  49. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  50. data/lib/doorkeeper/oauth/code_request.rb +4 -4
  51. data/lib/doorkeeper/oauth/code_response.rb +24 -14
  52. data/lib/doorkeeper/oauth/error.rb +1 -1
  53. data/lib/doorkeeper/oauth/error_response.rb +10 -11
  54. data/lib/doorkeeper/oauth/forbidden_token_response.rb +2 -1
  55. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +8 -12
  56. data/lib/doorkeeper/oauth/helpers/unique_token.rb +10 -7
  57. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -19
  58. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  59. data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
  60. data/lib/doorkeeper/oauth/invalid_token_response.rb +7 -4
  61. data/lib/doorkeeper/oauth/password_access_token_request.rb +28 -10
  62. data/lib/doorkeeper/oauth/pre_authorization.rb +73 -37
  63. data/lib/doorkeeper/oauth/refresh_token_request.rb +35 -26
  64. data/lib/doorkeeper/oauth/token.rb +6 -7
  65. data/lib/doorkeeper/oauth/token_introspection.rb +12 -16
  66. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  67. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  68. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  69. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  70. data/lib/doorkeeper/orm/active_record/application.rb +5 -95
  71. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +69 -0
  72. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +60 -0
  73. data/lib/doorkeeper/orm/active_record/mixins/application.rb +199 -0
  74. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +8 -3
  75. data/lib/doorkeeper/orm/active_record.rb +5 -7
  76. data/lib/doorkeeper/rails/helpers.rb +4 -4
  77. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  78. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  79. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  80. data/lib/doorkeeper/rails/routes.rb +17 -25
  81. data/lib/doorkeeper/rake/db.rake +6 -6
  82. data/lib/doorkeeper/rake/setup.rake +5 -0
  83. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  84. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  85. data/lib/doorkeeper/request/password.rb +3 -2
  86. data/lib/doorkeeper/request/refresh_token.rb +5 -4
  87. data/lib/doorkeeper/request/strategy.rb +2 -2
  88. data/lib/doorkeeper/request.rb +49 -12
  89. data/lib/doorkeeper/server.rb +5 -5
  90. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  91. data/lib/doorkeeper/version.rb +2 -6
  92. data/lib/doorkeeper.rb +112 -81
  93. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  94. data/lib/generators/doorkeeper/confidential_applications_generator.rb +2 -2
  95. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  96. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  97. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  98. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
  99. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +3 -1
  100. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  101. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  102. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  103. data/lib/generators/doorkeeper/templates/initializer.rb +99 -14
  104. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  105. metadata +37 -306
  106. data/Appraisals +0 -40
  107. data/CODE_OF_CONDUCT.md +0 -46
  108. data/CONTRIBUTING.md +0 -49
  109. data/Dangerfile +0 -67
  110. data/Dockerfile +0 -29
  111. data/Gemfile +0 -25
  112. data/NEWS.md +0 -1
  113. data/RELEASING.md +0 -11
  114. data/Rakefile +0 -28
  115. data/SECURITY.md +0 -15
  116. data/UPGRADE.md +0 -2
  117. data/bin/console +0 -16
  118. data/doorkeeper.gemspec +0 -42
  119. data/gemfiles/rails_5_0.gemfile +0 -18
  120. data/gemfiles/rails_5_1.gemfile +0 -18
  121. data/gemfiles/rails_5_2.gemfile +0 -18
  122. data/gemfiles/rails_6_0.gemfile +0 -18
  123. data/gemfiles/rails_master.gemfile +0 -18
  124. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  125. data/spec/controllers/applications_controller_spec.rb +0 -273
  126. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  127. data/spec/controllers/protected_resources_controller_spec.rb +0 -353
  128. data/spec/controllers/token_info_controller_spec.rb +0 -50
  129. data/spec/controllers/tokens_controller_spec.rb +0 -498
  130. data/spec/dummy/Rakefile +0 -9
  131. data/spec/dummy/app/assets/config/manifest.js +0 -2
  132. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  133. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  134. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  135. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  136. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  137. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  138. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  139. data/spec/dummy/app/models/user.rb +0 -7
  140. data/spec/dummy/app/views/home/index.html.erb +0 -0
  141. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  142. data/spec/dummy/config/application.rb +0 -49
  143. data/spec/dummy/config/boot.rb +0 -7
  144. data/spec/dummy/config/database.yml +0 -15
  145. data/spec/dummy/config/environment.rb +0 -5
  146. data/spec/dummy/config/environments/development.rb +0 -31
  147. data/spec/dummy/config/environments/production.rb +0 -64
  148. data/spec/dummy/config/environments/test.rb +0 -45
  149. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  150. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  151. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  152. data/spec/dummy/config/initializers/session_store.rb +0 -10
  153. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  154. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  155. data/spec/dummy/config/routes.rb +0 -13
  156. data/spec/dummy/config.ru +0 -6
  157. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  158. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  159. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  160. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  161. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  162. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  163. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  164. data/spec/dummy/db/schema.rb +0 -68
  165. data/spec/dummy/public/404.html +0 -26
  166. data/spec/dummy/public/422.html +0 -26
  167. data/spec/dummy/public/500.html +0 -26
  168. data/spec/dummy/public/favicon.ico +0 -0
  169. data/spec/dummy/script/rails +0 -9
  170. data/spec/factories.rb +0 -30
  171. data/spec/generators/application_owner_generator_spec.rb +0 -28
  172. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  173. data/spec/generators/install_generator_spec.rb +0 -36
  174. data/spec/generators/migration_generator_spec.rb +0 -28
  175. data/spec/generators/pkce_generator_spec.rb +0 -28
  176. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  177. data/spec/generators/templates/routes.rb +0 -4
  178. data/spec/generators/views_generator_spec.rb +0 -29
  179. data/spec/grape/grape_integration_spec.rb +0 -137
  180. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  181. data/spec/lib/config_spec.rb +0 -739
  182. data/spec/lib/doorkeeper_spec.rb +0 -27
  183. data/spec/lib/models/expirable_spec.rb +0 -61
  184. data/spec/lib/models/reusable_spec.rb +0 -40
  185. data/spec/lib/models/revocable_spec.rb +0 -59
  186. data/spec/lib/models/scopes_spec.rb +0 -53
  187. data/spec/lib/models/secret_storable_spec.rb +0 -135
  188. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  189. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -168
  190. data/spec/lib/oauth/base_request_spec.rb +0 -222
  191. data/spec/lib/oauth/base_response_spec.rb +0 -47
  192. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  193. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -97
  194. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  195. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  196. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -29
  197. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -109
  198. data/spec/lib/oauth/client_spec.rb +0 -38
  199. data/spec/lib/oauth/code_request_spec.rb +0 -46
  200. data/spec/lib/oauth/code_response_spec.rb +0 -36
  201. data/spec/lib/oauth/error_response_spec.rb +0 -66
  202. data/spec/lib/oauth/error_spec.rb +0 -23
  203. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -22
  204. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -98
  205. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  206. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  207. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -75
  208. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -55
  209. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -192
  210. data/spec/lib/oauth/pre_authorization_spec.rb +0 -225
  211. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -178
  212. data/spec/lib/oauth/scopes_spec.rb +0 -148
  213. data/spec/lib/oauth/token_request_spec.rb +0 -153
  214. data/spec/lib/oauth/token_response_spec.rb +0 -86
  215. data/spec/lib/oauth/token_spec.rb +0 -158
  216. data/spec/lib/request/strategy_spec.rb +0 -54
  217. data/spec/lib/secret_storing/base_spec.rb +0 -60
  218. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  219. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  220. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  221. data/spec/lib/server_spec.rb +0 -49
  222. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  223. data/spec/models/doorkeeper/access_grant_spec.rb +0 -163
  224. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  225. data/spec/models/doorkeeper/application_spec.rb +0 -377
  226. data/spec/requests/applications/applications_request_spec.rb +0 -259
  227. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  228. data/spec/requests/endpoints/authorization_spec.rb +0 -89
  229. data/spec/requests/endpoints/token_spec.rb +0 -75
  230. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  231. data/spec/requests/flows/authorization_code_spec.rb +0 -513
  232. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  233. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  234. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  235. data/spec/requests/flows/password_spec.rb +0 -296
  236. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  237. data/spec/requests/flows/revoke_token_spec.rb +0 -151
  238. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  239. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  240. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  241. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  242. data/spec/routing/default_routes_spec.rb +0 -41
  243. data/spec/routing/scoped_routes_spec.rb +0 -47
  244. data/spec/spec_helper.rb +0 -57
  245. data/spec/spec_helper_integration.rb +0 -4
  246. data/spec/support/dependencies/factory_bot.rb +0 -4
  247. data/spec/support/doorkeeper_rspec.rb +0 -22
  248. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  249. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  250. data/spec/support/helpers/config_helper.rb +0 -11
  251. data/spec/support/helpers/model_helper.rb +0 -78
  252. data/spec/support/helpers/request_spec_helper.rb +0 -110
  253. data/spec/support/helpers/url_helper.rb +0 -62
  254. data/spec/support/http_method_shim.rb +0 -29
  255. data/spec/support/orm/active_record.rb +0 -5
  256. data/spec/support/shared/controllers_shared_context.rb +0 -123
  257. data/spec/support/shared/hashing_shared_context.rb +0 -36
  258. data/spec/support/shared/models_shared_examples.rb +0 -54
  259. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  260. data/spec/version/version_spec.rb +0 -17
@@ -11,9 +11,8 @@ module Doorkeeper
11
11
  validate :client_match, error: :invalid_grant
12
12
  validate :scope, error: :invalid_scope
13
13
 
14
- attr_accessor :access_token, :client, :credentials, :refresh_token,
15
- :server
16
- attr_reader :missing_param
14
+ attr_reader :access_token, :client, :credentials, :refresh_token
15
+ attr_reader :missing_param
17
16
 
18
17
  def initialize(server, refresh_token, credentials, parameters = {})
19
18
  @server = server
@@ -27,7 +26,7 @@ module Doorkeeper
27
26
  private
28
27
 
29
28
  def load_client(credentials)
30
- Application.by_uid_and_secret(credentials.uid, credentials.secret)
29
+ server_config.application_model.by_uid_and_secret(credentials.uid, credentials.secret)
31
30
  end
32
31
 
33
32
  def before_successful_response
@@ -42,7 +41,7 @@ module Doorkeeper
42
41
  end
43
42
 
44
43
  def refresh_token_revoked_on_use?
45
- Doorkeeper::AccessToken.refresh_token_revoked_on_use?
44
+ server_config.access_token_model.refresh_token_revoked_on_use?
46
45
  end
47
46
 
48
47
  def default_scopes
@@ -50,30 +49,40 @@ module Doorkeeper
50
49
  end
51
50
 
52
51
  def create_access_token
53
- @access_token = AccessToken.create!(access_token_attributes)
54
- end
52
+ attributes = {}
55
53
 
56
- def access_token_attributes
57
- {
58
- application_id: refresh_token.application_id,
59
- resource_owner_id: refresh_token.resource_owner_id,
60
- scopes: scopes.to_s,
61
- expires_in: access_token_expires_in,
62
- use_refresh_token: true,
63
- }.tap do |attributes|
64
- if refresh_token_revoked_on_use?
65
- attributes[:previous_refresh_token] = refresh_token.refresh_token
54
+ resource_owner =
55
+ if Doorkeeper.config.polymorphic_resource_owner?
56
+ refresh_token.resource_owner
57
+ else
58
+ refresh_token.resource_owner_id
66
59
  end
60
+
61
+ if refresh_token_revoked_on_use?
62
+ attributes[:previous_refresh_token] = refresh_token.refresh_token
67
63
  end
68
- end
69
64
 
70
- def access_token_expires_in
71
- context = Authorization::Token.build_context(
72
- client,
73
- Doorkeeper::OAuth::REFRESH_TOKEN,
74
- scopes
65
+ # RFC6749
66
+ # 1.5. Refresh Token
67
+ #
68
+ # Refresh tokens are issued to the client by the authorization server and are
69
+ # used to obtain a new access token when the current access token
70
+ # becomes invalid or expires, or to obtain additional access tokens
71
+ # with identical or narrower scope (access tokens may have a shorter
72
+ # lifetime and fewer permissions than authorized by the resource
73
+ # owner).
74
+ #
75
+ # Here we assume that TTL of the token received after refreshing should be
76
+ # the same as that of the original token.
77
+ #
78
+ @access_token = server_config.access_token_model.create_for(
79
+ application: refresh_token.application,
80
+ resource_owner: resource_owner,
81
+ scopes: scopes,
82
+ expires_in: refresh_token.expires_in,
83
+ use_refresh_token: true,
84
+ **attributes,
75
85
  )
76
- Authorization::Token.access_token_expires_in(server, context)
77
86
  end
78
87
 
79
88
  def validate_token_presence
@@ -92,7 +101,7 @@ module Doorkeeper
92
101
  client.present?
93
102
  end
94
103
 
95
- # @see https://tools.ietf.org/html/draft-ietf-oauth-v2-22#section-1.5
104
+ # @see https://datatracker.ietf.org/doc/html/rfc6749#section-1.5
96
105
  #
97
106
  def validate_client_match
98
107
  return true if refresh_token.application_id.blank?
@@ -104,7 +113,7 @@ module Doorkeeper
104
113
  if @original_scopes.present?
105
114
  ScopeChecker.valid?(
106
115
  scope_str: @original_scopes,
107
- server_scopes: refresh_token.scopes
116
+ server_scopes: refresh_token.scopes,
108
117
  )
109
118
  else
110
119
  true
@@ -8,15 +8,14 @@ module Doorkeeper
8
8
  methods.inject(nil) do |_, method|
9
9
  method = self.method(method) if method.is_a?(Symbol)
10
10
  credentials = method.call(request)
11
- break credentials unless credentials.blank?
11
+ break credentials if credentials.present?
12
12
  end
13
13
  end
14
14
 
15
15
  def authenticate(request, *methods)
16
16
  if (token = from_request(request, *methods))
17
- access_token = AccessToken.by_token(token)
18
- refresh_token_enabled = Doorkeeper.configuration.refresh_token_enabled?
19
- if access_token.present? && refresh_token_enabled
17
+ access_token = Doorkeeper.config.access_token_model.by_token(token)
18
+ if access_token.present? && Doorkeeper.config.refresh_token_enabled?
20
19
  access_token.revoke_previous_refresh_token!
21
20
  end
22
21
  access_token
@@ -33,13 +32,13 @@ module Doorkeeper
33
32
 
34
33
  def from_bearer_authorization(request)
35
34
  pattern = /^Bearer /i
36
- header = request.authorization
35
+ header = request.authorization
37
36
  token_from_header(header, pattern) if match?(header, pattern)
38
37
  end
39
38
 
40
39
  def from_basic_authorization(request)
41
40
  pattern = /^Basic /i
42
- header = request.authorization
41
+ header = request.authorization
43
42
  token_from_basic_header(header, pattern) if match?(header, pattern)
44
43
  end
45
44
 
@@ -55,7 +54,7 @@ module Doorkeeper
55
54
  end
56
55
 
57
56
  def token_from_header(header, pattern)
58
- header.gsub pattern, ""
57
+ header.gsub(pattern, "")
59
58
  end
60
59
 
61
60
  def match?(header, pattern)
@@ -4,11 +4,8 @@ module Doorkeeper
4
4
  module OAuth
5
5
  # RFC7662 OAuth 2.0 Token Introspection
6
6
  #
7
- # @see https://tools.ietf.org/html/rfc7662
7
+ # @see https://datatracker.ietf.org/doc/html/rfc7662
8
8
  class TokenIntrospection
9
- attr_reader :server, :token
10
- attr_reader :error, :invalid_request_reason
11
-
12
9
  def initialize(server, token)
13
10
  @server = server
14
11
  @token = token
@@ -38,6 +35,9 @@ module Doorkeeper
38
35
 
39
36
  private
40
37
 
38
+ attr_reader :server, :token
39
+ attr_reader :error, :invalid_request_reason
40
+
41
41
  # If the protected resource uses OAuth 2.0 client credentials to
42
42
  # authenticate to the introspection endpoint and its credentials are
43
43
  # invalid, the authorization server responds with an HTTP 401
@@ -94,7 +94,7 @@ module Doorkeeper
94
94
  client_id: @token.try(:application).try(:uid),
95
95
  token_type: @token.token_type,
96
96
  exp: @token.expires_at.to_i,
97
- iat: @token.created_at.to_i
97
+ iat: @token.created_at.to_i,
98
98
  )
99
99
  end
100
100
 
@@ -107,7 +107,7 @@ module Doorkeeper
107
107
  # authorization server SHOULD NOT include any additional information
108
108
  # about an inactive token, including why the token is inactive.
109
109
  #
110
- # @see https://tools.ietf.org/html/rfc7662 2.2. Introspection Response
110
+ # @see https://datatracker.ietf.org/doc/html/rfc7662 2.2. Introspection Response
111
111
  #
112
112
  def failure_response
113
113
  {
@@ -174,28 +174,24 @@ module Doorkeeper
174
174
  authorized_token.token == @token&.token
175
175
  end
176
176
 
177
- # config constraints for introspection in Doorkeeper.configuration.allow_token_introspection
177
+ # Config constraints for introspection in Doorkeeper.config.allow_token_introspection
178
178
  def token_introspection_allowed?(auth_client: nil, auth_token: nil)
179
- allow_introspection = Doorkeeper.configuration.allow_token_introspection
179
+ allow_introspection = Doorkeeper.config.allow_token_introspection
180
180
  return allow_introspection unless allow_introspection.respond_to?(:call)
181
181
 
182
- allow_introspection.call(
183
- @token,
184
- auth_client,
185
- auth_token
186
- )
182
+ allow_introspection.call(@token, auth_client, auth_token)
187
183
  end
188
184
 
189
185
  # Allows to customize introspection response.
190
186
  # Provides context (controller) and token for generating developer-specific
191
187
  # response.
192
188
  #
193
- # @see https://tools.ietf.org/html/rfc7662#section-2.2
189
+ # @see https://datatracker.ietf.org/doc/html/rfc7662#section-2.2
194
190
  #
195
191
  def customize_response(response)
196
- customized_response = Doorkeeper.configuration.custom_introspection_response.call(
192
+ customized_response = Doorkeeper.config.custom_introspection_response.call(
197
193
  token,
198
- server.context
194
+ server.context,
199
195
  )
200
196
  return response if customized_response.blank?
201
197
 
@@ -3,16 +3,16 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class TokenRequest
6
- attr_accessor :pre_auth, :resource_owner
6
+ attr_reader :pre_auth, :resource_owner
7
7
 
8
8
  def initialize(pre_auth, resource_owner)
9
- @pre_auth = pre_auth
9
+ @pre_auth = pre_auth
10
10
  @resource_owner = resource_owner
11
11
  end
12
12
 
13
13
  def authorize
14
14
  auth = Authorization::Token.new(pre_auth, resource_owner)
15
- auth.issue_token
15
+ auth.issue_token!
16
16
  CodeResponse.new(pre_auth, auth, response_on_fragment: true)
17
17
  end
18
18
 
@@ -3,7 +3,7 @@
3
3
  module Doorkeeper
4
4
  module OAuth
5
5
  class TokenResponse
6
- attr_accessor :token
6
+ attr_reader :token
7
7
 
8
8
  def initialize(token)
9
9
  @token = token
@@ -1,48 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Doorkeeper
4
- class AccessGrant < ActiveRecord::Base
5
- self.table_name = "#{table_name_prefix}oauth_access_grants#{table_name_suffix}"
6
-
7
- include AccessGrantMixin
8
-
9
- belongs_to :application, class_name: "Doorkeeper::Application",
10
- optional: true, inverse_of: :access_grants
11
-
12
- validates :resource_owner_id,
13
- :application_id,
14
- :token,
15
- :expires_in,
16
- :redirect_uri,
17
- presence: true
18
-
19
- validates :token, uniqueness: { case_sensitive: true }
3
+ require "doorkeeper/orm/active_record/mixins/access_grant"
20
4
 
21
- before_validation :generate_token, on: :create
22
-
23
- # We keep a volatile copy of the raw token for initial communication
24
- # The stored refresh_token may be mapped and not available in cleartext.
25
- #
26
- # Some strategies allow restoring stored secrets (e.g. symmetric encryption)
27
- # while hashing strategies do not, so you cannot rely on this value
28
- # returning a present value for persisted tokens.
29
- def plaintext_token
30
- if secret_strategy.allows_restoring_secrets?
31
- secret_strategy.restore_secret(self, :token)
32
- else
33
- @raw_token
34
- end
35
- end
36
-
37
- private
38
-
39
- # Generates token value with UniqueToken class.
40
- #
41
- # @return [String] token value
42
- #
43
- def generate_token
44
- @raw_token = UniqueToken.generate
45
- secret_strategy.store_secret(self, :token, @raw_token)
46
- end
5
+ module Doorkeeper
6
+ class AccessGrant < ::ActiveRecord::Base
7
+ include Doorkeeper::Orm::ActiveRecord::Mixins::AccessGrant
47
8
  end
48
9
  end
@@ -1,40 +1,9 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Doorkeeper
4
- class AccessToken < ActiveRecord::Base
5
- self.table_name = "#{table_name_prefix}oauth_access_tokens#{table_name_suffix}"
6
-
7
- include AccessTokenMixin
8
-
9
- belongs_to :application, class_name: "Doorkeeper::Application",
10
- inverse_of: :access_tokens, optional: true
11
-
12
- validates :token, presence: true, uniqueness: { case_sensitive: true }
13
- validates :refresh_token, uniqueness: { case_sensitive: true }, if: :use_refresh_token?
3
+ require "doorkeeper/orm/active_record/mixins/access_token"
14
4
 
15
- # @attr_writer [Boolean, nil] use_refresh_token
16
- # indicates the possibility of using refresh token
17
- attr_writer :use_refresh_token
18
-
19
- before_validation :generate_token, on: :create
20
- before_validation :generate_refresh_token,
21
- on: :create, if: :use_refresh_token?
22
-
23
- # Searches for not revoked Access Tokens associated with the
24
- # specific Resource Owner.
25
- #
26
- # @param resource_owner [ActiveRecord::Base]
27
- # Resource Owner model instance
28
- #
29
- # @return [ActiveRecord::Relation]
30
- # active Access Tokens for Resource Owner
31
- #
32
- def self.active_for(resource_owner)
33
- where(resource_owner_id: resource_owner.id, revoked_at: nil)
34
- end
35
-
36
- def self.refresh_token_revoked_on_use?
37
- column_names.include?("previous_refresh_token")
38
- end
5
+ module Doorkeeper
6
+ class AccessToken < ::ActiveRecord::Base
7
+ include Doorkeeper::Orm::ActiveRecord::Mixins::AccessToken
39
8
  end
40
9
  end
@@ -1,100 +1,10 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module Doorkeeper
4
- class Application < ActiveRecord::Base
5
- self.table_name = "#{table_name_prefix}oauth_applications#{table_name_suffix}"
6
-
7
- include ApplicationMixin
8
-
9
- has_many :access_grants, dependent: :delete_all, class_name: "Doorkeeper::AccessGrant"
10
- has_many :access_tokens, dependent: :delete_all, class_name: "Doorkeeper::AccessToken"
11
-
12
- validates :name, :secret, :uid, presence: true
13
- validates :uid, uniqueness: { case_sensitive: true }
14
- validates :redirect_uri, "doorkeeper/redirect_uri": true
15
- validates :confidential, inclusion: { in: [true, false] }
16
-
17
- validate :scopes_match_configured, if: :enforce_scopes?
18
-
19
- before_validation :generate_uid, :generate_secret, on: :create
20
-
21
- has_many :authorized_tokens, -> { where(revoked_at: nil) }, class_name: "AccessToken"
22
- has_many :authorized_applications, through: :authorized_tokens, source: :application
23
-
24
- # Returns Applications associated with active (not revoked) Access Tokens
25
- # that are owned by the specific Resource Owner.
26
- #
27
- # @param resource_owner [ActiveRecord::Base]
28
- # Resource Owner model instance
29
- #
30
- # @return [ActiveRecord::Relation]
31
- # Applications authorized for the Resource Owner
32
- #
33
- def self.authorized_for(resource_owner)
34
- resource_access_tokens = AccessToken.active_for(resource_owner)
35
- where(id: resource_access_tokens.select(:application_id).distinct)
36
- end
37
-
38
- # Revokes AccessToken and AccessGrant records that have not been revoked and
39
- # associated with the specific Application and Resource Owner.
40
- #
41
- # @param resource_owner [ActiveRecord::Base]
42
- # instance of the Resource Owner model
43
- #
44
- def self.revoke_tokens_and_grants_for(id, resource_owner)
45
- AccessToken.revoke_all_for(id, resource_owner)
46
- AccessGrant.revoke_all_for(id, resource_owner)
47
- end
3
+ require "doorkeeper/orm/active_record/redirect_uri_validator"
4
+ require "doorkeeper/orm/active_record/mixins/application"
48
5
 
49
- # Generates a new secret for this application, intended to be used
50
- # for rotating the secret or in case of compromise.
51
- #
52
- def renew_secret
53
- @raw_secret = UniqueToken.generate
54
- secret_strategy.store_secret(self, :secret, @raw_secret)
55
- end
56
-
57
- # We keep a volatile copy of the raw secret for initial communication
58
- # The stored refresh_token may be mapped and not available in cleartext.
59
- #
60
- # Some strategies allow restoring stored secrets (e.g. symmetric encryption)
61
- # while hashing strategies do not, so you cannot rely on this value
62
- # returning a present value for persisted tokens.
63
- def plaintext_secret
64
- if secret_strategy.allows_restoring_secrets?
65
- secret_strategy.restore_secret(self, :secret)
66
- else
67
- @raw_secret
68
- end
69
- end
70
-
71
- def to_json(options = nil)
72
- serializable_hash(except: :secret)
73
- .merge(secret: plaintext_secret)
74
- .to_json(options)
75
- end
76
-
77
- private
78
-
79
- def generate_uid
80
- self.uid = UniqueToken.generate if uid.blank?
81
- end
82
-
83
- def generate_secret
84
- return unless secret.blank?
85
- renew_secret
86
- end
87
-
88
- def scopes_match_configured
89
- if scopes.present? &&
90
- !ScopeChecker.valid?(scope_str: scopes.to_s,
91
- server_scopes: Doorkeeper.configuration.scopes)
92
- errors.add(:scopes, :not_match_configured)
93
- end
94
- end
95
-
96
- def enforce_scopes?
97
- Doorkeeper.configuration.enforce_configured_scopes?
98
- end
6
+ module Doorkeeper
7
+ class Application < ::ActiveRecord::Base
8
+ include ::Doorkeeper::Orm::ActiveRecord::Mixins::Application
99
9
  end
100
10
  end
@@ -0,0 +1,69 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper::Orm::ActiveRecord::Mixins
4
+ module AccessGrant
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ self.table_name = compute_doorkeeper_table_name
9
+ self.strict_loading_by_default = false if respond_to?(:strict_loading_by_default)
10
+
11
+ include ::Doorkeeper::AccessGrantMixin
12
+
13
+ belongs_to :application, class_name: Doorkeeper.config.application_class.to_s,
14
+ optional: true,
15
+ inverse_of: :access_grants
16
+
17
+ if Doorkeeper.config.polymorphic_resource_owner?
18
+ belongs_to :resource_owner, polymorphic: true, optional: false
19
+ else
20
+ validates :resource_owner_id, presence: true
21
+ end
22
+
23
+ validates :application_id,
24
+ :token,
25
+ :expires_in,
26
+ :redirect_uri,
27
+ presence: true
28
+
29
+ validates :token, uniqueness: { case_sensitive: true }
30
+
31
+ before_validation :generate_token, on: :create
32
+
33
+ # We keep a volatile copy of the raw token for initial communication
34
+ # The stored refresh_token may be mapped and not available in cleartext.
35
+ #
36
+ # Some strategies allow restoring stored secrets (e.g. symmetric encryption)
37
+ # while hashing strategies do not, so you cannot rely on this value
38
+ # returning a present value for persisted tokens.
39
+ def plaintext_token
40
+ if secret_strategy.allows_restoring_secrets?
41
+ secret_strategy.restore_secret(self, :token)
42
+ else
43
+ @raw_token
44
+ end
45
+ end
46
+
47
+ private
48
+
49
+ # Generates token value with UniqueToken class.
50
+ #
51
+ # @return [String] token value
52
+ #
53
+ def generate_token
54
+ @raw_token = Doorkeeper::OAuth::Helpers::UniqueToken.generate
55
+ secret_strategy.store_secret(self, :token, @raw_token)
56
+ end
57
+ end
58
+
59
+ module ClassMethods
60
+ private
61
+
62
+ def compute_doorkeeper_table_name
63
+ table_name = "oauth_access_grant"
64
+ table_name = table_name.pluralize if pluralize_table_names
65
+ "#{table_name_prefix}#{table_name}#{table_name_suffix}"
66
+ end
67
+ end
68
+ end
69
+ end
@@ -0,0 +1,60 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper::Orm::ActiveRecord::Mixins
4
+ module AccessToken
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ self.table_name = compute_doorkeeper_table_name
9
+ self.strict_loading_by_default = false if respond_to?(:strict_loading_by_default)
10
+
11
+ include ::Doorkeeper::AccessTokenMixin
12
+
13
+ belongs_to :application, class_name: Doorkeeper.config.application_class.to_s,
14
+ inverse_of: :access_tokens,
15
+ optional: true
16
+
17
+ if Doorkeeper.config.polymorphic_resource_owner?
18
+ belongs_to :resource_owner, polymorphic: true, optional: true
19
+ end
20
+
21
+ validates :token, presence: true, uniqueness: { case_sensitive: true }
22
+ validates :refresh_token, uniqueness: { case_sensitive: true }, if: :use_refresh_token?
23
+
24
+ # @attr_writer [Boolean, nil] use_refresh_token
25
+ # indicates the possibility of using refresh token
26
+ attr_writer :use_refresh_token
27
+
28
+ before_validation :generate_token, on: :create
29
+ before_validation :generate_refresh_token,
30
+ on: :create, if: :use_refresh_token?
31
+ end
32
+
33
+ module ClassMethods
34
+ # Searches for not revoked Access Tokens associated with the
35
+ # specific Resource Owner.
36
+ #
37
+ # @param resource_owner [ActiveRecord::Base]
38
+ # Resource Owner model instance
39
+ #
40
+ # @return [ActiveRecord::Relation]
41
+ # active Access Tokens for Resource Owner
42
+ #
43
+ def active_for(resource_owner)
44
+ by_resource_owner(resource_owner).where(revoked_at: nil)
45
+ end
46
+
47
+ def refresh_token_revoked_on_use?
48
+ column_names.include?("previous_refresh_token")
49
+ end
50
+
51
+ private
52
+
53
+ def compute_doorkeeper_table_name
54
+ table_name = "oauth_access_token"
55
+ table_name = table_name.pluralize if pluralize_table_names
56
+ "#{table_name_prefix}#{table_name}#{table_name_suffix}"
57
+ end
58
+ end
59
+ end
60
+ end