require "authlogic/acts_as_authentic/queries/find_with_case"
module Authlogic
module ActsAsAuthentic
# Handles everything related to the login field.
module Login
def self.included(klass)
klass.class_eval do
extend Config
add_acts_as_authentic_module(Methods)
end
end
# Configuration for the login field.
module Config
# The name of the login field in the database.
#
# * Default: :login or :username, if they exist
# * Accepts: Symbol
def login_field(value = nil)
rw_config(:login_field, value, first_column_to_exist(nil, :login, :username))
end
alias_method :login_field=, :login_field
# Whether or not to validate the login field
#
# * Default: true
# * Accepts: Boolean
def validate_login_field(value = nil)
rw_config(:validate_login_field, value, true)
end
alias_method :validate_login_field=, :validate_login_field
# A hash of options for the validates_length_of call for the login
# field. Allows you to change this however you want.
#
# Keep in mind this is ruby. I wanted to keep this as flexible as
# possible, so you can completely replace the hash or merge options into
# it. Checkout the convenience function
# merge_validates_length_of_login_field_options to merge options.
#
# * Default: {:within => 3..100}
# * Accepts: Hash of options accepted by validates_length_of
def validates_length_of_login_field_options(value = nil)
rw_config(:validates_length_of_login_field_options, value, within: 3..100)
end
alias_method(
:validates_length_of_login_field_options=,
:validates_length_of_login_field_options
)
# A convenience function to merge options into the
# validates_length_of_login_field_options. So instead of:
#
# self.validates_length_of_login_field_options =
# validates_length_of_login_field_options.merge(:my_option => my_value)
#
# You can do this:
#
# merge_validates_length_of_login_field_options :my_option => my_value
def merge_validates_length_of_login_field_options(options = {})
self.validates_length_of_login_field_options =
validates_length_of_login_field_options.merge(options)
end
# A hash of options for the validates_format_of call for the login
# field. Allows you to change this however you want.
#
# Keep in mind this is ruby. I wanted to keep this as flexible as
# possible, so you can completely replace the hash or merge options into
# it. Checkout the convenience function
# merge_validates_format_of_login_field_options to merge options.
#
# * Default:
#
# {
# :with => Authlogic::Regex.login,
# :message => lambda {
# I18n.t(
# 'error_messages.login_invalid',
# :default => "should use only letters, numbers, spaces, and .-_@+ please."
# )
# }
# }
#
# * Accepts: Hash of options accepted by validates_format_of
def validates_format_of_login_field_options(value = nil)
rw_config(
:validates_format_of_login_field_options,
value,
with: Authlogic::Regex::LOGIN,
message: proc do
I18n.t(
"error_messages.login_invalid",
default: "should use only letters, numbers, spaces, and .-_@+ please."
)
end
)
end
alias_method(
:validates_format_of_login_field_options=,
:validates_format_of_login_field_options
)
# See merge_validates_length_of_login_field_options. The same thing,
# except for validates_format_of_login_field_options
def merge_validates_format_of_login_field_options(options = {})
self.validates_format_of_login_field_options =
validates_format_of_login_field_options.merge(options)
end
# A hash of options for the validates_uniqueness_of call for the login
# field. Allows you to change this however you want.
#
# Keep in mind this is ruby. I wanted to keep this as flexible as
# possible, so you can completely replace the hash or merge options into
# it. Checkout the convenience function
# merge_validates_format_of_login_field_options to merge options.
#
# * Default:
#
# {
# :case_sensitive => false,
# :scope => validations_scope,
# :if => "#{login_field}_changed?".to_sym
# }
#
# * Accepts: Hash of options accepted by validates_uniqueness_of
def validates_uniqueness_of_login_field_options(value = nil)
rw_config(
:validates_uniqueness_of_login_field_options,
value,
case_sensitive: false,
scope: validations_scope,
if: "#{login_field}_changed?".to_sym
)
end
alias_method(
:validates_uniqueness_of_login_field_options=,
:validates_uniqueness_of_login_field_options
)
# See merge_validates_length_of_login_field_options. The same thing,
# except for validates_uniqueness_of_login_field_options
def merge_validates_uniqueness_of_login_field_options(options = {})
self.validates_uniqueness_of_login_field_options =
validates_uniqueness_of_login_field_options.merge(options)
end
# This method allows you to find a record with the given login. If you
# notice, with Active Record you have the UniquenessValidator class.
# They give you a :case_sensitive option. I handle this in the same
# manner that they handle that. If you are using the login field, set
# false for the :case_sensitive option in
# validates_uniqueness_of_login_field_options and the column doesn't
# have a case-insensitive collation, this method will modify the query
# to look something like:
#
# "LOWER(#{quoted_table_name}.#{login_field}) = LOWER(#{login})"
#
# If you don't specify this it just uses a regular case-sensitive search
# (with the binary modifier if necessary):
#
# "BINARY #{login_field} = #{login}"
#
# The above also applies for using email as your login, except that you
# need to set the :case_sensitive in
# validates_uniqueness_of_email_field_options to false.
#
# @api public
def find_by_smart_case_login_field(login)
if login_field
find_with_case(
login_field,
login,
validates_uniqueness_of_login_field_options[:case_sensitive] != false
)
else
find_with_case(
email_field,
login,
validates_uniqueness_of_email_field_options[:case_sensitive] != false
)
end
end
private
# @api private
def find_with_case(field, value, sensitive)
Queries::FindWithCase.new(self, field, value, sensitive).execute
end
end
# All methods relating to the login field
module Methods
# Adds in various validations, modules, etc.
def self.included(klass)
klass.class_eval do
if validate_login_field && login_field
validates_length_of login_field, validates_length_of_login_field_options
validates_format_of login_field, validates_format_of_login_field_options
validates_uniqueness_of login_field, validates_uniqueness_of_login_field_options
end
end
end
end
end
end
end