diff --git a/lib/devise/models/authenticatable.rb b/lib/devise/models/authenticatable.rb index aa86448e..660403db 100644 --- a/lib/devise/models/authenticatable.rb +++ b/lib/devise/models/authenticatable.rb @@ -67,6 +67,17 @@ module Devise password_digest(incoming_password) == encrypted_password end + # Update record attributes when :old_password matches, otherwise returns + # error on :old_password. + def update_with_password(params={}) + if valid_password?(params[:old_password]) + update_attributes(params) + else + errors.add(:old_password, :invalid) + false + end + end + protected # Digests the password using the configured encryptor. diff --git a/test/models/authenticatable_test.rb b/test/models/authenticatable_test.rb index c61e61e7..3f6cdf45 100644 --- a/test/models/authenticatable_test.rb +++ b/test/models/authenticatable_test.rb @@ -152,4 +152,26 @@ class AuthenticatableTest < ActiveSupport::TestCase User.serialize_from_session([Admin, user.id]) end end + + test 'should update password with valid old password' do + user = create_user + assert user.update_with_password(:old_password => '123456', + :password => 'pass321', :password_confirmation => 'pass321') + assert user.reload.valid_password?('pass321') + end + + test 'should add an error to old password when it is invalid' do + user = create_user + assert_not user.update_with_password(:old_password => 'other', + :password => 'pass321', :password_confirmation => 'pass321') + assert_equal 'is invalid', user.errors[:old_password] + assert user.reload.valid_password?('123456') + end + + test 'should not update password with invalid confirmation' do + user = create_user + assert_not user.update_with_password(:old_password => '123456', + :password => 'pass321', :password_confirmation => 'other') + assert user.reload.valid_password?('123456') + end end