authlogic 4.5.0 → 6.4.2
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.
- checksums.yaml +4 -4
- data/lib/authlogic/acts_as_authentic/base.rb +19 -19
- data/lib/authlogic/acts_as_authentic/email.rb +3 -170
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +3 -1
- data/lib/authlogic/acts_as_authentic/login.rb +7 -174
- data/lib/authlogic/acts_as_authentic/magic_columns.rb +7 -4
- data/lib/authlogic/acts_as_authentic/password.rb +67 -256
- data/lib/authlogic/acts_as_authentic/perishable_token.rb +8 -5
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -4
- data/lib/authlogic/acts_as_authentic/queries/case_sensitivity.rb +53 -0
- data/lib/authlogic/acts_as_authentic/queries/find_with_case.rb +36 -20
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +12 -8
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +10 -8
- data/lib/authlogic/config.rb +9 -1
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +28 -4
- data/lib/authlogic/controller_adapters/rack_adapter.rb +2 -0
- data/lib/authlogic/controller_adapters/rails_adapter.rb +7 -30
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +6 -0
- data/lib/authlogic/cookie_credentials.rb +63 -0
- data/lib/authlogic/crypto_providers/bcrypt.rb +3 -3
- data/lib/authlogic/crypto_providers/md5/v2.rb +35 -0
- data/lib/authlogic/crypto_providers/md5.rb +6 -6
- data/lib/authlogic/crypto_providers/scrypt.rb +2 -0
- data/lib/authlogic/crypto_providers/sha1/v2.rb +41 -0
- data/lib/authlogic/crypto_providers/sha1.rb +7 -6
- data/lib/authlogic/crypto_providers/sha256/v2.rb +58 -0
- data/lib/authlogic/crypto_providers/sha256.rb +5 -0
- data/lib/authlogic/crypto_providers/sha512/v2.rb +39 -0
- data/lib/authlogic/crypto_providers/sha512.rb +9 -5
- data/lib/authlogic/crypto_providers.rb +5 -20
- data/lib/authlogic/errors.rb +50 -0
- data/lib/authlogic/i18n/translator.rb +4 -1
- data/lib/authlogic/i18n.rb +3 -1
- data/lib/authlogic/random.rb +2 -0
- data/lib/authlogic/session/base.rb +2197 -39
- data/lib/authlogic/session/magic_column/assigns_last_request_at.rb +46 -0
- data/lib/authlogic/test_case/mock_api_controller.rb +52 -0
- data/lib/authlogic/test_case/mock_controller.rb +3 -1
- data/lib/authlogic/test_case/mock_cookie_jar.rb +32 -6
- data/lib/authlogic/test_case/mock_logger.rb +2 -0
- data/lib/authlogic/test_case/mock_request.rb +12 -0
- data/lib/authlogic/test_case/rails_request_adapter.rb +9 -1
- data/lib/authlogic/test_case.rb +5 -0
- data/lib/authlogic/version.rb +2 -1
- data/lib/authlogic.rb +5 -28
- metadata +175 -200
- data/.github/ISSUE_TEMPLATE/bug_report.md +0 -28
- data/.github/ISSUE_TEMPLATE/feature_proposal.md +0 -32
- data/.github/triage.md +0 -86
- data/.gitignore +0 -15
- data/.rubocop.yml +0 -133
- data/.rubocop_todo.yml +0 -74
- data/.travis.yml +0 -24
- data/CHANGELOG.md +0 -348
- data/CONTRIBUTING.md +0 -91
- data/Gemfile +0 -6
- data/LICENSE +0 -20
- data/README.md +0 -448
- data/Rakefile +0 -21
- data/UPGRADING.md +0 -22
- data/authlogic.gemspec +0 -40
- data/doc/use_normal_rails_validation.md +0 -82
- data/gemfiles/Gemfile.rails-4.2.x +0 -6
- data/gemfiles/Gemfile.rails-5.1.x +0 -6
- data/gemfiles/Gemfile.rails-5.2.x +0 -6
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +0 -106
- data/lib/authlogic/acts_as_authentic/validations_scope.rb +0 -35
- data/lib/authlogic/authenticates_many/association.rb +0 -50
- data/lib/authlogic/authenticates_many/base.rb +0 -81
- data/lib/authlogic/crypto_providers/aes256.rb +0 -71
- data/lib/authlogic/crypto_providers/wordpress.rb +0 -72
- data/lib/authlogic/regex.rb +0 -79
- data/lib/authlogic/session/activation.rb +0 -73
- data/lib/authlogic/session/active_record_trickery.rb +0 -65
- data/lib/authlogic/session/brute_force_protection.rb +0 -127
- data/lib/authlogic/session/callbacks.rb +0 -153
- data/lib/authlogic/session/cookies.rb +0 -329
- data/lib/authlogic/session/existence.rb +0 -103
- data/lib/authlogic/session/foundation.rb +0 -105
- data/lib/authlogic/session/http_auth.rb +0 -107
- data/lib/authlogic/session/id.rb +0 -53
- data/lib/authlogic/session/klass.rb +0 -73
- data/lib/authlogic/session/magic_columns.rb +0 -119
- data/lib/authlogic/session/magic_states.rb +0 -82
- data/lib/authlogic/session/params.rb +0 -130
- data/lib/authlogic/session/password.rb +0 -318
- data/lib/authlogic/session/perishable_token.rb +0 -24
- data/lib/authlogic/session/persistence.rb +0 -77
- data/lib/authlogic/session/priority_record.rb +0 -38
- data/lib/authlogic/session/scopes.rb +0 -138
- data/lib/authlogic/session/session.rb +0 -77
- data/lib/authlogic/session/timeout.rb +0 -103
- data/lib/authlogic/session/unauthorized_record.rb +0 -56
- data/lib/authlogic/session/validation.rb +0 -93
- data/test/acts_as_authentic_test/base_test.rb +0 -27
- data/test/acts_as_authentic_test/email_test.rb +0 -241
- data/test/acts_as_authentic_test/logged_in_status_test.rb +0 -64
- data/test/acts_as_authentic_test/login_test.rb +0 -153
- data/test/acts_as_authentic_test/magic_columns_test.rb +0 -29
- data/test/acts_as_authentic_test/password_test.rb +0 -263
- data/test/acts_as_authentic_test/perishable_token_test.rb +0 -98
- data/test/acts_as_authentic_test/persistence_token_test.rb +0 -62
- data/test/acts_as_authentic_test/restful_authentication_test.rb +0 -48
- data/test/acts_as_authentic_test/session_maintenance_test.rb +0 -150
- data/test/acts_as_authentic_test/single_access_test.rb +0 -46
- data/test/adapter_test.rb +0 -23
- data/test/authenticates_many_test.rb +0 -33
- data/test/config_test.rb +0 -38
- data/test/crypto_provider_test/aes256_test.rb +0 -16
- data/test/crypto_provider_test/bcrypt_test.rb +0 -16
- data/test/crypto_provider_test/scrypt_test.rb +0 -16
- data/test/crypto_provider_test/sha1_test.rb +0 -25
- data/test/crypto_provider_test/sha256_test.rb +0 -16
- data/test/crypto_provider_test/sha512_test.rb +0 -16
- data/test/crypto_provider_test/wordpress_test.rb +0 -26
- data/test/fixtures/companies.yml +0 -5
- data/test/fixtures/employees.yml +0 -17
- data/test/fixtures/projects.yml +0 -3
- data/test/fixtures/users.yml +0 -41
- data/test/i18n/lol.yml +0 -4
- data/test/i18n_test.rb +0 -35
- data/test/libs/affiliate.rb +0 -9
- data/test/libs/company.rb +0 -8
- data/test/libs/employee.rb +0 -9
- data/test/libs/employee_session.rb +0 -4
- data/test/libs/ldaper.rb +0 -5
- data/test/libs/project.rb +0 -5
- data/test/libs/user.rb +0 -9
- data/test/libs/user_session.rb +0 -27
- data/test/random_test.rb +0 -15
- data/test/session_test/activation_test.rb +0 -45
- data/test/session_test/active_record_trickery_test.rb +0 -78
- data/test/session_test/brute_force_protection_test.rb +0 -110
- data/test/session_test/callbacks_test.rb +0 -42
- data/test/session_test/cookies_test.rb +0 -244
- data/test/session_test/credentials_test.rb +0 -0
- data/test/session_test/existence_test.rb +0 -88
- data/test/session_test/foundation_test.rb +0 -24
- data/test/session_test/http_auth_test.rb +0 -60
- data/test/session_test/id_test.rb +0 -19
- data/test/session_test/klass_test.rb +0 -42
- data/test/session_test/magic_columns_test.rb +0 -62
- data/test/session_test/magic_states_test.rb +0 -60
- data/test/session_test/params_test.rb +0 -61
- data/test/session_test/password_test.rb +0 -107
- data/test/session_test/perishability_test.rb +0 -17
- data/test/session_test/persistence_test.rb +0 -35
- data/test/session_test/scopes_test.rb +0 -68
- data/test/session_test/session_test.rb +0 -80
- data/test/session_test/timeout_test.rb +0 -84
- data/test/session_test/unauthorized_record_test.rb +0 -15
- data/test/session_test/validation_test.rb +0 -25
- 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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
#
|
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>
|
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
|
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
|
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
|
-
|
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
|
-
|
285
|
-
|
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.
|
293
|
-
|
294
|
-
|
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
|
-
|
359
|
-
|
360
|
-
|
361
|
-
|
362
|
-
|
363
|
-
|
364
|
-
|
365
|
-
|
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
|
-
|
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
|
-
|
388
|
-
|
389
|
-
|
390
|
-
|
391
|
-
|
392
|
-
|
393
|
-
|
394
|
-
|
395
|
-
|
396
|
-
|
397
|
-
|
398
|
-
|
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
|
-
|
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
|
-
|
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}
|
426
|
-
send("#{crypted_password_field}
|
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
|
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}
|
447
|
-
send("#{password_salt_field}
|
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
|
-
|
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
|
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}
|
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
|
-
|
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
|
-
|
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,
|
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
|
-
#
|
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
|
-
#
|
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,
|
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
|
-
#
|
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
|
-
#
|
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
|
-
|
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
|