Move param filtering to its own object and make all finder methods pass through it, closes #1413.

This commit is contained in:
José Valim
2011-11-10 10:14:02 -02:00
parent ab54e1f66a
commit dc8aa9ef83
5 changed files with 65 additions and 39 deletions

View File

@@ -9,6 +9,7 @@ module Devise
autoload :Delegator, 'devise/delegator'
autoload :FailureApp, 'devise/failure_app'
autoload :OmniAuth, 'devise/omniauth'
autoload :ParamFilter, 'devise/param_filter'
autoload :PathChecker, 'devise/path_checker'
autoload :Schema, 'devise/schema'
autoload :TestHelpers, 'devise/test_helpers'

View File

@@ -112,10 +112,11 @@ module Devise
# end
#
def find_for_authentication(conditions)
conditions = filter_auth_params(conditions.dup)
(case_insensitive_keys || []).each { |k| conditions[k].try(:downcase!) }
(strip_whitespace_keys || []).each { |k| conditions[k].try(:strip!) }
to_adapter.find_first(conditions)
find_first_by_auth_conditions(conditions)
end
def find_first_by_auth_conditions(conditions)
to_adapter.find_first devise_param_filter.filter(conditions)
end
# Find an initialize a record setting an error if it can't be found.
@@ -125,14 +126,11 @@ module Devise
# Find an initialize a group of attributes based on a list of required attributes.
def find_or_initialize_with_errors(required_attributes, attributes, error=:invalid) #:nodoc:
(case_insensitive_keys || []).each { |k| attributes[k].try(:downcase!) }
(strip_whitespace_keys || []).each { |k| attributes[k].try(:strip!) }
attributes = attributes.slice(*required_attributes)
attributes.delete_if { |key, value| value.blank? }
if attributes.size == required_attributes.size
record = to_adapter.find_first(filter_auth_params(attributes))
record = find_first_by_auth_conditions(attributes)
end
unless record
@@ -150,16 +148,8 @@ module Devise
protected
# Force keys to be string to avoid injection on mongoid related database.
def filter_auth_params(conditions)
conditions.each do |k, v|
conditions[k] = v.to_s if auth_param_requires_string_conversion?(v)
end if conditions.is_a?(Hash)
end
# Determine which values should be transformed to string or passed as-is to the query builder underneath
def auth_param_requires_string_conversion?(value)
true unless value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.is_a?(Fixnum)
def devise_param_filter
@devise_param_filter ||= Devise::ParamFilter.new(case_insensitive_keys, strip_whitespace_keys)
end
# Generate a token by looping and ensuring does not already exist.

View File

@@ -0,0 +1,41 @@
module Devise
class ParamFilter
def initialize(case_insensitive_keys, strip_whitespace_keys)
@case_insensitive_keys = case_insensitive_keys || []
@strip_whitespace_keys = strip_whitespace_keys || []
end
def filter(conditions)
conditions = stringify_params(conditions.dup)
@case_insensitive_keys.each do |k|
value = conditions[k]
next unless value.respond_to?(:downcase)
conditions[k] = value.downcase
end
@strip_whitespace_keys.each do |k|
value = conditions[k]
next unless value.respond_to?(:strip)
conditions[k] = value.strip
end
conditions
end
# Force keys to be string to avoid injection on mongoid related database.
def stringify_params(conditions)
return conditions unless conditions.is_a?(Hash)
conditions.each do |k, v|
conditions[k] = v.to_s if param_requires_string_conversion?(v)
end
end
private
# Determine which values should be transformed to string or passed as-is to the query builder underneath
def param_requires_string_conversion?(value)
true unless value.is_a?(TrueClass) || value.is_a?(FalseClass) || value.is_a?(Fixnum)
end
end
end