Authenticatable Module, responsible for encrypting password and validating authenticity of a user while signing in.
DatabaseAuthenticable adds the following options to devise_for:
* +pepper+: a random string used to provide a more secure hash. Use `rake secret` to generate new keys. * +stretches+: the cost given to bcrypt.
User.find(1).valid_password?('password123') # returns true/false
# File lib/devise/models/database_authenticatable.rb, line 94 def after_database_authentication end
A reliable way to expose the salt regardless of the implementation.
# File lib/devise/models/database_authenticatable.rb, line 98 def authenticatable_salt self.encrypted_password[0,29] if self.encrypted_password end
Set password and password confirmation to nil
# File lib/devise/models/database_authenticatable.rb, line 45 def clean_up_passwords self.password = self.password_confirmation = nil end
Generates password encryption based on the given value.
# File lib/devise/models/database_authenticatable.rb, line 31 def password=(new_password) @password = new_password self.encrypted_password = password_digest(@password) if @password.present? end
Update record attributes when :current_password matches, otherwise returns error on :current_password. It also automatically rejects :password and :password_confirmation if they are blank.
# File lib/devise/models/database_authenticatable.rb, line 52 def update_with_password(params, *options) current_password = params.delete(:current_password) if params[:password].blank? params.delete(:password) params.delete(:password_confirmation) if params[:password_confirmation].blank? end result = if valid_password?(current_password) update_attributes(params, *options) else self.attributes = params self.valid? self.errors.add(:current_password, current_password.blank? ? :blank : :invalid) false end clean_up_passwords result end
Updates record attributes without asking for the current password. Never allows to change the current password. If you are using this method, you should probably override this method to protect other attributes you would not like to be updated without a password.
Example:
def update_without_password(params={}) params.delete(:email) super(params) end
# File lib/devise/models/database_authenticatable.rb, line 85 def update_without_password(params, *options) params.delete(:password) params.delete(:password_confirmation) result = update_attributes(params, *options) clean_up_passwords result end
Verifies whether an password (ie from sign in) is the user password.
# File lib/devise/models/database_authenticatable.rb, line 37 def valid_password?(password) return false if encrypted_password.blank? bcrypt = ::BCrypt::Password.new(self.encrypted_password) password = ::BCrypt::Engine.hash_secret("#{password}#{self.class.pepper}", bcrypt.salt) Devise.secure_compare(password, self.encrypted_password) end
Digests the password using bcrypt.
# File lib/devise/models/database_authenticatable.rb, line 105 def password_digest(password) ::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s end