# module Devise::Models::DatabaseAuthenticatable

Authenticatable Module, responsible for encrypting password and validating authenticity of a user while signing in.

## Options

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.

## Examples

    User.find(1).valid_password?('password123')         # returns true/false

### Public Instance Methods

after_database_authentication() click to toggle source

    # File lib/devise/models/database_authenticatable.rb, line 94
    def after_database_authentication
    end

authenticatable_salt() click to toggle source

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

clean_up_passwords() click to toggle source

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

password=(new_password) click to toggle source

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_with_password(params, *options) click to toggle source

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

update_without_password(params, *options) click to toggle source

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

valid_password?(password) click to toggle source

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

### Protected Instance Methods

password_digest(password) click to toggle source

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