Changesets can be listed by changeset number.
The Git repository is here.
- Revision:
- 260
- Log:
Make e-mail address comparison case-insensitive everywhere - see e.g.
Ticket #165. Run *all* flash updates through hubssolib_set_flash as
this seems to guarantee correct persistence, fixing things like the bug
reported in Ticket #199. Note that this may worsen problems with flash
persistence in the cache (see e.g. Ticket #159). I can't really test
for it except by running it on the live system with all caches flushed,
due to limitations with the way the development web server runs in
relation to database access and redirections from strange port numbers.Unrelated fix - the check for zero users when signing up the very first
Hub user was terrible (find all users, count the array size - rather
than doing User.count.zero?). Fixed.
- Author:
- rool
- Date:
- Wed Feb 25 19:21:38 +0000 2009
- Size:
- 3861 Bytes
1 | require 'digest/sha1' |
2 | |
3 | class User < ActiveRecord::Base |
4 | belongs_to :member |
5 | before_create :make_activation_code |
6 | |
7 | # Virtual attribute for the unencrypted password |
8 | attr_accessor :password |
9 | |
10 | # Stop mass-assignment of the User model when we do something like |
11 | # "@user = User.new(params[:user])" in the Controller. Someone could |
12 | # build a form which submitted any value for all columns in the User |
13 | # table without this - e.g. they could assign "admin" to "roles". |
14 | # The line below states which attributes are accessible to mass |
15 | # assignment - everything else must be explicitly assigned. |
16 | attr_accessible :email, :real_name, :password, :password_confirmation |
17 | |
18 | validates_presence_of :email, :real_name |
19 | validates_presence_of :password, :if => :password_required? |
20 | validates_presence_of :password_confirmation, :if => :password_required? |
21 | validates_length_of :password, :within => 4..40, :if => :password_required? |
22 | validates_confirmation_of :password, :if => :password_required? |
23 | validates_length_of :email, :within => 3..200 |
24 | validates_length_of :real_name, :within => 3..200 |
25 | validates_uniqueness_of :email, :case_sensitive => false |
26 | before_save :encrypt_password |
27 | |
28 | # Authenticates a user by e-mail address and unencrypted password. Returns the user or nil. |
29 | def self.authenticate(email, password) |
30 | # hide records with a nil activated_at |
31 | u = find :first, :conditions => ['LOWER(email) = ? and activated_at IS NOT NULL', email.downcase] |
32 | u && u.authenticated?(password) ? u : nil |
33 | end |
34 | |
35 | # Encrypts some data with the salt. |
36 | def self.encrypt(password, salt) |
37 | Digest::SHA1.hexdigest("--#{salt}--#{password}--") |
38 | end |
39 | |
40 | # Encrypts the password with the user salt |
41 | def encrypt(password) |
42 | self.class.encrypt(password, salt) |
43 | end |
44 | |
45 | def authenticated?(password) |
46 | crypted_password == encrypt(password) |
47 | end |
48 | |
49 | # Activates the user in the database. |
50 | def activate |
51 | @activated = true |
52 | self.activated_at = Time.now.utc |
53 | self.activation_code = nil |
54 | save(false) |
55 | end |
56 | |
57 | # Returns true if the user has just been activated. |
58 | def recently_activated? |
59 | activated = @activated |
60 | @activated = false |
61 | return activated |
62 | end |
63 | |
64 | # Deal with forgotten passwords |
65 | def forgot_password |
66 | self.password_reset_code_expires_at = (Time.now.utc) + RESET_TIME_LIMIT |
67 | self.make_password_reset_code |
68 | save(false) |
69 | @forgotten_password = true |
70 | end |
71 | |
72 | def reset_password |
73 | # First update the password_reset_code before setting the |
74 | # reset_password flag to avoid duplicate email notifications. |
75 | self.password_reset_code_expires_at = nil |
76 | self.password_reset_code = nil |
77 | save(false) |
78 | @reset_password = true |
79 | end |
80 | |
81 | def recently_reset_password? |
82 | reset_password = @reset_password |
83 | @reset_password = false |
84 | return reset_password |
85 | end |
86 | |
87 | def recently_forgot_password? |
88 | forgotten_password = @forgotten_password |
89 | @forgotten_password = false |
90 | return forgotten_password |
91 | end |
92 | |
93 | def destroy |
94 | UserNotifier.deliver_destruction(self) |
95 | super |
96 | end |
97 | |
98 | protected |
99 | # before filter |
100 | def encrypt_password |
101 | return if password.blank? |
102 | self.salt = Digest::SHA1.hexdigest("--#{Time.now.to_s}--#{email}--") if new_record? |
103 | self.crypted_password = encrypt(password) |
104 | end |
105 | |
106 | def password_required? |
107 | crypted_password.blank? || !password.blank? |
108 | end |
109 | |
110 | # Create a user activation code for activation e-mail messages |
111 | def make_activation_code |
112 | self.activation_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join) |
113 | end |
114 | |
115 | # Make a password reset code for users who've forgotten their password |
116 | def make_password_reset_code |
117 | self.password_reset_code = Digest::SHA1.hexdigest(Time.now.to_s.split(//).sort_by {rand}.join) |
118 | end |
119 | end |