doorkeeper 5.2.2 → 5.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (126) hide show
  1. checksums.yaml +4 -4
  2. data/Appraisals +2 -2
  3. data/CHANGELOG.md +29 -2
  4. data/Gemfile +2 -2
  5. data/app/controllers/doorkeeper/application_controller.rb +2 -2
  6. data/app/controllers/doorkeeper/application_metal_controller.rb +2 -2
  7. data/app/controllers/doorkeeper/applications_controller.rb +0 -1
  8. data/app/controllers/doorkeeper/authorizations_controller.rb +2 -2
  9. data/app/controllers/doorkeeper/authorized_applications_controller.rb +2 -2
  10. data/gemfiles/rails_5_0.gemfile +2 -2
  11. data/gemfiles/rails_5_1.gemfile +2 -2
  12. data/gemfiles/rails_5_2.gemfile +2 -2
  13. data/gemfiles/rails_6_0.gemfile +2 -2
  14. data/gemfiles/rails_master.gemfile +2 -2
  15. data/lib/doorkeeper/config.rb +71 -38
  16. data/lib/doorkeeper/grape/helpers.rb +1 -1
  17. data/lib/doorkeeper/helpers/controller.rb +10 -8
  18. data/lib/doorkeeper/models/access_grant_mixin.rb +7 -6
  19. data/lib/doorkeeper/models/access_token_mixin.rb +56 -18
  20. data/lib/doorkeeper/models/application_mixin.rb +3 -3
  21. data/lib/doorkeeper/models/concerns/ownership.rb +1 -1
  22. data/lib/doorkeeper/models/concerns/reusable.rb +1 -1
  23. data/lib/doorkeeper/models/concerns/revocable.rb +0 -27
  24. data/lib/doorkeeper/oauth/authorization/code.rb +4 -4
  25. data/lib/doorkeeper/oauth/authorization/token.rb +9 -6
  26. data/lib/doorkeeper/oauth/authorization_code_request.rb +13 -6
  27. data/lib/doorkeeper/oauth/base_request.rb +8 -4
  28. data/lib/doorkeeper/oauth/client.rb +7 -8
  29. data/lib/doorkeeper/oauth/client_credentials/creator.rb +16 -9
  30. data/lib/doorkeeper/oauth/client_credentials/issuer.rb +7 -7
  31. data/lib/doorkeeper/oauth/client_credentials/{validation.rb → validator.rb} +4 -4
  32. data/lib/doorkeeper/oauth/client_credentials_request.rb +1 -1
  33. data/lib/doorkeeper/oauth/code_response.rb +2 -2
  34. data/lib/doorkeeper/oauth/error.rb +1 -1
  35. data/lib/doorkeeper/oauth/error_response.rb +5 -5
  36. data/lib/doorkeeper/oauth/helpers/scope_checker.rb +7 -5
  37. data/lib/doorkeeper/oauth/helpers/unique_token.rb +8 -5
  38. data/lib/doorkeeper/oauth/helpers/uri_checker.rb +1 -1
  39. data/lib/doorkeeper/oauth/invalid_request_response.rb +3 -3
  40. data/lib/doorkeeper/oauth/invalid_token_response.rb +5 -2
  41. data/lib/doorkeeper/oauth/password_access_token_request.rb +3 -3
  42. data/lib/doorkeeper/oauth/pre_authorization.rb +12 -7
  43. data/lib/doorkeeper/oauth/refresh_token_request.rb +5 -5
  44. data/lib/doorkeeper/oauth/token.rb +2 -2
  45. data/lib/doorkeeper/oauth/token_introspection.rb +6 -6
  46. data/lib/doorkeeper/orm/active_record/access_grant.rb +4 -43
  47. data/lib/doorkeeper/orm/active_record/access_token.rb +4 -35
  48. data/lib/doorkeeper/orm/active_record/application.rb +5 -95
  49. data/lib/doorkeeper/orm/active_record/mixins/access_grant.rb +53 -0
  50. data/lib/doorkeeper/orm/active_record/mixins/access_token.rb +47 -0
  51. data/lib/doorkeeper/orm/active_record/mixins/application.rb +128 -0
  52. data/lib/doorkeeper/orm/active_record/redirect_uri_validator.rb +3 -3
  53. data/lib/doorkeeper/orm/active_record.rb +3 -4
  54. data/lib/doorkeeper/rails/helpers.rb +4 -4
  55. data/lib/doorkeeper/rails/routes.rb +5 -7
  56. data/lib/doorkeeper/rake/db.rake +3 -3
  57. data/lib/doorkeeper/request/authorization_code.rb +3 -3
  58. data/lib/doorkeeper/request/client_credentials.rb +2 -2
  59. data/lib/doorkeeper/request/password.rb +2 -2
  60. data/lib/doorkeeper/request/refresh_token.rb +3 -3
  61. data/lib/doorkeeper/request.rb +1 -1
  62. data/lib/doorkeeper/server.rb +1 -1
  63. data/lib/doorkeeper/stale_records_cleaner.rb +1 -1
  64. data/lib/doorkeeper/version.rb +2 -2
  65. data/lib/doorkeeper.rb +2 -3
  66. data/lib/generators/doorkeeper/application_owner_generator.rb +1 -1
  67. data/lib/generators/doorkeeper/confidential_applications_generator.rb +1 -1
  68. data/lib/generators/doorkeeper/migration_generator.rb +1 -1
  69. data/lib/generators/doorkeeper/pkce_generator.rb +1 -1
  70. data/lib/generators/doorkeeper/previous_refresh_token_generator.rb +2 -2
  71. data/lib/generators/doorkeeper/templates/initializer.rb +39 -0
  72. data/spec/controllers/application_metal_controller_spec.rb +1 -1
  73. data/spec/controllers/applications_controller_spec.rb +3 -2
  74. data/spec/controllers/authorizations_controller_spec.rb +18 -18
  75. data/spec/controllers/protected_resources_controller_spec.rb +25 -17
  76. data/spec/controllers/token_info_controller_spec.rb +1 -1
  77. data/spec/controllers/tokens_controller_spec.rb +1 -1
  78. data/spec/dummy/db/migrate/20151223192035_create_doorkeeper_tables.rb +3 -3
  79. data/spec/dummy/db/migrate/20160320211015_add_previous_refresh_token_to_access_tokens.rb +1 -1
  80. data/spec/dummy/db/migrate/20180210183654_add_confidential_to_applications.rb +1 -1
  81. data/spec/generators/install_generator_spec.rb +1 -1
  82. data/spec/generators/previous_refresh_token_generator_spec.rb +2 -2
  83. data/spec/helpers/doorkeeper/dashboard_helper_spec.rb +1 -1
  84. data/spec/lib/config_spec.rb +62 -7
  85. data/spec/lib/doorkeeper_spec.rb +1 -1
  86. data/spec/lib/models/revocable_spec.rb +3 -3
  87. data/spec/lib/oauth/authorization_code_request_spec.rb +127 -125
  88. data/spec/lib/oauth/base_request_spec.rb +160 -158
  89. data/spec/lib/oauth/base_response_spec.rb +27 -29
  90. data/spec/lib/oauth/client/credentials_spec.rb +1 -1
  91. data/spec/lib/oauth/client_credentials/creator_spec.rb +42 -5
  92. data/spec/lib/oauth/client_credentials/issuer_spec.rb +12 -12
  93. data/spec/lib/oauth/client_credentials/validation_spec.rb +4 -4
  94. data/spec/lib/oauth/client_credentials_integration_spec.rb +16 -18
  95. data/spec/lib/oauth/client_credentials_request_spec.rb +78 -80
  96. data/spec/lib/oauth/client_spec.rb +26 -26
  97. data/spec/lib/oauth/code_request_spec.rb +34 -34
  98. data/spec/lib/oauth/code_response_spec.rb +21 -25
  99. data/spec/lib/oauth/error_response_spec.rb +42 -44
  100. data/spec/lib/oauth/error_spec.rb +12 -14
  101. data/spec/lib/oauth/forbidden_token_response_spec.rb +11 -13
  102. data/spec/lib/oauth/helpers/scope_checker_spec.rb +30 -18
  103. data/spec/lib/oauth/invalid_request_response_spec.rb +48 -50
  104. data/spec/lib/oauth/invalid_token_response_spec.rb +32 -34
  105. data/spec/lib/oauth/password_access_token_request_spec.rb +145 -147
  106. data/spec/lib/oauth/pre_authorization_spec.rb +159 -161
  107. data/spec/lib/oauth/refresh_token_request_spec.rb +138 -139
  108. data/spec/lib/oauth/scopes_spec.rb +104 -106
  109. data/spec/lib/oauth/token_request_spec.rb +115 -111
  110. data/spec/lib/oauth/token_response_spec.rb +71 -73
  111. data/spec/lib/oauth/token_spec.rb +121 -123
  112. data/spec/models/doorkeeper/access_grant_spec.rb +3 -5
  113. data/spec/models/doorkeeper/access_token_spec.rb +7 -7
  114. data/spec/models/doorkeeper/application_spec.rb +104 -77
  115. data/spec/requests/applications/applications_request_spec.rb +1 -1
  116. data/spec/requests/endpoints/authorization_spec.rb +5 -3
  117. data/spec/requests/flows/authorization_code_spec.rb +34 -22
  118. data/spec/requests/flows/client_credentials_spec.rb +1 -1
  119. data/spec/requests/flows/password_spec.rb +32 -12
  120. data/spec/requests/flows/refresh_token_spec.rb +19 -19
  121. data/spec/requests/flows/revoke_token_spec.rb +18 -12
  122. data/spec/spec_helper.rb +1 -4
  123. data/spec/support/shared/controllers_shared_context.rb +33 -23
  124. data/spec/validators/redirect_uri_validator_spec.rb +1 -1
  125. metadata +6 -5
  126. data/spec/support/http_method_shim.rb +0 -29
@@ -18,7 +18,7 @@ module Doorkeeper
18
18
 
19
19
  # For backward compatibility with old rubies
20
20
  if Gem::Version.new(RUBY_VERSION) < Gem::Version.new("2.5.0")
21
- IPAddr.send(:include, Doorkeeper::IPAddrLoopback)
21
+ IPAddr.include Doorkeeper::IPAddrLoopback
22
22
  end
23
23
 
24
24
  module OAuth
@@ -11,8 +11,8 @@ module Doorkeeper
11
11
  state: request.try(:state),
12
12
  redirect_uri: request.try(:redirect_uri),
13
13
  missing_param: request.try(:missing_param),
14
- reason: request.try(:invalid_request_reason)
15
- )
14
+ reason: request.try(:invalid_request_reason),
15
+ ),
16
16
  )
17
17
  end
18
18
 
@@ -31,7 +31,7 @@ module Doorkeeper
31
31
  reason,
32
32
  scope: %i[doorkeeper errors messages invalid_request],
33
33
  default: :unknown,
34
- value: @missing_param
34
+ value: @missing_param,
35
35
  )
36
36
  end
37
37
 
@@ -27,8 +27,11 @@ module Doorkeeper
27
27
  end
28
28
 
29
29
  def description
30
- scope = { scope: %i[doorkeeper errors messages invalid_token] }
31
- @description ||= I18n.translate @reason, scope
30
+ @description ||=
31
+ I18n.translate(
32
+ @reason,
33
+ scope: %i[doorkeeper errors messages invalid_token],
34
+ )
32
35
  end
33
36
 
34
37
  protected
@@ -37,12 +37,12 @@ module Doorkeeper
37
37
  scope_str: scopes.to_s,
38
38
  server_scopes: server.scopes,
39
39
  app_scopes: client_scopes,
40
- grant_type: grant_type
40
+ grant_type: grant_type,
41
41
  )
42
42
  end
43
43
 
44
44
  def validate_resource_owner
45
- !resource_owner.nil?
45
+ resource_owner.present?
46
46
  end
47
47
 
48
48
  def validate_client
@@ -50,7 +50,7 @@ module Doorkeeper
50
50
  end
51
51
 
52
52
  def validate_client_supports_grant_flow
53
- Doorkeeper.configuration.allow_grant_flow_for_client?(grant_type, client)
53
+ server_config.allow_grant_flow_for_client?(grant_type, client)
54
54
  end
55
55
  end
56
56
  end
@@ -33,7 +33,7 @@ module Doorkeeper
33
33
  end
34
34
 
35
35
  def validate_client_supports_grant_flow
36
- Doorkeeper.configuration.allow_grant_flow_for_client?(grant_type, client.application)
36
+ Doorkeeper.config.allow_grant_flow_for_client?(grant_type, client.application)
37
37
  end
38
38
 
39
39
  def scopes
@@ -45,12 +45,13 @@ module Doorkeeper
45
45
  end
46
46
 
47
47
  def error_response
48
- is_implicit_flow = response_type == "token"
49
-
50
48
  if error == :invalid_request
51
- OAuth::InvalidRequestResponse.from_request(self, response_on_fragment: is_implicit_flow)
49
+ OAuth::InvalidRequestResponse.from_request(
50
+ self,
51
+ response_on_fragment: response_on_fragment?,
52
+ )
52
53
  else
53
- OAuth::ErrorResponse.from_request(self, response_on_fragment: is_implicit_flow)
54
+ OAuth::ErrorResponse.from_request(self, response_on_fragment: response_on_fragment?)
54
55
  end
55
56
  end
56
57
 
@@ -87,7 +88,7 @@ module Doorkeeper
87
88
 
88
89
  Helpers::URIChecker.valid_for_authorization?(
89
90
  redirect_uri,
90
- client.redirect_uri
91
+ client.redirect_uri,
91
92
  )
92
93
  end
93
94
 
@@ -110,7 +111,7 @@ module Doorkeeper
110
111
  scope_str: scope,
111
112
  server_scopes: server.scopes,
112
113
  app_scopes: client.scopes,
113
- grant_type: grant_type
114
+ grant_type: grant_type,
114
115
  )
115
116
  end
116
117
 
@@ -123,6 +124,10 @@ module Doorkeeper
123
124
  (code_challenge_method.present? && code_challenge_method =~ /^plain$|^S256$/)
124
125
  end
125
126
 
127
+ def response_on_fragment?
128
+ response_type == "token"
129
+ end
130
+
126
131
  def pre_auth_hash
127
132
  {
128
133
  client_id: client.uid,
@@ -27,7 +27,7 @@ module Doorkeeper
27
27
  private
28
28
 
29
29
  def load_client(credentials)
30
- Application.by_uid_and_secret(credentials.uid, credentials.secret)
30
+ server_config.application_model.by_uid_and_secret(credentials.uid, credentials.secret)
31
31
  end
32
32
 
33
33
  def before_successful_response
@@ -42,7 +42,7 @@ module Doorkeeper
42
42
  end
43
43
 
44
44
  def refresh_token_revoked_on_use?
45
- Doorkeeper::AccessToken.refresh_token_revoked_on_use?
45
+ server_config.access_token_model.refresh_token_revoked_on_use?
46
46
  end
47
47
 
48
48
  def default_scopes
@@ -50,7 +50,7 @@ module Doorkeeper
50
50
  end
51
51
 
52
52
  def create_access_token
53
- @access_token = AccessToken.create!(access_token_attributes)
53
+ @access_token = server_config.access_token_model.create!(access_token_attributes)
54
54
  end
55
55
 
56
56
  def access_token_attributes
@@ -71,7 +71,7 @@ module Doorkeeper
71
71
  context = Authorization::Token.build_context(
72
72
  client,
73
73
  Doorkeeper::OAuth::REFRESH_TOKEN,
74
- scopes
74
+ scopes,
75
75
  )
76
76
  Authorization::Token.access_token_expires_in(server, context)
77
77
  end
@@ -104,7 +104,7 @@ module Doorkeeper
104
104
  if @original_scopes.present?
105
105
  ScopeChecker.valid?(
106
106
  scope_str: @original_scopes,
107
- server_scopes: refresh_token.scopes
107
+ server_scopes: refresh_token.scopes,
108
108
  )
109
109
  else
110
110
  true
@@ -14,8 +14,8 @@ module Doorkeeper
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?
17
+ access_token = Doorkeeper.config.access_token_model.by_token(token)
18
+ refresh_token_enabled = Doorkeeper.config.refresh_token_enabled?
19
19
  if access_token.present? && refresh_token_enabled
20
20
  access_token.revoke_previous_refresh_token!
21
21
  end
@@ -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
 
@@ -174,15 +174,15 @@ 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
182
  allow_introspection.call(
183
183
  @token,
184
184
  auth_client,
185
- auth_token
185
+ auth_token,
186
186
  )
187
187
  end
188
188
 
@@ -193,9 +193,9 @@ module Doorkeeper
193
193
  # @see https://tools.ietf.org/html/rfc7662#section-2.2
194
194
  #
195
195
  def customize_response(response)
196
- customized_response = Doorkeeper.configuration.custom_introspection_response.call(
196
+ customized_response = Doorkeeper.config.custom_introspection_response.call(
197
197
  token,
198
- server.context
198
+ server.context,
199
199
  )
200
200
  return response if customized_response.blank?
201
201
 
@@ -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,53 @@
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 = "#{table_name_prefix}oauth_access_grants#{table_name_suffix}"
9
+
10
+ include ::Doorkeeper::AccessGrantMixin
11
+
12
+ belongs_to :application, class_name: Doorkeeper.config.application_class,
13
+ optional: true,
14
+ inverse_of: :access_grants
15
+
16
+ validates :resource_owner_id,
17
+ :application_id,
18
+ :token,
19
+ :expires_in,
20
+ :redirect_uri,
21
+ presence: true
22
+
23
+ validates :token, uniqueness: { case_sensitive: true }
24
+
25
+ before_validation :generate_token, on: :create
26
+
27
+ # We keep a volatile copy of the raw token for initial communication
28
+ # The stored refresh_token may be mapped and not available in cleartext.
29
+ #
30
+ # Some strategies allow restoring stored secrets (e.g. symmetric encryption)
31
+ # while hashing strategies do not, so you cannot rely on this value
32
+ # returning a present value for persisted tokens.
33
+ def plaintext_token
34
+ if secret_strategy.allows_restoring_secrets?
35
+ secret_strategy.restore_secret(self, :token)
36
+ else
37
+ @raw_token
38
+ end
39
+ end
40
+
41
+ private
42
+
43
+ # Generates token value with UniqueToken class.
44
+ #
45
+ # @return [String] token value
46
+ #
47
+ def generate_token
48
+ @raw_token = Doorkeeper::OAuth::Helpers::UniqueToken.generate
49
+ secret_strategy.store_secret(self, :token, @raw_token)
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,47 @@
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 = "#{table_name_prefix}oauth_access_tokens#{table_name_suffix}"
9
+
10
+ include ::Doorkeeper::AccessTokenMixin
11
+
12
+ belongs_to :application, class_name: Doorkeeper.config.application_class,
13
+ inverse_of: :access_tokens,
14
+ optional: true
15
+
16
+ validates :token, presence: true, uniqueness: { case_sensitive: true }
17
+ validates :refresh_token, uniqueness: { case_sensitive: true }, if: :use_refresh_token?
18
+
19
+ # @attr_writer [Boolean, nil] use_refresh_token
20
+ # indicates the possibility of using refresh token
21
+ attr_writer :use_refresh_token
22
+
23
+ before_validation :generate_token, on: :create
24
+ before_validation :generate_refresh_token,
25
+ on: :create, if: :use_refresh_token?
26
+ end
27
+
28
+ class_methods do
29
+ # Searches for not revoked Access Tokens associated with the
30
+ # specific Resource Owner.
31
+ #
32
+ # @param resource_owner [ActiveRecord::Base]
33
+ # Resource Owner model instance
34
+ #
35
+ # @return [ActiveRecord::Relation]
36
+ # active Access Tokens for Resource Owner
37
+ #
38
+ def active_for(resource_owner)
39
+ where(resource_owner_id: resource_owner.id, revoked_at: nil)
40
+ end
41
+
42
+ def refresh_token_revoked_on_use?
43
+ column_names.include?("previous_refresh_token")
44
+ end
45
+ end
46
+ end
47
+ end
@@ -0,0 +1,128 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Doorkeeper::Orm::ActiveRecord::Mixins
4
+ module Application
5
+ extend ActiveSupport::Concern
6
+
7
+ included do
8
+ self.table_name = "#{table_name_prefix}oauth_applications#{table_name_suffix}"
9
+
10
+ include ::Doorkeeper::ApplicationMixin
11
+
12
+ has_many :access_grants,
13
+ foreign_key: :application_id,
14
+ dependent: :delete_all,
15
+ class_name: Doorkeeper.config.access_grant_class
16
+
17
+ has_many :access_tokens,
18
+ foreign_key: :application_id,
19
+ dependent: :delete_all,
20
+ class_name: Doorkeeper.config.access_token_class
21
+
22
+ validates :name, :secret, :uid, presence: true
23
+ validates :uid, uniqueness: { case_sensitive: true }
24
+ validates :redirect_uri, "doorkeeper/redirect_uri": true
25
+ validates :confidential, inclusion: { in: [true, false] }
26
+
27
+ validate :scopes_match_configured, if: :enforce_scopes?
28
+
29
+ before_validation :generate_uid, :generate_secret, on: :create
30
+
31
+ has_many :authorized_tokens,
32
+ -> { where(revoked_at: nil) },
33
+ foreign_key: :application_id,
34
+ class_name: Doorkeeper.config.access_token_class
35
+
36
+ has_many :authorized_applications,
37
+ through: :authorized_tokens,
38
+ source: :application
39
+
40
+ # Generates a new secret for this application, intended to be used
41
+ # for rotating the secret or in case of compromise.
42
+ #
43
+ # @return [String] new transformed secret value
44
+ #
45
+ def renew_secret
46
+ @raw_secret = Doorkeeper::OAuth::Helpers::UniqueToken.generate
47
+ secret_strategy.store_secret(self, :secret, @raw_secret)
48
+ end
49
+
50
+ # We keep a volatile copy of the raw secret for initial communication
51
+ # The stored refresh_token may be mapped and not available in cleartext.
52
+ #
53
+ # Some strategies allow restoring stored secrets (e.g. symmetric encryption)
54
+ # while hashing strategies do not, so you cannot rely on this value
55
+ # returning a present value for persisted tokens.
56
+ def plaintext_secret
57
+ if secret_strategy.allows_restoring_secrets?
58
+ secret_strategy.restore_secret(self, :secret)
59
+ else
60
+ @raw_secret
61
+ end
62
+ end
63
+
64
+ # This is the right way how we want to override ActiveRecord #to_json
65
+ #
66
+ # @return [String] entity attributes as JSON
67
+ #
68
+ def as_json(options = {})
69
+ hash = super
70
+
71
+ hash["secret"] = plaintext_secret if hash.key?("secret")
72
+ hash
73
+ end
74
+
75
+ private
76
+
77
+ def generate_uid
78
+ self.uid = Doorkeeper::OAuth::Helpers::UniqueToken.generate if uid.blank?
79
+ end
80
+
81
+ def generate_secret
82
+ return unless secret.blank?
83
+
84
+ renew_secret
85
+ end
86
+
87
+ def scopes_match_configured
88
+ if scopes.present? && !Doorkeeper::OAuth::Helpers::ScopeChecker.valid?(
89
+ scope_str: scopes.to_s,
90
+ server_scopes: Doorkeeper.config.scopes,
91
+ )
92
+ errors.add(:scopes, :not_match_configured)
93
+ end
94
+ end
95
+
96
+ def enforce_scopes?
97
+ Doorkeeper.config.enforce_configured_scopes?
98
+ end
99
+ end
100
+
101
+ class_methods do
102
+ # Returns Applications associated with active (not revoked) Access Tokens
103
+ # that are owned by the specific Resource Owner.
104
+ #
105
+ # @param resource_owner [ActiveRecord::Base]
106
+ # Resource Owner model instance
107
+ #
108
+ # @return [ActiveRecord::Relation]
109
+ # Applications authorized for the Resource Owner
110
+ #
111
+ def authorized_for(resource_owner)
112
+ resource_access_tokens = Doorkeeper.config.access_token_model.active_for(resource_owner)
113
+ where(id: resource_access_tokens.select(:application_id).distinct)
114
+ end
115
+
116
+ # Revokes AccessToken and AccessGrant records that have not been revoked and
117
+ # associated with the specific Application and Resource Owner.
118
+ #
119
+ # @param resource_owner [ActiveRecord::Base]
120
+ # instance of the Resource Owner model
121
+ #
122
+ def revoke_tokens_and_grants_for(id, resource_owner)
123
+ Doorkeeper.config.access_token_model.revoke_all_for(id, resource_owner)
124
+ Doorkeeper.config.access_grant_model.revoke_all_for(id, resource_owner)
125
+ end
126
+ end
127
+ end
128
+ end
@@ -8,7 +8,7 @@ module Doorkeeper
8
8
  class RedirectUriValidator < ActiveModel::EachValidator
9
9
  def validate_each(record, attribute, value)
10
10
  if value.blank?
11
- return if Doorkeeper.configuration.allow_blank_redirect_uri?(record)
11
+ return if Doorkeeper.config.allow_blank_redirect_uri?(record)
12
12
 
13
13
  record.errors.add(attribute, :blank)
14
14
  else
@@ -34,7 +34,7 @@ module Doorkeeper
34
34
  end
35
35
 
36
36
  def forbidden_uri?(uri)
37
- Doorkeeper.configuration.forbid_redirect_uri.call(uri)
37
+ Doorkeeper.config.forbid_redirect_uri.call(uri)
38
38
  end
39
39
 
40
40
  def unspecified_scheme?(uri)
@@ -48,7 +48,7 @@ module Doorkeeper
48
48
  end
49
49
 
50
50
  def invalid_ssl_uri?(uri)
51
- forces_ssl = Doorkeeper.configuration.force_ssl_in_redirect_uri
51
+ forces_ssl = Doorkeeper.config.force_ssl_in_redirect_uri
52
52
  non_https = uri.try(:scheme) == "http"
53
53
 
54
54
  if forces_ssl.respond_to?(:call)