authlogic 3.8.0 → 4.5.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 (143) hide show
  1. checksums.yaml +7 -0
  2. data/.github/ISSUE_TEMPLATE/bug_report.md +28 -0
  3. data/.github/ISSUE_TEMPLATE/feature_proposal.md +32 -0
  4. data/.github/triage.md +86 -0
  5. data/.gitignore +4 -3
  6. data/.rubocop.yml +109 -9
  7. data/.rubocop_todo.yml +38 -355
  8. data/.travis.yml +11 -35
  9. data/CHANGELOG.md +345 -2
  10. data/CONTRIBUTING.md +45 -14
  11. data/Gemfile +3 -2
  12. data/README.md +244 -90
  13. data/Rakefile +10 -10
  14. data/UPGRADING.md +22 -0
  15. data/authlogic.gemspec +34 -21
  16. data/doc/use_normal_rails_validation.md +82 -0
  17. data/gemfiles/Gemfile.rails-4.2.x +6 -0
  18. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.1.x +2 -2
  19. data/{test/gemfiles → gemfiles}/Gemfile.rails-5.2.x +2 -2
  20. data/lib/authlogic/acts_as_authentic/base.rb +36 -24
  21. data/lib/authlogic/acts_as_authentic/email.rb +65 -31
  22. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +14 -9
  23. data/lib/authlogic/acts_as_authentic/login.rb +61 -45
  24. data/lib/authlogic/acts_as_authentic/magic_columns.rb +6 -6
  25. data/lib/authlogic/acts_as_authentic/password.rb +267 -146
  26. data/lib/authlogic/acts_as_authentic/perishable_token.rb +24 -19
  27. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -15
  28. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +67 -0
  29. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +50 -14
  30. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +88 -60
  31. data/lib/authlogic/acts_as_authentic/single_access_token.rb +23 -11
  32. data/lib/authlogic/acts_as_authentic/validations_scope.rb +9 -6
  33. data/lib/authlogic/authenticates_many/association.rb +7 -7
  34. data/lib/authlogic/authenticates_many/base.rb +37 -21
  35. data/lib/authlogic/config.rb +21 -10
  36. data/lib/authlogic/controller_adapters/abstract_adapter.rb +38 -11
  37. data/lib/authlogic/controller_adapters/rack_adapter.rb +9 -5
  38. data/lib/authlogic/controller_adapters/rails_adapter.rb +12 -7
  39. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +2 -2
  40. data/lib/authlogic/crypto_providers/aes256.rb +37 -32
  41. data/lib/authlogic/crypto_providers/bcrypt.rb +21 -15
  42. data/lib/authlogic/crypto_providers/md5.rb +4 -2
  43. data/lib/authlogic/crypto_providers/scrypt.rb +22 -17
  44. data/lib/authlogic/crypto_providers/sha1.rb +11 -5
  45. data/lib/authlogic/crypto_providers/sha256.rb +13 -9
  46. data/lib/authlogic/crypto_providers/sha512.rb +0 -21
  47. data/lib/authlogic/crypto_providers/wordpress.rb +32 -3
  48. data/lib/authlogic/crypto_providers.rb +91 -0
  49. data/lib/authlogic/i18n.rb +26 -19
  50. data/lib/authlogic/random.rb +10 -28
  51. data/lib/authlogic/regex.rb +59 -28
  52. data/lib/authlogic/session/activation.rb +10 -7
  53. data/lib/authlogic/session/active_record_trickery.rb +13 -9
  54. data/lib/authlogic/session/base.rb +15 -4
  55. data/lib/authlogic/session/brute_force_protection.rb +40 -33
  56. data/lib/authlogic/session/callbacks.rb +94 -46
  57. data/lib/authlogic/session/cookies.rb +130 -45
  58. data/lib/authlogic/session/existence.rb +21 -11
  59. data/lib/authlogic/session/foundation.rb +64 -14
  60. data/lib/authlogic/session/http_auth.rb +35 -28
  61. data/lib/authlogic/session/id.rb +9 -4
  62. data/lib/authlogic/session/klass.rb +15 -12
  63. data/lib/authlogic/session/magic_columns.rb +58 -55
  64. data/lib/authlogic/session/magic_states.rb +25 -19
  65. data/lib/authlogic/session/params.rb +42 -28
  66. data/lib/authlogic/session/password.rb +130 -120
  67. data/lib/authlogic/session/perishable_token.rb +5 -4
  68. data/lib/authlogic/session/persistence.rb +18 -12
  69. data/lib/authlogic/session/priority_record.rb +15 -12
  70. data/lib/authlogic/session/scopes.rb +51 -32
  71. data/lib/authlogic/session/session.rb +38 -28
  72. data/lib/authlogic/session/timeout.rb +13 -13
  73. data/lib/authlogic/session/unauthorized_record.rb +18 -13
  74. data/lib/authlogic/session/validation.rb +9 -9
  75. data/lib/authlogic/test_case/mock_controller.rb +5 -4
  76. data/lib/authlogic/test_case/mock_cookie_jar.rb +47 -3
  77. data/lib/authlogic/test_case/mock_request.rb +6 -3
  78. data/lib/authlogic/test_case/rails_request_adapter.rb +3 -2
  79. data/lib/authlogic/test_case.rb +70 -2
  80. data/lib/authlogic/version.rb +21 -0
  81. data/lib/authlogic.rb +51 -49
  82. data/test/acts_as_authentic_test/base_test.rb +3 -1
  83. data/test/acts_as_authentic_test/email_test.rb +43 -42
  84. data/test/acts_as_authentic_test/logged_in_status_test.rb +6 -4
  85. data/test/acts_as_authentic_test/login_test.rb +77 -80
  86. data/test/acts_as_authentic_test/magic_columns_test.rb +3 -1
  87. data/test/acts_as_authentic_test/password_test.rb +51 -37
  88. data/test/acts_as_authentic_test/perishable_token_test.rb +13 -5
  89. data/test/acts_as_authentic_test/persistence_token_test.rb +7 -1
  90. data/test/acts_as_authentic_test/restful_authentication_test.rb +14 -3
  91. data/test/acts_as_authentic_test/session_maintenance_test.rb +69 -15
  92. data/test/acts_as_authentic_test/single_access_test.rb +3 -1
  93. data/test/adapter_test.rb +23 -0
  94. data/test/authenticates_many_test.rb +3 -1
  95. data/test/config_test.rb +11 -9
  96. data/test/crypto_provider_test/aes256_test.rb +3 -1
  97. data/test/crypto_provider_test/bcrypt_test.rb +3 -1
  98. data/test/crypto_provider_test/scrypt_test.rb +3 -1
  99. data/test/crypto_provider_test/sha1_test.rb +3 -1
  100. data/test/crypto_provider_test/sha256_test.rb +3 -1
  101. data/test/crypto_provider_test/sha512_test.rb +3 -1
  102. data/test/crypto_provider_test/wordpress_test.rb +26 -0
  103. data/test/fixtures/companies.yml +2 -2
  104. data/test/fixtures/employees.yml +1 -1
  105. data/test/i18n_test.rb +6 -4
  106. data/test/libs/affiliate.rb +2 -0
  107. data/test/libs/company.rb +4 -2
  108. data/test/libs/employee.rb +2 -0
  109. data/test/libs/employee_session.rb +2 -0
  110. data/test/libs/ldaper.rb +2 -0
  111. data/test/libs/project.rb +2 -0
  112. data/test/libs/user.rb +2 -0
  113. data/test/libs/user_session.rb +4 -2
  114. data/test/random_test.rb +10 -38
  115. data/test/session_test/activation_test.rb +3 -1
  116. data/test/session_test/active_record_trickery_test.rb +7 -4
  117. data/test/session_test/brute_force_protection_test.rb +11 -9
  118. data/test/session_test/callbacks_test.rb +12 -4
  119. data/test/session_test/cookies_test.rb +48 -5
  120. data/test/session_test/existence_test.rb +18 -5
  121. data/test/session_test/foundation_test.rb +19 -1
  122. data/test/session_test/http_auth_test.rb +11 -7
  123. data/test/session_test/id_test.rb +3 -1
  124. data/test/session_test/klass_test.rb +3 -1
  125. data/test/session_test/magic_columns_test.rb +13 -13
  126. data/test/session_test/magic_states_test.rb +3 -1
  127. data/test/session_test/params_test.rb +13 -5
  128. data/test/session_test/password_test.rb +10 -8
  129. data/test/session_test/perishability_test.rb +3 -1
  130. data/test/session_test/persistence_test.rb +4 -1
  131. data/test/session_test/scopes_test.rb +16 -8
  132. data/test/session_test/session_test.rb +6 -4
  133. data/test/session_test/timeout_test.rb +4 -2
  134. data/test/session_test/unauthorized_record_test.rb +4 -2
  135. data/test/session_test/validation_test.rb +3 -1
  136. data/test/test_helper.rb +84 -45
  137. metadata +87 -73
  138. data/.github/ISSUE_TEMPLATE.md +0 -13
  139. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  140. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  141. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
  142. data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
  143. data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
@@ -22,7 +22,13 @@ module Authlogic
22
22
  rw_config(
23
23
  :crypted_password_field,
24
24
  value,
25
- first_column_to_exist(nil, :crypted_password, :encrypted_password, :password_hash, :pw_hash)
25
+ first_column_to_exist(
26
+ nil,
27
+ :crypted_password,
28
+ :encrypted_password,
29
+ :password_hash,
30
+ :pw_hash
31
+ )
26
32
  )
27
33
  end
28
34
  alias_method :crypted_password_field=, :crypted_password_field
@@ -91,6 +97,8 @@ module Authlogic
91
97
  #
92
98
  # * <tt>Default:</tt> true
93
99
  # * <tt>Accepts:</tt> Boolean
100
+ #
101
+ # @deprecated
94
102
  def validate_password_field(value = nil)
95
103
  rw_config(:validate_password_field, value, true)
96
104
  end
@@ -99,17 +107,28 @@ module Authlogic
99
107
  # A hash of options for the validates_length_of call for the password field.
100
108
  # Allows you to change this however you want.
101
109
  #
102
- # <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
103
- # you can completely replace the hash or merge options into it. Checkout the
104
- # convenience function merge_validates_length_of_password_field_options to merge
105
- # options.</b>
110
+ # **Keep in mind this is ruby. I wanted to keep this as flexible as
111
+ # possible, so you can completely replace the hash or merge options into
112
+ # it. Checkout the convenience function
113
+ # merge_validates_length_of_password_field_options to merge options.**
106
114
  #
107
115
  # * <tt>Default:</tt> {:minimum => 8, :if => :require_password?}
108
116
  # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
117
+ #
118
+ # @deprecated
109
119
  def validates_length_of_password_field_options(value = nil)
110
- rw_config(:validates_length_of_password_field_options, value, { :minimum => 8, :if => :require_password? })
120
+ deprecate_authlogic_config("validates_length_of_password_field_options") if value
121
+ rw_config(
122
+ :validates_length_of_password_field_options,
123
+ value,
124
+ minimum: 8,
125
+ if: :require_password?
126
+ )
111
127
  end
112
- alias_method :validates_length_of_password_field_options=, :validates_length_of_password_field_options
128
+ alias_method(
129
+ :validates_length_of_password_field_options=,
130
+ :validates_length_of_password_field_options
131
+ )
113
132
 
114
133
  # A convenience function to merge options into the
115
134
  # validates_length_of_login_field_options. So instead of:
@@ -120,29 +139,53 @@ module Authlogic
120
139
  # You can do this:
121
140
  #
122
141
  # merge_validates_length_of_password_field_options :my_option => my_value
142
+ #
143
+ # @deprecated
123
144
  def merge_validates_length_of_password_field_options(options = {})
124
- self.validates_length_of_password_field_options = validates_length_of_password_field_options.merge(options)
145
+ deprecate_authlogic_config(
146
+ "merge_validates_length_of_password_field_options"
147
+ )
148
+ self.validates_length_of_password_field_options =
149
+ validates_length_of_password_field_options.merge(options)
125
150
  end
126
151
 
127
- # A hash of options for the validates_confirmation_of call for the password field.
128
- # Allows you to change this however you want.
152
+ # A hash of options for the validates_confirmation_of call for the
153
+ # password field. Allows you to change this however you want.
129
154
  #
130
- # <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
131
- # you can completely replace the hash or merge options into it. Checkout the
132
- # convenience function merge_validates_length_of_password_field_options to merge
133
- # options.</b>
155
+ # **Keep in mind this is ruby. I wanted to keep this as flexible as
156
+ # possible, so you can completely replace the hash or merge options into
157
+ # it. Checkout the convenience function
158
+ # merge_validates_length_of_password_field_options to merge options.**
134
159
  #
135
160
  # * <tt>Default:</tt> {:if => :require_password?}
136
161
  # * <tt>Accepts:</tt> Hash of options accepted by validates_confirmation_of
162
+ #
163
+ # @deprecated
137
164
  def validates_confirmation_of_password_field_options(value = nil)
138
- rw_config(:validates_confirmation_of_password_field_options, value, { :if => :require_password? })
165
+ if value
166
+ deprecate_authlogic_config(
167
+ "validates_confirmation_of_password_field_options"
168
+ )
169
+ end
170
+ rw_config(
171
+ :validates_confirmation_of_password_field_options,
172
+ value,
173
+ if: :require_password?
174
+ )
139
175
  end
140
- alias_method :validates_confirmation_of_password_field_options=, :validates_confirmation_of_password_field_options
176
+ alias_method :validates_confirmation_of_password_field_options=,
177
+ :validates_confirmation_of_password_field_options
141
178
 
142
179
  # See merge_validates_length_of_password_field_options. The same thing, except for
143
180
  # validates_confirmation_of_password_field_options
181
+ #
182
+ # @deprecated
144
183
  def merge_validates_confirmation_of_password_field_options(options = {})
145
- self.validates_confirmation_of_password_field_options = validates_confirmation_of_password_field_options.merge(options)
184
+ deprecate_authlogic_config(
185
+ "merge_validates_confirmation_of_password_field_options"
186
+ )
187
+ self.validates_confirmation_of_password_field_options =
188
+ validates_confirmation_of_password_field_options.merge(options)
146
189
  end
147
190
 
148
191
  # A hash of options for the validates_length_of call for the password_confirmation
@@ -155,7 +198,14 @@ module Authlogic
155
198
  #
156
199
  # * <tt>Default:</tt> validates_length_of_password_field_options
157
200
  # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
201
+ #
202
+ # @deprecated
158
203
  def validates_length_of_password_confirmation_field_options(value = nil)
204
+ if value
205
+ deprecate_authlogic_config(
206
+ "validates_length_of_password_confirmation_field_options"
207
+ )
208
+ end
159
209
  rw_config(
160
210
  :validates_length_of_password_confirmation_field_options,
161
211
  value,
@@ -169,74 +219,101 @@ module Authlogic
169
219
 
170
220
  # See merge_validates_length_of_password_field_options. The same thing, except for
171
221
  # validates_length_of_password_confirmation_field_options
222
+ #
223
+ # @deprecated
172
224
  def merge_validates_length_of_password_confirmation_field_options(options = {})
225
+ deprecate_authlogic_config(
226
+ "merge_validates_length_of_password_confirmation_field_options"
227
+ )
173
228
  self.validates_length_of_password_confirmation_field_options =
174
229
  validates_length_of_password_confirmation_field_options.merge(options)
175
230
  end
176
231
 
177
- # The class you want to use to encrypt and verify your encrypted passwords. See
178
- # the Authlogic::CryptoProviders module for more info on the available methods and
179
- # how to create your own.
232
+ # The class you want to use to encrypt and verify your encrypted
233
+ # passwords. See the Authlogic::CryptoProviders module for more info on
234
+ # the available methods and how to create your own.
235
+ #
236
+ # The family of adaptive hash functions (BCrypt, SCrypt, PBKDF2) is the
237
+ # best choice for password storage today. We recommend SCrypt. Other
238
+ # one-way functions like SHA512 are inferior, but widely used.
239
+ # Reverisbile functions like AES256 are the worst choice.
240
+ #
241
+ # You can use the `transition_from_crypto_providers` option to gradually
242
+ # transition to a better crypto provider without causing your users any
243
+ # pain.
180
244
  #
181
245
  # * <tt>Default:</tt> CryptoProviders::SCrypt
182
246
  # * <tt>Accepts:</tt> Class
183
247
  def crypto_provider(value = nil)
248
+ CryptoProviders::Guidance.new(value).impart_wisdom
184
249
  rw_config(:crypto_provider, value, CryptoProviders::SCrypt)
185
250
  end
186
251
  alias_method :crypto_provider=, :crypto_provider
187
252
 
188
- # Let's say you originally encrypted your passwords with Sha1. Sha1 is starting to
189
- # join the party with MD5 and you want to switch to something stronger. No
190
- # problem, just specify your new and improved algorithm with the crypt_provider
191
- # option and then let Authlogic know you are transitioning from Sha1 using this
192
- # option. Authlogic will take care of everything, including transitioning your
193
- # users to the new algorithm. The next time a user logs in, they will be granted
194
- # access using the old algorithm and their password will be resaved with the new
195
- # algorithm. All new users will obviously use the new algorithm as well.
253
+ # Let's say you originally encrypted your passwords with Sha1. Sha1 is
254
+ # starting to join the party with MD5 and you want to switch to
255
+ # something stronger. No problem, just specify your new and improved
256
+ # algorithm with the crypt_provider option and then let Authlogic know
257
+ # you are transitioning from Sha1 using this option. Authlogic will take
258
+ # care of everything, including transitioning your users to the new
259
+ # algorithm. The next time a user logs in, they will be granted access
260
+ # using the old algorithm and their password will be resaved with the
261
+ # new algorithm. All new users will obviously use the new algorithm as
262
+ # well.
196
263
  #
197
- # Lastly, if you want to transition again, you can pass an array of crypto
198
- # providers. So you can transition from as many algorithms as you want.
264
+ # Lastly, if you want to transition again, you can pass an array of
265
+ # crypto providers. So you can transition from as many algorithms as you
266
+ # want.
199
267
  #
200
268
  # * <tt>Default:</tt> nil
201
269
  # * <tt>Accepts:</tt> Class or Array
202
270
  def transition_from_crypto_providers(value = nil)
203
- rw_config(:transition_from_crypto_providers, (!value.nil? && [value].flatten.compact) || value, [])
271
+ rw_config(
272
+ :transition_from_crypto_providers,
273
+ (!value.nil? && [value].flatten.compact) || value,
274
+ []
275
+ )
204
276
  end
205
277
  alias_method :transition_from_crypto_providers=, :transition_from_crypto_providers
206
278
  end
207
279
 
208
280
  # Callbacks / hooks to allow other modules to modify the behavior of this module.
209
281
  module Callbacks
210
- METHODS = [
211
- "before_password_set", "after_password_set",
212
- "before_password_verification", "after_password_verification"
213
- ]
282
+ # Does the order of this array matter?
283
+ METHODS = %w[
284
+ before_password_set
285
+ after_password_set
286
+ before_password_verification
287
+ after_password_verification
288
+ ].freeze
214
289
 
215
290
  def self.included(klass)
216
291
  return if klass.crypted_password_field.nil?
217
- klass.define_callbacks *METHODS
292
+ klass.define_callbacks(*METHODS)
218
293
 
219
294
  # If Rails 3, support the new callback syntax
220
- if klass.send(klass.respond_to?(:singleton_class) ? :singleton_class : :metaclass).method_defined?(:set_callback)
295
+ if klass.singleton_class.method_defined?(:set_callback)
221
296
  METHODS.each do |method|
222
- klass.class_eval <<-"end_eval", __FILE__, __LINE__
297
+ klass.class_eval <<-EOS, __FILE__, __LINE__ + 1
223
298
  def self.#{method}(*methods, &block)
224
299
  set_callback :#{method}, *methods, &block
225
300
  end
226
- end_eval
301
+ EOS
227
302
  end
228
303
  end
229
304
  end
230
305
 
231
- private
232
-
233
- METHODS.each do |method|
234
- class_eval <<-"end_eval", __FILE__, __LINE__
235
- def #{method}
236
- run_callbacks(:#{method}) { |result, object| result == false }
237
- end
238
- end_eval
239
- end
306
+ # TODO: Ideally, once this module is included, the included copies of
307
+ # the following methods would be private. This cannot be accomplished
308
+ # by using calling `private` here in the module. Maybe we can set the
309
+ # privacy inside `included`?
310
+ METHODS.each do |method|
311
+ class_eval <<-EOS, __FILE__, __LINE__ + 1
312
+ def #{method}
313
+ run_callbacks(:#{method}) { |result, object| result == false }
314
+ end
315
+ EOS
316
+ end
240
317
  end
241
318
 
242
319
  # The methods related to the password field.
@@ -251,8 +328,14 @@ module Authlogic
251
328
  validates_length_of :password, validates_length_of_password_field_options
252
329
 
253
330
  if require_password_confirmation
254
- validates_confirmation_of :password, validates_confirmation_of_password_field_options
255
- validates_length_of :password_confirmation, validates_length_of_password_confirmation_field_options
331
+ validates_confirmation_of(
332
+ :password,
333
+ validates_confirmation_of_password_field_options
334
+ )
335
+ validates_length_of(
336
+ :password_confirmation,
337
+ validates_length_of_password_confirmation_field_options
338
+ )
256
339
  end
257
340
  end
258
341
 
@@ -260,9 +343,11 @@ module Authlogic
260
343
  end
261
344
  end
262
345
 
346
+ # :nodoc:
263
347
  module InstanceMethods
264
348
  # The password
265
349
  def password
350
+ return nil unless defined?(@password)
266
351
  @password
267
352
  end
268
353
 
@@ -272,40 +357,48 @@ module Authlogic
272
357
  return if ignore_blank_passwords? && pass.blank?
273
358
  before_password_set
274
359
  @password = pass
275
- send("#{password_salt_field}=", Authlogic::Random.friendly_token) if password_salt_field
276
- encryptor_arguments_type = act_like_restful_authentication? ? :restful_authentication : nil
360
+ if password_salt_field
361
+ send("#{password_salt_field}=", Authlogic::Random.friendly_token)
362
+ end
363
+ encryptor_args_type = act_like_restful_authentication? ? :restful_authentication : nil
277
364
  send(
278
365
  "#{crypted_password_field}=",
279
- crypto_provider.encrypt(*encrypt_arguments(@password, false, encryptor_arguments_type))
366
+ crypto_provider.encrypt(
367
+ *encrypt_arguments(@password, false, encryptor_args_type)
368
+ )
280
369
  )
281
370
  @password_changed = true
282
371
  after_password_set
283
372
  end
284
373
 
285
- # Accepts a raw password to determine if it is the correct password or not.
286
- # Notice the second argument. That defaults to the value of
287
- # check_passwords_against_database. See that method for more information, but
288
- # basically it just tells Authlogic to check the password against the value in
289
- # the database or the value in the object.
290
- def valid_password?(attempted_password, check_against_database = check_passwords_against_database?)
291
- crypted =
292
- if check_against_database && send("#{crypted_password_field}_changed?")
293
- send("#{crypted_password_field}_was")
294
- else
295
- send(crypted_password_field)
296
- end
297
-
374
+ # Accepts a raw password to determine if it is the correct password.
375
+ #
376
+ # - attempted_password [String] - password entered by user
377
+ # - check_against_database [boolean] - Should we check the password
378
+ # against the value in the database or the value in the object?
379
+ # Default taken from config option check_passwords_against_database.
380
+ # See config method for more information.
381
+ def valid_password?(
382
+ attempted_password,
383
+ check_against_database = check_passwords_against_database?
384
+ )
385
+ crypted = crypted_password_to_validate_against(check_against_database)
298
386
  return false if attempted_password.blank? || crypted.blank?
299
387
  before_password_verification
300
388
 
301
389
  crypto_providers.each_with_index do |encryptor, index|
302
- if encryptor_matches?(crypted, encryptor, index, attempted_password, check_against_database)
303
- if transition_password?(index, encryptor, crypted, check_against_database)
304
- transition_password(attempted_password)
305
- end
306
- after_password_verification
307
- return true
390
+ next unless encryptor_matches?(
391
+ crypted,
392
+ encryptor,
393
+ index,
394
+ attempted_password,
395
+ check_against_database
396
+ )
397
+ if transition_password?(index, encryptor, check_against_database)
398
+ transition_password(attempted_password)
308
399
  end
400
+ after_password_verification
401
+ return true
309
402
  end
310
403
 
311
404
  false
@@ -322,102 +415,130 @@ module Authlogic
322
415
  # Resets the password to a random friendly token and then saves the record.
323
416
  def reset_password!
324
417
  reset_password
325
- save_without_session_maintenance(:validate => false)
418
+ save_without_session_maintenance(validate: false)
326
419
  end
327
420
  alias_method :randomize_password!, :reset_password!
328
421
 
329
422
  private
330
423
 
331
- def check_passwords_against_database?
332
- self.class.check_passwords_against_database == true
424
+ def crypted_password_to_validate_against(check_against_database)
425
+ if check_against_database && send("#{crypted_password_field}_changed?")
426
+ send("#{crypted_password_field}_was")
427
+ else
428
+ send(crypted_password_field)
333
429
  end
430
+ end
334
431
 
335
- def crypto_providers
336
- [crypto_provider] + transition_from_crypto_providers
337
- end
432
+ def check_passwords_against_database?
433
+ self.class.check_passwords_against_database == true
434
+ end
338
435
 
339
- # Returns an array of arguments to be passed to a crypto provider, either its
340
- # `matches?` or its `encrypt` method.
341
- def encrypt_arguments(raw_password, check_against_database, arguments_type = nil)
342
- salt = nil
343
- if password_salt_field
344
- salt =
345
- if check_against_database && send("#{password_salt_field}_changed?")
346
- send("#{password_salt_field}_was")
347
- else
348
- send(password_salt_field)
349
- end
350
- end
436
+ def crypto_providers
437
+ [crypto_provider] + transition_from_crypto_providers
438
+ end
351
439
 
352
- case arguments_type
353
- when :restful_authentication
354
- [REST_AUTH_SITE_KEY, salt, raw_password, REST_AUTH_SITE_KEY].compact
355
- when nil
356
- [raw_password, salt].compact
357
- else
358
- raise "Invalid encryptor arguments_type: #{arguments_type}"
359
- end
440
+ # Returns an array of arguments to be passed to a crypto provider, either its
441
+ # `matches?` or its `encrypt` method.
442
+ def encrypt_arguments(raw_password, check_against_database, arguments_type = nil)
443
+ salt = nil
444
+ if password_salt_field
445
+ salt =
446
+ if check_against_database && send("#{password_salt_field}_changed?")
447
+ send("#{password_salt_field}_was")
448
+ else
449
+ send(password_salt_field)
450
+ end
360
451
  end
361
452
 
362
- # Given `encryptor`, does `attempted_password` match the `crypted` password?
363
- def encryptor_matches?(crypted, encryptor, index, attempted_password, check_against_database)
364
- # The arguments_type for the transitioning from restful_authentication
365
- acting_restful = act_like_restful_authentication? && index == 0
366
- transitioning = transition_from_restful_authentication? &&
367
- index > 0 &&
368
- encryptor == Authlogic::CryptoProviders::Sha1
369
- restful = acting_restful || transitioning
370
- arguments_type = restful ? :restful_authentication : nil
371
- encryptor_args = encrypt_arguments(attempted_password, check_against_database, arguments_type)
372
- encryptor.matches?(crypted, *encryptor_args)
453
+ case arguments_type
454
+ when :restful_authentication
455
+ [REST_AUTH_SITE_KEY, salt, raw_password, REST_AUTH_SITE_KEY].compact
456
+ when nil
457
+ [raw_password, salt].compact
458
+ else
459
+ raise "Invalid encryptor arguments_type: #{arguments_type}"
373
460
  end
461
+ end
374
462
 
375
- # Determines if we need to transition the password.
376
- # If the index > 0 then we are using an "transition from" crypto provider.
377
- # If the encryptor has a cost and the cost it outdated.
378
- # If we aren't using database values
379
- # If we are using database values, only if the password hasn't changed so we don't overwrite any changes
380
- def transition_password?(index, encryptor, crypted, check_against_database)
381
- (index > 0 || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(send(crypted_password_field)))) &&
382
- (!check_against_database || !send("#{crypted_password_field}_changed?"))
383
- end
463
+ # Given `encryptor`, does `attempted_password` match the `crypted` password?
464
+ def encryptor_matches?(
465
+ crypted,
466
+ encryptor,
467
+ index,
468
+ attempted_password,
469
+ check_against_database
470
+ )
471
+ # The arguments_type for the transitioning from restful_authentication
472
+ acting_restful = act_like_restful_authentication? && index.zero?
473
+ transitioning = transition_from_restful_authentication? &&
474
+ index > 0 &&
475
+ encryptor == Authlogic::CryptoProviders::Sha1
476
+ restful = acting_restful || transitioning
477
+ arguments_type = restful ? :restful_authentication : nil
478
+ encryptor_args = encrypt_arguments(
479
+ attempted_password,
480
+ check_against_database,
481
+ arguments_type
482
+ )
483
+ encryptor.matches?(crypted, *encryptor_args)
484
+ end
384
485
 
385
- def transition_password(attempted_password)
386
- self.password = attempted_password
387
- save(:validate => false)
388
- end
486
+ # Determines if we need to transition the password.
487
+ #
488
+ # - If the index > 0 then we are using an "transition from" crypto
489
+ # provider.
490
+ # - If the encryptor has a cost and the cost it outdated.
491
+ # - If we aren't using database values
492
+ # - If we are using database values, only if the password hasn't
493
+ # changed so we don't overwrite any changes
494
+ def transition_password?(index, encryptor, check_against_database)
495
+ (
496
+ index > 0 ||
497
+ (encryptor.respond_to?(:cost_matches?) &&
498
+ !encryptor.cost_matches?(send(crypted_password_field)))
499
+ ) &&
500
+ (
501
+ !check_against_database ||
502
+ !send("#{crypted_password_field}_changed?")
503
+ )
504
+ end
389
505
 
390
- def require_password?
391
- new_record? || password_changed? || send(crypted_password_field).blank?
392
- end
506
+ def transition_password(attempted_password)
507
+ self.password = attempted_password
508
+ save(validate: false)
509
+ end
393
510
 
394
- def ignore_blank_passwords?
395
- self.class.ignore_blank_passwords == true
396
- end
511
+ def require_password?
512
+ new_record? || password_changed? || send(crypted_password_field).blank?
513
+ end
397
514
 
398
- def password_changed?
399
- @password_changed == true
400
- end
515
+ def ignore_blank_passwords?
516
+ self.class.ignore_blank_passwords == true
517
+ end
401
518
 
402
- def reset_password_changed
403
- @password_changed = nil
404
- end
519
+ def password_changed?
520
+ defined?(@password_changed) && @password_changed == true
521
+ end
405
522
 
406
- def crypted_password_field
407
- self.class.crypted_password_field
408
- end
523
+ def reset_password_changed
524
+ @password_changed = nil
525
+ end
409
526
 
410
- def password_salt_field
411
- self.class.password_salt_field
412
- end
527
+ def crypted_password_field
528
+ self.class.crypted_password_field
529
+ end
413
530
 
414
- def crypto_provider
415
- self.class.crypto_provider
416
- end
531
+ def password_salt_field
532
+ self.class.password_salt_field
533
+ end
417
534
 
418
- def transition_from_crypto_providers
419
- self.class.transition_from_crypto_providers
420
- end
535
+ def crypto_provider
536
+ self.class.crypto_provider
537
+ end
538
+
539
+ def transition_from_crypto_providers
540
+ self.class.transition_from_crypto_providers
541
+ end
421
542
  end
422
543
  end
423
544
  end