require 'digest/sha1' class User < ActiveRecord::Base ACCESS_LEVEL_ADMIN = 999 # administrator access ACCESS_LEVEL_DISABLED = 0 # disabled access # validation validates_presence_of :full_name validates_presence_of :email validates_presence_of :time_zone validates_presence_of :login # validates_presence_of :password, :on => :create # validates_length_of :password, :within => 4..40, :on => :create validates_confirmation_of :password, :unless => Proc.new{|user| user.password.blank? } validates_length_of :password_confirmation, :within => 4..40, :unless => Proc.new{|user| user.password.blank? } validates_uniqueness_of :email, :case_sensitive => false, :message=>"alread taken." validates_presence_of :login validates_format_of :login, :with => /\A[a-zA-ZZ0-9._]+\Z/, :unless => Proc.new { |user| user.login.blank? } validates_uniqueness_of :login, :case_sensitive => false, :message=>"alread taken." # anything else you want your user to change should be added here. attr_accessor :password, :old_password attr_accessible :full_name, :login, :email, :time_zone, :password, :password_confirmation, :access_level, :old_password before_create :set_fields_before_create before_save :set_fields_before_save # named scope named_scope :by_email, lambda {|email| {:conditions => ['email = ?', email]} } named_scope :by_login, lambda {|login| {:conditions => ['login = ?', login]} } named_scope :by_ge_email, lambda {|email| {:conditions => ['email >= ?', email]} } named_scope :by_ge_login, lambda {|login| {:conditions => ['login >= ?', login]} } named_scope :by_ge_full_name, lambda {|full_name| {:conditions => ['full_name >= ?', full_name]} } named_scope :by_access_level, lambda {|access_level| {:conditions => ['access_level = ?', access_level]} } named_scope :by_remember_token, lambda {|remember_token| {:conditions => ['remember_token = ?', remember_token]} } named_scope :by_reset_token, lambda {|reset_token| {:conditions => ['reset_token = ?', reset_token]} } named_scope :order_email, :order => 'email ASC' named_scope :order_login, :order => 'email ASC' named_scope :order_full_name, :order => 'full_name ASC' # def self.at_page(page, options = {}) # paginate(options.reverse_merge(:page => page, :per_page => 20)) # end ##### Authentication def self.authenticate_by_email(email, password) u = User.by_email(email).find(:first) return nil unless u return nil unless u.crypted_password == generate_encryption(password, u.salt) u end def self.authenticate_by_login(login, password) u = User.by_login(login).find(:first) return nil unless u return nil unless u.crypted_password == generate_encryption(password, u.salt) u end def self.authenticate_by_remember_token(remember_token) u= self.by_remember_token(remember_token).find(:first) return nil unless u return nil unless u.remember_token_expires_at > Time.now.utc u end def self.authenticate_by_reset_token(reset_token) u= self.by_reset_token(reset_token).find(:first) return nil unless u return nil unless u.reset_token_expires_at > Time.now.utc u end ##### Tokens def set_remember_token self.remember_token_expires_at = 30.days.from_now.utc self.remember_token = User.generate_encryption(email, "#{self.remember_token_expires_at}") save(false) end def reset_remember_token self.remember_token_expires_at = nil self.remember_token = nil save(false) end def self.set_reset_token(email) u = self.by_email(email).find(:first) return nil unless u u.reset_token_expires_at = 2.days.from_now.utc u.reset_token = self.generate_encryption(email, "#{u.reset_token_expires_at}") u.save(false) u end private def set_fields_before_create self.reset_token_expires_at = 2.days.from_now.utc self.reset_token = User.generate_encryption(self.email, "#{self.reset_token_expires_at}") end def set_fields_before_save return if self.password.blank? # if password not set no need to change the crypted password self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{self.email}--") if new_record? self.crypted_password = User.generate_encryption(self.password, self.salt) self.reset_token_expires_at = nil self.reset_token = nil end def self.generate_encryption(password, salt) Digest::SHA1.hexdigest("--#{salt}--#{password}--") end end