authlogic 3.8.0 → 6.0.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 (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