1 #---
2 # Excerpted from "Agile Web Development with Rails, 3rd Ed.",
3 # published by The Pragmatic Bookshelf.
4 # Copyrights apply to this code. It may not be used to create training material,
5 # courses, books, articles, and the like. Contact us if you are in doubt.
6 # We make no guarantees that this code is fit for any purpose.
7 # Visit http://www.pragmaticprogrammer.com/titles/rails3 for more book information.
8 #---
9 require 'digest/sha1'
10
11
12 class User < ActiveRecord::Base
13
14 validates_presence_of :name
15 validates_uniqueness_of :name
16
17 attr_accessor :password_confirmation
18 validates_confirmation_of :password
19
20 validate :password_non_blank
21
22
23
24 def self.authenticate(name, password)
25 user = self.find_by_name(name)
26 if user
27 expected_password = encrypted_password(password, user.salt)
28 if user.hashed_password != expected_password
29 user = nil
30 end
31 end
32 user
33 end
34
35
36 # 'password' is a virtual attribute
37
38 def password
39 @password
40 end
41
42 def password=(pwd)
43 @password = pwd
44 return if pwd.blank?
45 create_new_salt
46 self.hashed_password = User.encrypted_password(self.password, self.salt)
47 end
48
49
50
51
52 def after_destroy
53 if User.count.zero?
54 raise "Can't delete last user"
55 end
56 end
57
58
59 private
60
61 def password_non_blank
62 errors.add(:password, "Missing password") if hashed_password.blank?
63 end
64
65
66
67 def create_new_salt
68 self.salt = self.object_id.to_s + rand.to_s
69 end
70
71
72
73 def self.encrypted_password(password, salt)
74 string_to_hash = password + "wibble" + salt
75 Digest::SHA1.hexdigest(string_to_hash)
76 end
77
78
79 end
80