How can I override the default validations that come with Authlogic? - ruby-on-rails

I have my own password/login rules that I want to implement such as:
Password: At least one number, one lower case character and one upper case character
Login: Alphanumeric and between 4 and 15 characters long
etc...
Currently when I do not enter a password and login in my form, I get the following errors (from Authlogic's default validations):
Login is too short (minimum is 3 characters)
Password is too short (minimum is 4 characters)
Password confirmation is too short (minimum is 4 characters)
These validation rules are not in my model, they come from the Authlogic gem. I know there are configurations that I can add using:
acts_as_authentic do |config|
config.validate_password_field = false
end
The problem is that I can't find good documentation for these configurations and when I try the one above so I can use my own, it complains:
undefined method 'password_confirmation' for #<User:0x7f5fac8fe7c0>
Doing this:
acts_as_authentic do |config|
config.validate_password_field = false
# added this so it might stop complaining
config.require_password_confirmation = true
end
Does nothing.
Is there a way to have Authlogic require password confirmation while ignore all other validation so that I can control this?

The undefined method 'password_confirmation' can be avoided simply by adding this line in your model:
attr_accessor :password_confirmation
If you want to handle the confirmation yourself, then just add:
validates_confirmation_of :password
If you dive into the code, you will find this in password.rb:
if require_password_confirmation
validates_confirmation_of :password, validates_confirmation_of_password_field_options
validates_length_of :password_confirmation, validates_length_of_password_confirmation_field_options
end

Related

Validation for a certain action in ruby on rails

In my current ROR project I am using devise pluing for validation. In my change password form validation, I am using the following code in the user model
validates_presence_of :password, :password_confirmation
But I wants to validate is only for an action. I have a function in my user controller named update_password. I found the that I can assign the action as follows:
validates_presence_of :password, :password_confirmation, :on => :update_password
But its not working. Even if the password and password confirmation fields are empty, the form is submitted. Can anyone help me to solve how to set the validation only for a particular action. Will be a great help
Thanks a lot
You can use :validatable option implemented in devise.
Just add to your model
devise :validatable
And set validation options in your config/initializers/devise.rb file
# ==> Configuration for :validatable
# Range for password length. Default is 6..128.
config.password_length = 6..128
# Email regex used to validate email formats. It simply asserts that
# an one (and only one) # exists in the given string. This is mainly
# to give user feedback and not to assert the e-mail validity.
config.email_regexp = /\A[^#]+#[^#]+\z/
Another way is to use your own regexp validations. You can add to your model
validates :password, :format => { :with => /\A[a-zA-Z]+\z/, :message => "Only letters allowed" }
After that you can call #user.valid? in your controller to check that your user instance is correct.
There are many different ways to validate your model.
You can read more about validation and ActiveRecord callbacks in guides: http://guides.rubyonrails.org/active_record_validations_callbacks.html
If you're using devise, there's no need to check for that. It's handle for you by default.

rails 3.1 partial_updates doesn't seem to work with password

i have a user model with a password attribute, which gets saved as password_digest.
What i want to do is have the edit user page and the edit password page separated, so that
the admin doesn't need to input the password everytime he needs to change something else. For this i have made an extra action / view.
My problem is that when i update the user info, i get password validation errors even though
i have no password field in the form. Which leads me to the conclusion that partial_updates isn't working with the password attribute (as i have already tested in the console that it is enabled, and it is)
Is this me doing something wrong, or should i approach this differently?
Similar to the railscasts approach mentioned by #normalocity, but without the need to set a pseudo-attribute in the controller, we do this (which is essentially taken from restful_authentication):
attr_accessor :password
validates :password,
:length => { :minimum => 8 },
:confirmation => true,
:presence => true,
:if => :password_required?
def password_required?
password_digest.blank? || !password.blank?
end
Basically, we assume that if the password_digest hasn't been set yet (for a new record), or if the password pseudo-attribute has been set, then that means the password is being changed and the validations have to be run. So we don't need to set a updating_password pseudo-attribute like they do in the railscasts episode.
You need to validate the password only if it's being changed. If it's not being changed, then the validation for the password field should be skipped.
Railscasts.com episode #41 shows you how to do this.

Authlogic: How can I only validate the password if the password is being updated?

I'm using authlogic with rails 3. I have this in my user model:
validates :last_name, :presence => true
acts_as_authentic do |c|
c.validates_length_of_password_field_options = {:minimum => 7}
end
And then I have a controller action that updates the user's name:
def update_name
if #current_user.update_attributes(params[:user])
flash[:success_name] = true
redirect_to edit_user_via_account_settings_path
else
render 'edit_user_via_account_settings'
end
end
If the user enters a blank last name and attempts to update their name with this controller action, the #current_user model correctly has errors on last name, but it also has errors on password (password must be a minimum of 7 chars). How can I only validate the password if the password is being updated?
You need to use the merge_validates_* config methods instead of the validates_* methods. The former keeps the conditionals (like ignore blank password) and the latter overwrites them. That should clear everything up. And don't use the assignment on the merge_* methods.
a.merge_validates_length_of_password_field_options :minimum => 7
I think the config you are looking for is found here
http://rdoc.info/github/binarylogic/authlogic/master/Authlogic/ActsAsAuthentic/Password/Config#ignore_blank_passwords-instance_method
Unless its a new user, if no password is supplied it does not validate the password.

Excess errors on model from somewhere

I have a User model, and use an acts_as_authentic (from authlogic) on it. My User model have 3 validations on username and looks as following:
User < ActiveRecord::Base
acts_as_authentic
validates_presence_of :username
validates_length_of :username, :within => 4..40
validates_uniqueness_of :username
end
I'm writing a test to see my validations in action. Somehow, I get 2 errors instead of one when validating a uniqueness of a name. To see excess error, I do the following test:
describe User do
before(:each) do
#user = Factory.build(:user)
end
it "should have a username longer then 3 symbols" do
#user2 = Factory(:user)
#user.username = #user2.username
#user.save
puts #user.errors.inspect
end
end
I got 2 errors on username: #errors={"username"=>["has already been taken", "has already been taken"]}.
Another case of problem is when I set username to nil. Somehow I get four validation errors instead of three: #errors={"username"=>["is too short (minimum is 3 characters)", "should use only letters, numbers, spaces, and .-_# please.", "can't be blank", "is too short (minimum is 4 characters)"]}
I think authlogic is one that causes this strange behaviour. But I can't even imagine on how to solve that. Any ideas?
I think this is because authlogic has some build in validations and both them and your validations are run.
Google seems to give some answers to this topic. This one is for example for password field.

validating password format in Authlogic

Is there a way to get Authlogic to validate the format of a password, for instance must contain at least one letter and at least one number? The omission of a validates_format_of_password_options method to be used in the acts_as_authentic config block seems to indicate that Authlogic has the opinion that one should not be imposing such a constraint on one's users.
I thought I would simply put in a normal ActiveRecord validates_format_of :password, but this means that a current_user object I build is inherently invalid, as I can't retrieve the plaintext password (and wouldn't be storing it in that object even if I could!). Upon detecting that my current_user is invalid, Rails or Authlogic (not sure which, since I'm fairly new to both) directs me to my 'edit user' page with a validation error for its password.
requires no monkey-patching, but not tied to any future Authlogic changes. Just add this to your User model:
validates_format_of :password, :with => /^(?=.\d)(?=.([a-z]|[A-Z]))([\x20-\x7E]){6,40}$/, :if => :require_password?, :message => "must include one number, one letter and be between 6 and 40 characters"
Of course you can alter the regex to suite your needs.
You can use the configuration options given by acts_as_authentic like so:
# Configuration is easy:
#
# acts_as_authentic do |c|
# c.my_configuration_option = my_value
# end
#
# See the various sub modules for the configuration they provide.
If you go to the modules in the gem you can see additional options they provide. For example if I want to change the default options of the password's length validation:
acts_as_authentic do |c|
c.merge_validates_length_of_password_field_options({:minimum => 3})
end
You can look inside the acts_as_authentic folder in your "(gems || plugins)/authlogic/acts_as_authentic/" directory for more options. Cheers!

Resources