| Class | Account |
| In: |
app/models/account.rb
|
| Parent: | ActiveRecord::Base |
| password | [RW] |
Authenticates a user by their login name and password. Returns the user or nil.
# File app/models/account.rb, line 68
68: def self.authenticate(login, password)
69: if a = find(:first, :conditions => ['login = ? and enabled = ? and activated_at IS NOT NULL', login, true]) # need to get the salt
70: if a.authenticated?(password)
71: a.last_authenticated_at, a.last_authenticated_with_yubikey = Time.now, a.authenticated_with_yubikey?
72: a.save(false)
73: a
74: end
75: end
76: end
Encrypts some data with the salt.
# File app/models/account.rb, line 79
79: def self.encrypt(password, salt)
80: Digest::SHA1.hexdigest("--#{salt}--#{password}--")
81: end
Finds the user with the corresponding activation code, activates their account and returns the user.
Raises:
# File app/models/account.rb, line 38
38: def self.find_and_activate!(activation_code)
39: raise ArgumentError if activation_code.nil?
40: user = find_by_activation_code(activation_code)
41: raise ActivationCodeNotFound unless user
42: raise AlreadyActivated.new(user) if user.active?
43: user.send(:activate!)
44: user
45: end
The existence of an activation code means they have not activated yet
# File app/models/account.rb, line 52
52: def active?
53: activation_code.nil?
54: end
# File app/models/account.rb, line 110
110: def associate_with_yubikey(otp)
111: if Account.verify_yubico_otp(otp)
112: self.yubico_identity = Account.extract_yubico_identity_from_otp(otp)
113: save(false)
114: else
115: false
116: end
117: end
# File app/models/account.rb, line 88
88: def authenticated?(password)
89: if password.length < 50
90: encrypt(password) == crypted_password
91: else
92: password, yubico_otp = Account.split_password_and_yubico_otp(password)
93: encrypt(password) == crypted_password && @authenticated_with_yubikey = yubikey_authenticated?(yubico_otp)
94: end
95: end
# File app/models/account.rb, line 106
106: def authenticated_with_yubikey?
107: @authenticated_with_yubikey || false
108: end
# File app/models/account.rb, line 165
165: def disable!
166: update_attribute(:enabled, false)
167: end
Encrypts the password with the user salt
# File app/models/account.rb, line 84
84: def encrypt(password)
85: self.class.encrypt(password, salt)
86: end
# File app/models/account.rb, line 138
138: def forget_me
139: self.remember_token_expires_at = nil
140: self.remember_token = nil
141: save(false)
142: end
# File app/models/account.rb, line 144
144: def forgot_password!
145: @forgotten_password = true
146: self.make_password_reset_code
147: self.save
148: end
Does the user have the possibility to authenticate with a one time password?
# File app/models/account.rb, line 62
62: def has_otp_device?
63: !yubico_identity.nil?
64: end
True if the user has just been activated
# File app/models/account.rb, line 57
57: def pending?
58: @activated
59: end
# File app/models/account.rb, line 157
157: def recently_forgot_password?
158: @forgotten_password
159: end
# File app/models/account.rb, line 161
161: def recently_reset_password?
162: @reset_password
163: end
These create and unset the fields required for remembering users between browser closes
# File app/models/account.rb, line 124
124: def remember_me
125: remember_me_for 2.weeks
126: end
# File app/models/account.rb, line 128
128: def remember_me_for(time)
129: remember_me_until time.from_now.utc
130: end
# File app/models/account.rb, line 132
132: def remember_me_until(time)
133: self.remember_token_expires_at = time
134: self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
135: save(false)
136: end
# File app/models/account.rb, line 119
119: def remember_token?
120: remember_token_expires_at && Time.now.utc < remember_token_expires_at
121: end
First update the password_reset_code before setting the reset_password flag to avoid duplicate email notifications.
# File app/models/account.rb, line 152
152: def reset_password
153: update_attribute(:password_reset_code, nil)
154: @reset_password = true
155: end
Is the Yubico OTP valid and belongs to this account?
# File app/models/account.rb, line 98
98: def yubikey_authenticated?(otp)
99: if yubico_identity? && Account.verify_yubico_otp(otp)
100: (Account.extract_yubico_identity_from_otp(otp) == yubico_identity)
101: else
102: false
103: end
104: end
# File app/models/account.rb, line 171
171: def encrypt_password
172: return if password.blank?
173: self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
174: self.crypted_password = encrypt(password)
175: end
# File app/models/account.rb, line 181
181: def make_activation_code
182: self.activation_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
183: end
# File app/models/account.rb, line 185
185: def make_password_reset_code
186: self.password_reset_code = Digest::SHA1.hexdigest( Time.now.to_s.split(//).sort_by {rand}.join )
187: end