diff options
Diffstat (limited to 'activemodel/lib/active_model/mass_assignment_security/sanitizer.rb')
-rw-r--r-- | activemodel/lib/active_model/mass_assignment_security/sanitizer.rb | 65 |
1 files changed, 40 insertions, 25 deletions
diff --git a/activemodel/lib/active_model/mass_assignment_security/sanitizer.rb b/activemodel/lib/active_model/mass_assignment_security/sanitizer.rb index bbdddfb50d..dafb7cdff3 100644 --- a/activemodel/lib/active_model/mass_assignment_security/sanitizer.rb +++ b/activemodel/lib/active_model/mass_assignment_security/sanitizer.rb @@ -1,51 +1,63 @@ -require 'active_support/core_ext/module/delegation' - module ActiveModel module MassAssignmentSecurity - class Sanitizer - def initialize(target=nil) - end - + class Sanitizer #:nodoc: # Returns all attributes not denied by the authorizer. - def sanitize(attributes, authorizer) - sanitized_attributes = attributes.reject { |key, value| authorizer.deny?(key) } - debug_protected_attribute_removal(attributes, sanitized_attributes) + def sanitize(klass, attributes, authorizer) + rejected = [] + sanitized_attributes = attributes.reject do |key, value| + rejected << key if authorizer.deny?(key) + end + process_removed_attributes(klass, rejected) unless rejected.empty? sanitized_attributes end protected - def debug_protected_attribute_removal(attributes, sanitized_attributes) - removed_keys = attributes.keys - sanitized_attributes.keys - process_removed_attributes(removed_keys) if removed_keys.any? - end - - def process_removed_attributes(attrs) + def process_removed_attributes(klass, attrs) raise NotImplementedError, "#process_removed_attributes(attrs) suppose to be overwritten" end end - class LoggerSanitizer < Sanitizer - delegate :logger, :to => :@target - + class LoggerSanitizer < Sanitizer #:nodoc: def initialize(target) @target = target - super + super() + end + + def logger + @target.logger end def logger? @target.respond_to?(:logger) && @target.logger end - def process_removed_attributes(attrs) - logger.debug "WARNING: Can't mass-assign protected attributes: #{attrs.join(', ')}" if logger? + def backtrace + if defined? Rails + Rails.backtrace_cleaner.clean(caller) + else + caller + end + end + + def process_removed_attributes(klass, attrs) + if logger? + logger.warn do + "WARNING: Can't mass-assign protected attributes for #{klass.name}: #{attrs.join(', ')}\n" + + backtrace.map { |trace| "\t#{trace}" }.join("\n") + end + end end end - class StrictSanitizer < Sanitizer - def process_removed_attributes(attrs) + class StrictSanitizer < Sanitizer #:nodoc: + def initialize(target = nil) + super() + end + + def process_removed_attributes(klass, attrs) return if (attrs - insensitive_attributes).empty? - raise ActiveModel::MassAssignmentSecurity::Error, "Can't mass-assign protected attributes: #{attrs.join(', ')}" + raise ActiveModel::MassAssignmentSecurity::Error.new(klass, attrs) end def insensitive_attributes @@ -53,7 +65,10 @@ module ActiveModel end end - class Error < StandardError + class Error < StandardError #:nodoc: + def initialize(klass, attrs) + super("Can't mass-assign protected attributes for #{klass.name}: #{attrs.join(', ')}") + end end end end |