authlogic 4.4.2 → 5.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 (146) hide show
  1. checksums.yaml +4 -4
  2. data/lib/authlogic/acts_as_authentic/base.rb +3 -18
  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 +54 -253
  8. data/lib/authlogic/acts_as_authentic/perishable_token.rb +7 -5
  9. data/lib/authlogic/acts_as_authentic/persistence_token.rb +9 -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 +17 -22
  12. data/lib/authlogic/acts_as_authentic/session_maintenance.rb +8 -6
  13. data/lib/authlogic/acts_as_authentic/single_access_token.rb +9 -8
  14. data/lib/authlogic/config.rb +9 -1
  15. data/lib/authlogic/controller_adapters/abstract_adapter.rb +7 -4
  16. data/lib/authlogic/controller_adapters/rack_adapter.rb +2 -0
  17. data/lib/authlogic/controller_adapters/rails_adapter.rb +17 -14
  18. data/lib/authlogic/controller_adapters/sinatra_adapter.rb +6 -0
  19. data/lib/authlogic/crypto_providers/bcrypt.rb +3 -3
  20. data/lib/authlogic/crypto_providers/md5.rb +3 -6
  21. data/lib/authlogic/crypto_providers/scrypt.rb +2 -0
  22. data/lib/authlogic/crypto_providers/sha1.rb +4 -6
  23. data/lib/authlogic/crypto_providers/sha256.rb +2 -0
  24. data/lib/authlogic/crypto_providers/sha512.rb +6 -5
  25. data/lib/authlogic/crypto_providers.rb +5 -20
  26. data/lib/authlogic/i18n/translator.rb +3 -0
  27. data/lib/authlogic/i18n.rb +3 -1
  28. data/lib/authlogic/random.rb +2 -0
  29. data/lib/authlogic/session/base.rb +2089 -39
  30. data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
  31. data/lib/authlogic/test_case/mock_controller.rb +2 -0
  32. data/lib/authlogic/test_case/mock_cookie_jar.rb +7 -0
  33. data/lib/authlogic/test_case/mock_logger.rb +2 -0
  34. data/lib/authlogic/test_case/mock_request.rb +2 -0
  35. data/lib/authlogic/test_case/rails_request_adapter.rb +2 -0
  36. data/lib/authlogic/test_case.rb +4 -0
  37. data/lib/authlogic/version.rb +2 -1
  38. data/lib/authlogic.rb +3 -28
  39. metadata +36 -180
  40. data/.github/ISSUE_TEMPLATE/bug_report.md +0 -28
  41. data/.github/ISSUE_TEMPLATE/feature_proposal.md +0 -32
  42. data/.github/triage.md +0 -86
  43. data/.gitignore +0 -15
  44. data/.rubocop.yml +0 -133
  45. data/.rubocop_todo.yml +0 -74
  46. data/.travis.yml +0 -24
  47. data/CHANGELOG.md +0 -326
  48. data/CONTRIBUTING.md +0 -91
  49. data/Gemfile +0 -6
  50. data/LICENSE +0 -20
  51. data/README.md +0 -439
  52. data/Rakefile +0 -21
  53. data/UPGRADING.md +0 -22
  54. data/authlogic.gemspec +0 -40
  55. data/doc/use_normal_rails_validation.md +0 -82
  56. data/gemfiles/Gemfile.rails-4.2.x +0 -6
  57. data/gemfiles/Gemfile.rails-5.1.x +0 -6
  58. data/gemfiles/Gemfile.rails-5.2.x +0 -6
  59. data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -106
  60. data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -35
  61. data/lib/authlogic/authenticates_many/association.rb +0 -50
  62. data/lib/authlogic/authenticates_many/base.rb +0 -81
  63. data/lib/authlogic/crypto_providers/aes256.rb +0 -71
  64. data/lib/authlogic/crypto_providers/wordpress.rb +0 -72
  65. data/lib/authlogic/regex.rb +0 -79
  66. data/lib/authlogic/session/activation.rb +0 -73
  67. data/lib/authlogic/session/active_record_trickery.rb +0 -65
  68. data/lib/authlogic/session/brute_force_protection.rb +0 -127
  69. data/lib/authlogic/session/callbacks.rb +0 -153
  70. data/lib/authlogic/session/cookies.rb +0 -296
  71. data/lib/authlogic/session/existence.rb +0 -103
  72. data/lib/authlogic/session/foundation.rb +0 -105
  73. data/lib/authlogic/session/http_auth.rb +0 -107
  74. data/lib/authlogic/session/id.rb +0 -53
  75. data/lib/authlogic/session/klass.rb +0 -73
  76. data/lib/authlogic/session/magic_columns.rb +0 -119
  77. data/lib/authlogic/session/magic_states.rb +0 -82
  78. data/lib/authlogic/session/params.rb +0 -130
  79. data/lib/authlogic/session/password.rb +0 -318
  80. data/lib/authlogic/session/perishable_token.rb +0 -24
  81. data/lib/authlogic/session/persistence.rb +0 -77
  82. data/lib/authlogic/session/priority_record.rb +0 -38
  83. data/lib/authlogic/session/scopes.rb +0 -138
  84. data/lib/authlogic/session/session.rb +0 -77
  85. data/lib/authlogic/session/timeout.rb +0 -103
  86. data/lib/authlogic/session/unauthorized_record.rb +0 -56
  87. data/lib/authlogic/session/validation.rb +0 -93
  88. data/test/acts_as_authentic_test/base_test.rb +0 -27
  89. data/test/acts_as_authentic_test/email_test.rb +0 -241
  90. data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -64
  91. data/test/acts_as_authentic_test/login_test.rb +0 -153
  92. data/test/acts_as_authentic_test/magic_columns_test.rb +0 -29
  93. data/test/acts_as_authentic_test/password_test.rb +0 -263
  94. data/test/acts_as_authentic_test/perishable_token_test.rb +0 -98
  95. data/test/acts_as_authentic_test/persistence_token_test.rb +0 -62
  96. data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -48
  97. data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -150
  98. data/test/acts_as_authentic_test/single_access_test.rb +0 -46
  99. data/test/adapter_test.rb +0 -23
  100. data/test/authenticates_many_test.rb +0 -33
  101. data/test/config_test.rb +0 -38
  102. data/test/crypto_provider_test/aes256_test.rb +0 -16
  103. data/test/crypto_provider_test/bcrypt_test.rb +0 -16
  104. data/test/crypto_provider_test/scrypt_test.rb +0 -16
  105. data/test/crypto_provider_test/sha1_test.rb +0 -25
  106. data/test/crypto_provider_test/sha256_test.rb +0 -16
  107. data/test/crypto_provider_test/sha512_test.rb +0 -16
  108. data/test/crypto_provider_test/wordpress_test.rb +0 -26
  109. data/test/fixtures/companies.yml +0 -5
  110. data/test/fixtures/employees.yml +0 -17
  111. data/test/fixtures/projects.yml +0 -3
  112. data/test/fixtures/users.yml +0 -41
  113. data/test/i18n/lol.yml +0 -4
  114. data/test/i18n_test.rb +0 -35
  115. data/test/libs/affiliate.rb +0 -9
  116. data/test/libs/company.rb +0 -8
  117. data/test/libs/employee.rb +0 -9
  118. data/test/libs/employee_session.rb +0 -4
  119. data/test/libs/ldaper.rb +0 -5
  120. data/test/libs/project.rb +0 -5
  121. data/test/libs/user.rb +0 -9
  122. data/test/libs/user_session.rb +0 -27
  123. data/test/random_test.rb +0 -15
  124. data/test/session_test/activation_test.rb +0 -45
  125. data/test/session_test/active_record_trickery_test.rb +0 -78
  126. data/test/session_test/brute_force_protection_test.rb +0 -110
  127. data/test/session_test/callbacks_test.rb +0 -42
  128. data/test/session_test/cookies_test.rb +0 -226
  129. data/test/session_test/credentials_test.rb +0 -0
  130. data/test/session_test/existence_test.rb +0 -88
  131. data/test/session_test/foundation_test.rb +0 -24
  132. data/test/session_test/http_auth_test.rb +0 -60
  133. data/test/session_test/id_test.rb +0 -19
  134. data/test/session_test/klass_test.rb +0 -42
  135. data/test/session_test/magic_columns_test.rb +0 -62
  136. data/test/session_test/magic_states_test.rb +0 -60
  137. data/test/session_test/params_test.rb +0 -61
  138. data/test/session_test/password_test.rb +0 -107
  139. data/test/session_test/perishability_test.rb +0 -17
  140. data/test/session_test/persistence_test.rb +0 -35
  141. data/test/session_test/scopes_test.rb +0 -68
  142. data/test/session_test/session_test.rb +0 -80
  143. data/test/session_test/timeout_test.rb +0 -84
  144. data/test/session_test/unauthorized_record_test.rb +0 -15
  145. data/test/session_test/validation_test.rb +0 -25
  146. 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,7 +102,8 @@ 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
+ # Reverisbile 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
@@ -248,7 +115,7 @@ module Authlogic
248
115
  CryptoProviders::Guidance.new(value).impart_wisdom
249
116
  rw_config(:crypto_provider, value, CryptoProviders::SCrypt)
250
117
  end
251
- alias_method :crypto_provider=, :crypto_provider
118
+ alias crypto_provider= crypto_provider
252
119
 
253
120
  # Let's say you originally encrypted your passwords with Sha1. Sha1 is
254
121
  # starting to join the party with MD5 and you want to switch to
@@ -274,46 +141,24 @@ module Authlogic
274
141
  []
275
142
  )
276
143
  end
277
- alias_method :transition_from_crypto_providers=, :transition_from_crypto_providers
144
+ alias transition_from_crypto_providers= transition_from_crypto_providers
278
145
  end
279
146
 
280
147
  # Callbacks / hooks to allow other modules to modify the behavior of this module.
281
148
  module Callbacks
282
149
  # Does the order of this array matter?
283
150
  METHODS = %w[
284
- before_password_set
285
- after_password_set
286
- before_password_verification
287
- after_password_verification
151
+ password_set
152
+ password_verification
288
153
  ].freeze
289
154
 
290
155
  def self.included(klass)
291
156
  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
157
+ klass.send :extend, ActiveModel::Callbacks
158
+ METHODS.each do |method|
159
+ klass.define_model_callbacks method, only: %i[before after]
303
160
  end
304
161
  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
162
  end
318
163
 
319
164
  # The methods related to the password field.
@@ -323,22 +168,6 @@ module Authlogic
323
168
 
324
169
  klass.class_eval do
325
170
  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
171
  after_save :reset_password_changed
343
172
  end
344
173
  end
@@ -355,20 +184,17 @@ module Authlogic
355
184
  # create new password salt as well as encrypt the password.
356
185
  def password=(pass)
357
186
  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)
187
+ run_callbacks :password_set do
188
+ @password = pass
189
+ if password_salt_field
190
+ send("#{password_salt_field}=", Authlogic::Random.friendly_token)
191
+ end
192
+ send(
193
+ "#{crypted_password_field}=",
194
+ crypto_provider.encrypt(*encrypt_arguments(@password, false))
368
195
  )
369
- )
370
- @password_changed = true
371
- after_password_set
196
+ @password_changed = true
197
+ end
372
198
  end
373
199
 
374
200
  # Accepts a raw password to determine if it is the correct password.
@@ -384,24 +210,23 @@ module Authlogic
384
210
  )
385
211
  crypted = crypted_password_to_validate_against(check_against_database)
386
212
  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)
213
+ run_callbacks :password_verification do
214
+ crypto_providers.each_with_index.any? do |encryptor, index|
215
+ if encryptor_matches?(
216
+ crypted,
217
+ encryptor,
218
+ attempted_password,
219
+ check_against_database
220
+ )
221
+ if transition_password?(index, encryptor, check_against_database)
222
+ transition_password(attempted_password)
223
+ end
224
+ true
225
+ else
226
+ false
227
+ end
399
228
  end
400
- after_password_verification
401
- return true
402
229
  end
403
-
404
- false
405
230
  end
406
231
 
407
232
  # Resets the password to a random friendly token.
@@ -410,20 +235,20 @@ module Authlogic
410
235
  self.password = friendly_token
411
236
  self.password_confirmation = friendly_token if self.class.require_password_confirmation
412
237
  end
413
- alias_method :randomize_password, :reset_password
238
+ alias randomize_password reset_password
414
239
 
415
240
  # Resets the password to a random friendly token and then saves the record.
416
241
  def reset_password!
417
242
  reset_password
418
243
  save_without_session_maintenance(validate: false)
419
244
  end
420
- alias_method :randomize_password!, :reset_password!
245
+ alias randomize_password! reset_password!
421
246
 
422
247
  private
423
248
 
424
249
  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")
250
+ if check_against_database && send("will_save_change_to_#{crypted_password_field}?")
251
+ send("#{crypted_password_field}_in_database")
427
252
  else
428
253
  send(crypted_password_field)
429
254
  end
@@ -439,53 +264,28 @@ module Authlogic
439
264
 
440
265
  # Returns an array of arguments to be passed to a crypto provider, either its
441
266
  # `matches?` or its `encrypt` method.
442
- def encrypt_arguments(raw_password, check_against_database, arguments_type = nil)
267
+ def encrypt_arguments(raw_password, check_against_database)
443
268
  salt = nil
444
269
  if password_salt_field
445
270
  salt =
446
- if check_against_database && send("#{password_salt_field}_changed?")
447
- send("#{password_salt_field}_was")
271
+ if check_against_database && send("will_save_change_to_#{password_salt_field}?")
272
+ send("#{password_salt_field}_in_database")
448
273
  else
449
274
  send(password_salt_field)
450
275
  end
451
276
  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
277
+ [raw_password, salt].compact
461
278
  end
462
279
 
463
280
  # 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
- )
281
+ def encryptor_matches?(crypted, encryptor, attempted_password, check_against_database)
282
+ encryptor_args = encrypt_arguments(attempted_password, check_against_database)
483
283
  encryptor.matches?(crypted, *encryptor_args)
484
284
  end
485
285
 
486
286
  # Determines if we need to transition the password.
487
287
  #
488
- # - If the index > 0 then we are using an "transition from" crypto
288
+ # - If the index > 0 then we are using a "transition from" crypto
489
289
  # provider.
490
290
  # - If the encryptor has a cost and the cost it outdated.
491
291
  # - If we aren't using database values
@@ -499,7 +299,7 @@ module Authlogic
499
299
  ) &&
500
300
  (
501
301
  !check_against_database ||
502
- !send("#{crypted_password_field}_changed?")
302
+ !send("will_save_change_to_#{crypted_password_field}?")
503
303
  )
504
304
  end
505
305
 
@@ -509,6 +309,7 @@ module Authlogic
509
309
  end
510
310
 
511
311
  def require_password?
312
+ # this is _not_ the activemodel changed? method, see below
512
313
  new_record? || password_changed? || send(crypted_password_field).blank?
513
314
  end
514
315
 
@@ -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,12 @@ 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, if: :will_save_change_to_perishable_token?
60
62
  before_save :reset_perishable_token, unless: :disable_perishable_token_maintenance?
61
63
  end
62
64
  end
63
65
 
64
- # Class methods for the perishable token
66
+ # :nodoc:
65
67
  module ClassMethods
66
68
  # Use this method to find a record with a perishable token. This
67
69
  # method does 2 things for you:
@@ -94,7 +96,7 @@ module Authlogic
94
96
  end
95
97
  end
96
98
 
97
- # Instance level methods for the perishable token.
99
+ # :nodoc:
98
100
  module InstanceMethods
99
101
  # Resets the perishable token to a random friendly token.
100
102
  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,22 @@ 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, if: :will_save_change_to_persistence_token?
26
31
 
27
32
  before_validation :reset_persistence_token, if: :reset_persistence_token?
28
33
  end
29
34
  end
30
35
 
31
- # Class level methods for the persistence token.
36
+ # :nodoc:
32
37
  module ClassMethods
33
38
  # Resets ALL persistence tokens in the database, which will require
34
39
  # all users to re-authenticate.
@@ -38,7 +43,7 @@ module Authlogic
38
43
  end
39
44
  end
40
45
 
41
- # Instance level methods for the persistence token.
46
+ # :nodoc:
42
47
  module InstanceMethods
43
48
  # Resets the persistence_token field to a random hex value.
44
49
  def reset_persistence_token
@@ -50,7 +55,7 @@ module Authlogic
50
55
  reset_persistence_token
51
56
  save_without_session_maintenance(validate: false)
52
57
  end
53
- alias_method :forget!, :reset_persistence_token!
58
+ alias forget! reset_persistence_token!
54
59
 
55
60
  private
56
61
 
@@ -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
@@ -9,7 +9,7 @@ module Authlogic
9
9
  # Dup ActiveRecord.gem_version before freezing, in case someone
10
10
  # else wants to modify it. Freezing modifies an object in place.
11
11
  # https://github.com/binarylogic/authlogic/pull/590
12
- AR_GEM_VERSION = ActiveRecord.gem_version.dup.freeze
12
+ AR_GEM_VERSION = ::ActiveRecord.gem_version.dup.freeze
13
13
 
14
14
  # @api private
15
15
  def initialize(model_class, field, value, sensitive)
@@ -21,35 +21,30 @@ module Authlogic
21
21
 
22
22
  # @api private
23
23
  def execute
24
- bind(relation).first
24
+ @model_class.where(comparison).first
25
25
  end
26
26
 
27
27
  private
28
28
 
29
29
  # @api private
30
- def bind(relation)
31
- if AR_GEM_VERSION >= Gem::Version.new("5")
32
- bind = ActiveRecord::Relation::QueryAttribute.new(
33
- @field,
34
- @value,
35
- ActiveRecord::Type::Value.new
36
- )
37
- @model_class.where(relation, bind)
38
- else
39
- @model_class.where(relation)
40
- end
30
+ # @return Arel::Nodes::Equality
31
+ def comparison
32
+ @sensitive ? sensitive_comparison : insensitive_comparison
41
33
  end
42
34
 
43
35
  # @api private
44
- def relation
45
- if !@sensitive
46
- @model_class.connection.case_insensitive_comparison(
47
- @model_class.arel_table,
48
- @field,
49
- @model_class.columns_hash[@field],
50
- @value
51
- )
52
- elsif AR_GEM_VERSION >= Gem::Version.new("5.0")
36
+ def insensitive_comparison
37
+ @model_class.connection.case_insensitive_comparison(
38
+ @model_class.arel_table,
39
+ @field,
40
+ @model_class.columns_hash[@field],
41
+ @value
42
+ )
43
+ end
44
+
45
+ # @api private
46
+ def sensitive_comparison
47
+ if AR_GEM_VERSION >= Gem::Version.new("5.0")
53
48
  @model_class.connection.case_sensitive_comparison(
54
49
  @model_class.arel_table,
55
50
  @field,