comparison app/models/.svn/text-base/user.rb.svn-base @ 245:051f544170fe

* Update to SVN trunk revision 4993
author Chris Cannam
date Thu, 03 Mar 2011 11:42:28 +0000
parents 0579821a129a
children eeebe205a056 cbce1fd3b1b7
comparison
equal deleted inserted replaced
244:8972b600f4fb 245:051f544170fe
81 true 81 true
82 end 82 end
83 83
84 def before_save 84 def before_save
85 # update hashed_password if password was set 85 # update hashed_password if password was set
86 self.hashed_password = User.hash_password(self.password) if self.password && self.auth_source_id.blank? 86 if self.password && self.auth_source_id.blank?
87 salt_password(password)
88 end
87 end 89 end
88 90
89 def reload(*args) 91 def reload(*args)
90 @name = nil 92 @name = nil
91 super 93 super
119 if user.auth_source 121 if user.auth_source
120 # user has an external authentication method 122 # user has an external authentication method
121 return nil unless user.auth_source.authenticate(login, password) 123 return nil unless user.auth_source.authenticate(login, password)
122 else 124 else
123 # authentication with local password 125 # authentication with local password
124 return nil unless User.hash_password(password) == user.hashed_password 126 return nil unless user.check_password?(password)
125 end 127 end
126 else 128 else
127 # user is not yet registered, try to authenticate with available sources 129 # user is not yet registered, try to authenticate with available sources
128 attrs = AuthSource.authenticate(login, password) 130 attrs = AuthSource.authenticate(login, password)
129 if attrs 131 if attrs
198 200
199 def lock! 201 def lock!
200 update_attribute(:status, STATUS_LOCKED) 202 update_attribute(:status, STATUS_LOCKED)
201 end 203 end
202 204
205 # Returns true if +clear_password+ is the correct user's password, otherwise false
203 def check_password?(clear_password) 206 def check_password?(clear_password)
204 if auth_source_id.present? 207 if auth_source_id.present?
205 auth_source.authenticate(self.login, clear_password) 208 auth_source.authenticate(self.login, clear_password)
206 else 209 else
207 User.hash_password(clear_password) == self.hashed_password 210 User.hash_password("#{salt}#{User.hash_password clear_password}") == hashed_password
208 end 211 end
212 end
213
214 # Generates a random salt and computes hashed_password for +clear_password+
215 # The hashed password is stored in the following form: SHA1(salt + SHA1(password))
216 def salt_password(clear_password)
217 self.salt = User.generate_salt
218 self.hashed_password = User.hash_password("#{salt}#{User.hash_password clear_password}")
209 end 219 end
210 220
211 # Does the backend storage allow this user to change their password? 221 # Does the backend storage allow this user to change their password?
212 def change_password_allowed? 222 def change_password_allowed?
213 return true if auth_source_id.blank? 223 return true if auth_source_id.blank?
471 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0) 481 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
472 raise 'Unable to create the anonymous user.' if anonymous_user.new_record? 482 raise 'Unable to create the anonymous user.' if anonymous_user.new_record?
473 end 483 end
474 anonymous_user 484 anonymous_user
475 end 485 end
486
487 # Salts all existing unsalted passwords
488 # It changes password storage scheme from SHA1(password) to SHA1(salt + SHA1(password))
489 # This method is used in the SaltPasswords migration and is to be kept as is
490 def self.salt_unsalted_passwords!
491 transaction do
492 User.find_each(:conditions => "salt IS NULL OR salt = ''") do |user|
493 next if user.hashed_password.blank?
494 salt = User.generate_salt
495 hashed_password = User.hash_password("#{salt}#{user.hashed_password}")
496 User.update_all("salt = '#{salt}', hashed_password = '#{hashed_password}'", ["id = ?", user.id] )
497 end
498 end
499 end
476 500
477 protected 501 protected
478 502
479 def validate 503 def validate
480 # Password length validation based on setting 504 # Password length validation based on setting
512 536
513 # Return password digest 537 # Return password digest
514 def self.hash_password(clear_password) 538 def self.hash_password(clear_password)
515 Digest::SHA1.hexdigest(clear_password || "") 539 Digest::SHA1.hexdigest(clear_password || "")
516 end 540 end
541
542 # Returns a 128bits random salt as a hex string (32 chars long)
543 def self.generate_salt
544 ActiveSupport::SecureRandom.hex(16)
545 end
546
517 end 547 end
518 548
519 class AnonymousUser < User 549 class AnonymousUser < User
520 550
521 def validate_on_create 551 def validate_on_create