I use Authlogic for authentication in my Rails project.
It provide default validation for email and login field.
But, I want to allow email to be null for join because my service is for mobile and it is difficult to insert email field in mobile device.
How can I skip email validation with Authlogic in Rails?
class User < ActiveRecord::Base
acts_as_authentic do |c|
c.validate_email_field = false
end
end
I was digging for this one for awhile - extending on what jaehyun said - say you want to skip email validation in Authlogic on a conditional basis
acts_as_authentic do |c|
c.merge_validates_length_of_email_field_options({:unless => Proc.new { |user| user.has_no_email? }})
c.merge_validates_format_of_email_field_options({:unless => Proc.new { |user| user.has_no_email? }})
end
Related
I'm using has_secure_password in a User model. I have implemented a way for users to change their password outside of the model, but to keep things DRY, I'm trying to move the validations needed from the controller to the model.
The User model looks something like this:
class User
include Mongoid::Document
include ActiveModel::SecurePassword
has_secure_password
field: :password_digest, type: String
attr_accessible :password, :password_confirmation, :current_password
end
Users change their passwords by submitting the following:
user[current_password] - Currently stored password
user[password] - New password
user[password_confirmation] - New password confirmation
I'm using update_attributes(params[:user]) on the User model for the current user. My problem is that calling update_attributes updates the password_digest before using validations, so the following code won't work:
def password_validation_required?
password_digest.blank? || !password.blank? || !password_confirmation.blank?
end
validate(on: :update, if: :password_validation_required?) do
unless authenticate(current_password)
add(:current_password, 'invalid password')
end
end
authenticate is authenticating based on the new password_digest generated from user[password]. Is there an elegant way to access the old password_digest value for authentication? One idea I had was to re-query the user to gain access to another authenticate method that will authenticate against the old password_digest value. The problem is that it's not a clean solution.
I think this one's a bit cleaner than #Parazuce's:
validate :validates_current_password
private
def validates_current_password
return if password_digest_was.nil? || !password_digest_changed?
unless BCrypt::Password.new(password_digest_was) == current_password
errors.add(:current_password, "is incorrect")
end
end
The password_digest field has ActiveModel::Dirty methods associated with it, so I decided to go with:
validate(on: :update, if: :password_validation_required?) do
unless BCrypt::Password.new(password_digest_was) == current_password
errors.add(:current_password, "is incorrect")
end
end
This prevents the need to override password= with additional logic which could introduce bugs in the future if other features used password=.
In my rails 3 application, I have a user sign up form. I have it require and validate the password for signing up, however, if a user connects using omniauth, I cannot retrieve their password which brings me to my question. How can I make it so the password field does not get validated in certain cases?
I am aware that I can do user.save(:validate => false), but that takes off all the validations.
P.S. i watched railscasts episode 235 & 236, however Ryan Bates does it with Devise, and I am doing it with my own login system.
You can write your own validation for password with a check if the user is using oauth.
Check this method: validate(*args, &block)
you can add conditions to the validation in the model:
validates_presence_of :password, :unless => :account_from_omniauth?
assuming you also define the method
def account_from_omniauth?
true if //...your conditions
false
end
Rails 3.0
Authlogic 2.1.6
Using username (not email) for authentication.
Authlogic requires username to be at least 3 characters.
How does one convince Authologic to allow a 2 character username?
Thanks for your help.
You can override the authlogic default username length by adding the following code to models/user.rb
class User < ActiveRecord::Base
acts_as_authentic do |c|
c.merge_validates_length_of_login_field_options :within => 4..100
end
#....
end
This assumes your user model is called User
When a user registers on my app they have to confirm their email, powered by Devise + Rails 3.
The email address defines the user's permissions so I don't want the user to be able to change it once registered. so removed :email from the users.rb attr_accessible which worked for a logged in user, but now user's can't register.
What's the right way to handle this? So users can't update their email but can register with their email using devise.
Thanks
This is the perfect case for a custom validator. Since Rails3, they are much easier to do than before.
class ImmutableValidator < ActiveModel::EachValidator
def validate_each(record, attribute, value)
record.errors[attribute] << "cannot be changed after creation" if record.send("#{attribute}_changed?") && !record.new_record?
end
end
class User < ActiveRecord::Base
validates :email, :immutable => true
end
attr_readonly :email
That solved the problem easily.
https://groups.google.com/forum/#!topic/plataformatec-devise/skCarCHr0p8
I would personally leave the attr_accessible for :email and just remove the email field from the edit view. Also, you will want to strip out any email param from the params hash in the update action.
I'm using Authlogic to manage my user sessions. I'm using the LDAP add-on, so I have the following in my users model
acts_as_authentic do |c|
c.validate_password_field = false
end
The problem is that recently I found out that there will be some users inside the application that won't be part of the LDAP (and can't be added!). So I would need to validate SOME passwords against the database and the others against the LDAP.
The users whose password will be validated against the database will have an specific attribute that will tell me that that password will be validated in my database.
How can I manage that? Is it possible that the validate_password_field receives a "variable"? That way I could create some method that will return true/false depending on where the password validation will be done?
Thanks!
Nicolás Hock Isaza
You should be able to do this:
acts_as_authentic do |u|
u.validate_password_field = true
authentic_options = {:unless => Proc.new{|c| c.ldap}}
u.merge_validates_confirmation_of_password_field_options(authentic_options)
u.merge_validates_length_of_password_confirmation_field_options(authentic_options)
u.merge_validates_length_of_password_field_options(authentic_options)
end
If you were writing the validation yourself (not using authlogic) you would want to do something like this in the validation:
validates_presence_of :password, :unless => Proc.new{|u| u.ldap }
Since authlogic provides the 3 helper methods to add options to the end of the validates methods, you can use this to turn off validations when using LDAP.
You should be able to do an unless in your validation.
acts_as_authentic do |c|
c.validate_password_field = false if c.ldap
end
Or even (as your model field is a boolean) :
acts_as_authentic do |c|
c.validate_password_field = c.ldap
end