public
Fork of halorgium/mephisto
Description: A mirror of the mephisto code-base
Homepage: http://mephistoblog.com/
Clone URL: git://github.com/technoweenie/mephisto.git
Click here to lend your support to: mephisto and make a donation at www.pledgie.com !
mephisto / app / models / user.rb
100644 111 lines (88 sloc) 3.889 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
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
require 'digest/sha1'
class User < ActiveRecord::Base
  @@admin_scope = {:find => { :conditions => ['admin = ?', true] } }
  @@membership_options = {:select => 'distinct users.*, memberships.admin as site_admin', :order => 'users.login',
    :joins => 'left outer join memberships on users.id = memberships.user_id'}
 
  # Virtual attribute for the unencrypted password
  attr_accessor :password
 
  validates_presence_of :login, :email
  validates_format_of :email, :with => Format::EMAIL
  validates_presence_of :password, :if => :password_required?
  validates_presence_of :password_confirmation, :if => :password_required?
  validates_length_of :password, :within => 5..40, :if => :password_required?
  validates_confirmation_of :password, :if => :password_required?
  validates_length_of :login, :within => 3..40
  validates_uniqueness_of :login, :email, :case_sensitve => false
  before_save :encrypt_password
 
  has_many :articles
  acts_as_paranoid
 
  has_many :memberships, :dependent => :destroy
  has_many :sites, :through => :memberships, :order => 'title, host'
 
  def self.find_admins(*args)
    with_scope(@@admin_scope) { find *args }
  end
 
  # Authenticates a user by their login name and unencrypted password. Returns the user or nil.
  def self.authenticate_for(site, login, password)
    u = find(:first, @@membership_options.merge(
      :conditions => ['users.login = ? and (memberships.site_id = ? or users.admin = ?)', login, site.id, true]))
    u && u.authenticated?(password) ? u : nil
  end
 
  def self.find_by_site(site, id)
    with_deleted_scope { find_by_site_with_deleted(site, id) }
  end
 
  def self.find_by_site_with_deleted(site, id)
    find_with_deleted(:first, @@membership_options.merge(
      :conditions => ['users.id = ? and (memberships.site_id = ? or users.admin = ?)', id, site.id, true]))
  end
 
  def self.find_all_by_site(site, options = {})
    with_deleted_scope { find_all_by_site_with_deleted(site, options) }
  end
 
  def self.find_all_by_site_with_deleted(site, options = {})
    find_with_deleted(:all, @@membership_options.merge(options.reverse_merge(:conditions => ['memberships.site_id = ? or users.admin = ?', site.id, true]))).uniq
  end
 
  def self.find_by_token(site, token)
    find(:first, @@membership_options.merge(:conditions => ['token = ? and token_expires_at > ? and (memberships.site_id = ? or users.admin = ?)', token, Time.now.utc, site.id, true]))
  end
  
  def self.find_by_email(site, email)
    find(:first, @@membership_options.merge(:conditions => ['email = ? and (memberships.site_id = ? or users.admin = ?)', email, site.id, true]))
  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 token?
    token_expires_at && Time.now.utc < token_expires_at
  end
 
  # The site admin property is brought in from memberships.admin, when joined with the sites table.
  def site_admin?
    ActiveRecord::ConnectionAdapters::Column.value_to_boolean read_attribute(:site_admin)
  end
 
  def reset_token!
    returning self.token = rand_key do |t|
      self.token_expires_at = 2.weeks.from_now.utc
      save!
    end
  end
 
  def to_liquid
    UserDrop.new self
  end
 
  protected
    def encrypt_password
      return if password.blank?
      self.salt = rand_key if new_record?
      self.crypted_password = encrypt(password)
    end
    
    def password_required?
      crypted_password.nil? || !password.blank?
    end
    
    def rand_key
      Digest::SHA1.hexdigest("--#{Time.now.to_s.split(//).sort_by {rand}.join}--#{login}--")
    end
end