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 98 def after_database_authentication end
A reliable way to expose the salt regardless of the implementation.
# File lib/devise/models/database_authenticatable.rb, line 102 def authenticatable_salt encrypted_password[0,29] if encrypted_password end
Set password and password confirmation to nil
# File lib/devise/models/database_authenticatable.rb, line 49 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 35 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 56 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.assign_attributes(params, *options) 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 89 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 41 def valid_password?(password) return false if encrypted_password.blank? bcrypt = ::BCrypt::Password.new(encrypted_password) password = ::BCrypt::Engine.hash_secret("#{password}#{self.class.pepper}", bcrypt.salt) Devise.secure_compare(password, encrypted_password) end
Digests the password using bcrypt.
# File lib/devise/models/database_authenticatable.rb, line 109 def password_digest(password) ::BCrypt::Password.create("#{password}#{self.class.pepper}", :cost => self.class.stretches).to_s end
# File lib/devise/models/database_authenticatable.rb, line 30 def self.required_fields(klass) [:encrypted_password] + klass.authentication_keys end