I have a User model:
class User < ActiveRecord::Base
has_secure_password
# validation lets users update accounts without entering password
validates :password, presence: { on: :create }, allow_blank: { on: :update }
validates :password_confirmation, presence: { if: :password_digest_changed? }
end
I also have a password_reset_controller:
def update
# this is emailed to the user by the create action - not shown
@user=User.find_by_password_reset_token!(params[:id])
if @user.update_attributes(params[:user])
# user is signed in if password and confirmation pass validations
sign_in @user
redirect_to root_url, :notice => "Password has been reset."
else
flash.now[:error] = "Something went wrong, please try again."
render :edit
end
end
Can you see the problem here? A user can submit a blank a password/confirmation and rails will sign them in, because the User model allows blank on update.
It's not a security concern, since an attacker would still need access to a user's email account before they could get anywhere near this action, but my problem is that a user submitting 6 blank chars would be signed in, and their password would not be changed for them, which could lead to confusion later on.
So, I've come up with the following solution, and I'd like to check if there's a better way of doing it, before I push to production:
def update
@user=User.find_by_password_reset_token!(params[:id])
# if user submits blank password, add an error, and render edit action
if params[:user][:password].blank?
@user.errors.add(:password_digest, "can't be blank.")
render :edit
elsif @user.update_attributes(params[:user])
sign_in @user
redirect_to root_url, :notice => "Password has been reset."
else
flash.now[:error] = "Something went wrong, please try again."
render :edit
end
end
Should I be checking for nil as well as blank? Are there any rails patterns or idiomatic ruby techniques for solving this?
[Fwiw, I've got required: true on the html inputs, but want this handled server side too.]