module Negroni::Models::Base

The `Base` module contains methods that should be included in all Negroni models. It holds common settings for all authentication, as well as some shared behavior across all modules.

## Options

Base adds the following options:

* `authentication_keys`: parameters used for authentication.
   Default [:email].

* `strip_whitespace_keys`: keys from which whitespace should be
   stripped prior to validation.  Default [:email].

Constants

SERIALIZATION_BLACKLIST

Blacklisted attributes for serialization.

Public Class Methods

required_fields(_klass) click to toggle source

Required fields for this module (none).

# File lib/negroni/models/base.rb, line 38
def self.required_fields(_klass)
  []
end

Public Instance Methods

active_for_auth?() click to toggle source

Returns whether or not the including class is active for authentication. This method is primarily intended to be overriden by other modules, including `Lockable`.

@return [Boolean]

# File lib/negroni/models/base.rb, line 67
def active_for_auth?
  true
end
inactive_message() click to toggle source

The message that will be populated if an inactive record attempts to authenticate.

@return [Symbol] the key of the translation to look up

# File lib/negroni/models/base.rb, line 75
def inactive_message
  :inactive
end
inspect() click to toggle source

Redefine inspect using serializable_hash, to ensure we don't accidentally leak passwords into exceptions.

# File lib/negroni/models/base.rb, line 100
def inspect
  inspection = serializable_hash.collect do |k, v|
    value = if respond_to?(:attribute_for_inspect)
              attribute_for_inspect(k)
            else
              v.inspect
            end

    "#{k}: #{value}"
  end

  "#<#{self.class} #{inspection.join(', ')}>"
end
serializable_hash(options = nil) click to toggle source

Redefine serializable_hash in models for more secure defaults. By default, it removes from the serializable model all attributes that are __not__ accessible. You can remove this default by using :force_except and passing a new list of attributes you want to exempt. All attributes given to :except will simply add names to exempt to Negroni internal list.

Calls superclass method
# File lib/negroni/models/base.rb, line 85
def serializable_hash(options = nil)
  options ||= {}
  options[:except] = Array(options[:except])

  if options[:force_except]
    options[:except].concat Array(options[:force_except])
  else
    options[:except].concat SERIALIZATION_BLACKLIST
  end

  super(options)
end
unauthenticated_message() click to toggle source

The message that will be populated if an invalid record attempts to authenticate.

@return [Symbol] the key of the translation to look up

# File lib/negroni/models/base.rb, line 58
def unauthenticated_message
  :invalid
end
valid_for_auth?() { |: true| ... } click to toggle source

Returns whether or not the including class is active for authentication. This method is primarily intended to be overriden by other modules, including `Lockable`.

Yields and returns the return value of the given block, if a block is given. Otherwise returns true.

@return [Boolean]

# File lib/negroni/models/base.rb, line 50
def valid_for_auth?
  block_given? ? yield : true
end

Protected Instance Methods

auth_mailer() click to toggle source
# File lib/negroni/models/base.rb, line 116
def auth_mailer
  Negroni.mailer
end
downcase_keys() click to toggle source

Downcase keys before validation

# File lib/negroni/models/base.rb, line 183
def downcase_keys
  self.class.case_insensitive_keys.each { |k| _apply(k, :downcase) }
end
send_auth_notification(notification, *args) click to toggle source

This is an internal method called every time Negroni needs to send a notification/mail. This can be overridden if you need to customize the e-mail delivery logic. For instance, if you are using a queue to deliver e-mails (delayed job, sidekiq, resque, etc), you must add the delivery to the queue just after the transaction was committed. To achieve this, you can override send_auth_notification to store the deliveries until the after_commit callback is triggered:

@example

class User
  negroni :authenticable, :confirmable

  after_commit :send_pending_notifications

  protected

  def send_auth_notification(notification, *args)
    # If the record is new or changed then delay the
    # delivery until the after_commit callback otherwise
    # send now because after_commit will not be called.
    if new_record? || changed?
      pending_notifications << [notification, args]
    else
      message = auth_mailer.send(notification, self, *args)
      Remove once we move to Rails 4.2+ only.
      if message.respond_to?(:deliver_now)
        message.deliver_now
      else
        message.deliver
      end
    end
  end

  def send_pending_notifications
    pending_notifications.each do |notification, args|
      message = auth_mailer.send(notification, self, *args)
      Remove once we move to Rails 4.2+ only.
      if message.respond_to?(:deliver_now)
        message.deliver_now
      else
        message.deliver
      end
    end

    # Empty the pending notifications array because the
    # after_commit hook can be called multiple times which
    # could cause multiple emails to be sent.
    pending_notifications.clear
  end

  def pending_notifications
    \@pending_notifications ||= []
  end
end
# File lib/negroni/models/base.rb, line 175
def send_auth_notification(notification, *args)
  message = auth_mailer.send(notification, self, *args)
  message.deliver_now
end
strip_whitespace() click to toggle source

Strip whitespace from requested keys before validation

# File lib/negroni/models/base.rb, line 188
def strip_whitespace
  self.class.strip_whitespace_keys.each { |k| _apply(k, :strip) }
end

Private Instance Methods

_apply(attr, method) click to toggle source

Apply `method` to `attr`

# File lib/negroni/models/base.rb, line 197
def _apply(attr, method)
  if self[attr]
    self[attr] = self[attr].try(method)
  elsif respond_to?(attr) && respond_to?("#{attr}=")
    new_value = send(attr).try(method)
    send("#{attr}=", new_value)
  end
end