Reputation: 2080
I'm trying to implement a method to allow password to be changed from another service outside devise anyhow.
# Profile password change
def change_password(oldpass, newpass)
pepper = nil
cost = 10
# Encrypt plain text passwords
encrypt_old = ::BCrypt::Password.create("#{oldpass}#{pepper}", :cost => cost).to_s
# Validate old
if self.encrypted_password == encrypt_old
encrypt_new = ::BCrypt::Password.create("#{newpass}#{pepper}", :cost => cost).to_s
self.encrypted_password = encrypt_new
self.save
else
Logger.new("Wrong old password!")
end
end
It seems i got the password encryption wrong oldpass contains a plain text of old password i need to hash it see if it matches the current password then allow new password to be stored. However all that i'm getting is wrong password.
Reworked:
def change_password(oldpass, newpass)
if valid_password?(oldpass)
password = newpass
save
return true
else
return false
end
end
Upvotes: 5
Views: 13380
Reputation: 3066
With Devise, you don't need to handle using bcrypt yourself. By default, it handles this and the change password method. You can look at source here or just look in config/intitalizers/devise.rb
in your Rails app.
Also, if you use the #update_with_password
method provided by Devise, then you can pass it a hash like this:
{ :current_password => 'pass', :password => 'pass_new', :password_confirmation => 'pass_new' }
Or you can omit :password_confirmation
if you don't want the user to have to provide a confirmation.
EDIT: I used the wrong field; it should have been 'current_password' instead of 'old_password'.
Here's the method in question in the source for Devise:
# Update record attributes when :current_password matches, otherwise returns
# error on :current_password. It also automatically rejects :password and
# :password_confirmation if they are blank.
def update_with_password(params, *options)
current_password = params.delete(:current_password)
if params[:password].blank?
params.delete(:password)
params.delete(:password_confirmation) if params[:password_confirmation].blank?
end
result = if valid_password?(current_password)
update_attributes(params, *options)
else
self.assign_attributes(params, *options)
self.valid?
self.errors.add(:current_password, current_password.blank? ? :blank : :invalid)
false
end
clean_up_passwords
result
end
Upvotes: 3
Reputation: 1060
You don't need to encrypt the password yourself, if you are in the application or in Rails console.
Just update the user following way and Devise will take care of it itself.
user.password = new_password
user.save
Devise will then encrypt the password and store it. You just need to ensure that user.password_confirmation
is nil
. If password_confirmation
is anything else, it will be matched against password
.
EDIT
You can check the existing password with: user.valid_password?(old_password)
Upvotes: 11