comparison app/models/.svn/text-base/user.rb.svn-base @ 246:eeebe205a056 cannam

* Merge from default branch, bringing us up to SVN trunk rev 4993
author Chris Cannam
date Thu, 03 Mar 2011 12:02:03 +0000
parents 5e974759e8b2 051f544170fe
children 753f1380d6bc
comparison
equal deleted inserted replaced
138:fca2657f4aa5 246:eeebe205a056
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?
422 def notify_about?(object) 432 def notify_about?(object)
423 case mail_notification 433 case mail_notification
424 when 'all' 434 when 'all'
425 true 435 true
426 when 'selected' 436 when 'selected'
427 # Handled by the Project 437 # user receives notifications for created/assigned issues on unselected projects
438 if object.is_a?(Issue) && (object.author == self || object.assigned_to == self)
439 true
440 else
441 false
442 end
428 when 'none' 443 when 'none'
429 false 444 false
430 when 'only_my_events' 445 when 'only_my_events'
431 if object.is_a?(Issue) && (object.author == self || object.assigned_to == self) 446 if object.is_a?(Issue) && (object.author == self || object.assigned_to == self)
432 true 447 true
465 if anonymous_user.nil? 480 if anonymous_user.nil?
466 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0) 481 anonymous_user = AnonymousUser.create(:lastname => 'Anonymous', :firstname => '', :mail => '', :login => '', :status => 0)
467 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?
468 end 483 end
469 anonymous_user 484 anonymous_user
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
470 end 499 end
471 500
472 protected 501 protected
473 502
474 def validate 503 def validate
507 536
508 # Return password digest 537 # Return password digest
509 def self.hash_password(clear_password) 538 def self.hash_password(clear_password)
510 Digest::SHA1.hexdigest(clear_password || "") 539 Digest::SHA1.hexdigest(clear_password || "")
511 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
512 end 547 end
513 548
514 class AnonymousUser < User 549 class AnonymousUser < User
515 550
516 def validate_on_create 551 def validate_on_create