authlogic 3.8.0 → 6.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (150) hide show
  1. checksums.yaml +7 -0
  2. data/lib/authlogic/acts_as_authentic/base.rb +33 -36
  3. data/lib/authlogic/acts_as_authentic/email.rb +8 -141
  4. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +17 -10
  5. data/lib/authlogic/acts_as_authentic/login.rb +14 -165
  6. data/lib/authlogic/acts_as_authentic/magic_columns.rb +13 -10
  7. data/lib/authlogic/acts_as_authentic/password.rb +186 -254
  8. data/lib/authlogic/acts_as_authentic/perishable_token.rb +30 -22
  9. data/lib/authlogic/acts_as_authentic/persistence_token.rb +19 -18
  10. data/lib/authlogic/acts_as_authentic/queries/case_sensitivity.rb +53 -0
  11. data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +83 -0
  12. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +94 -62
  13. data/lib/authlogic/acts_as_authentic/single_access_token.rb +28 -14
  14. data/lib/authlogic/config.rb +29 -10
  15. data/lib/authlogic/controller_adapters/abstract_adapter.rb +43 -13
  16. data/lib/authlogic/controller_adapters/rack_adapter.rb +11 -5
  17. data/lib/authlogic/controller_adapters/rails_adapter.rb +11 -29
  18. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +8 -2
  19. data/lib/authlogic/cookie_credentials.rb +63 -0
  20. data/lib/authlogic/crypto_providers/bcrypt.rb +24 -18
  21. data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
  22. data/lib/authlogic/crypto_providers/md5.rb +8 -6
  23. data/lib/authlogic/crypto_providers/scrypt.rb +24 -17
  24. data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
  25. data/lib/authlogic/crypto_providers/sha1.rb +12 -5
  26. data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
  27. data/lib/authlogic/crypto_providers/sha256.rb +18 -9
  28. data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
  29. data/lib/authlogic/crypto_providers/sha512.rb +9 -26
  30. data/lib/authlogic/crypto_providers.rb +77 -1
  31. data/lib/authlogic/errors.rb +35 -0
  32. data/lib/authlogic/i18n/translator.rb +4 -1
  33. data/lib/authlogic/i18n.rb +29 -20
  34. data/lib/authlogic/random.rb +12 -28
  35. data/lib/authlogic/session/base.rb +2087 -33
  36. data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
  37. data/lib/authlogic/test_case/mock_controller.rb +7 -4
  38. data/lib/authlogic/test_case/mock_cookie_jar.rb +19 -3
  39. data/lib/authlogic/test_case/mock_logger.rb +2 -0
  40. data/lib/authlogic/test_case/mock_request.rb +8 -3
  41. data/lib/authlogic/test_case/rails_request_adapter.rb +5 -2
  42. data/lib/authlogic/test_case.rb +74 -2
  43. data/lib/authlogic/version.rb +22 -0
  44. data/lib/authlogic.rb +33 -54
  45. metadata +208 -234
  46. data/.github/ISSUE_TEMPLATE.md +0 -13
  47. data/.gitignore +0 -14
  48. data/.rubocop.yml +0 -33
  49. data/.rubocop_todo.yml +0 -391
  50. data/.travis.yml +0 -48
  51. data/CHANGELOG.md +0 -5
  52. data/CONTRIBUTING.md +0 -60
  53. data/Gemfile +0 -5
  54. data/LICENSE +0 -20
  55. data/README.md +0 -294
  56. data/Rakefile +0 -21
  57. data/authlogic.gemspec +0 -27
  58. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -70
  59. data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -32
  60. data/lib/authlogic/authenticates_many/association.rb +0 -50
  61. data/lib/authlogic/authenticates_many/base.rb +0 -65
  62. data/lib/authlogic/crypto_providers/aes256.rb +0 -66
  63. data/lib/authlogic/crypto_providers/wordpress.rb +0 -43
  64. data/lib/authlogic/regex.rb +0 -48
  65. data/lib/authlogic/session/activation.rb +0 -70
  66. data/lib/authlogic/session/active_record_trickery.rb +0 -61
  67. data/lib/authlogic/session/brute_force_protection.rb +0 -120
  68. data/lib/authlogic/session/callbacks.rb +0 -105
  69. data/lib/authlogic/session/cookies.rb +0 -244
  70. data/lib/authlogic/session/existence.rb +0 -93
  71. data/lib/authlogic/session/foundation.rb +0 -55
  72. data/lib/authlogic/session/http_auth.rb +0 -100
  73. data/lib/authlogic/session/id.rb +0 -48
  74. data/lib/authlogic/session/klass.rb +0 -70
  75. data/lib/authlogic/session/magic_columns.rb +0 -116
  76. data/lib/authlogic/session/magic_states.rb +0 -76
  77. data/lib/authlogic/session/params.rb +0 -116
  78. data/lib/authlogic/session/password.rb +0 -308
  79. data/lib/authlogic/session/perishable_token.rb +0 -23
  80. data/lib/authlogic/session/persistence.rb +0 -71
  81. data/lib/authlogic/session/priority_record.rb +0 -35
  82. data/lib/authlogic/session/scopes.rb +0 -119
  83. data/lib/authlogic/session/session.rb +0 -67
  84. data/lib/authlogic/session/timeout.rb +0 -103
  85. data/lib/authlogic/session/unauthorized_record.rb +0 -51
  86. data/lib/authlogic/session/validation.rb +0 -93
  87. data/test/acts_as_authentic_test/base_test.rb +0 -25
  88. data/test/acts_as_authentic_test/email_test.rb +0 -240
  89. data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -62
  90. data/test/acts_as_authentic_test/login_test.rb +0 -156
  91. data/test/acts_as_authentic_test/magic_columns_test.rb +0 -27
  92. data/test/acts_as_authentic_test/password_test.rb +0 -249
  93. data/test/acts_as_authentic_test/perishable_token_test.rb +0 -90
  94. data/test/acts_as_authentic_test/persistence_token_test.rb +0 -56
  95. data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -37
  96. data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -96
  97. data/test/acts_as_authentic_test/single_access_test.rb +0 -44
  98. data/test/authenticates_many_test.rb +0 -31
  99. data/test/config_test.rb +0 -36
  100. data/test/crypto_provider_test/aes256_test.rb +0 -14
  101. data/test/crypto_provider_test/bcrypt_test.rb +0 -14
  102. data/test/crypto_provider_test/scrypt_test.rb +0 -14
  103. data/test/crypto_provider_test/sha1_test.rb +0 -23
  104. data/test/crypto_provider_test/sha256_test.rb +0 -14
  105. data/test/crypto_provider_test/sha512_test.rb +0 -14
  106. data/test/fixtures/companies.yml +0 -5
  107. data/test/fixtures/employees.yml +0 -17
  108. data/test/fixtures/projects.yml +0 -3
  109. data/test/fixtures/users.yml +0 -41
  110. data/test/gemfiles/Gemfile.rails-3.2.x +0 -7
  111. data/test/gemfiles/Gemfile.rails-4.0.x +0 -7
  112. data/test/gemfiles/Gemfile.rails-4.1.x +0 -7
  113. data/test/gemfiles/Gemfile.rails-4.2.x +0 -7
  114. data/test/gemfiles/Gemfile.rails-5.0.x +0 -6
  115. data/test/gemfiles/Gemfile.rails-5.1.x +0 -6
  116. data/test/gemfiles/Gemfile.rails-5.2.x +0 -6
  117. data/test/i18n/lol.yml +0 -4
  118. data/test/i18n_test.rb +0 -33
  119. data/test/libs/affiliate.rb +0 -7
  120. data/test/libs/company.rb +0 -6
  121. data/test/libs/employee.rb +0 -7
  122. data/test/libs/employee_session.rb +0 -2
  123. data/test/libs/ldaper.rb +0 -3
  124. data/test/libs/project.rb +0 -3
  125. data/test/libs/user.rb +0 -7
  126. data/test/libs/user_session.rb +0 -25
  127. data/test/random_test.rb +0 -43
  128. data/test/session_test/activation_test.rb +0 -43
  129. data/test/session_test/active_record_trickery_test.rb +0 -75
  130. data/test/session_test/brute_force_protection_test.rb +0 -108
  131. data/test/session_test/callbacks_test.rb +0 -34
  132. data/test/session_test/cookies_test.rb +0 -201
  133. data/test/session_test/credentials_test.rb +0 -0
  134. data/test/session_test/existence_test.rb +0 -75
  135. data/test/session_test/foundation_test.rb +0 -6
  136. data/test/session_test/http_auth_test.rb +0 -56
  137. data/test/session_test/id_test.rb +0 -17
  138. data/test/session_test/klass_test.rb +0 -40
  139. data/test/session_test/magic_columns_test.rb +0 -62
  140. data/test/session_test/magic_states_test.rb +0 -58
  141. data/test/session_test/params_test.rb +0 -53
  142. data/test/session_test/password_test.rb +0 -105
  143. data/test/session_test/perishability_test.rb +0 -15
  144. data/test/session_test/persistence_test.rb +0 -32
  145. data/test/session_test/scopes_test.rb +0 -60
  146. data/test/session_test/session_test.rb +0 -78
  147. data/test/session_test/timeout_test.rb +0 -82
  148. data/test/session_test/unauthorized_record_test.rb +0 -13
  149. data/test/session_test/validation_test.rb +0 -23
  150. data/test/test_helper.rb +0 -233
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  module ActsAsAuthentic
3
5
  # This module has a lot of neat functionality. It is responsible for encrypting your
@@ -22,10 +24,16 @@ module Authlogic
22
24
  rw_config(
23
25
  :crypted_password_field,
24
26
  value,
25
- first_column_to_exist(nil, :crypted_password, :encrypted_password, :password_hash, :pw_hash)
27
+ first_column_to_exist(
28
+ nil,
29
+ :crypted_password,
30
+ :encrypted_password,
31
+ :password_hash,
32
+ :pw_hash
33
+ )
26
34
  )
27
35
  end
28
- alias_method :crypted_password_field=, :crypted_password_field
36
+ alias crypted_password_field= crypted_password_field
29
37
 
30
38
  # The name of the password_salt field in the database.
31
39
  #
@@ -38,7 +46,7 @@ module Authlogic
38
46
  first_column_to_exist(nil, :password_salt, :pw_salt, :salt)
39
47
  )
40
48
  end
41
- alias_method :password_salt_field=, :password_salt_field
49
+ alias password_salt_field= password_salt_field
42
50
 
43
51
  # Whether or not to require a password confirmation. If you don't want your users
44
52
  # to confirm their password just set this to false.
@@ -48,7 +56,7 @@ module Authlogic
48
56
  def require_password_confirmation(value = nil)
49
57
  rw_config(:require_password_confirmation, value, true)
50
58
  end
51
- alias_method :require_password_confirmation=, :require_password_confirmation
59
+ alias require_password_confirmation= require_password_confirmation
52
60
 
53
61
  # By default passwords are required when a record is new or the crypted_password
54
62
  # is blank, but if both of these things are met a password is not required. In
@@ -67,7 +75,7 @@ module Authlogic
67
75
  def ignore_blank_passwords(value = nil)
68
76
  rw_config(:ignore_blank_passwords, value, true)
69
77
  end
70
- alias_method :ignore_blank_passwords=, :ignore_blank_passwords
78
+ alias ignore_blank_passwords= ignore_blank_passwords
71
79
 
72
80
  # When calling valid_password?("some pass") do you want to check that password
73
81
  # against what's in that object or whats in the database. Take this example:
@@ -85,158 +93,82 @@ module Authlogic
85
93
  def check_passwords_against_database(value = nil)
86
94
  rw_config(:check_passwords_against_database, value, true)
87
95
  end
88
- alias_method :check_passwords_against_database=, :check_passwords_against_database
89
-
90
- # Whether or not to validate the password field.
91
- #
92
- # * <tt>Default:</tt> true
93
- # * <tt>Accepts:</tt> Boolean
94
- def validate_password_field(value = nil)
95
- rw_config(:validate_password_field, value, true)
96
- end
97
- alias_method :validate_password_field=, :validate_password_field
98
-
99
- # A hash of options for the validates_length_of call for the password field.
100
- # Allows you to change this however you want.
101
- #
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>
106
- #
107
- # * <tt>Default:</tt> {:minimum => 8, :if => :require_password?}
108
- # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
109
- def validates_length_of_password_field_options(value = nil)
110
- rw_config(:validates_length_of_password_field_options, value, { :minimum => 8, :if => :require_password? })
111
- end
112
- alias_method :validates_length_of_password_field_options=, :validates_length_of_password_field_options
96
+ alias check_passwords_against_database= check_passwords_against_database
113
97
 
114
- # A convenience function to merge options into the
115
- # validates_length_of_login_field_options. So instead of:
98
+ # The class you want to use to encrypt and verify your encrypted
99
+ # passwords. See the Authlogic::CryptoProviders module for more info on
100
+ # the available methods and how to create your own.
116
101
  #
117
- # self.validates_length_of_password_field_options =
118
- # validates_length_of_password_field_options.merge(:my_option => my_value)
102
+ # The family of adaptive hash functions (BCrypt, SCrypt, PBKDF2) is the
103
+ # best choice for password storage today. We recommend SCrypt. Other
104
+ # one-way functions like SHA512 are inferior, but widely used.
105
+ # Reverisbile functions like AES256 are the worst choice, and we no
106
+ # longer support them.
119
107
  #
120
- # You can do this:
108
+ # You can use the `transition_from_crypto_providers` option to gradually
109
+ # transition to a better crypto provider without causing your users any
110
+ # pain.
121
111
  #
122
- # merge_validates_length_of_password_field_options :my_option => my_value
123
- 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)
125
- end
126
-
127
- # A hash of options for the validates_confirmation_of call for the password field.
128
- # Allows you to change this however you want.
129
- #
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>
134
- #
135
- # * <tt>Default:</tt> {:if => :require_password?}
136
- # * <tt>Accepts:</tt> Hash of options accepted by validates_confirmation_of
137
- def validates_confirmation_of_password_field_options(value = nil)
138
- rw_config(:validates_confirmation_of_password_field_options, value, { :if => :require_password? })
139
- end
140
- alias_method :validates_confirmation_of_password_field_options=, :validates_confirmation_of_password_field_options
141
-
142
- # See merge_validates_length_of_password_field_options. The same thing, except for
143
- # validates_confirmation_of_password_field_options
144
- 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)
112
+ # * <tt>Default:</tt> There is no longer a default value. Prior to
113
+ # Authlogic 6, the default was `CryptoProviders::SCrypt`. If you try
114
+ # to read this config option before setting it, it will raise a
115
+ # `NilCryptoProvider` error. See that error's message for further
116
+ # details, and rationale for this change.
117
+ # * <tt>Accepts:</tt> Class
118
+ def crypto_provider
119
+ acts_as_authentic_config[:crypto_provider].tap { |provider|
120
+ raise NilCryptoProvider if provider.nil?
121
+ }
146
122
  end
147
123
 
148
- # A hash of options for the validates_length_of call for the password_confirmation
149
- # field. Allows you to change this however you want.
150
- #
151
- # <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
152
- # you can completely replace the hash or merge options into it. Checkout the
153
- # convenience function merge_validates_length_of_password_field_options to merge
154
- # options.</b>
155
- #
156
- # * <tt>Default:</tt> validates_length_of_password_field_options
157
- # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
158
- def validates_length_of_password_confirmation_field_options(value = nil)
159
- rw_config(
160
- :validates_length_of_password_confirmation_field_options,
161
- value,
162
- validates_length_of_password_field_options
163
- )
164
- end
165
- alias_method(
166
- :validates_length_of_password_confirmation_field_options=,
167
- :validates_length_of_password_confirmation_field_options
168
- )
169
-
170
- # See merge_validates_length_of_password_field_options. The same thing, except for
171
- # validates_length_of_password_confirmation_field_options
172
- def merge_validates_length_of_password_confirmation_field_options(options = {})
173
- self.validates_length_of_password_confirmation_field_options =
174
- validates_length_of_password_confirmation_field_options.merge(options)
124
+ def crypto_provider=(value)
125
+ raise NilCryptoProvider if value.nil?
126
+ CryptoProviders::Guidance.new(value).impart_wisdom
127
+ rw_config(:crypto_provider, value)
175
128
  end
176
129
 
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.
180
- #
181
- # * <tt>Default:</tt> CryptoProviders::SCrypt
182
- # * <tt>Accepts:</tt> Class
183
- def crypto_provider(value = nil)
184
- rw_config(:crypto_provider, value, CryptoProviders::SCrypt)
185
- end
186
- alias_method :crypto_provider=, :crypto_provider
187
-
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.
130
+ # Let's say you originally encrypted your passwords with Sha1. Sha1 is
131
+ # starting to join the party with MD5 and you want to switch to
132
+ # something stronger. No problem, just specify your new and improved
133
+ # algorithm with the crypt_provider option and then let Authlogic know
134
+ # you are transitioning from Sha1 using this option. Authlogic will take
135
+ # care of everything, including transitioning your users to the new
136
+ # algorithm. The next time a user logs in, they will be granted access
137
+ # using the old algorithm and their password will be resaved with the
138
+ # new algorithm. All new users will obviously use the new algorithm as
139
+ # well.
196
140
  #
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.
141
+ # Lastly, if you want to transition again, you can pass an array of
142
+ # crypto providers. So you can transition from as many algorithms as you
143
+ # want.
199
144
  #
200
145
  # * <tt>Default:</tt> nil
201
146
  # * <tt>Accepts:</tt> Class or Array
202
147
  def transition_from_crypto_providers(value = nil)
203
- rw_config(:transition_from_crypto_providers, (!value.nil? && [value].flatten.compact) || value, [])
148
+ rw_config(
149
+ :transition_from_crypto_providers,
150
+ (!value.nil? && [value].flatten.compact) || value,
151
+ []
152
+ )
204
153
  end
205
- alias_method :transition_from_crypto_providers=, :transition_from_crypto_providers
154
+ alias transition_from_crypto_providers= transition_from_crypto_providers
206
155
  end
207
156
 
208
157
  # Callbacks / hooks to allow other modules to modify the behavior of this module.
209
158
  module Callbacks
210
- METHODS = [
211
- "before_password_set", "after_password_set",
212
- "before_password_verification", "after_password_verification"
213
- ]
159
+ # Does the order of this array matter?
160
+ METHODS = %w[
161
+ password_set
162
+ password_verification
163
+ ].freeze
214
164
 
215
165
  def self.included(klass)
216
166
  return if klass.crypted_password_field.nil?
217
- klass.define_callbacks *METHODS
218
-
219
- # If Rails 3, support the new callback syntax
220
- if klass.send(klass.respond_to?(:singleton_class) ? :singleton_class : :metaclass).method_defined?(:set_callback)
221
- METHODS.each do |method|
222
- klass.class_eval <<-"end_eval", __FILE__, __LINE__
223
- def self.#{method}(*methods, &block)
224
- set_callback :#{method}, *methods, &block
225
- end
226
- end_eval
227
- end
228
- end
229
- end
230
-
231
- private
232
-
167
+ klass.send :extend, ActiveModel::Callbacks
233
168
  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
169
+ klass.define_model_callbacks method, only: %i[before after]
239
170
  end
171
+ end
240
172
  end
241
173
 
242
174
  # The methods related to the password field.
@@ -246,23 +178,15 @@ module Authlogic
246
178
 
247
179
  klass.class_eval do
248
180
  include InstanceMethods
249
-
250
- if validate_password_field
251
- validates_length_of :password, validates_length_of_password_field_options
252
-
253
- 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
256
- end
257
- end
258
-
259
181
  after_save :reset_password_changed
260
182
  end
261
183
  end
262
184
 
185
+ # :nodoc:
263
186
  module InstanceMethods
264
187
  # The password
265
188
  def password
189
+ return nil unless defined?(@password)
266
190
  @password
267
191
  end
268
192
 
@@ -270,45 +194,49 @@ module Authlogic
270
194
  # create new password salt as well as encrypt the password.
271
195
  def password=(pass)
272
196
  return if ignore_blank_passwords? && pass.blank?
273
- before_password_set
274
- @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
277
- send(
278
- "#{crypted_password_field}=",
279
- crypto_provider.encrypt(*encrypt_arguments(@password, false, encryptor_arguments_type))
280
- )
281
- @password_changed = true
282
- after_password_set
283
- end
284
-
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)
197
+ run_callbacks :password_set do
198
+ @password = pass
199
+ if password_salt_field
200
+ send("#{password_salt_field}=", Authlogic::Random.friendly_token)
296
201
  end
202
+ send(
203
+ "#{crypted_password_field}=",
204
+ crypto_provider.encrypt(*encrypt_arguments(@password, false))
205
+ )
206
+ @password_changed = true
207
+ end
208
+ end
297
209
 
210
+ # Accepts a raw password to determine if it is the correct password.
211
+ #
212
+ # - attempted_password [String] - password entered by user
213
+ # - check_against_database [boolean] - Should we check the password
214
+ # against the value in the database or the value in the object?
215
+ # Default taken from config option check_passwords_against_database.
216
+ # See config method for more information.
217
+ def valid_password?(
218
+ attempted_password,
219
+ check_against_database = check_passwords_against_database?
220
+ )
221
+ crypted = crypted_password_to_validate_against(check_against_database)
298
222
  return false if attempted_password.blank? || crypted.blank?
299
- before_password_verification
300
-
301
- 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)
223
+ run_callbacks :password_verification do
224
+ crypto_providers.each_with_index.any? do |encryptor, index|
225
+ if encryptor_matches?(
226
+ crypted,
227
+ encryptor,
228
+ attempted_password,
229
+ check_against_database
230
+ )
231
+ if transition_password?(index, encryptor, check_against_database)
232
+ transition_password(attempted_password)
233
+ end
234
+ true
235
+ else
236
+ false
305
237
  end
306
- after_password_verification
307
- return true
308
238
  end
309
239
  end
310
-
311
- false
312
240
  end
313
241
 
314
242
  # Resets the password to a random friendly token.
@@ -317,107 +245,111 @@ module Authlogic
317
245
  self.password = friendly_token
318
246
  self.password_confirmation = friendly_token if self.class.require_password_confirmation
319
247
  end
320
- alias_method :randomize_password, :reset_password
248
+ alias randomize_password reset_password
321
249
 
322
250
  # Resets the password to a random friendly token and then saves the record.
323
251
  def reset_password!
324
252
  reset_password
325
- save_without_session_maintenance(:validate => false)
253
+ save_without_session_maintenance(validate: false)
326
254
  end
327
- alias_method :randomize_password!, :reset_password!
255
+ alias randomize_password! reset_password!
328
256
 
329
257
  private
330
258
 
331
- def check_passwords_against_database?
332
- self.class.check_passwords_against_database == true
259
+ def crypted_password_to_validate_against(check_against_database)
260
+ if check_against_database && send("will_save_change_to_#{crypted_password_field}?")
261
+ send("#{crypted_password_field}_in_database")
262
+ else
263
+ send(crypted_password_field)
333
264
  end
265
+ end
334
266
 
335
- def crypto_providers
336
- [crypto_provider] + transition_from_crypto_providers
337
- end
267
+ def check_passwords_against_database?
268
+ self.class.check_passwords_against_database == true
269
+ end
338
270
 
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
271
+ def crypto_providers
272
+ [crypto_provider] + transition_from_crypto_providers
273
+ end
351
274
 
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
275
+ # Returns an array of arguments to be passed to a crypto provider, either its
276
+ # `matches?` or its `encrypt` method.
277
+ def encrypt_arguments(raw_password, check_against_database)
278
+ salt = nil
279
+ if password_salt_field
280
+ salt =
281
+ if check_against_database && send("will_save_change_to_#{password_salt_field}?")
282
+ send("#{password_salt_field}_in_database")
283
+ else
284
+ send(password_salt_field)
285
+ end
360
286
  end
287
+ [raw_password, salt].compact
288
+ end
361
289
 
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)
373
- end
290
+ # Given `encryptor`, does `attempted_password` match the `crypted` password?
291
+ def encryptor_matches?(crypted, encryptor, attempted_password, check_against_database)
292
+ encryptor_args = encrypt_arguments(attempted_password, check_against_database)
293
+ encryptor.matches?(crypted, *encryptor_args)
294
+ end
374
295
 
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
296
+ # Determines if we need to transition the password.
297
+ #
298
+ # - If the index > 0 then we are using a "transition from" crypto
299
+ # provider.
300
+ # - If the encryptor has a cost and the cost it outdated.
301
+ # - If we aren't using database values
302
+ # - If we are using database values, only if the password hasn't
303
+ # changed so we don't overwrite any changes
304
+ def transition_password?(index, encryptor, check_against_database)
305
+ (
306
+ index > 0 ||
307
+ (encryptor.respond_to?(:cost_matches?) &&
308
+ !encryptor.cost_matches?(send(crypted_password_field)))
309
+ ) &&
310
+ (
311
+ !check_against_database ||
312
+ !send("will_save_change_to_#{crypted_password_field}?")
313
+ )
314
+ end
384
315
 
385
- def transition_password(attempted_password)
386
- self.password = attempted_password
387
- save(:validate => false)
388
- end
316
+ def transition_password(attempted_password)
317
+ self.password = attempted_password
318
+ save(validate: false)
319
+ end
389
320
 
390
- def require_password?
391
- new_record? || password_changed? || send(crypted_password_field).blank?
392
- end
321
+ def require_password?
322
+ # this is _not_ the activemodel changed? method, see below
323
+ new_record? || password_changed? || send(crypted_password_field).blank?
324
+ end
393
325
 
394
- def ignore_blank_passwords?
395
- self.class.ignore_blank_passwords == true
396
- end
326
+ def ignore_blank_passwords?
327
+ self.class.ignore_blank_passwords == true
328
+ end
397
329
 
398
- def password_changed?
399
- @password_changed == true
400
- end
330
+ def password_changed?
331
+ defined?(@password_changed) && @password_changed == true
332
+ end
401
333
 
402
- def reset_password_changed
403
- @password_changed = nil
404
- end
334
+ def reset_password_changed
335
+ @password_changed = nil
336
+ end
405
337
 
406
- def crypted_password_field
407
- self.class.crypted_password_field
408
- end
338
+ def crypted_password_field
339
+ self.class.crypted_password_field
340
+ end
409
341
 
410
- def password_salt_field
411
- self.class.password_salt_field
412
- end
342
+ def password_salt_field
343
+ self.class.password_salt_field
344
+ end
413
345
 
414
- def crypto_provider
415
- self.class.crypto_provider
416
- end
346
+ def crypto_provider
347
+ self.class.crypto_provider
348
+ end
417
349
 
418
- def transition_from_crypto_providers
419
- self.class.transition_from_crypto_providers
420
- end
350
+ def transition_from_crypto_providers
351
+ self.class.transition_from_crypto_providers
352
+ end
421
353
  end
422
354
  end
423
355
  end