class NaClPassword::Concern::InstanceMethodsOnActivation

Public Class Methods

new(attribute, digest_attribute, **attribute_opts) click to toggle source
# File lib/nacl_password/concern.rb, line 108
def initialize(attribute, digest_attribute, **attribute_opts)
  # == Constants ============================================================
  confirmation_var = "@#{attribute}_confirmation"

  # == Attributes ===========================================================
  attr_reader attribute

  define_method("#{attribute}=") do |given_password|
    instance_variable_set("@#{attribute}", given_password.presence)

    if given_password.nil? || given_password.empty?
      self.__send__("#{digest_attribute}=", nil)
    else
      self.__send__(
        "#{digest_attribute}=",
        NaClPassword.generate(given_password)
      )
    end
  end

  define_method("#{attribute}_confirmation=") do |given_password|
    instance_variable_set(confirmation_var, given_password)
  end

  # == Boolean Methods ======================================================
  define_method("#{attribute}_length_valid?") do
    value = self.__send__(attribute)
    invalid = false

    if attribute_opts[:maximum].present?
      invalid ||= (value.length > attribute_opts[:maximum])
    end

    if attribute_opts[:minimum].present?
      invalid ||= (value.length < attribute_opts[:minimum])
    end

    !invalid
  end

  define_method("#{attribute}_confirmed?") do
    self.__send__(attribute) == self.instance_variable_get(confirmation_var)
  end

  define_method("#{attribute}_ready?") do |require_confirmation = false|
    value = self.__send__(attribute)
    if value.nil? || value.empty?
      self.__send__("#{digest_attribute}").present?
    else
      confirmation = self.instance_variable_get(confirmation_var)
      if !require_confirmation && (confirmation.nil? || confirmation.empty?)
        self.__send__("#{attribute}_length_valid?")
      else
        self.__send__("#{attribute}_confirmed?") \
        && self.__send__("#{attribute}_length_valid?")
      end
    end
  end

  # == Instance Methods =====================================================

  # Returns +self+ if the password is correct, otherwise +nil+.
  #
  #   class User < ActiveRecord::Base
  #     nacl_password validations: false
  #   end
  #
  #   user = User.new(name: 'david', password: 'mUc3m00RsqyRe')
  #   user.save
  #   user.authenticate_password('mUc3m00RsqyRe') # => user
  #   user.authenticate_password('notright')      # => nil
  define_method("authenticate_#{attribute}") do |given_password|
    return nil unless attribute_digest = __send__(digest_attribute)
    if NaClPassword.authenticate(attribute_digest, given_password)
      self
    end
  end

  alias_method :authenticate, :authenticate_password if attribute == :password
end