root/trunk/radiant/app/models/user.rb

Revision 857, 2.3 kB (checked in by seancribbs, 4 months ago)

Add per-user salting to password encryption.

Line 
1 require 'digest/sha1'
2
3 class User < ActiveRecord::Base
4  
5   # Default Order
6   order_by 'name'
7  
8   # Associations
9   belongs_to :created_by, :class_name => 'User'
10   belongs_to :updated_by, :class_name => 'User'
11  
12   # Validations
13   validates_uniqueness_of :login, :message => 'login already in use'
14  
15   validates_confirmation_of :password, :message => 'must match confirmation', :if => :confirm_password?
16  
17   validates_presence_of :name, :login, :message => 'required'
18   validates_presence_of :password, :password_confirmation, :message => 'required', :if => :new_record?
19  
20   validates_format_of :email, :message => 'invalid e-mail address', :allow_nil => true, :with => /^$|^([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})$/i
21  
22   validates_length_of :name, :maximum => 100, :allow_nil => true, :message => '%d-character limit'
23   validates_length_of :login, :within => 3..40, :allow_nil => true, :too_long => '%d-character limit', :too_short => '%d-character minimum'
24   validates_length_of :password, :within => 5..40, :allow_nil => true, :too_long => '%d-character limit', :too_short => '%d-character minimum', :if => :validate_length_of_password?
25   validates_length_of :email, :maximum => 255, :allow_nil => true, :message => '%d-character limit'
26  
27   validates_numericality_of :id, :only_integer => true, :allow_nil => true, :message => 'must be a number'
28    
29   attr_writer :confirm_password
30  
31   def sha1(phrase)
32     Digest::SHA1.hexdigest("--#{salt}--#{phrase}--")
33   end
34  
35   def self.authenticate(login, password)
36     user = find_by_login(login)
37     user if user && user.password == user.sha1(password)
38   end
39  
40   def after_initialize
41     @confirm_password = true
42   end
43  
44   def confirm_password?
45     @confirm_password
46   end
47  
48   private
49  
50     def validate_length_of_password?
51       new_record? or not password.to_s.empty?
52     end
53  
54     before_create :encrypt_password
55     def encrypt_password
56       self.salt = Digest::SHA1.hexdigest("--#{Time.now}--#{login}--sweet harmonious biscuits--")
57       self.password = sha1(password)
58     end
59  
60     before_update :encrypt_password_unless_empty_or_unchanged
61     def encrypt_password_unless_empty_or_unchanged
62       user = self.class.find(self.id)
63       case password
64       when ''
65         self.password = user.password
66       when user.password 
67       else
68         encrypt_password
69       end
70     end
71
72 end
Note: See TracBrowser for help on using the browser.