20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
|
# File 'lib/authlogic/orm_adapters/active_record_adapter/acts_as_authentic/credentials.rb', line 20
def acts_as_authentic_with_credentials(options = {})
acts_as_authentic_without_credentials(options)
if options[:validate_fields]
email_name_regex = '[\w\.%\+\-]+'
domain_head_regex = '(?:[A-Z0-9\-]+\.)+'
domain_tld_regex = '(?:[A-Z]{2}|aero|ag|asia|at|be|biz|ca|cc|cn|com|de|edu|eu|fm|gov|gs|jobs|jp|in|info|me|mil|mobi|museum|ms|name|net|nu|nz|org|tc|tw|tv|uk|us|vg|ws)'
email_field_regex ||= /\A#{email_name_regex}@#{domain_head_regex}#{domain_tld_regex}\z/i
if options[:validate_login_field]
case options[:login_field_type]
when :email
validates_length_of options[:login_field], sanitize_validation_length_options({:within => 6..100}, options[:login_field_validates_length_of_options])
validates_format_of options[:login_field], {:with => email_field_regex, :message => I18n.t('error_messages.email_invalid', :default => "should look like an email address.")}.merge(options[:login_field_validates_format_of_options])
else
validates_length_of options[:login_field], sanitize_validation_length_options({:within => 2..100}, options[:login_field_validates_length_of_options])
validates_format_of options[:login_field], {:with => /\A\w[\w\.\-_@ ]+\z/, :message => I18n.t('error_messages.login_invalid', :default => "should use only letters, numbers, spaces, and .-_@ please.")}.merge(options[:login_field_validates_format_of_options])
end
validates_uniqueness_of options[:login_field], {:allow_blank => true}.merge(options[:login_field_validates_uniqueness_of_options].merge(:if => "#{options[:login_field]}_changed?".to_sym))
end
if options[:validate_password_field]
validates_length_of options[:password_field], sanitize_validation_length_options({:minimum => 4}, options[:password_field_validates_length_of_options].merge(:if => "validate_#{options[:password_field]}?".to_sym))
validates_confirmation_of options[:password_field], options[:password_field_validates_confirmation_of_options].merge(:if => "#{options[:password_salt_field]}_changed?".to_sym)
validates_presence_of "#{options[:password_field]}_confirmation", options[:password_confirmation_field_validates_presence_of_options].merge(:if => "#{options[:password_salt_field]}_changed?".to_sym)
end
if options[:validate_email_field] && options[:email_field]
validates_length_of options[:email_field], sanitize_validation_length_options({:within => 6..100}, options[:email_field_validates_length_of_options])
validates_format_of options[:email_field], {:with => email_field_regex, :message => I18n.t('error_messages.email_invalid', :default => "should look like an email address.")}.merge(options[:email_field_validates_format_of_options])
validates_uniqueness_of options[:email_field], options[:email_field_validates_uniqueness_of_options].merge(:if => "#{options[:email_field]}_changed?".to_sym)
end
end
attr_accessor "validate_#{options[:password_field]}".to_sym
attr_reader options[:password_field]
class_eval <<-"end_eval", __FILE__, __LINE__
def self.friendly_unique_token
chars = ("a".."z").to_a + ("A".."Z").to_a + ("0".."9").to_a
newpass = ""
1.upto(20) { |i| newpass << chars[rand(chars.size-1)] }
newpass
end
def #{options[:password_field]}=(pass)
return if pass.blank?
@#{options[:password_field]} = pass
self.#{options[:password_salt_field]} = self.class.unique_token
self.#{options[:crypted_password_field]} = #{options[:crypto_provider]}.encrypt(*encrypt_arguments(@#{options[:password_field]}, #{options[:act_like_restful_authentication].inspect} ? :restful_authentication : nil))
end
def valid_#{options[:password_field]}?(attempted_password)
return false if attempted_password.blank? || #{options[:crypted_password_field]}.blank? || #{options[:password_salt_field]}.blank?
([#{options[:crypto_provider]}] + #{options[:transition_from_crypto_provider].inspect}).each_with_index do |encryptor, index|
# The arguments_type of for the transitioning from restful_authentication
arguments_type = (#{options[:act_like_restful_authentication].inspect} && index == 0) ||
(#{options[:transition_from_restful_authentication].inspect} && index > 0 && encryptor == Authlogic::CryptoProviders::Sha1) ?
:restful_authentication : nil
if encryptor.matches?(#{options[:crypted_password_field]}, *encrypt_arguments(attempted_password, arguments_type))
# If we are transitioning from an older encryption algorithm and the password is still using the old algorithm
# then let's reset the password using the new algorithm. If the algorithm has a cost (BCrypt) and the cost has changed, update the password with
# the new cost.
if index > 0 || (encryptor.respond_to?(:cost_matches?) && !encryptor.cost_matches?(#{options[:crypted_password_field]}))
self.password = attempted_password
save(false)
end
return true
end
end
false
end
def reset_#{options[:password_field]}
friendly_token = self.class.friendly_unique_token
self.#{options[:password_field]} = friendly_token
self.#{options[:password_field]}_confirmation = friendly_token
end
alias_method :randomize_#{options[:password_field]}, :reset_#{options[:password_field]}
def confirm_#{options[:password_field]}
raise "confirm_#{options[:password_field]} has been removed, please use #{options[:password_field]}_confirmation. " +
"As this is the field that ActiveRecord automatically creates with validates_confirmation_of."
end
def reset_#{options[:password_field]}!
reset_#{options[:password_field]}
save_without_session_maintenance(false)
end
alias_method :randomize_#{options[:password_field]}!, :reset_#{options[:password_field]}!
def validate_#{options[:password_field]}?
case #{options[:password_field_validates_length_of_options][:if].inspect}
when String
return false if !eval('#{options[:password_field_validates_length_of_options][:if]}')
when Symbol
return false if !send(#{options[:password_field_validates_length_of_options][:if].inspect})
end
new_record? || #{options[:password_salt_field]}_changed? || #{options[:crypted_password_field]}.blank? || ["true", "1", "yes"].include?(validate_#{options[:password_field]}.to_s)
end
private
def encrypt_arguments(raw_password, arguments_type = nil)
case arguments_type
when :restful_authentication
[REST_AUTH_SITE_KEY, #{options[:password_salt_field]}, raw_password, REST_AUTH_SITE_KEY]
else
[raw_password, #{options[:password_salt_field]}]
end
end
end_eval
end
|