@@ -112,7 +112,7 class User < Principal | |||
|
112 | 112 | before_create :set_mail_notification |
|
113 | 113 | before_save :generate_password_if_needed, :update_hashed_password |
|
114 | 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 | 117 | scope :in_group, lambda {|group| |
|
118 | 118 | group_id = group.is_a?(Group) ? group.id : group.to_i |
@@ -681,6 +681,18 class User < Principal | |||
|
681 | 681 | end |
|
682 | 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 | 696 | # Removes references that are not handled by associations |
|
685 | 697 | # Things that are not deleted are reassociated with the anonymous user |
|
686 | 698 | def remove_references_before_destroy |
@@ -403,6 +403,42 class UserTest < ActiveSupport::TestCase | |||
|
403 | 403 | end |
|
404 | 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 | 442 | def test_validate_login_presence |
|
407 | 443 | @admin.login = "" |
|
408 | 444 | assert !@admin.save |
General Comments 0
You need to be logged in to leave comments.
Login now