How to Skip Has_Secure_Password Validations

How to skip has_secure_password validations

I decided to do my own custom authentication. The following solution will validate passwords but only when they are being set. This allows admins to create users without adding a password.

class User < ActiveRecord::Base
include BCrypt

attr_accessor :password, :password_confirmation

validates :password, length: (6..32), confirmation: true, if: :setting_password?

def password=(password)
@password = password
self.password_hash = Password.create(password)
end

def authenticate(password)
password.present? && password_hash.present? && Password.new(password_hash) == password
end

private

def setting_password?
password || password_confirmation
end

end

If someone posts an answer that allows me to still use the has_secure_password method, I'll accept it instead.

How to disable password/confirmation validations when using has_secure_password in Rails 3.2?

You could add a conditional :if to both validators:

Option 1:

validates :password             , length: { minimum: 6 }, :if => :validate_password?
validates :password_confirmation, presence: true , :if => :validate_password?

def validate_password?
password.present? || password_confirmation.present?
end

Option 2:

Or use a method for validation, moving the validation checks into the method instead of as separate validates calls:

validate :check_password, :on => :update

def check_password
return unless password.present? || password_confirmation.present?
..validations for both attributes here..
..check presence, length etc. as required and add to the errors variable as necessary..
end

How to skip validation on regeneration of secure token

You can do

def generate_password_reset_token
self.reset_password_token = generate_token
self.reset_password_sent_at = Time.now
save!
end


def generate_token
SecureRandom.base58(5)
end

Can I conditionally remove the has_secure_password requirement when creating a second user?

We had the same issue in our app. Our solution was to generate a password for the users when new users are created using this: before_validation :set_random_password, on: :create

Then the users can select their own password when they activate their account. This way we do not have to do anything custom with the validations which might compromise security for active users.

More of the code (as requested)

def set_random_password
password = SecureRandom.base64(100)
end

Then we use perishable tokens for finding the user and allowing them to update their password. A perishable token is some secure string that updates every time the user is updated in the database. We use the same pattern for "forgot password emails".

We build a link looking like /users/activate?token=#{user.token} and send that in a email.

Then in the controller

def activate_user_form
@user = User.find_by(token: params[:token])
render :select_password_form
end

def activate_user
@user = User.find_by(token: params[:token])
@user.password = params[:password]
@user.active = true
if @user.save
...
end

Or something along those lines.

Rails has_secure_password - either no blankness validation or two validation errors

You can pass an option to has_secure_password to skip its built-in validations and use your own:

has_secure_password(validations: false)

https://github.com/rails/rails/blob/869a90512f36b04914d73cbf58317d953caea7c5/activemodel/lib/active_model/secure_password.rb#L66

Validating presence of has_secure_password only when password is in params

To answer your question, It seems best to have change_password and reset_password controller actions and do your validations in there.

First, have your model validate password only on create or when it's already entered as such:

validates :password, :presence => true,
:length => { minimum: 6 },
:if => lambda{ new_record? || !password.nil? }

Then for your new controller actions, something along the lines of:

class UsersController < ApplicationController

def change_password
...
if params[:user][:password].present?
@user.update_attributes(params[:user])
redirect_to root_path, notice: "Success!"
else
flash.now.alert "Please enter password!"
render "change_password"
end
end
end

Do the same for reset_password and you should be golden!



Related Topics



Leave a reply



Submit