doorkeeper 5.3.3 → 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 (224) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +82 -4
  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/config/abstract_builder.rb +28 -0
  12. data/lib/doorkeeper/config/option.rb +28 -14
  13. data/lib/doorkeeper/config.rb +64 -35
  14. data/lib/doorkeeper/engine.rb +1 -1
  15. data/lib/doorkeeper/grape/helpers.rb +1 -1
  16. data/lib/doorkeeper/helpers/controller.rb +4 -4
  17. data/lib/doorkeeper/models/access_grant_mixin.rb +20 -16
  18. data/lib/doorkeeper/models/access_token_mixin.rb +108 -45
  19. data/lib/doorkeeper/models/application_mixin.rb +5 -4
  20. data/lib/doorkeeper/models/concerns/resource_ownerable.rb +47 -0
  21. data/lib/doorkeeper/models/concerns/revocable.rb +1 -1
  22. data/lib/doorkeeper/models/concerns/scopes.rb +5 -1
  23. data/lib/doorkeeper/models/concerns/secret_storable.rb +1 -3
  24. data/lib/doorkeeper/oauth/authorization/code.rb +15 -6
  25. data/lib/doorkeeper/oauth/authorization/context.rb +2 -2
  26. data/lib/doorkeeper/oauth/authorization/token.rb +8 -12
  27. data/lib/doorkeeper/oauth/authorization/uri_builder.rb +4 -4
  28. data/lib/doorkeeper/oauth/authorization_code_request.rb +18 -8
  29. data/lib/doorkeeper/oauth/base_request.rb +11 -19
  30. data/lib/doorkeeper/oauth/client/credentials.rb +2 -4
  31. data/lib/doorkeeper/oauth/client.rb +1 -1
  32. data/lib/doorkeeper/oauth/client_credentials/creator.rb +26 -8
  33. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +3 -2
  34. data/lib/doorkeeper/oauth/client_credentials/validator.rb +4 -2
  35. data/lib/doorkeeper/oauth/client_credentials_request.rb +8 -7
  36. data/lib/doorkeeper/oauth/code_request.rb +3 -3
  37. data/lib/doorkeeper/oauth/code_response.rb +6 -2
  38. data/lib/doorkeeper/oauth/error_response.rb +2 -4
  39. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +1 -5
  40. data/lib/doorkeeper/oauth/hooks/context.rb +21 -0
  41. data/lib/doorkeeper/oauth/invalid_token_response.rb +2 -2
  42. data/lib/doorkeeper/oauth/password_access_token_request.rb +4 -6
  43. data/lib/doorkeeper/oauth/pre_authorization.rb +36 -30
  44. data/lib/doorkeeper/oauth/refresh_token_request.rb +18 -22
  45. data/lib/doorkeeper/oauth/token.rb +5 -6
  46. data/lib/doorkeeper/oauth/token_introspection.rb +4 -8
  47. data/lib/doorkeeper/oauth/token_request.rb +3 -3
  48. data/lib/doorkeeper/oauth/token_response.rb +1 -1
  49. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +8 -3
  50. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +7 -3
  51. data/lib/doorkeeper/orm/active_record.rb +10 -2
  52. data/lib/doorkeeper/rails/routes/abstract_router.rb +35 -0
  53. data/lib/doorkeeper/rails/routes/mapper.rb +2 -2
  54. data/lib/doorkeeper/rails/routes/registry.rb +45 -0
  55. data/lib/doorkeeper/rails/routes.rb +13 -17
  56. data/lib/doorkeeper/request/refresh_token.rb +2 -1
  57. data/lib/doorkeeper/request/strategy.rb +2 -2
  58. data/lib/doorkeeper/server.rb +4 -4
  59. data/lib/doorkeeper/stale_records_cleaner.rb +4 -4
  60. data/lib/doorkeeper/version.rb +2 -2
  61. data/lib/doorkeeper.rb +106 -79
  62. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  63. data/lib/generators/doorkeeper/enable_polymorphic_resource_owner_generator.rb +39 -0
  64. data/lib/generators/doorkeeper/templates/add_owner_to_application_migration.rb.erb +2 -0
  65. data/lib/generators/doorkeeper/templates/add_previous_refresh_token_to_access_tokens.rb.erb +2 -0
  66. data/lib/generators/doorkeeper/templates/enable_pkce_migration.rb.erb +2 -0
  67. data/lib/generators/doorkeeper/templates/enable_polymorphic_resource_owner_migration.rb.erb +17 -0
  68. data/lib/generators/doorkeeper/templates/initializer.rb +39 -3
  69. data/lib/generators/doorkeeper/templates/migration.rb.erb +14 -5
  70. metadata +13 -296
  71. data/Appraisals +0 -40
  72. data/CODE_OF_CONDUCT.md +0 -46
  73. data/CONTRIBUTING.md +0 -49
  74. data/Dangerfile +0 -67
  75. data/Dockerfile +0 -29
  76. data/Gemfile +0 -25
  77. data/NEWS.md +0 -1
  78. data/RELEASING.md +0 -11
  79. data/Rakefile +0 -28
  80. data/SECURITY.md +0 -15
  81. data/UPGRADE.md +0 -2
  82. data/bin/console +0 -16
  83. data/doorkeeper.gemspec +0 -42
  84. data/gemfiles/rails_5_0.gemfile +0 -18
  85. data/gemfiles/rails_5_1.gemfile +0 -18
  86. data/gemfiles/rails_5_2.gemfile +0 -18
  87. data/gemfiles/rails_6_0.gemfile +0 -18
  88. data/gemfiles/rails_master.gemfile +0 -18
  89. data/spec/controllers/application_metal_controller_spec.rb +0 -64
  90. data/spec/controllers/applications_controller_spec.rb +0 -274
  91. data/spec/controllers/authorizations_controller_spec.rb +0 -608
  92. data/spec/controllers/protected_resources_controller_spec.rb +0 -361
  93. data/spec/controllers/token_info_controller_spec.rb +0 -50
  94. data/spec/controllers/tokens_controller_spec.rb +0 -498
  95. data/spec/dummy/Rakefile +0 -9
  96. data/spec/dummy/app/assets/config/manifest.js +0 -2
  97. data/spec/dummy/app/controllers/application_controller.rb +0 -5
  98. data/spec/dummy/app/controllers/custom_authorizations_controller.rb +0 -9
  99. data/spec/dummy/app/controllers/full_protected_resources_controller.rb +0 -14
  100. data/spec/dummy/app/controllers/home_controller.rb +0 -18
  101. data/spec/dummy/app/controllers/metal_controller.rb +0 -13
  102. data/spec/dummy/app/controllers/semi_protected_resources_controller.rb +0 -13
  103. data/spec/dummy/app/helpers/application_helper.rb +0 -7
  104. data/spec/dummy/app/models/user.rb +0 -7
  105. data/spec/dummy/app/views/home/index.html.erb +0 -0
  106. data/spec/dummy/app/views/layouts/application.html.erb +0 -14
  107. data/spec/dummy/config/application.rb +0 -49
  108. data/spec/dummy/config/boot.rb +0 -7
  109. data/spec/dummy/config/database.yml +0 -15
  110. data/spec/dummy/config/environment.rb +0 -5
  111. data/spec/dummy/config/environments/development.rb +0 -31
  112. data/spec/dummy/config/environments/production.rb +0 -64
  113. data/spec/dummy/config/environments/test.rb +0 -45
  114. data/spec/dummy/config/initializers/backtrace_silencers.rb +0 -9
  115. data/spec/dummy/config/initializers/doorkeeper.rb +0 -166
  116. data/spec/dummy/config/initializers/secret_token.rb +0 -10
  117. data/spec/dummy/config/initializers/session_store.rb +0 -10
  118. data/spec/dummy/config/initializers/wrap_parameters.rb +0 -16
  119. data/spec/dummy/config/locales/doorkeeper.en.yml +0 -5
  120. data/spec/dummy/config/routes.rb +0 -13
  121. data/spec/dummy/config.ru +0 -6
  122. data/spec/dummy/db/migrate/20111122132257_create_users.rb +0 -11
  123. data/spec/dummy/db/migrate/20120312140401_add_password_to_users.rb +0 -7
  124. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +0 -69
  125. data/spec/dummy/db/migrate/20151223200000_add_owner_to_application.rb +0 -9
  126. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +0 -13
  127. data/spec/dummy/db/migrate/20170822064514_enable_pkce.rb +0 -8
  128. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +0 -13
  129. data/spec/dummy/db/schema.rb +0 -68
  130. data/spec/dummy/public/404.html +0 -26
  131. data/spec/dummy/public/422.html +0 -26
  132. data/spec/dummy/public/500.html +0 -26
  133. data/spec/dummy/public/favicon.ico +0 -0
  134. data/spec/dummy/script/rails +0 -9
  135. data/spec/factories.rb +0 -30
  136. data/spec/generators/application_owner_generator_spec.rb +0 -28
  137. data/spec/generators/confidential_applications_generator_spec.rb +0 -29
  138. data/spec/generators/install_generator_spec.rb +0 -36
  139. data/spec/generators/migration_generator_spec.rb +0 -28
  140. data/spec/generators/pkce_generator_spec.rb +0 -28
  141. data/spec/generators/previous_refresh_token_generator_spec.rb +0 -44
  142. data/spec/generators/templates/routes.rb +0 -4
  143. data/spec/generators/views_generator_spec.rb +0 -29
  144. data/spec/grape/grape_integration_spec.rb +0 -137
  145. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +0 -26
  146. data/spec/lib/config_spec.rb +0 -809
  147. data/spec/lib/doorkeeper_spec.rb +0 -27
  148. data/spec/lib/models/expirable_spec.rb +0 -61
  149. data/spec/lib/models/reusable_spec.rb +0 -40
  150. data/spec/lib/models/revocable_spec.rb +0 -59
  151. data/spec/lib/models/scopes_spec.rb +0 -53
  152. data/spec/lib/models/secret_storable_spec.rb +0 -135
  153. data/spec/lib/oauth/authorization/uri_builder_spec.rb +0 -39
  154. data/spec/lib/oauth/authorization_code_request_spec.rb +0 -170
  155. data/spec/lib/oauth/base_request_spec.rb +0 -224
  156. data/spec/lib/oauth/base_response_spec.rb +0 -45
  157. data/spec/lib/oauth/client/credentials_spec.rb +0 -90
  158. data/spec/lib/oauth/client_credentials/creator_spec.rb +0 -134
  159. data/spec/lib/oauth/client_credentials/issuer_spec.rb +0 -112
  160. data/spec/lib/oauth/client_credentials/validation_spec.rb +0 -59
  161. data/spec/lib/oauth/client_credentials_integration_spec.rb +0 -27
  162. data/spec/lib/oauth/client_credentials_request_spec.rb +0 -107
  163. data/spec/lib/oauth/client_spec.rb +0 -38
  164. data/spec/lib/oauth/code_request_spec.rb +0 -46
  165. data/spec/lib/oauth/code_response_spec.rb +0 -32
  166. data/spec/lib/oauth/error_response_spec.rb +0 -64
  167. data/spec/lib/oauth/error_spec.rb +0 -21
  168. data/spec/lib/oauth/forbidden_token_response_spec.rb +0 -20
  169. data/spec/lib/oauth/helpers/scope_checker_spec.rb +0 -110
  170. data/spec/lib/oauth/helpers/unique_token_spec.rb +0 -21
  171. data/spec/lib/oauth/helpers/uri_checker_spec.rb +0 -262
  172. data/spec/lib/oauth/invalid_request_response_spec.rb +0 -73
  173. data/spec/lib/oauth/invalid_token_response_spec.rb +0 -53
  174. data/spec/lib/oauth/password_access_token_request_spec.rb +0 -190
  175. data/spec/lib/oauth/pre_authorization_spec.rb +0 -223
  176. data/spec/lib/oauth/refresh_token_request_spec.rb +0 -177
  177. data/spec/lib/oauth/scopes_spec.rb +0 -146
  178. data/spec/lib/oauth/token_request_spec.rb +0 -157
  179. data/spec/lib/oauth/token_response_spec.rb +0 -84
  180. data/spec/lib/oauth/token_spec.rb +0 -156
  181. data/spec/lib/request/strategy_spec.rb +0 -54
  182. data/spec/lib/secret_storing/base_spec.rb +0 -60
  183. data/spec/lib/secret_storing/bcrypt_spec.rb +0 -49
  184. data/spec/lib/secret_storing/plain_spec.rb +0 -44
  185. data/spec/lib/secret_storing/sha256_hash_spec.rb +0 -48
  186. data/spec/lib/server_spec.rb +0 -49
  187. data/spec/lib/stale_records_cleaner_spec.rb +0 -89
  188. data/spec/models/doorkeeper/access_grant_spec.rb +0 -161
  189. data/spec/models/doorkeeper/access_token_spec.rb +0 -622
  190. data/spec/models/doorkeeper/application_spec.rb +0 -482
  191. data/spec/requests/applications/applications_request_spec.rb +0 -259
  192. data/spec/requests/applications/authorized_applications_spec.rb +0 -32
  193. data/spec/requests/endpoints/authorization_spec.rb +0 -91
  194. data/spec/requests/endpoints/token_spec.rb +0 -75
  195. data/spec/requests/flows/authorization_code_errors_spec.rb +0 -79
  196. data/spec/requests/flows/authorization_code_spec.rb +0 -525
  197. data/spec/requests/flows/client_credentials_spec.rb +0 -166
  198. data/spec/requests/flows/implicit_grant_errors_spec.rb +0 -46
  199. data/spec/requests/flows/implicit_grant_spec.rb +0 -91
  200. data/spec/requests/flows/password_spec.rb +0 -316
  201. data/spec/requests/flows/refresh_token_spec.rb +0 -233
  202. data/spec/requests/flows/revoke_token_spec.rb +0 -157
  203. data/spec/requests/flows/skip_authorization_spec.rb +0 -66
  204. data/spec/requests/protected_resources/metal_spec.rb +0 -16
  205. data/spec/requests/protected_resources/private_api_spec.rb +0 -83
  206. data/spec/routing/custom_controller_routes_spec.rb +0 -133
  207. data/spec/routing/default_routes_spec.rb +0 -41
  208. data/spec/routing/scoped_routes_spec.rb +0 -47
  209. data/spec/spec_helper.rb +0 -54
  210. data/spec/spec_helper_integration.rb +0 -4
  211. data/spec/support/dependencies/factory_bot.rb +0 -4
  212. data/spec/support/doorkeeper_rspec.rb +0 -22
  213. data/spec/support/helpers/access_token_request_helper.rb +0 -13
  214. data/spec/support/helpers/authorization_request_helper.rb +0 -43
  215. data/spec/support/helpers/config_helper.rb +0 -11
  216. data/spec/support/helpers/model_helper.rb +0 -78
  217. data/spec/support/helpers/request_spec_helper.rb +0 -110
  218. data/spec/support/helpers/url_helper.rb +0 -62
  219. data/spec/support/orm/active_record.rb +0 -5
  220. data/spec/support/shared/controllers_shared_context.rb +0 -133
  221. data/spec/support/shared/hashing_shared_context.rb +0 -36
  222. data/spec/support/shared/models_shared_examples.rb +0 -54
  223. data/spec/validators/redirect_uri_validator_spec.rb +0 -183
  224. data/spec/version/version_spec.rb +0 -17
@@ -5,39 +5,37 @@ module Doorkeeper
5
5
  class PreAuthorization
6
6
  include Validations
7
7
 
8
- validate :client_id, error: :invalid_request
9
- validate :client, error: :invalid_client
10
- validate :redirect_uri, error: :invalid_redirect_uri
11
- validate :params, error: :invalid_request
12
- validate :response_type, error: :unsupported_response_type
13
- validate :scopes, error: :invalid_scope
14
- validate :code_challenge_method, error: :invalid_code_challenge_method
8
+ validate :client_id, error: :invalid_request
9
+ validate :client, error: :invalid_client
15
10
  validate :client_supports_grant_flow, error: :unauthorized_client
11
+ validate :resource_owner_authorize_for_client, error: :invalid_client
12
+ validate :redirect_uri, error: :invalid_redirect_uri
13
+ validate :params, error: :invalid_request
14
+ validate :response_type, error: :unsupported_response_type
15
+ validate :scopes, error: :invalid_scope
16
+ validate :code_challenge_method, error: :invalid_code_challenge_method
16
17
 
17
- attr_reader :server, :client_id, :client, :redirect_uri, :response_type, :state,
18
- :code_challenge, :code_challenge_method, :missing_param
18
+ attr_reader :client, :code_challenge, :code_challenge_method, :missing_param,
19
+ :redirect_uri, :resource_owner, :response_type, :state
19
20
 
20
- def initialize(server, attrs = {})
21
+ def initialize(server, parameters = {}, resource_owner = nil)
21
22
  @server = server
22
- @client_id = attrs[:client_id]
23
- @response_type = attrs[:response_type]
24
- @redirect_uri = attrs[:redirect_uri]
25
- @scope = attrs[:scope]
26
- @state = attrs[:state]
27
- @code_challenge = attrs[:code_challenge]
28
- @code_challenge_method = attrs[:code_challenge_method]
23
+ @client_id = parameters[:client_id]
24
+ @response_type = parameters[:response_type]
25
+ @redirect_uri = parameters[:redirect_uri]
26
+ @scope = parameters[:scope]
27
+ @state = parameters[:state]
28
+ @code_challenge = parameters[:code_challenge]
29
+ @code_challenge_method = parameters[:code_challenge_method]
30
+ @resource_owner = resource_owner
29
31
  end
30
32
 
31
33
  def authorizable?
32
34
  valid?
33
35
  end
34
36
 
35
- def validate_client_supports_grant_flow
36
- Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client.application)
37
- end
38
-
39
37
  def scopes
40
- Scopes.from_string scope
38
+ Scopes.from_string(scope)
41
39
  end
42
40
 
43
41
  def scope
@@ -55,14 +53,14 @@ module Doorkeeper
55
53
  end
56
54
  end
57
55
 
58
- def as_json(attributes = {})
59
- return pre_auth_hash.merge(attributes.to_h) if attributes.respond_to?(:to_h)
60
-
56
+ def as_json(_options = nil)
61
57
  pre_auth_hash
62
58
  end
63
59
 
64
60
  private
65
61
 
62
+ attr_reader :client_id, :server
63
+
66
64
  def build_scopes
67
65
  client_scopes = client.scopes
68
66
  if client_scopes.blank?
@@ -74,7 +72,6 @@ module Doorkeeper
74
72
 
75
73
  def validate_client_id
76
74
  @missing_param = :client_id if client_id.blank?
77
-
78
75
  @missing_param.nil?
79
76
  end
80
77
 
@@ -83,6 +80,10 @@ module Doorkeeper
83
80
  @client.present?
84
81
  end
85
82
 
83
+ def validate_client_supports_grant_flow
84
+ Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client.application)
85
+ end
86
+
86
87
  def validate_redirect_uri
87
88
  return false if redirect_uri.blank?
88
89
 
@@ -115,19 +116,24 @@ module Doorkeeper
115
116
  )
116
117
  end
117
118
 
118
- def grant_type
119
- response_type == "code" ? AUTHORIZATION_CODE : IMPLICIT
120
- end
121
-
122
119
  def validate_code_challenge_method
123
120
  code_challenge.blank? ||
124
121
  (code_challenge_method.present? && code_challenge_method =~ /^plain$|^S256$/)
125
122
  end
126
123
 
124
+ def validate_resource_owner_authorize_for_client
125
+ # The `authorize_resource_owner_for_client` config option is used for this validation
126
+ client.application.authorized_for_resource_owner?(@resource_owner)
127
+ end
128
+
127
129
  def response_on_fragment?
128
130
  response_type == "token"
129
131
  end
130
132
 
133
+ def grant_type
134
+ response_type == "code" ? AUTHORIZATION_CODE : IMPLICIT
135
+ end
136
+
131
137
  def pre_auth_hash
132
138
  {
133
139
  client_id: client.uid,
@@ -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
@@ -50,30 +49,27 @@ module Doorkeeper
50
49
  end
51
50
 
52
51
  def create_access_token
53
- @access_token = server_config.access_token_model.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
+ @access_token = server_config.access_token_model.create_for(
66
+ application: refresh_token.application,
67
+ resource_owner: resource_owner,
68
+ scopes: scopes,
69
+ expires_in: refresh_token.expires_in,
70
+ use_refresh_token: true,
71
+ **attributes,
75
72
  )
76
- Authorization::Token.access_token_expires_in(server, context)
77
73
  end
78
74
 
79
75
  def validate_token_presence
@@ -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
17
  access_token = Doorkeeper.config.access_token_model.by_token(token)
18
- refresh_token_enabled = Doorkeeper.config.refresh_token_enabled?
19
- if access_token.present? && refresh_token_enabled
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)
@@ -6,9 +6,6 @@ module Doorkeeper
6
6
  #
7
7
  # @see https://tools.ietf.org/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
@@ -179,11 +179,7 @@ module Doorkeeper
179
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.
@@ -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
@@ -9,12 +9,17 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
9
9
 
10
10
  include ::Doorkeeper::AccessGrantMixin
11
11
 
12
- belongs_to :application, class_name: Doorkeeper.config.application_class,
12
+ belongs_to :application, class_name: Doorkeeper.config.application_class.to_s,
13
13
  optional: true,
14
14
  inverse_of: :access_grants
15
15
 
16
- validates :resource_owner_id,
17
- :application_id,
16
+ if Doorkeeper.config.polymorphic_resource_owner?
17
+ belongs_to :resource_owner, polymorphic: true, optional: false
18
+ else
19
+ validates :resource_owner_id, presence: true
20
+ end
21
+
22
+ validates :application_id,
18
23
  :token,
19
24
  :expires_in,
20
25
  :redirect_uri,
@@ -9,10 +9,14 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
9
9
 
10
10
  include ::Doorkeeper::AccessTokenMixin
11
11
 
12
- belongs_to :application, class_name: Doorkeeper.config.application_class,
12
+ belongs_to :application, class_name: Doorkeeper.config.application_class.to_s,
13
13
  inverse_of: :access_tokens,
14
14
  optional: true
15
15
 
16
+ if Doorkeeper.config.polymorphic_resource_owner?
17
+ belongs_to :resource_owner, polymorphic: true, optional: true
18
+ end
19
+
16
20
  validates :token, presence: true, uniqueness: { case_sensitive: true }
17
21
  validates :refresh_token, uniqueness: { case_sensitive: true }, if: :use_refresh_token?
18
22
 
@@ -25,7 +29,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
25
29
  on: :create, if: :use_refresh_token?
26
30
  end
27
31
 
28
- class_methods do
32
+ module ClassMethods
29
33
  # Searches for not revoked Access Tokens associated with the
30
34
  # specific Resource Owner.
31
35
  #
@@ -36,7 +40,7 @@ module Doorkeeper::Orm::ActiveRecord::Mixins
36
40
  # active Access Tokens for Resource Owner
37
41
  #
38
42
  def active_for(resource_owner)
39
- where(resource_owner_id: resource_owner.id, revoked_at: nil)
43
+ by_resource_owner(resource_owner).where(revoked_at: nil)
40
44
  end
41
45
 
42
46
  def refresh_token_revoked_on_use?
@@ -33,12 +33,20 @@ module Doorkeeper
33
33
  lazy_load do
34
34
  require "doorkeeper/models/concerns/ownership"
35
35
 
36
- Doorkeeper.config.application_model.send :include, Doorkeeper::Models::Ownership
36
+ Doorkeeper.config.application_model.include(Doorkeeper::Models::Ownership)
37
37
  end
38
38
  end
39
39
 
40
40
  def self.lazy_load(&block)
41
- ActiveSupport.on_load(:active_record, {}, &block)
41
+ # ActiveSupport has no public interface to check if something
42
+ # already lazy-loaded :(
43
+ loaded = ActiveSupport.instance_variable_get(:"@loaded") || {}
44
+
45
+ if loaded.key?(:active_record)
46
+ block.call
47
+ else
48
+ ActiveSupport.on_load(:active_record, {}, &block)
49
+ end
42
50
  end
43
51
 
44
52
  def self.models
@@ -0,0 +1,35 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ # Abstract router module that implements base behavior
6
+ # for generating and mapping Rails routes.
7
+ #
8
+ # Could be reused in Doorkeeper extensions.
9
+ #
10
+ module AbstractRouter
11
+ extend ActiveSupport::Concern
12
+
13
+ attr_reader :routes
14
+
15
+ def initialize(routes, mapper = Mapper.new, &block)
16
+ @routes = routes
17
+ @mapping = mapper.map(&block)
18
+ end
19
+
20
+ def generate_routes!(**_options)
21
+ raise NotImplementedError, "must be redefined for #{self.class.name}!"
22
+ end
23
+
24
+ private
25
+
26
+ def map_route(name, method)
27
+ return if @mapping.skipped?(name)
28
+
29
+ send(method, @mapping[name])
30
+
31
+ mapping[name] = @mapping[name]
32
+ end
33
+ end
34
+ end
35
+ end
@@ -4,8 +4,8 @@ module Doorkeeper
4
4
  module Rails
5
5
  class Routes # :nodoc:
6
6
  class Mapper
7
- def initialize
8
- @mapping = Mapping.new
7
+ def initialize(mapping = Mapping.new)
8
+ @mapping = mapping
9
9
  end
10
10
 
11
11
  def map(&block)
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper
4
+ module Rails
5
+ class Routes
6
+ # Thread-safe registry of any Doorkeeper additional routes.
7
+ # Used to allow implementing of Doorkeeper extensions that must
8
+ # use their own routes.
9
+ #
10
+ module Registry
11
+ ROUTES_ACCESS_LOCK = Mutex.new
12
+ ROUTES_DEFINITION_LOCK = Mutex.new
13
+
14
+ InvalidRouterClass = Class.new(StandardError)
15
+
16
+ # Collection of additional registered routes for Doorkeeper.
17
+ #
18
+ # @return [Array<Object>] set of registered routes
19
+ #
20
+ def registered_routes
21
+ ROUTES_DEFINITION_LOCK.synchronize do
22
+ @registered_routes ||= Set.new
23
+ end
24
+ end
25
+
26
+ # Registers additional routes in the Doorkeeper registry
27
+ #
28
+ # @param [Object] routes
29
+ # routes class
30
+ #
31
+ def register_routes(routes)
32
+ if !routes.is_a?(Module) || !(routes < AbstractRouter)
33
+ raise InvalidRouterClass, "routes class must include Doorkeeper::Rails::AbstractRouter"
34
+ end
35
+
36
+ ROUTES_ACCESS_LOCK.synchronize do
37
+ registered_routes << routes
38
+ end
39
+ end
40
+
41
+ alias register register_routes
42
+ end
43
+ end
44
+ end
45
+ end
@@ -2,29 +2,33 @@
2
2
 
3
3
  require "doorkeeper/rails/routes/mapping"
4
4
  require "doorkeeper/rails/routes/mapper"
5
+ require "doorkeeper/rails/routes/abstract_router"
6
+ require "doorkeeper/rails/routes/registry"
5
7
 
6
8
  module Doorkeeper
7
9
  module Rails
8
10
  class Routes # :nodoc:
9
- mattr_reader :mapping do
10
- {}
11
- end
12
-
13
11
  module Helper
14
12
  def use_doorkeeper(options = {}, &block)
15
13
  Doorkeeper::Rails::Routes.new(self, &block).generate_routes!(options)
16
14
  end
17
15
  end
18
16
 
17
+ include AbstractRouter
18
+ extend Registry
19
+
20
+ mattr_reader :mapping do
21
+ {}
22
+ end
23
+
19
24
  def self.install!
20
25
  ActionDispatch::Routing::Mapper.include Doorkeeper::Rails::Routes::Helper
21
- end
22
26
 
23
- attr_reader :routes
27
+ registered_routes.each(&:install!)
28
+ end
24
29
 
25
- def initialize(routes, &block)
26
- @routes = routes
27
- @mapping = Mapper.new.map(&block)
30
+ def initialize(routes, mapper = Mapper.new, &block)
31
+ super
28
32
 
29
33
  @mapping.skips.push(:applications, :authorized_applications) if Doorkeeper.config.api_only
30
34
  end
@@ -43,14 +47,6 @@ module Doorkeeper
43
47
 
44
48
  private
45
49
 
46
- def map_route(name, method)
47
- return if @mapping.skipped?(name)
48
-
49
- send(method, @mapping[name])
50
-
51
- mapping[name] = @mapping[name]
52
- end
53
-
54
50
  def authorization_routes(mapping)
55
51
  routes.resource(
56
52
  :authorization,
@@ -12,7 +12,8 @@ module Doorkeeper
12
12
  def request
13
13
  @request ||= OAuth::RefreshTokenRequest.new(
14
14
  Doorkeeper.config,
15
- refresh_token, credentials,
15
+ refresh_token,
16
+ credentials,
16
17
  parameters,
17
18
  )
18
19
  end
@@ -3,12 +3,12 @@
3
3
  module Doorkeeper
4
4
  module Request
5
5
  class Strategy
6
- attr_accessor :server
6
+ attr_reader :server
7
7
 
8
8
  delegate :authorize, to: :request
9
9
 
10
10
  def initialize(server)
11
- self.server = server
11
+ @server = server
12
12
  end
13
13
 
14
14
  def request
@@ -2,19 +2,19 @@
2
2
 
3
3
  module Doorkeeper
4
4
  class Server
5
- attr_accessor :context
5
+ attr_reader :context
6
6
 
7
- def initialize(context = nil)
7
+ def initialize(context)
8
8
  @context = context
9
9
  end
10
10
 
11
11
  def authorization_request(strategy)
12
- klass = Request.authorization_strategy strategy
12
+ klass = Request.authorization_strategy(strategy)
13
13
  klass.new(self)
14
14
  end
15
15
 
16
16
  def token_request(strategy)
17
- klass = Request.token_strategy strategy
17
+ klass = Request.token_strategy(strategy)
18
18
  klass.new(self)
19
19
  end
20
20
 
@@ -13,12 +13,12 @@ module Doorkeeper
13
13
  raise Doorkeeper::Errors::NoOrmCleaner, "'#{configured_orm}' ORM has no cleaner!"
14
14
  end
15
15
 
16
- def self.configured_orm
17
- Doorkeeper.config.orm
18
- end
19
-
20
16
  def self.new(base_scope)
21
17
  self.for(base_scope)
22
18
  end
19
+
20
+ def self.configured_orm
21
+ Doorkeeper.config.orm
22
+ end
23
23
  end
24
24
  end
@@ -8,8 +8,8 @@ module Doorkeeper
8
8
  module VERSION
9
9
  # Semantic versioning
10
10
  MAJOR = 5
11
- MINOR = 3
12
- TINY = 3
11
+ MINOR = 4
12
+ TINY = 0
13
13
  PRE = nil
14
14
 
15
15
  # Full version number