module Negroni::Models::Authenticable
The `Authenticable` module should be included in any application classes that should be authenticable via a JSON web token.
This module makes a few assumptions about your class:
* It has an `email` attribute
Public Class Methods
Required fields for this module
# File lib/negroni/models/authenticable.rb, line 26 def self.required_fields(klass) [:password_digest] + klass.authentication_keys end
Public Instance Methods
Reliably returns the salt, regardless of implementation
@return [String]
# File lib/negroni/models/authenticable.rb, line 136 def authenticable_salt password_digest[0, 29] if password_digest end
Authenticates the including class with `unencrypted_password`.
@param unencrypted_password [String] the password to auth against
@return [Boolean] if the user is successfully authenticated
# File lib/negroni/models/authenticable.rb, line 115 def authenticate(unencrypted_password) valid_password?(unencrypted_password) && self end
Authenticates the including class with `unencrypted_password`.
@param unencrypted_password [String] the password to auth against
@raise [ActiveRecord::RecordNotFound] if the user is not successfully
authenticated
@return [Boolean] if the user is successfully authenticated
# File lib/negroni/models/authenticable.rb, line 127 def authenticate!(unencrypted_password) authenticate(unencrypted_password) || raise('Bad password!') end
Destroy record when :current_password matches, otherwise returns error on :current_password. It also automatically rejects :current_password if it is blank.
@param current_password [String] the current password for the record
# File lib/negroni/models/authenticable.rb, line 95 def destroy_with_password(current_password) result = if valid_password?(current_password) destroy # rubocop:disable Rails/SaveBang else valid? message = current_password.blank? ? :blank : :invalid errors.add(:current_password, message) false end result end
Generates a hashed password based on the given value.
# File lib/negroni/models/authenticable.rb, line 31 def password=(new_password) @password = new_password self.password_digest = digest_password(@password) if @password.present? end
Update record attributes when :current_password matches, otherwise returns error on :current_password.
This method also rejects the password field if it is blank (allowing users to change relevant information like the e-mail without changing their password). In case the password field is rejected, the confirmation is also rejected as long as it is also blank.
@param params [Hash] params from the controller @param options [Hash] a hash of options
# File lib/negroni/models/authenticable.rb, line 53 def update_with_password(params, *options) current_password = params.delete :current_password params = _sanitize_password_params(params) result = if valid_password?(current_password) update_attributes(params, *options) else _invalid_update(current_password, params, *options) end clean_up_passwords result end
Updates record attributes without asking for the current password. Never allows a change to 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, *options) params.delete(:email) super(params) end
# File lib/negroni/models/authenticable.rb, line 80 def update_without_password(params, *options) params.delete(:password) params.delete(:password_confirmation) result = update_attributes(params, *options) clean_up_passwords result end
Checks if a password is valid for the given instance
# File lib/negroni/models/authenticable.rb, line 37 def valid_password?(password) Negroni::Encryptor.compare(self.class, password_digest, password) end
Protected Instance Methods
Cleans up the @password and @password_confirmation ivars
# File lib/negroni/models/authenticable.rb, line 157 def clean_up_passwords self.password = self.password_confirmation = nil end
# File lib/negroni/models/authenticable.rb, line 142 def digest_password(password) Negroni::Encryptor.digest(self.class, password) end
@!group Callbacks
# File lib/negroni/models/authenticable.rb, line 152 def send_password_change_notification send_auth_notification(:password_change) end
# File lib/negroni/models/authenticable.rb, line 146 def send_password_change_notification? self.class.send_password_change_notification && password_digest_changed? end
Private Instance Methods
# File lib/negroni/models/authenticable.rb, line 179 def _invalid_update(current_password, params, *options) _sanitize_password_params(params, remove_all: true) assign_attributes(params, *options) valid? message = current_password.blank? ? :blank : :invalid errors.add(:current_password, message) false end
remove :password and :password_confirmation if they are present
@param params [Hash] the params hash to sanitize @return [Hash] the sanitized params
# File lib/negroni/models/authenticable.rb, line 169 def _sanitize_password_params(params, remove_all: false) params.delete(:password) if params[:password].blank? || remove_all if params[:password_confirmation].blank? || remove_all params.delete(:password_confirmation) end params end