diff options
Diffstat (limited to 'activemodel/lib/active_model/mass_assignment_security')
-rw-r--r-- | activemodel/lib/active_model/mass_assignment_security/permission_set.rb | 10 | ||||
-rw-r--r-- | activemodel/lib/active_model/mass_assignment_security/sanitizer.rb | 65 |
2 files changed, 45 insertions, 30 deletions
diff --git a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb index a1fcdf1a38..f104d0306c 100644 --- a/activemodel/lib/active_model/mass_assignment_security/permission_set.rb +++ b/activemodel/lib/active_model/mass_assignment_security/permission_set.rb @@ -2,10 +2,10 @@ require 'set' module ActiveModel module MassAssignmentSecurity - class PermissionSet < Set + class PermissionSet < Set #:nodoc: def +(values) - super(values.map(&:to_s)) + super(values.compact.map(&:to_s)) end def include?(key) @@ -13,7 +13,7 @@ module ActiveModel end def deny?(key) - raise NotImplementedError, "#deny?(key) suppose to be overwritten" + raise NotImplementedError, "#deny?(key) supposed to be overwritten" end protected @@ -23,14 +23,14 @@ module ActiveModel end end - class WhiteList < PermissionSet + class WhiteList < PermissionSet #:nodoc: def deny?(key) !include?(key) end end - class BlackList < PermissionSet + class BlackList < PermissionSet #:nodoc: def deny?(key) include?(key) 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 |