[1] | 1 | require 'digest/sha1' |
---|
| 2 | class User < ActiveRecord::Base |
---|
| 3 | # Virtual attribute for the unencrypted password |
---|
| 4 | attr_accessor :password |
---|
| 5 | |
---|
| 6 | validates_presence_of :login, :email |
---|
| 7 | validates_presence_of :password, :if => :password_required? |
---|
| 8 | validates_presence_of :password_confirmation, :if => :password_required? |
---|
| 9 | validates_length_of :password, :within => 4..40, :if => :password_required? |
---|
| 10 | validates_confirmation_of :password, :if => :password_required? |
---|
| 11 | validates_length_of :login, :within => 3..40 |
---|
| 12 | validates_length_of :email, :within => 3..100 |
---|
| 13 | validates_uniqueness_of :login, :email, :case_sensitive => false |
---|
| 14 | before_save :encrypt_password |
---|
| 15 | |
---|
| 16 | # return array of roles |
---|
| 17 | def roles |
---|
| 18 | if self.role |
---|
| 19 | self.role.gsub(',',' ').split(' ') |
---|
| 20 | else |
---|
| 21 | [] |
---|
| 22 | end |
---|
| 23 | end |
---|
| 24 | |
---|
| 25 | # Authenticates a user by their login name and unencrypted password. Returns the user or nil. |
---|
| 26 | def self.authenticate(login, password) |
---|
| 27 | u = find_by_login(login) # need to get the salt |
---|
| 28 | u && u.authenticated?(password) ? u : nil |
---|
| 29 | end |
---|
| 30 | |
---|
| 31 | # Encrypts some data with the salt. |
---|
| 32 | def self.encrypt(password, salt) |
---|
| 33 | Digest::SHA1.hexdigest("--#{salt}--#{password}--") |
---|
| 34 | end |
---|
| 35 | |
---|
| 36 | # Encrypts the password with the user salt |
---|
| 37 | def encrypt(password) |
---|
| 38 | self.class.encrypt(password, salt) |
---|
| 39 | end |
---|
| 40 | |
---|
| 41 | def authenticated?(password) |
---|
| 42 | crypted_password == encrypt(password) |
---|
| 43 | end |
---|
| 44 | |
---|
| 45 | def remember_token? |
---|
| 46 | remember_token_expires_at && Time.now.utc < remember_token_expires_at |
---|
| 47 | end |
---|
| 48 | |
---|
| 49 | # These create and unset the fields required for remembering users between browser closes |
---|
| 50 | def remember_me |
---|
| 51 | self.remember_token_expires_at = 2.weeks.from_now.utc |
---|
| 52 | self.remember_token = encrypt("#{email}--#{remember_token_expires_at}") |
---|
| 53 | save(false) |
---|
| 54 | end |
---|
| 55 | |
---|
| 56 | def forget_me |
---|
| 57 | self.remember_token_expires_at = nil |
---|
| 58 | self.remember_token = nil |
---|
| 59 | save(false) |
---|
| 60 | end |
---|
| 61 | |
---|
| 62 | protected |
---|
| 63 | # before filter |
---|
| 64 | def encrypt_password |
---|
| 65 | return if password.blank? |
---|
| 66 | self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{login}--") if new_record? |
---|
| 67 | self.crypted_password = encrypt(password) |
---|
| 68 | end |
---|
| 69 | |
---|
| 70 | def password_required? |
---|
| 71 | crypted_password.blank? || !password.blank? |
---|
| 72 | end |
---|
| 73 | end |
---|