mirror of
				https://github.com/heartcombo/devise.git
				synced 2022-11-09 12:18:31 -05:00 
			
		
		
		
	Always return an error when confirmation_token is blank (#5132)
				
					
				
			As reported in https://github.com/plataformatec/devise/issues/5071, if for some reason, a user in the database had the `confirmation_token` column as a blank string, Devise would confirm that user after receiving a request with a blank `confirmation_token` parameter. After this commit, a request sending a blank `confirmation_token` parameter will receive a validation error. For applications that have users with a blank `confirmation_token` in the database, it's recommended to manually regenerate or to nullify them.
This commit is contained in:
		
							parent
							
								
									fad60747d5
								
							
						
					
					
						commit
						fee43f3c11
					
				
					 3 changed files with 60 additions and 0 deletions
				
			
		| 
						 | 
				
			
			@ -348,7 +348,19 @@ module Devise
 | 
			
		|||
        # If the user is already confirmed, create an error for the user
 | 
			
		||||
        # Options must have the confirmation_token
 | 
			
		||||
        def confirm_by_token(confirmation_token)
 | 
			
		||||
          # When the `confirmation_token` parameter is blank, if there are any users with a blank
 | 
			
		||||
          # `confirmation_token` in the database, the first one would be confirmed here.
 | 
			
		||||
          # The error is being manually added here to ensure no users are confirmed by mistake.
 | 
			
		||||
          # This was done in the model for convenience, since validation errors are automatically
 | 
			
		||||
          # displayed in the view.
 | 
			
		||||
          if confirmation_token.blank?
 | 
			
		||||
            confirmable = new
 | 
			
		||||
            confirmable.errors.add(:confirmation_token, :blank)
 | 
			
		||||
            return confirmable
 | 
			
		||||
          end
 | 
			
		||||
 | 
			
		||||
          confirmable = find_first_by_auth_conditions(confirmation_token: confirmation_token)
 | 
			
		||||
 | 
			
		||||
          unless confirmable
 | 
			
		||||
            confirmation_digest = Devise.token_generator.digest(self, :confirmation_token, confirmation_token)
 | 
			
		||||
            confirmable = find_or_initialize_with_error_by(:confirmation_token, confirmation_digest)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -175,6 +175,36 @@ class ConfirmationTest < Devise::IntegrationTest
 | 
			
		|||
    assert_current_url '/users/sign_in'
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "should not be able to confirm an email with a blank confirmation token" do
 | 
			
		||||
    visit_user_confirmation_with_token("")
 | 
			
		||||
 | 
			
		||||
    assert_contain "Confirmation token can't be blank"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "should not be able to confirm an email with a nil confirmation token" do
 | 
			
		||||
    visit_user_confirmation_with_token(nil)
 | 
			
		||||
 | 
			
		||||
    assert_contain "Confirmation token can't be blank"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "should not be able to confirm user with blank confirmation token" do
 | 
			
		||||
    user = create_user(confirm: false)
 | 
			
		||||
    user.update_attribute(:confirmation_token, "")
 | 
			
		||||
 | 
			
		||||
    visit_user_confirmation_with_token("")
 | 
			
		||||
 | 
			
		||||
    assert_contain "Confirmation token can't be blank"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test "should not be able to confirm user with nil confirmation token" do
 | 
			
		||||
    user = create_user(confirm: false)
 | 
			
		||||
    user.update_attribute(:confirmation_token, nil)
 | 
			
		||||
 | 
			
		||||
    visit_user_confirmation_with_token(nil)
 | 
			
		||||
 | 
			
		||||
    assert_contain "Confirmation token can't be blank"
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test 'error message is configurable by resource name' do
 | 
			
		||||
    store_translations :en, devise: {
 | 
			
		||||
      failure: { user: { unconfirmed: "Not confirmed user" } }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -77,6 +77,24 @@ class ConfirmableTest < ActiveSupport::TestCase
 | 
			
		|||
    assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test 'should return a new record with errors when a blank token is given and a record exists on the database' do
 | 
			
		||||
    user = create_user(confirmation_token: '')
 | 
			
		||||
 | 
			
		||||
    confirmed_user = User.confirm_by_token('')
 | 
			
		||||
 | 
			
		||||
    refute user.reload.confirmed?
 | 
			
		||||
    assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test 'should return a new record with errors when a nil token is given and a record exists on the database' do
 | 
			
		||||
    user = create_user(confirmation_token: nil)
 | 
			
		||||
 | 
			
		||||
    confirmed_user = User.confirm_by_token(nil)
 | 
			
		||||
 | 
			
		||||
    refute user.reload.confirmed?
 | 
			
		||||
    assert_equal "can't be blank", confirmed_user.errors[:confirmation_token].join
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  test 'should generate errors for a user email if user is already confirmed' do
 | 
			
		||||
    user = create_user
 | 
			
		||||
    user.confirmed_at = Time.now
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue