authlogic 3.4.6 → 3.5.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 +4 -4
- data/.gitignore +2 -0
- data/.rubocop.yml +33 -0
- data/.rubocop_todo.yml +427 -0
- data/.travis.yml +24 -3
- data/CHANGELOG.md +9 -2
- data/CONTRIBUTING.md +40 -1
- data/Gemfile +1 -1
- data/README.md +295 -0
- data/Rakefile +10 -2
- data/authlogic.gemspec +6 -5
- data/lib/authlogic.rb +2 -2
- data/lib/authlogic/acts_as_authentic/base.rb +2 -2
- data/lib/authlogic/acts_as_authentic/email.rb +59 -14
- data/lib/authlogic/acts_as_authentic/logged_in_status.rb +4 -3
- data/lib/authlogic/acts_as_authentic/login.rb +62 -12
- data/lib/authlogic/acts_as_authentic/magic_columns.rb +17 -6
- data/lib/authlogic/acts_as_authentic/password.rb +107 -53
- data/lib/authlogic/acts_as_authentic/persistence_token.rb +10 -9
- data/lib/authlogic/acts_as_authentic/restful_authentication.rb +2 -0
- data/lib/authlogic/acts_as_authentic/session_maintenance.rb +48 -35
- data/lib/authlogic/acts_as_authentic/single_access_token.rb +19 -15
- data/lib/authlogic/acts_as_authentic/validations_scope.rb +2 -2
- data/lib/authlogic/authenticates_many/association.rb +6 -5
- data/lib/authlogic/authenticates_many/base.rb +22 -12
- data/lib/authlogic/config.rb +2 -1
- data/lib/authlogic/controller_adapters/abstract_adapter.rb +2 -1
- data/lib/authlogic/controller_adapters/rack_adapter.rb +3 -4
- data/lib/authlogic/controller_adapters/rails_adapter.rb +26 -14
- data/lib/authlogic/controller_adapters/sinatra_adapter.rb +1 -1
- data/lib/authlogic/crypto_providers/aes256.rb +16 -12
- data/lib/authlogic/crypto_providers/bcrypt.rb +10 -4
- data/lib/authlogic/crypto_providers/md5.rb +7 -7
- data/lib/authlogic/crypto_providers/scrypt.rb +10 -2
- data/lib/authlogic/crypto_providers/sha1.rb +3 -3
- data/lib/authlogic/crypto_providers/sha256.rb +3 -3
- data/lib/authlogic/crypto_providers/sha512.rb +4 -4
- data/lib/authlogic/crypto_providers/wordpress.rb +13 -13
- data/lib/authlogic/i18n.rb +22 -16
- data/lib/authlogic/i18n/translator.rb +1 -1
- data/lib/authlogic/random.rb +13 -12
- data/lib/authlogic/regex.rb +3 -3
- data/lib/authlogic/session/activation.rb +7 -6
- data/lib/authlogic/session/active_record_trickery.rb +1 -2
- data/lib/authlogic/session/base.rb +7 -6
- data/lib/authlogic/session/brute_force_protection.rb +58 -34
- data/lib/authlogic/session/callbacks.rb +16 -12
- data/lib/authlogic/session/cookies.rb +29 -14
- data/lib/authlogic/session/existence.rb +10 -10
- data/lib/authlogic/session/foundation.rb +11 -7
- data/lib/authlogic/session/http_auth.rb +6 -5
- data/lib/authlogic/session/id.rb +5 -4
- data/lib/authlogic/session/klass.rb +2 -1
- data/lib/authlogic/session/magic_columns.rb +21 -14
- data/lib/authlogic/session/magic_states.rb +25 -14
- data/lib/authlogic/session/params.rb +41 -26
- data/lib/authlogic/session/password.rb +62 -40
- data/lib/authlogic/session/perishable_token.rb +3 -2
- data/lib/authlogic/session/persistence.rb +3 -3
- data/lib/authlogic/session/priority_record.rb +5 -4
- data/lib/authlogic/session/scopes.rb +20 -9
- data/lib/authlogic/session/session.rb +9 -4
- data/lib/authlogic/session/timeout.rb +40 -23
- data/lib/authlogic/session/unauthorized_record.rb +6 -5
- data/lib/authlogic/session/validation.rb +18 -9
- data/lib/authlogic/test_case.rb +2 -2
- data/lib/authlogic/test_case/mock_controller.rb +9 -9
- data/lib/authlogic/test_case/mock_cookie_jar.rb +2 -2
- data/lib/authlogic/test_case/mock_logger.rb +1 -1
- data/lib/authlogic/test_case/mock_request.rb +2 -1
- data/lib/authlogic/test_case/rails_request_adapter.rb +5 -5
- data/test/acts_as_authentic_test/email_test.rb +29 -17
- data/test/acts_as_authentic_test/logged_in_status_test.rb +9 -3
- data/test/acts_as_authentic_test/login_test.rb +47 -13
- data/test/acts_as_authentic_test/magic_columns_test.rb +4 -4
- data/test/acts_as_authentic_test/password_test.rb +31 -21
- data/test/acts_as_authentic_test/perishable_token_test.rb +15 -15
- data/test/acts_as_authentic_test/session_maintenance_test.rb +20 -13
- data/test/acts_as_authentic_test/single_access_test.rb +8 -8
- data/test/authenticates_many_test.rb +4 -4
- data/test/crypto_provider_test/aes256_test.rb +2 -2
- data/test/crypto_provider_test/scrypt_test.rb +1 -1
- data/test/crypto_provider_test/sha1_test.rb +3 -3
- data/test/crypto_provider_test/sha256_test.rb +1 -1
- data/test/crypto_provider_test/sha512_test.rb +2 -2
- data/test/gemfiles/Gemfile.rails-3.2.x +2 -2
- data/test/gemfiles/Gemfile.rails-5.0.x +6 -0
- data/test/i18n_test.rb +5 -5
- data/test/libs/affiliate.rb +2 -2
- data/test/libs/company.rb +1 -1
- data/test/libs/employee.rb +2 -2
- data/test/libs/employee_session.rb +1 -1
- data/test/libs/ldaper.rb +1 -1
- data/test/libs/project.rb +1 -1
- data/test/random_test.rb +5 -4
- data/test/session_test/activation_test.rb +5 -5
- data/test/session_test/active_record_trickery_test.rb +7 -5
- data/test/session_test/cookies_test.rb +8 -6
- data/test/session_test/existence_test.rb +19 -13
- data/test/session_test/http_auth_test.rb +0 -3
- data/test/session_test/id_test.rb +2 -2
- data/test/session_test/klass_test.rb +1 -1
- data/test/session_test/magic_columns_test.rb +0 -3
- data/test/session_test/magic_states_test.rb +11 -11
- data/test/session_test/params_test.rb +10 -10
- data/test/session_test/password_test.rb +4 -5
- data/test/session_test/perishability_test.rb +3 -3
- data/test/session_test/scopes_test.rb +8 -8
- data/test/session_test/session_test.rb +5 -4
- data/test/session_test/timeout_test.rb +8 -8
- data/test/session_test/unauthorized_record_test.rb +2 -2
- data/test/session_test/validation_test.rb +3 -3
- data/test/test_helper.rb +9 -5
- metadata +54 -24
- data/README.rdoc +0 -232
data/lib/authlogic.rb
CHANGED
@@ -55,5 +55,5 @@ path = File.dirname(__FILE__) + "/authlogic/"
|
|
55
55
|
require path + library
|
56
56
|
end
|
57
57
|
|
58
|
-
require path + "controller_adapters/rails_adapter" if defined?(
|
59
|
-
require path + "controller_adapters/sinatra_adapter" if defined?(
|
58
|
+
require path + "controller_adapters/rails_adapter" if defined?(Rails)
|
59
|
+
require path + "controller_adapters/sinatra_adapter" if defined?(Sinatra)
|
@@ -67,11 +67,12 @@ module Authlogic
|
|
67
67
|
end
|
68
68
|
|
69
69
|
private
|
70
|
+
|
70
71
|
def db_setup?
|
71
72
|
begin
|
72
73
|
column_names
|
73
74
|
true
|
74
|
-
rescue
|
75
|
+
rescue StandardError
|
75
76
|
false
|
76
77
|
end
|
77
78
|
end
|
@@ -99,4 +100,3 @@ end
|
|
99
100
|
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::SessionMaintenance
|
100
101
|
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::SingleAccessToken
|
101
102
|
::ActiveRecord::Base.send :include, Authlogic::ActsAsAuthentic::ValidationsScope
|
102
|
-
|
@@ -41,11 +41,11 @@ module Authlogic
|
|
41
41
|
# * <tt>Default:</tt> {:maximum => 100}
|
42
42
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
|
43
43
|
def validates_length_of_email_field_options(value = nil)
|
44
|
-
rw_config(:validates_length_of_email_field_options, value, {:maximum => 100})
|
44
|
+
rw_config(:validates_length_of_email_field_options, value, { :maximum => 100 })
|
45
45
|
end
|
46
46
|
alias_method :validates_length_of_email_field_options=, :validates_length_of_email_field_options
|
47
47
|
|
48
|
-
# A convenience function to merge options into the validates_length_of_email_field_options. So
|
48
|
+
# A convenience function to merge options into the validates_length_of_email_field_options. So instead of:
|
49
49
|
#
|
50
50
|
# self.validates_length_of_email_field_options = validates_length_of_email_field_options.merge(:my_option => my_value)
|
51
51
|
#
|
@@ -56,19 +56,46 @@ module Authlogic
|
|
56
56
|
self.validates_length_of_email_field_options = validates_length_of_email_field_options.merge(options)
|
57
57
|
end
|
58
58
|
|
59
|
-
# A hash of options for the validates_format_of call for the email
|
59
|
+
# A hash of options for the validates_format_of call for the email
|
60
|
+
# field. Allows you to change this however you want.
|
60
61
|
#
|
61
|
-
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as
|
62
|
-
#
|
63
|
-
#
|
62
|
+
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as
|
63
|
+
# possible, so you can completely replace the hash or merge options into
|
64
|
+
# it. Checkout the convenience function
|
65
|
+
# merge_validates_format_of_email_field_options to merge options.</b>
|
66
|
+
#
|
67
|
+
# To validate international email addresses, enable the provided
|
68
|
+
# alternate regex:
|
64
69
|
#
|
65
|
-
# To validate international email addresses, enable the provided alternate regex:
|
66
70
|
# * <tt>validates_format_of_email_field_options({:with => Authlogic::Regex.email_nonascii})</tt>
|
67
71
|
#
|
68
|
-
# * <tt>Default:</tt>
|
72
|
+
# * <tt>Default:</tt>
|
73
|
+
#
|
74
|
+
# {
|
75
|
+
# :with => Authlogic::Regex.email,
|
76
|
+
# :message => Proc.new {
|
77
|
+
# I18n.t(
|
78
|
+
# 'error_messages.email_invalid',
|
79
|
+
# :default => "should look like an email address."
|
80
|
+
# )
|
81
|
+
# }
|
82
|
+
# }
|
83
|
+
#
|
69
84
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_format_of
|
70
85
|
def validates_format_of_email_field_options(value = nil)
|
71
|
-
rw_config(
|
86
|
+
rw_config(
|
87
|
+
:validates_format_of_email_field_options,
|
88
|
+
value,
|
89
|
+
{
|
90
|
+
:with => Authlogic::Regex.email,
|
91
|
+
:message => Proc.new do
|
92
|
+
I18n.t(
|
93
|
+
'error_messages.email_invalid',
|
94
|
+
:default => "should look like an email address."
|
95
|
+
)
|
96
|
+
end
|
97
|
+
}
|
98
|
+
)
|
72
99
|
end
|
73
100
|
alias_method :validates_format_of_email_field_options=, :validates_format_of_email_field_options
|
74
101
|
|
@@ -77,16 +104,34 @@ module Authlogic
|
|
77
104
|
self.validates_format_of_email_field_options = validates_format_of_email_field_options.merge(options)
|
78
105
|
end
|
79
106
|
|
80
|
-
# A hash of options for the validates_uniqueness_of call for the email
|
107
|
+
# A hash of options for the validates_uniqueness_of call for the email
|
108
|
+
# field. Allows you to change this however you want.
|
81
109
|
#
|
82
|
-
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as
|
83
|
-
#
|
110
|
+
# <b>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_uniqueness_of_email_field_options to merge
|
84
114
|
# options.</b>
|
85
115
|
#
|
86
|
-
# * <tt>Default:</tt>
|
116
|
+
# * <tt>Default:</tt>
|
117
|
+
#
|
118
|
+
# {
|
119
|
+
# :case_sensitive => false,
|
120
|
+
# :scope => validations_scope,
|
121
|
+
# :if => "#{email_field}_changed?".to_sym
|
122
|
+
# }
|
123
|
+
#
|
87
124
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_uniqueness_of
|
88
125
|
def validates_uniqueness_of_email_field_options(value = nil)
|
89
|
-
rw_config(
|
126
|
+
rw_config(
|
127
|
+
:validates_uniqueness_of_email_field_options,
|
128
|
+
value,
|
129
|
+
{
|
130
|
+
:case_sensitive => false,
|
131
|
+
:scope => validations_scope,
|
132
|
+
:if => "#{email_field}_changed?".to_sym
|
133
|
+
}
|
134
|
+
)
|
90
135
|
end
|
91
136
|
alias_method :validates_uniqueness_of_email_field_options=, :validates_uniqueness_of_email_field_options
|
92
137
|
|
@@ -31,8 +31,8 @@ module Authlogic
|
|
31
31
|
|
32
32
|
klass.class_eval do
|
33
33
|
include InstanceMethods
|
34
|
-
scope :logged_in, lambda{ where("last_request_at > ? and current_login_at IS NOT NULL", logged_in_timeout.seconds.ago) }
|
35
|
-
scope :logged_out, lambda{ where("last_request_at is NULL or last_request_at <= ?", logged_in_timeout.seconds.ago) }
|
34
|
+
scope :logged_in, lambda { where("last_request_at > ? and current_login_at IS NOT NULL", logged_in_timeout.seconds.ago) }
|
35
|
+
scope :logged_out, lambda { where("last_request_at is NULL or last_request_at <= ?", logged_in_timeout.seconds.ago) }
|
36
36
|
end
|
37
37
|
end
|
38
38
|
|
@@ -49,6 +49,7 @@ module Authlogic
|
|
49
49
|
end
|
50
50
|
|
51
51
|
private
|
52
|
+
|
52
53
|
def logged_in_timeout
|
53
54
|
self.class.logged_in_timeout
|
54
55
|
end
|
@@ -56,4 +57,4 @@ module Authlogic
|
|
56
57
|
end
|
57
58
|
end
|
58
59
|
end
|
59
|
-
end
|
60
|
+
end
|
@@ -38,7 +38,7 @@ module Authlogic
|
|
38
38
|
# * <tt>Default:</tt> {:within => 3..100}
|
39
39
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
|
40
40
|
def validates_length_of_login_field_options(value = nil)
|
41
|
-
rw_config(:validates_length_of_login_field_options, value, {:within => 3..100})
|
41
|
+
rw_config(:validates_length_of_login_field_options, value, { :within => 3..100 })
|
42
42
|
end
|
43
43
|
alias_method :validates_length_of_login_field_options=, :validates_length_of_login_field_options
|
44
44
|
|
@@ -59,10 +59,31 @@ module Authlogic
|
|
59
59
|
# merge options into it. Checkout the convenience function merge_validates_format_of_login_field_options to merge
|
60
60
|
# options.</b>
|
61
61
|
#
|
62
|
-
# * <tt>Default:</tt>
|
62
|
+
# * <tt>Default:</tt>
|
63
|
+
#
|
64
|
+
# {
|
65
|
+
# :with => Authlogic::Regex.login,
|
66
|
+
# :message => lambda {
|
67
|
+
# I18n.t(
|
68
|
+
# 'error_messages.login_invalid',
|
69
|
+
# :default => "should use only letters, numbers, spaces, and .-_@+ please."
|
70
|
+
# )
|
71
|
+
# }
|
72
|
+
# }
|
73
|
+
#
|
63
74
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_format_of
|
64
75
|
def validates_format_of_login_field_options(value = nil)
|
65
|
-
rw_config(
|
76
|
+
rw_config(
|
77
|
+
:validates_format_of_login_field_options,
|
78
|
+
value,
|
79
|
+
{
|
80
|
+
:with => Authlogic::Regex.login,
|
81
|
+
:message => I18n.t(
|
82
|
+
'error_messages.login_invalid',
|
83
|
+
:default => "should use only letters, numbers, spaces, and .-_@+ please."
|
84
|
+
)
|
85
|
+
}
|
86
|
+
)
|
66
87
|
end
|
67
88
|
alias_method :validates_format_of_login_field_options=, :validates_format_of_login_field_options
|
68
89
|
|
@@ -71,16 +92,33 @@ module Authlogic
|
|
71
92
|
self.validates_format_of_login_field_options = validates_format_of_login_field_options.merge(options)
|
72
93
|
end
|
73
94
|
|
74
|
-
# A hash of options for the validates_uniqueness_of call for the login
|
95
|
+
# A hash of options for the validates_uniqueness_of call for the login
|
96
|
+
# field. Allows you to change this however you want.
|
75
97
|
#
|
76
|
-
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as
|
77
|
-
#
|
78
|
-
#
|
98
|
+
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as
|
99
|
+
# possible, so you can completely replace the hash or merge options into
|
100
|
+
# it. Checkout the convenience function
|
101
|
+
# merge_validates_format_of_login_field_options to merge options.</b>
|
102
|
+
#
|
103
|
+
# * <tt>Default:</tt>
|
104
|
+
#
|
105
|
+
# {
|
106
|
+
# :case_sensitive => false,
|
107
|
+
# :scope => validations_scope,
|
108
|
+
# :if => "#{login_field}_changed?".to_sym
|
109
|
+
# }
|
79
110
|
#
|
80
|
-
# * <tt>Default:</tt> {:case_sensitive => false, :scope => validations_scope, :if => "#{login_field}_changed?".to_sym}
|
81
111
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_uniqueness_of
|
82
112
|
def validates_uniqueness_of_login_field_options(value = nil)
|
83
|
-
rw_config(
|
113
|
+
rw_config(
|
114
|
+
:validates_uniqueness_of_login_field_options,
|
115
|
+
value,
|
116
|
+
{
|
117
|
+
:case_sensitive => false,
|
118
|
+
:scope => validations_scope,
|
119
|
+
:if => "#{login_field}_changed?".to_sym
|
120
|
+
}
|
121
|
+
)
|
84
122
|
end
|
85
123
|
alias_method :validates_uniqueness_of_login_field_options=, :validates_uniqueness_of_login_field_options
|
86
124
|
|
@@ -112,18 +150,30 @@ module Authlogic
|
|
112
150
|
end
|
113
151
|
|
114
152
|
private
|
153
|
+
|
115
154
|
def find_with_case(field, value, sensitivity = true)
|
155
|
+
ar_gem_version = Gem::Version.new(ActiveRecord::VERSION::STRING)
|
156
|
+
|
116
157
|
relation = if not sensitivity
|
117
158
|
connection.case_insensitive_comparison(arel_table, field.to_s, columns_hash[field.to_s], value)
|
159
|
+
elsif ar_gem_version >= Gem::Version.new('5.0')
|
160
|
+
connection.case_sensitive_comparison(arel_table, field.to_s, columns_hash[field.to_s], value)
|
118
161
|
else
|
119
|
-
if
|
162
|
+
if ar_gem_version < Gem::Version.new('4.2')
|
120
163
|
value = connection.case_sensitive_modifier(value)
|
121
164
|
else
|
122
165
|
value = connection.case_sensitive_modifier(value, field.to_s)
|
123
166
|
end
|
124
|
-
|
167
|
+
arel_table[field.to_s].eq(value)
|
168
|
+
end
|
169
|
+
|
170
|
+
# bind value in rails 5
|
171
|
+
if ar_gem_version >= Gem::Version.new('5')
|
172
|
+
bind = ActiveRecord::Relation::QueryAttribute.new(field.to_s, value, ActiveRecord::Type::Value.new)
|
173
|
+
where(relation, bind).first
|
174
|
+
else
|
175
|
+
where(relation).first
|
125
176
|
end
|
126
|
-
where(relation).first
|
127
177
|
end
|
128
178
|
end
|
129
179
|
|
@@ -1,21 +1,32 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ActsAsAuthentic
|
3
|
-
# Magic columns are like ActiveRecord's created_at and updated_at columns. They are
|
4
|
-
# you. Authlogic has the same thing, but these are
|
5
|
-
#
|
3
|
+
# Magic columns are like ActiveRecord's created_at and updated_at columns. They are
|
4
|
+
# "magically" maintained for you. Authlogic has the same thing, but these are
|
5
|
+
# maintained on the session side. Please see Authlogic::Session::MagicColumns for more
|
6
|
+
# details. This module merely adds validations for the magic columns if they exist.
|
6
7
|
module MagicColumns
|
7
8
|
def self.included(klass)
|
8
9
|
klass.class_eval do
|
9
10
|
add_acts_as_authentic_module(Methods)
|
10
11
|
end
|
11
12
|
end
|
12
|
-
|
13
|
+
|
13
14
|
# Methods relating to the magic columns
|
14
15
|
module Methods
|
15
16
|
def self.included(klass)
|
16
17
|
klass.class_eval do
|
17
|
-
|
18
|
-
|
18
|
+
if column_names.include?("login_count")
|
19
|
+
validates_numericality_of :login_count,
|
20
|
+
:only_integer => true,
|
21
|
+
:greater_than_or_equal_to => 0,
|
22
|
+
:allow_nil => true
|
23
|
+
end
|
24
|
+
if column_names.include?("failed_login_count")
|
25
|
+
validates_numericality_of :failed_login_count,
|
26
|
+
:only_integer => true,
|
27
|
+
:greater_than_or_equal_to => 0,
|
28
|
+
:allow_nil => true
|
29
|
+
end
|
19
30
|
end
|
20
31
|
end
|
21
32
|
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
module Authlogic
|
2
2
|
module ActsAsAuthentic
|
3
|
-
# This module has a lot of neat functionality. It is responsible for encrypting your
|
4
|
-
# It can also help you transition to a new
|
3
|
+
# This module has a lot of neat functionality. It is responsible for encrypting your
|
4
|
+
# password, salting it, and verifying it. It can also help you transition to a new
|
5
|
+
# encryption algorithm. See the Config sub module for configuration options.
|
5
6
|
module Password
|
6
7
|
def self.included(klass)
|
7
8
|
klass.class_eval do
|
@@ -18,7 +19,11 @@ module Authlogic
|
|
18
19
|
# * <tt>Default:</tt> :crypted_password, :encrypted_password, :password_hash, or :pw_hash
|
19
20
|
# * <tt>Accepts:</tt> Symbol
|
20
21
|
def crypted_password_field(value = nil)
|
21
|
-
rw_config(
|
22
|
+
rw_config(
|
23
|
+
:crypted_password_field,
|
24
|
+
value,
|
25
|
+
first_column_to_exist(nil, :crypted_password, :encrypted_password, :password_hash, :pw_hash)
|
26
|
+
)
|
22
27
|
end
|
23
28
|
alias_method :crypted_password_field=, :crypted_password_field
|
24
29
|
|
@@ -27,12 +32,16 @@ module Authlogic
|
|
27
32
|
# * <tt>Default:</tt> :password_salt, :pw_salt, :salt, nil if none exist
|
28
33
|
# * <tt>Accepts:</tt> Symbol
|
29
34
|
def password_salt_field(value = nil)
|
30
|
-
rw_config(
|
35
|
+
rw_config(
|
36
|
+
:password_salt_field,
|
37
|
+
value,
|
38
|
+
first_column_to_exist(nil, :password_salt, :pw_salt, :salt)
|
39
|
+
)
|
31
40
|
end
|
32
41
|
alias_method :password_salt_field=, :password_salt_field
|
33
42
|
|
34
|
-
# Whether or not to require a password confirmation. If you don't want your users
|
35
|
-
# just set this to false.
|
43
|
+
# Whether or not to require a password confirmation. If you don't want your users
|
44
|
+
# to confirm their password just set this to false.
|
36
45
|
#
|
37
46
|
# * <tt>Default:</tt> true
|
38
47
|
# * <tt>Accepts:</tt> Boolean
|
@@ -41,14 +50,17 @@ module Authlogic
|
|
41
50
|
end
|
42
51
|
alias_method :require_password_confirmation=, :require_password_confirmation
|
43
52
|
|
44
|
-
# By default passwords are required when a record is new or the crypted_password
|
45
|
-
# are met a password is not required. In
|
53
|
+
# By default passwords are required when a record is new or the crypted_password
|
54
|
+
# is blank, but if both of these things are met a password is not required. In
|
55
|
+
# this case, blank passwords are ignored.
|
46
56
|
#
|
47
|
-
# Think about a profile page, where the user can edit all of their information,
|
48
|
-
# If they do not want to change their password
|
49
|
-
#
|
50
|
-
#
|
51
|
-
#
|
57
|
+
# Think about a profile page, where the user can edit all of their information,
|
58
|
+
# including changing their password. If they do not want to change their password
|
59
|
+
# they just leave the fields blank. This will try to set the password to a blank
|
60
|
+
# value, in which case is incorrect behavior. As such, Authlogic ignores this. But
|
61
|
+
# let's say you have a completely separate page for resetting passwords, you might
|
62
|
+
# not want to ignore blank passwords. If this is the case for you, then just set
|
63
|
+
# this value to false.
|
52
64
|
#
|
53
65
|
# * <tt>Default:</tt> true
|
54
66
|
# * <tt>Accepts:</tt> Boolean
|
@@ -57,15 +69,16 @@ module Authlogic
|
|
57
69
|
end
|
58
70
|
alias_method :ignore_blank_passwords=, :ignore_blank_passwords
|
59
71
|
|
60
|
-
# When calling valid_password?("some pass") do you want to check that password
|
61
|
-
# the database. Take this example:
|
72
|
+
# When calling valid_password?("some pass") do you want to check that password
|
73
|
+
# against what's in that object or whats in the database. Take this example:
|
62
74
|
#
|
63
75
|
# u = User.first
|
64
76
|
# u.password = "new pass"
|
65
77
|
# u.valid_password?("old pass")
|
66
78
|
#
|
67
|
-
# Should the last line above return true or false? The record hasn't been saved
|
68
|
-
# Other would assume false. So I let you decide by
|
79
|
+
# Should the last line above return true or false? The record hasn't been saved
|
80
|
+
# yet, so most would assume true. Other would assume false. So I let you decide by
|
81
|
+
# giving you this option.
|
69
82
|
#
|
70
83
|
# * <tt>Default:</tt> true
|
71
84
|
# * <tt>Accepts:</tt> Boolean
|
@@ -83,22 +96,26 @@ module Authlogic
|
|
83
96
|
end
|
84
97
|
alias_method :validate_password_field=, :validate_password_field
|
85
98
|
|
86
|
-
# A hash of options for the validates_length_of call for the password field.
|
99
|
+
# A hash of options for the validates_length_of call for the password field.
|
100
|
+
# Allows you to change this however you want.
|
87
101
|
#
|
88
|
-
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
|
89
|
-
# merge options into it. Checkout the
|
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
|
90
105
|
# options.</b>
|
91
106
|
#
|
92
|
-
# * <tt>Default:</tt> {:minimum =>
|
107
|
+
# * <tt>Default:</tt> {:minimum => 8, :if => :require_password?}
|
93
108
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
|
94
109
|
def validates_length_of_password_field_options(value = nil)
|
95
|
-
rw_config(:validates_length_of_password_field_options, value, {:minimum =>
|
110
|
+
rw_config(:validates_length_of_password_field_options, value, { :minimum => 8, :if => :require_password? })
|
96
111
|
end
|
97
112
|
alias_method :validates_length_of_password_field_options=, :validates_length_of_password_field_options
|
98
113
|
|
99
|
-
# A convenience function to merge options into the
|
114
|
+
# A convenience function to merge options into the
|
115
|
+
# validates_length_of_login_field_options. So instead of:
|
100
116
|
#
|
101
|
-
# self.validates_length_of_password_field_options =
|
117
|
+
# self.validates_length_of_password_field_options =
|
118
|
+
# validates_length_of_password_field_options.merge(:my_option => my_value)
|
102
119
|
#
|
103
120
|
# You can do this:
|
104
121
|
#
|
@@ -107,44 +124,56 @@ module Authlogic
|
|
107
124
|
self.validates_length_of_password_field_options = validates_length_of_password_field_options.merge(options)
|
108
125
|
end
|
109
126
|
|
110
|
-
# A hash of options for the validates_confirmation_of call for the password field.
|
127
|
+
# A hash of options for the validates_confirmation_of call for the password field.
|
128
|
+
# Allows you to change this however you want.
|
111
129
|
#
|
112
|
-
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
|
113
|
-
# merge options into it. Checkout the
|
130
|
+
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
|
131
|
+
# you can completely replace the hash or merge options into it. Checkout the
|
132
|
+
# convenience function merge_validates_length_of_password_field_options to merge
|
114
133
|
# options.</b>
|
115
134
|
#
|
116
135
|
# * <tt>Default:</tt> {:if => :require_password?}
|
117
136
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_confirmation_of
|
118
137
|
def validates_confirmation_of_password_field_options(value = nil)
|
119
|
-
rw_config(:validates_confirmation_of_password_field_options, value, {:if => :require_password?})
|
138
|
+
rw_config(:validates_confirmation_of_password_field_options, value, { :if => :require_password? })
|
120
139
|
end
|
121
140
|
alias_method :validates_confirmation_of_password_field_options=, :validates_confirmation_of_password_field_options
|
122
141
|
|
123
|
-
# See merge_validates_length_of_password_field_options. The same thing, except for
|
142
|
+
# See merge_validates_length_of_password_field_options. The same thing, except for
|
143
|
+
# validates_confirmation_of_password_field_options
|
124
144
|
def merge_validates_confirmation_of_password_field_options(options = {})
|
125
145
|
self.validates_confirmation_of_password_field_options = validates_confirmation_of_password_field_options.merge(options)
|
126
146
|
end
|
127
147
|
|
128
|
-
# A hash of options for the validates_length_of call for the password_confirmation
|
148
|
+
# A hash of options for the validates_length_of call for the password_confirmation
|
149
|
+
# field. Allows you to change this however you want.
|
129
150
|
#
|
130
|
-
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
|
131
|
-
# merge options into it. Checkout the
|
151
|
+
# <b>Keep in mind this is ruby. I wanted to keep this as flexible as possible, so
|
152
|
+
# you can completely replace the hash or merge options into it. Checkout the
|
153
|
+
# convenience function merge_validates_length_of_password_field_options to merge
|
132
154
|
# options.</b>
|
133
155
|
#
|
134
156
|
# * <tt>Default:</tt> validates_length_of_password_field_options
|
135
157
|
# * <tt>Accepts:</tt> Hash of options accepted by validates_length_of
|
136
158
|
def validates_length_of_password_confirmation_field_options(value = nil)
|
137
|
-
rw_config(
|
159
|
+
rw_config(
|
160
|
+
:validates_length_of_password_confirmation_field_options,
|
161
|
+
value,
|
162
|
+
validates_length_of_password_field_options
|
163
|
+
)
|
138
164
|
end
|
139
165
|
alias_method :validates_length_of_password_confirmation_field_options=, :validates_length_of_password_confirmation_field_options
|
140
166
|
|
141
|
-
# See merge_validates_length_of_password_field_options. The same thing, except for
|
167
|
+
# See merge_validates_length_of_password_field_options. The same thing, except for
|
168
|
+
# validates_length_of_password_confirmation_field_options
|
142
169
|
def merge_validates_length_of_password_confirmation_field_options(options = {})
|
143
|
-
self.validates_length_of_password_confirmation_field_options =
|
170
|
+
self.validates_length_of_password_confirmation_field_options =
|
171
|
+
validates_length_of_password_confirmation_field_options.merge(options)
|
144
172
|
end
|
145
173
|
|
146
|
-
# The class you want to use to encrypt and verify your encrypted passwords. See
|
147
|
-
# on the available methods and
|
174
|
+
# The class you want to use to encrypt and verify your encrypted passwords. See
|
175
|
+
# the Authlogic::CryptoProviders module for more info on the available methods and
|
176
|
+
# how to create your own.
|
148
177
|
#
|
149
178
|
# * <tt>Default:</tt> CryptoProviders::SCrypt
|
150
179
|
# * <tt>Accepts:</tt> Class
|
@@ -153,14 +182,17 @@ module Authlogic
|
|
153
182
|
end
|
154
183
|
alias_method :crypto_provider=, :crypto_provider
|
155
184
|
|
156
|
-
# Let's say you originally encrypted your passwords with Sha1. Sha1 is starting to
|
157
|
-
#
|
158
|
-
#
|
159
|
-
#
|
160
|
-
#
|
185
|
+
# Let's say you originally encrypted your passwords with Sha1. Sha1 is starting to
|
186
|
+
# join the party with MD5 and you want to switch to something stronger. No
|
187
|
+
# problem, just specify your new and improved algorithm with the crypt_provider
|
188
|
+
# option and then let Authlogic know you are transitioning from Sha1 using this
|
189
|
+
# option. Authlogic will take care of everything, including transitioning your
|
190
|
+
# users to the new algorithm. The next time a user logs in, they will be granted
|
191
|
+
# access using the old algorithm and their password will be resaved with the new
|
192
|
+
# algorithm. All new users will obviously use the new algorithm as well.
|
161
193
|
#
|
162
|
-
# Lastly, if you want to transition again, you can pass an array of crypto
|
163
|
-
# as you want.
|
194
|
+
# Lastly, if you want to transition again, you can pass an array of crypto
|
195
|
+
# providers. So you can transition from as many algorithms as you want.
|
164
196
|
#
|
165
197
|
# * <tt>Default:</tt> nil
|
166
198
|
# * <tt>Accepts:</tt> Class or Array
|
@@ -194,6 +226,7 @@ module Authlogic
|
|
194
226
|
end
|
195
227
|
|
196
228
|
private
|
229
|
+
|
197
230
|
METHODS.each do |method|
|
198
231
|
class_eval <<-"end_eval", __FILE__, __LINE__
|
199
232
|
def #{method}
|
@@ -230,23 +263,36 @@ module Authlogic
|
|
230
263
|
@password
|
231
264
|
end
|
232
265
|
|
233
|
-
# This is a virtual method. Once a password is passed to it, it will
|
234
|
-
# the password.
|
266
|
+
# This is a virtual method. Once a password is passed to it, it will
|
267
|
+
# create new password salt as well as encrypt the password.
|
235
268
|
def password=(pass)
|
236
269
|
return if ignore_blank_passwords? && pass.blank?
|
237
270
|
before_password_set
|
238
271
|
@password = pass
|
239
272
|
send("#{password_salt_field}=", Authlogic::Random.friendly_token) if password_salt_field
|
240
|
-
send(
|
273
|
+
send(
|
274
|
+
"#{crypted_password_field}=",
|
275
|
+
crypto_provider.encrypt(
|
276
|
+
*encrypt_arguments(@password, false, act_like_restful_authentication? ? :restful_authentication : nil)
|
277
|
+
)
|
278
|
+
)
|
241
279
|
@password_changed = true
|
242
280
|
after_password_set
|
243
281
|
end
|
244
282
|
|
245
|
-
# Accepts a raw password to determine if it is the correct password or not.
|
246
|
-
#
|
247
|
-
#
|
283
|
+
# Accepts a raw password to determine if it is the correct password or not.
|
284
|
+
# Notice the second argument. That defaults to the value of
|
285
|
+
# check_passwords_against_database. See that method for more information, but
|
286
|
+
# basically it just tells Authlogic to check the password against the value in
|
287
|
+
# the database or the value in the object.
|
248
288
|
def valid_password?(attempted_password, check_against_database = check_passwords_against_database?)
|
249
|
-
crypted =
|
289
|
+
crypted =
|
290
|
+
if check_against_database && send("#{crypted_password_field}_changed?")
|
291
|
+
send("#{crypted_password_field}_was")
|
292
|
+
else
|
293
|
+
send(crypted_password_field)
|
294
|
+
end
|
295
|
+
|
250
296
|
return false if attempted_password.blank? || crypted.blank?
|
251
297
|
before_password_verification
|
252
298
|
|
@@ -282,6 +328,7 @@ module Authlogic
|
|
282
328
|
alias_method :randomize_password!, :reset_password!
|
283
329
|
|
284
330
|
private
|
331
|
+
|
285
332
|
def check_passwords_against_database?
|
286
333
|
self.class.check_passwords_against_database == true
|
287
334
|
end
|
@@ -292,7 +339,14 @@ module Authlogic
|
|
292
339
|
|
293
340
|
def encrypt_arguments(raw_password, check_against_database, arguments_type = nil)
|
294
341
|
salt = nil
|
295
|
-
|
342
|
+
if password_salt_field
|
343
|
+
salt =
|
344
|
+
if check_against_database && send("#{password_salt_field}_changed?")
|
345
|
+
send("#{password_salt_field}_was")
|
346
|
+
else
|
347
|
+
send(password_salt_field)
|
348
|
+
end
|
349
|
+
end
|
296
350
|
|
297
351
|
case arguments_type
|
298
352
|
when :restful_authentication
|
@@ -302,7 +356,7 @@ module Authlogic
|
|
302
356
|
end
|
303
357
|
end
|
304
358
|
|
305
|
-
# Determines if we need to
|
359
|
+
# Determines if we need to transition the password.
|
306
360
|
# If the index > 0 then we are using an "transition from" crypto provider.
|
307
361
|
# If the encryptor has a cost and the cost it outdated.
|
308
362
|
# If we aren't using database values
|