ruby on rails - Password validation triggers when it should not be triggering? -


working on password reset mechanism users. password length validation triggering , i'm trying understand why.

user.rb

class user < activerecord::base    has_secure_password    validates :password, length: { minimum: 6 }   ...    def create_password_reset_token     self.update_attributes!(password_reset_token: securerandom.urlsafe_base64,    password_reset_sent_at: time.zone.now)   end    def reset_password(params)     self.update_attributes!(params)     self.update_attributes!(password_reset_token: nil, password_reset_sent_at: nil)   end  end 

password_resets_controller.rb

def create   user = user.find_by_email(params[:email])   if user     user.create_password_reset_token     usermailer.password_reset_email(user).deliver      redirect_to root_url, :notice => "email sent password reset instructions!"   else     flash[:error] = "a user email address not found."     render 'new'   end end  def edit   @user = user.find_by_password_reset_token(params[:id])   if @user     render 'edit'   else     flash[:error] = "invalid password reset code."     redirect_to root_url   end end  def update   @user = user.find_by_password_reset_token(params[:id])   if @user.password_reset_sent_at < 2.hours.ago     flash[:error] = "password reset has expired."     redirect_to new_password_reset_path   elsif @user.reset_password(user_params)     flash[:success] = "password has been reset."     redirect_to root_url   else     render 'edit'   end end 

password_resets/new.html.erb:

<%= form_tag password_resets_path, :method => :post %>   <%= label_tag :email %>   <%= text_field_tag :email, params[:email] %>    <%= submit_tag "reset password" %> <% end %> 

password_resets/edit.html.erb:

<%= form_for @user, :url => password_reset_path(params[:id]) |f| %>    <h1 class="centertext">reset password</h1>    <%= render 'shared/error_messages', object: f.object %>    <%= f.label :password %>   <%= f.password_field :password %>    <%= f.label :password_confirmation, "confirm password" %>   <%= f.password_field :password_confirmation %>    <%= f.submit "update password" %>  <% end %> 

the error is:

validation failed: password short (minimum 6 characters) 

the line throws inside create_password_reset_token method:

self.update_attributes!(password_reset_token: securerandom.urlsafe_base64, password_reset_sent_at: time.zone.now) 

why validation trigger here? i'm not doing password itself. i'm creating token , time inside user record.

changing validation on: :create makes not trigger. problem users able reset password fewer 6 characters.

clarification

to clear, order of operations is:

  1. user clicks link saying "i forgot password."
  2. they taken password_reset_controller/new.html.erb. form has 1 field: email address. enter email , submit it.
  3. controller checks see if user exists. if does, tells model generate password_reset_token.
  4. controller orders email sent user url contains token.
  5. the user clicks url. if token valid, taken edit.html.erb , enter new email , confirmation.
  6. the controller calls reset_password method, resets user's password.

currently, validation triggers on step 2, after enter email , click submit.

your create_password_reset_token calling update_attributes trigger validations on every field in user model , hence trigger password validation doesn't have current 1 set

you need either

1) use update_attribute specific fields , wouldn't trigger validation

2) add password_reset field or enum model , set true when password reset button clicked , in user model

has_secure_password :validations => false validates :password, length: {minimum: 6}, unless: -> { user_password_reset? } 

3) use devise gem take care of you

update:

try this

def create_password_reset_token   self.update_attribute(:password_reset_token, securerandom.urlsafe_base64)           self.update_attribute(:password_reset_sent_at, time.zone.now) end 

Comments

Popular posts from this blog

database - VFP Grid + SQL server 2008 - grid not showing correctly -

jquery - Set jPicker field to empty value -

.htaccess - htaccess convert request to clean url and add slash at the end of the url -