authlogic 4.5.0 → 6.4.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (153) hide show
  1. checksums.yaml +4 -4
  2. data/lib/authlogic/acts_as_authentic/base.rb +19 -19
  3. data/lib/authlogic/acts_as_authentic/email.rb +3 -170
  4. data/lib/authlogic/acts_as_authentic/logged_in_status.rb +3 -1
  5. data/lib/authlogic/acts_as_authentic/login.rb +7 -174
  6. data/lib/authlogic/acts_as_authentic/magic_columns.rb +7 -4
  7. data/lib/authlogic/acts_as_authentic/password.rb +67 -256
  8. data/lib/authlogic/acts_as_authentic/perishable_token.rb +8 -5
  9. data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -4
  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 +36 -20
  12. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +12 -8
  13. data/lib/authlogic/acts_as_authentic/single_access_token.rb +10 -8
  14. data/lib/authlogic/config.rb +9 -1
  15. data/lib/authlogic/controller_adapters/abstract_adapter.rb +28 -4
  16. data/lib/authlogic/controller_adapters/rack_adapter.rb +2 -0
  17. data/lib/authlogic/controller_adapters/rails_adapter.rb +7 -30
  18. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +6 -0
  19. data/lib/authlogic/cookie_credentials.rb +63 -0
  20. data/lib/authlogic/crypto_providers/bcrypt.rb +3 -3
  21. data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
  22. data/lib/authlogic/crypto_providers/md5.rb +6 -6
  23. data/lib/authlogic/crypto_providers/scrypt.rb +2 -0
  24. data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
  25. data/lib/authlogic/crypto_providers/sha1.rb +7 -6
  26. data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
  27. data/lib/authlogic/crypto_providers/sha256.rb +5 -0
  28. data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
  29. data/lib/authlogic/crypto_providers/sha512.rb +9 -5
  30. data/lib/authlogic/crypto_providers.rb +5 -20
  31. data/lib/authlogic/errors.rb +50 -0
  32. data/lib/authlogic/i18n/translator.rb +4 -1
  33. data/lib/authlogic/i18n.rb +3 -1
  34. data/lib/authlogic/random.rb +2 -0
  35. data/lib/authlogic/session/base.rb +2197 -39
  36. data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
  37. data/lib/authlogic/test_case/mock_api_controller.rb +52 -0
  38. data/lib/authlogic/test_case/mock_controller.rb +3 -1
  39. data/lib/authlogic/test_case/mock_cookie_jar.rb +32 -6
  40. data/lib/authlogic/test_case/mock_logger.rb +2 -0
  41. data/lib/authlogic/test_case/mock_request.rb +12 -0
  42. data/lib/authlogic/test_case/rails_request_adapter.rb +9 -1
  43. data/lib/authlogic/test_case.rb +5 -0
  44. data/lib/authlogic/version.rb +2 -1
  45. data/lib/authlogic.rb +5 -28
  46. metadata +175 -200
  47. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -28
  48. data/.github/ISSUE_TEMPLATE/feature_proposal.md +0 -32
  49. data/.github/triage.md +0 -86
  50. data/.gitignore +0 -15
  51. data/.rubocop.yml +0 -133
  52. data/.rubocop_todo.yml +0 -74
  53. data/.travis.yml +0 -24
  54. data/CHANGELOG.md +0 -348
  55. data/CONTRIBUTING.md +0 -91
  56. data/Gemfile +0 -6
  57. data/LICENSE +0 -20
  58. data/README.md +0 -448
  59. data/Rakefile +0 -21
  60. data/UPGRADING.md +0 -22
  61. data/authlogic.gemspec +0 -40
  62. data/doc/use_normal_rails_validation.md +0 -82
  63. data/gemfiles/Gemfile.rails-4.2.x +0 -6
  64. data/gemfiles/Gemfile.rails-5.1.x +0 -6
  65. data/gemfiles/Gemfile.rails-5.2.x +0 -6
  66. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -106
  67. data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -35
  68. data/lib/authlogic/authenticates_many/association.rb +0 -50
  69. data/lib/authlogic/authenticates_many/base.rb +0 -81
  70. data/lib/authlogic/crypto_providers/aes256.rb +0 -71
  71. data/lib/authlogic/crypto_providers/wordpress.rb +0 -72
  72. data/lib/authlogic/regex.rb +0 -79
  73. data/lib/authlogic/session/activation.rb +0 -73
  74. data/lib/authlogic/session/active_record_trickery.rb +0 -65
  75. data/lib/authlogic/session/brute_force_protection.rb +0 -127
  76. data/lib/authlogic/session/callbacks.rb +0 -153
  77. data/lib/authlogic/session/cookies.rb +0 -329
  78. data/lib/authlogic/session/existence.rb +0 -103
  79. data/lib/authlogic/session/foundation.rb +0 -105
  80. data/lib/authlogic/session/http_auth.rb +0 -107
  81. data/lib/authlogic/session/id.rb +0 -53
  82. data/lib/authlogic/session/klass.rb +0 -73
  83. data/lib/authlogic/session/magic_columns.rb +0 -119
  84. data/lib/authlogic/session/magic_states.rb +0 -82
  85. data/lib/authlogic/session/params.rb +0 -130
  86. data/lib/authlogic/session/password.rb +0 -318
  87. data/lib/authlogic/session/perishable_token.rb +0 -24
  88. data/lib/authlogic/session/persistence.rb +0 -77
  89. data/lib/authlogic/session/priority_record.rb +0 -38
  90. data/lib/authlogic/session/scopes.rb +0 -138
  91. data/lib/authlogic/session/session.rb +0 -77
  92. data/lib/authlogic/session/timeout.rb +0 -103
  93. data/lib/authlogic/session/unauthorized_record.rb +0 -56
  94. data/lib/authlogic/session/validation.rb +0 -93
  95. data/test/acts_as_authentic_test/base_test.rb +0 -27
  96. data/test/acts_as_authentic_test/email_test.rb +0 -241
  97. data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -64
  98. data/test/acts_as_authentic_test/login_test.rb +0 -153
  99. data/test/acts_as_authentic_test/magic_columns_test.rb +0 -29
  100. data/test/acts_as_authentic_test/password_test.rb +0 -263
  101. data/test/acts_as_authentic_test/perishable_token_test.rb +0 -98
  102. data/test/acts_as_authentic_test/persistence_token_test.rb +0 -62
  103. data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -48
  104. data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -150
  105. data/test/acts_as_authentic_test/single_access_test.rb +0 -46
  106. data/test/adapter_test.rb +0 -23
  107. data/test/authenticates_many_test.rb +0 -33
  108. data/test/config_test.rb +0 -38
  109. data/test/crypto_provider_test/aes256_test.rb +0 -16
  110. data/test/crypto_provider_test/bcrypt_test.rb +0 -16
  111. data/test/crypto_provider_test/scrypt_test.rb +0 -16
  112. data/test/crypto_provider_test/sha1_test.rb +0 -25
  113. data/test/crypto_provider_test/sha256_test.rb +0 -16
  114. data/test/crypto_provider_test/sha512_test.rb +0 -16
  115. data/test/crypto_provider_test/wordpress_test.rb +0 -26
  116. data/test/fixtures/companies.yml +0 -5
  117. data/test/fixtures/employees.yml +0 -17
  118. data/test/fixtures/projects.yml +0 -3
  119. data/test/fixtures/users.yml +0 -41
  120. data/test/i18n/lol.yml +0 -4
  121. data/test/i18n_test.rb +0 -35
  122. data/test/libs/affiliate.rb +0 -9
  123. data/test/libs/company.rb +0 -8
  124. data/test/libs/employee.rb +0 -9
  125. data/test/libs/employee_session.rb +0 -4
  126. data/test/libs/ldaper.rb +0 -5
  127. data/test/libs/project.rb +0 -5
  128. data/test/libs/user.rb +0 -9
  129. data/test/libs/user_session.rb +0 -27
  130. data/test/random_test.rb +0 -15
  131. data/test/session_test/activation_test.rb +0 -45
  132. data/test/session_test/active_record_trickery_test.rb +0 -78
  133. data/test/session_test/brute_force_protection_test.rb +0 -110
  134. data/test/session_test/callbacks_test.rb +0 -42
  135. data/test/session_test/cookies_test.rb +0 -244
  136. data/test/session_test/credentials_test.rb +0 -0
  137. data/test/session_test/existence_test.rb +0 -88
  138. data/test/session_test/foundation_test.rb +0 -24
  139. data/test/session_test/http_auth_test.rb +0 -60
  140. data/test/session_test/id_test.rb +0 -19
  141. data/test/session_test/klass_test.rb +0 -42
  142. data/test/session_test/magic_columns_test.rb +0 -62
  143. data/test/session_test/magic_states_test.rb +0 -60
  144. data/test/session_test/params_test.rb +0 -61
  145. data/test/session_test/password_test.rb +0 -107
  146. data/test/session_test/perishability_test.rb +0 -17
  147. data/test/session_test/persistence_test.rb +0 -35
  148. data/test/session_test/scopes_test.rb +0 -68
  149. data/test/session_test/session_test.rb +0 -80
  150. data/test/session_test/timeout_test.rb +0 -84
  151. data/test/session_test/unauthorized_record_test.rb +0 -15
  152. data/test/session_test/validation_test.rb +0 -25
  153. data/test/test_helper.rb +0 -272
@@ -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
@@ -31,7 +33,7 @@ module Authlogic
31
33
  )
32
34
  )
33
35
  end
34
- alias_method :crypted_password_field=, :crypted_password_field
36
+ alias crypted_password_field= crypted_password_field
35
37
 
36
38
  # The name of the password_salt field in the database.
37
39
  #
@@ -44,7 +46,7 @@ module Authlogic
44
46
  first_column_to_exist(nil, :password_salt, :pw_salt, :salt)
45
47
  )
46
48
  end
47
- alias_method :password_salt_field=, :password_salt_field
49
+ alias password_salt_field= password_salt_field
48
50
 
49
51
  # Whether or not to require a password confirmation. If you don't want your users
50
52
  # to confirm their password just set this to false.
@@ -54,7 +56,7 @@ module Authlogic
54
56
  def require_password_confirmation(value = nil)
55
57
  rw_config(:require_password_confirmation, value, true)
56
58
  end
57
- alias_method :require_password_confirmation=, :require_password_confirmation
59
+ alias require_password_confirmation= require_password_confirmation
58
60
 
59
61
  # By default passwords are required when a record is new or the crypted_password
60
62
  # is blank, but if both of these things are met a password is not required. In
@@ -73,7 +75,7 @@ module Authlogic
73
75
  def ignore_blank_passwords(value = nil)
74
76
  rw_config(:ignore_blank_passwords, value, true)
75
77
  end
76
- alias_method :ignore_blank_passwords=, :ignore_blank_passwords
78
+ alias ignore_blank_passwords= ignore_blank_passwords
77
79
 
78
80
  # When calling valid_password?("some pass") do you want to check that password
79
81
  # against what's in that object or whats in the database. Take this example:
@@ -91,143 +93,7 @@ module Authlogic
91
93
  def check_passwords_against_database(value = nil)
92
94
  rw_config(:check_passwords_against_database, value, true)
93
95
  end
94
- alias_method :check_passwords_against_database=, :check_passwords_against_database
95
-
96
- # Whether or not to validate the password field.
97
- #
98
- # * <tt>Default:</tt> true
99
- # * <tt>Accepts:</tt> Boolean
100
- #
101
- # @deprecated
102
- def validate_password_field(value = nil)
103
- rw_config(:validate_password_field, value, true)
104
- end
105
- alias_method :validate_password_field=, :validate_password_field
106
-
107
- # A hash of options for the validates_length_of call for the password field.
108
- # Allows you to change this however you want.
109
- #
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.**
114
- #
115
- # * <tt>Default:</tt> {:minimum => 8, :if => :require_password?}
116
- # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
117
- #
118
- # @deprecated
119
- def validates_length_of_password_field_options(value = nil)
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
- )
127
- end
128
- alias_method(
129
- :validates_length_of_password_field_options=,
130
- :validates_length_of_password_field_options
131
- )
132
-
133
- # A convenience function to merge options into the
134
- # validates_length_of_login_field_options. So instead of:
135
- #
136
- # self.validates_length_of_password_field_options =
137
- # validates_length_of_password_field_options.merge(:my_option => my_value)
138
- #
139
- # You can do this:
140
- #
141
- # merge_validates_length_of_password_field_options :my_option => my_value
142
- #
143
- # @deprecated
144
- def merge_validates_length_of_password_field_options(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)
150
- end
151
-
152
- # A hash of options for the validates_confirmation_of call for the
153
- # password field. Allows you to change this however you want.
154
- #
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.**
159
- #
160
- # * <tt>Default:</tt> {:if => :require_password?}
161
- # * <tt>Accepts:</tt> Hash of options accepted by validates_confirmation_of
162
- #
163
- # @deprecated
164
- def validates_confirmation_of_password_field_options(value = nil)
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
- )
175
- end
176
- alias_method :validates_confirmation_of_password_field_options=,
177
- :validates_confirmation_of_password_field_options
178
-
179
- # See merge_validates_length_of_password_field_options. The same thing, except for
180
- # validates_confirmation_of_password_field_options
181
- #
182
- # @deprecated
183
- def merge_validates_confirmation_of_password_field_options(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)
189
- end
190
-
191
- # A hash of options for the validates_length_of call for the password_confirmation
192
- # field. Allows you to change this however you want.
193
- #
194
- # <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
195
- # you can completely replace the hash or merge options into it. Checkout the
196
- # convenience function merge_validates_length_of_password_field_options to merge
197
- # options.</b>
198
- #
199
- # * <tt>Default:</tt> validates_length_of_password_field_options
200
- # * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
201
- #
202
- # @deprecated
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
209
- rw_config(
210
- :validates_length_of_password_confirmation_field_options,
211
- value,
212
- validates_length_of_password_field_options
213
- )
214
- end
215
- alias_method(
216
- :validates_length_of_password_confirmation_field_options=,
217
- :validates_length_of_password_confirmation_field_options
218
- )
219
-
220
- # See merge_validates_length_of_password_field_options. The same thing, except for
221
- # validates_length_of_password_confirmation_field_options
222
- #
223
- # @deprecated
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
- )
228
- self.validates_length_of_password_confirmation_field_options =
229
- validates_length_of_password_confirmation_field_options.merge(options)
230
- end
96
+ alias check_passwords_against_database= check_passwords_against_database
231
97
 
232
98
  # The class you want to use to encrypt and verify your encrypted
233
99
  # passwords. See the Authlogic::CryptoProviders module for more info on
@@ -236,19 +102,30 @@ module Authlogic
236
102
  # The family of adaptive hash functions (BCrypt, SCrypt, PBKDF2) is the
237
103
  # best choice for password storage today. We recommend SCrypt. Other
238
104
  # one-way functions like SHA512 are inferior, but widely used.
239
- # Reverisbile functions like AES256 are the worst choice.
105
+ # Reversible functions like AES256 are the worst choice, and we no
106
+ # longer support them.
240
107
  #
241
108
  # You can use the `transition_from_crypto_providers` option to gradually
242
109
  # transition to a better crypto provider without causing your users any
243
110
  # pain.
244
111
  #
245
- # * <tt>Default:</tt> CryptoProviders::SCrypt
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.
246
117
  # * <tt>Accepts:</tt> Class
247
- def crypto_provider(value = nil)
118
+ def crypto_provider
119
+ acts_as_authentic_config[:crypto_provider].tap { |provider|
120
+ raise NilCryptoProvider if provider.nil?
121
+ }
122
+ end
123
+
124
+ def crypto_provider=(value)
125
+ raise NilCryptoProvider if value.nil?
248
126
  CryptoProviders::Guidance.new(value).impart_wisdom
249
- rw_config(:crypto_provider, value, CryptoProviders::SCrypt)
127
+ rw_config(:crypto_provider, value)
250
128
  end
251
- alias_method :crypto_provider=, :crypto_provider
252
129
 
253
130
  # Let's say you originally encrypted your passwords with Sha1. Sha1 is
254
131
  # starting to join the party with MD5 and you want to switch to
@@ -274,46 +151,24 @@ module Authlogic
274
151
  []
275
152
  )
276
153
  end
277
- alias_method :transition_from_crypto_providers=, :transition_from_crypto_providers
154
+ alias transition_from_crypto_providers= transition_from_crypto_providers
278
155
  end
279
156
 
280
157
  # Callbacks / hooks to allow other modules to modify the behavior of this module.
281
158
  module Callbacks
282
159
  # Does the order of this array matter?
283
160
  METHODS = %w[
284
- before_password_set
285
- after_password_set
286
- before_password_verification
287
- after_password_verification
161
+ password_set
162
+ password_verification
288
163
  ].freeze
289
164
 
290
165
  def self.included(klass)
291
166
  return if klass.crypted_password_field.nil?
292
- klass.define_callbacks(*METHODS)
293
-
294
- # If Rails 3, support the new callback syntax
295
- if klass.singleton_class.method_defined?(:set_callback)
296
- METHODS.each do |method|
297
- klass.class_eval <<-EOS, __FILE__, __LINE__ + 1
298
- def self.#{method}(*methods, &block)
299
- set_callback :#{method}, *methods, &block
300
- end
301
- EOS
302
- end
167
+ klass.send :extend, ActiveModel::Callbacks
168
+ METHODS.each do |method|
169
+ klass.define_model_callbacks method, only: %i[before after]
303
170
  end
304
171
  end
305
-
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
317
172
  end
318
173
 
319
174
  # The methods related to the password field.
@@ -323,22 +178,6 @@ module Authlogic
323
178
 
324
179
  klass.class_eval do
325
180
  include InstanceMethods
326
-
327
- if validate_password_field
328
- validates_length_of :password, validates_length_of_password_field_options
329
-
330
- if require_password_confirmation
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
- )
339
- end
340
- end
341
-
342
181
  after_save :reset_password_changed
343
182
  end
344
183
  end
@@ -355,20 +194,17 @@ module Authlogic
355
194
  # create new password salt as well as encrypt the password.
356
195
  def password=(pass)
357
196
  return if ignore_blank_passwords? && pass.blank?
358
- before_password_set
359
- @password = pass
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
364
- send(
365
- "#{crypted_password_field}=",
366
- crypto_provider.encrypt(
367
- *encrypt_arguments(@password, false, encryptor_args_type)
197
+ run_callbacks :password_set do
198
+ @password = pass
199
+ if password_salt_field
200
+ send("#{password_salt_field}=", Authlogic::Random.friendly_token)
201
+ end
202
+ send(
203
+ "#{crypted_password_field}=",
204
+ crypto_provider.encrypt(*encrypt_arguments(@password, false))
368
205
  )
369
- )
370
- @password_changed = true
371
- after_password_set
206
+ @password_changed = true
207
+ end
372
208
  end
373
209
 
374
210
  # Accepts a raw password to determine if it is the correct password.
@@ -384,24 +220,23 @@ module Authlogic
384
220
  )
385
221
  crypted = crypted_password_to_validate_against(check_against_database)
386
222
  return false if attempted_password.blank? || crypted.blank?
387
- before_password_verification
388
-
389
- crypto_providers.each_with_index do |encryptor, index|
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)
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
237
+ end
399
238
  end
400
- after_password_verification
401
- return true
402
239
  end
403
-
404
- false
405
240
  end
406
241
 
407
242
  # Resets the password to a random friendly token.
@@ -410,20 +245,20 @@ module Authlogic
410
245
  self.password = friendly_token
411
246
  self.password_confirmation = friendly_token if self.class.require_password_confirmation
412
247
  end
413
- alias_method :randomize_password, :reset_password
248
+ alias randomize_password reset_password
414
249
 
415
250
  # Resets the password to a random friendly token and then saves the record.
416
251
  def reset_password!
417
252
  reset_password
418
253
  save_without_session_maintenance(validate: false)
419
254
  end
420
- alias_method :randomize_password!, :reset_password!
255
+ alias randomize_password! reset_password!
421
256
 
422
257
  private
423
258
 
424
259
  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")
260
+ if check_against_database && send("will_save_change_to_#{crypted_password_field}?")
261
+ send("#{crypted_password_field}_in_database")
427
262
  else
428
263
  send(crypted_password_field)
429
264
  end
@@ -439,53 +274,28 @@ module Authlogic
439
274
 
440
275
  # Returns an array of arguments to be passed to a crypto provider, either its
441
276
  # `matches?` or its `encrypt` method.
442
- def encrypt_arguments(raw_password, check_against_database, arguments_type = nil)
277
+ def encrypt_arguments(raw_password, check_against_database)
443
278
  salt = nil
444
279
  if password_salt_field
445
280
  salt =
446
- if check_against_database && send("#{password_salt_field}_changed?")
447
- send("#{password_salt_field}_was")
281
+ if check_against_database && send("will_save_change_to_#{password_salt_field}?")
282
+ send("#{password_salt_field}_in_database")
448
283
  else
449
284
  send(password_salt_field)
450
285
  end
451
286
  end
452
-
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}"
460
- end
287
+ [raw_password, salt].compact
461
288
  end
462
289
 
463
290
  # 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
- )
291
+ def encryptor_matches?(crypted, encryptor, attempted_password, check_against_database)
292
+ encryptor_args = encrypt_arguments(attempted_password, check_against_database)
483
293
  encryptor.matches?(crypted, *encryptor_args)
484
294
  end
485
295
 
486
296
  # Determines if we need to transition the password.
487
297
  #
488
- # - If the index > 0 then we are using an "transition from" crypto
298
+ # - If the index > 0 then we are using a "transition from" crypto
489
299
  # provider.
490
300
  # - If the encryptor has a cost and the cost it outdated.
491
301
  # - If we aren't using database values
@@ -499,7 +309,7 @@ module Authlogic
499
309
  ) &&
500
310
  (
501
311
  !check_against_database ||
502
- !send("#{crypted_password_field}_changed?")
312
+ !send("will_save_change_to_#{crypted_password_field}?")
503
313
  )
504
314
  end
505
315
 
@@ -509,6 +319,7 @@ module Authlogic
509
319
  end
510
320
 
511
321
  def require_password?
322
+ # this is _not_ the activemodel changed? method, see below
512
323
  new_record? || password_changed? || send(crypted_password_field).blank?
513
324
  end
514
325
 
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  module ActsAsAuthentic
3
5
  # This provides a handy token that is "perishable", meaning the token is
@@ -33,7 +35,7 @@ module Authlogic
33
35
  10.minutes.to_i
34
36
  )
35
37
  end
36
- alias_method :perishable_token_valid_for=, :perishable_token_valid_for
38
+ alias perishable_token_valid_for= perishable_token_valid_for
37
39
 
38
40
  # Authlogic tries to expire and change the perishable token as much as
39
41
  # possible, without compromising its purpose. If you want to manage it
@@ -44,7 +46,7 @@ module Authlogic
44
46
  def disable_perishable_token_maintenance(value = nil)
45
47
  rw_config(:disable_perishable_token_maintenance, value, false)
46
48
  end
47
- alias_method :disable_perishable_token_maintenance=, :disable_perishable_token_maintenance
49
+ alias disable_perishable_token_maintenance= disable_perishable_token_maintenance
48
50
  end
49
51
 
50
52
  # All methods relating to the perishable token.
@@ -56,12 +58,13 @@ module Authlogic
56
58
  extend ClassMethods
57
59
  include InstanceMethods
58
60
 
59
- validates_uniqueness_of :perishable_token, if: :perishable_token_changed?
61
+ validates_uniqueness_of :perishable_token, case_sensitive: true,
62
+ if: :will_save_change_to_perishable_token?
60
63
  before_save :reset_perishable_token, unless: :disable_perishable_token_maintenance?
61
64
  end
62
65
  end
63
66
 
64
- # Class methods for the perishable token
67
+ # :nodoc:
65
68
  module ClassMethods
66
69
  # Use this method to find a record with a perishable token. This
67
70
  # method does 2 things for you:
@@ -94,7 +97,7 @@ module Authlogic
94
97
  end
95
98
  end
96
99
 
97
- # Instance level methods for the perishable token.
100
+ # :nodoc:
98
101
  module InstanceMethods
99
102
  # Resets the perishable token to a random friendly token.
100
103
  def reset_perishable_token
@@ -1,3 +1,5 @@
1
+ # frozen_string_literal: true
2
+
1
3
  module Authlogic
2
4
  module ActsAsAuthentic
3
5
  # Maintains the persistence token, the token responsible for persisting sessions. This token
@@ -16,19 +18,23 @@ module Authlogic
16
18
  extend ClassMethods
17
19
  include InstanceMethods
18
20
 
21
+ # If the table does not have a password column, then
22
+ # `after_password_set` etc. will not be defined. See
23
+ # `Authlogic::ActsAsAuthentic::Password::Callbacks.included`
19
24
  if respond_to?(:after_password_set) && respond_to?(:after_password_verification)
20
25
  after_password_set :reset_persistence_token
21
26
  after_password_verification :reset_persistence_token!, if: :reset_persistence_token?
22
27
  end
23
28
 
24
29
  validates_presence_of :persistence_token
25
- validates_uniqueness_of :persistence_token, if: :persistence_token_changed?
30
+ validates_uniqueness_of :persistence_token, case_sensitive: true,
31
+ if: :will_save_change_to_persistence_token?
26
32
 
27
33
  before_validation :reset_persistence_token, if: :reset_persistence_token?
28
34
  end
29
35
  end
30
36
 
31
- # Class level methods for the persistence token.
37
+ # :nodoc:
32
38
  module ClassMethods
33
39
  # Resets ALL persistence tokens in the database, which will require
34
40
  # all users to re-authenticate.
@@ -38,7 +44,7 @@ module Authlogic
38
44
  end
39
45
  end
40
46
 
41
- # Instance level methods for the persistence token.
47
+ # :nodoc:
42
48
  module InstanceMethods
43
49
  # Resets the persistence_token field to a random hex value.
44
50
  def reset_persistence_token
@@ -50,7 +56,7 @@ module Authlogic
50
56
  reset_persistence_token
51
57
  save_without_session_maintenance(validate: false)
52
58
  end
53
- alias_method :forget!, :reset_persistence_token!
59
+ alias forget! reset_persistence_token!
54
60
 
55
61
  private
56
62
 
@@ -0,0 +1,53 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Authlogic
4
+ module ActsAsAuthentic
5
+ module Queries
6
+ # @api private
7
+ class CaseSensitivity
8
+ E_UNABLE_TO_DETERMINE_SENSITIVITY = <<~EOS
9
+ Authlogic was unable to determine what case-sensitivity to use when
10
+ searching for email/login. To specify a sensitivity, validate the
11
+ uniqueness of the email/login and use the `case_sensitive` option,
12
+ like this:
13
+
14
+ validates :email, uniqueness: { case_sensitive: false }
15
+
16
+ Authlogic will now perform a case-insensitive query.
17
+ EOS
18
+
19
+ # @api private
20
+ def initialize(model_class, attribute)
21
+ @model_class = model_class
22
+ @attribute = attribute.to_sym
23
+ end
24
+
25
+ # @api private
26
+ def sensitive?
27
+ sensitive = uniqueness_validator_options[:case_sensitive]
28
+ if sensitive.nil?
29
+ ::Kernel.warn(E_UNABLE_TO_DETERMINE_SENSITIVITY)
30
+ false
31
+ else
32
+ sensitive
33
+ end
34
+ end
35
+
36
+ private
37
+
38
+ # @api private
39
+ def uniqueness_validator
40
+ @model_class.validators.select { |v|
41
+ v.is_a?(::ActiveRecord::Validations::UniquenessValidator) &&
42
+ v.attributes == [@attribute]
43
+ }.first
44
+ end
45
+
46
+ # @api private
47
+ def uniqueness_validator_options
48
+ uniqueness_validator&.options || {}
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end