Reputation: 101
I want to give the user the opportunity to update some user information. For now only the name and email. The User needs to type the current password to authorize the update. I tried several ways and it comes down to the following problem:
I call a "validate_password" method before updating the user attributes.
users_controller.rb:
def update
@user = User.find(params[:id])
respond_to do |format|
if validate_password(params[:password]) && @user.update_attributes(params[:user])
format.html { redirect_to @user, notice: 'Account was successfully updated.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @user.errors, status: :unprocessable_entity }
end
end
end
application_controller.rb:
def validate_password(pswd)
if current_user.password_hash == BCrypt::Engine.hash_secret(pswd, current_user.password_salt)
true
else
false
end
end
It returns false even with the correct password as "pswd". Am I missing something? You can recreate the password hash if you know the correct salt right?
Upvotes: 0
Views: 693
Reputation: 11
You can also use:
validates_presence_of :password, :on => :create
This way you will avoid password validation when updating.
Upvotes: 1
Reputation: 11726
Assuming that current_user.password_hash
contains a hash created using BCrypt::Password#create
, instead of
current_user.password_hash == BCrypt::Engine.hash_secret(...)
try
BCrypt::Password.new(current_user.password_hash) == passwd
Don't do the salting yourself. It's redundant as BCrypt does the salting already.
Another step in a good direction would be to abandon hand-written authentication and use an existing, battle-tested solution, e.g. Devise.
Upvotes: 1