Pickaxe
Pickaxe

Reputation: 101

Ruby on Rails - Bcyrpt update user attributes with password confirmation

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

Answers (2)

Alessandro Dimich
Alessandro Dimich

Reputation: 11

You can also use:

validates_presence_of :password, :on => :create

This way you will avoid password validation when updating.

Upvotes: 1

Jan
Jan

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

Related Questions