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