@@ -112,7 +112,7 class User < Principal | |||||
112 | before_create :set_mail_notification |
|
112 | before_create :set_mail_notification | |
113 | before_save :generate_password_if_needed, :update_hashed_password |
|
113 | before_save :generate_password_if_needed, :update_hashed_password | |
114 | before_destroy :remove_references_before_destroy |
|
114 | before_destroy :remove_references_before_destroy | |
115 | after_save :update_notified_project_ids |
|
115 | after_save :update_notified_project_ids, :destroy_tokens | |
116 |
|
116 | |||
117 | scope :in_group, lambda {|group| |
|
117 | scope :in_group, lambda {|group| | |
118 | group_id = group.is_a?(Group) ? group.id : group.to_i |
|
118 | group_id = group.is_a?(Group) ? group.id : group.to_i | |
@@ -681,6 +681,18 class User < Principal | |||||
681 | end |
|
681 | end | |
682 | end |
|
682 | end | |
683 |
|
683 | |||
|
684 | # Delete all outstanding password reset tokens on password or email change. | |||
|
685 | # Delete the autologin tokens on password change to prohibit session leakage. | |||
|
686 | # This helps to keep the account secure in case the associated email account | |||
|
687 | # was compromised. | |||
|
688 | def destroy_tokens | |||
|
689 | tokens = [] | |||
|
690 | tokens |= ['recovery', 'autologin'] if changes.has_key?('hashed_password') | |||
|
691 | tokens |= ['recovery'] if changes.has_key?('mail') | |||
|
692 | ||||
|
693 | Token.delete_all(['user_id = ? AND action IN (?)', self.id, tokens]) if tokens.any? | |||
|
694 | end | |||
|
695 | ||||
684 | # Removes references that are not handled by associations |
|
696 | # Removes references that are not handled by associations | |
685 | # Things that are not deleted are reassociated with the anonymous user |
|
697 | # Things that are not deleted are reassociated with the anonymous user | |
686 | def remove_references_before_destroy |
|
698 | def remove_references_before_destroy |
@@ -403,6 +403,42 class UserTest < ActiveSupport::TestCase | |||||
403 | end |
|
403 | end | |
404 | end |
|
404 | end | |
405 |
|
405 | |||
|
406 | def test_password_change_should_destroy_tokens | |||
|
407 | recovery_token = Token.create!(:user_id => 2, :action => 'recovery') | |||
|
408 | autologin_token = Token.create!(:user_id => 2, :action => 'autologin') | |||
|
409 | ||||
|
410 | user = User.find(2) | |||
|
411 | user.password, user.password_confirmation = "a new password", "a new password" | |||
|
412 | assert user.save | |||
|
413 | ||||
|
414 | assert_nil Token.find_by_id(recovery_token.id) | |||
|
415 | assert_nil Token.find_by_id(autologin_token.id) | |||
|
416 | end | |||
|
417 | ||||
|
418 | def test_mail_change_should_destroy_tokens | |||
|
419 | recovery_token = Token.create!(:user_id => 2, :action => 'recovery') | |||
|
420 | autologin_token = Token.create!(:user_id => 2, :action => 'autologin') | |||
|
421 | ||||
|
422 | user = User.find(2) | |||
|
423 | user.mail = "user@somwehere.com" | |||
|
424 | assert user.save | |||
|
425 | ||||
|
426 | assert_nil Token.find_by_id(recovery_token.id) | |||
|
427 | assert_equal autologin_token, Token.find_by_id(autologin_token.id) | |||
|
428 | end | |||
|
429 | ||||
|
430 | def test_change_on_other_fields_should_not_destroy_tokens | |||
|
431 | recovery_token = Token.create!(:user_id => 2, :action => 'recovery') | |||
|
432 | autologin_token = Token.create!(:user_id => 2, :action => 'autologin') | |||
|
433 | ||||
|
434 | user = User.find(2) | |||
|
435 | user.firstname = "Bobby" | |||
|
436 | assert user.save | |||
|
437 | ||||
|
438 | assert_equal recovery_token, Token.find_by_id(recovery_token.id) | |||
|
439 | assert_equal autologin_token, Token.find_by_id(autologin_token.id) | |||
|
440 | end | |||
|
441 | ||||
406 | def test_validate_login_presence |
|
442 | def test_validate_login_presence | |
407 | @admin.login = "" |
|
443 | @admin.login = "" | |
408 | assert !@admin.save |
|
444 | assert !@admin.save |
General Comments 0
You need to be logged in to leave comments.
Login now