user.rb
2.93 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
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
require 'digest/sha1'
# User models the system users, and is generated by the acts_as_authenticated
# Rails generator.
class User < ActiveRecord::Base
after_create do |user|
Person.create!(:identifier => user.login, :name => user.login, :user_id => user.id)
end
has_one :person
# Virtual attribute for the unencrypted password
attr_accessor :password
validates_presence_of :login, :email
validates_format_of :login, :with => Profile::IDENTIFIER_FORMAT
validates_presence_of :password, :if => :password_required?
validates_presence_of :password_confirmation, :if => :password_required?
validates_length_of :password, :within => 4..40, :if => :password_required?
validates_confirmation_of :password, :if => :password_required?
validates_length_of :login, :within => 2..40
validates_length_of :email, :within => 3..100
validates_uniqueness_of :login, :email, :case_sensitive => false
before_save :encrypt_password
# Authenticates a user by their login name and unencrypted password. Returns the user or nil.
def self.authenticate(login, password)
u = find_by_login(login) # need to get the salt
u && u.authenticated?(password) ? u : nil
end
# Encrypts some data with the salt.
def self.encrypt(password, salt)
Digest::SHA1.hexdigest("--#{salt}--#{password}--")
end
# Encrypts the password with the user salt
def encrypt(password)
self.class.encrypt(password, salt)
end
def authenticated?(password)
crypted_password == encrypt(password)
end
def remember_token?
remember_token_expires_at && Time.now.utc < remember_token_expires_at
end
# These create and unset the fields required for remembering users between browser closes
def remember_me
self.remember_token_expires_at = 2.weeks.from_now.utc
self.remember_token = encrypt("#{email}--#{remember_token_expires_at}")
save(false)
end
def forget_me
self.remember_token_expires_at = nil
self.remember_token = nil
save(false)
end
# Exception thrown when #change_password! is called with a wrong current
# password
class IncorrectPassword < Exception; end
# Changes the password of a user.
#
# * Raises IncorrectPassword if <tt>current</tt> is different from the user's
# current password.
# * Saves the record unless it is a new one.
def change_password!(current, new, confirmation)
raise IncorrectPassword unless self.authenticated?(current)
self.password = new
self.password_confirmation = confirmation
unless new_record?
save!
end
end
protected
# before filter
def encrypt_password
return if password.blank?
self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record?
self.crypted_password = encrypt(password)
end
def password_required?
crypted_password.blank? || !password.blank?
end
end