Improve logging of ActiveModel::MassAssignmentSecurity::Sanitizer
This commit is contained in:
parent
78b6fdd89f
commit
80a2c9e5db
@ -229,7 +229,7 @@ def accessible_attributes_configs
|
||||
protected
|
||||
|
||||
def sanitize_for_mass_assignment(attributes, role = nil)
|
||||
_mass_assignment_sanitizer.sanitize(attributes, mass_assignment_authorizer(role))
|
||||
_mass_assignment_sanitizer.sanitize(self.class, attributes, mass_assignment_authorizer(role))
|
||||
end
|
||||
|
||||
def mass_assignment_authorizer(role)
|
||||
|
@ -2,18 +2,18 @@ module ActiveModel
|
||||
module MassAssignmentSecurity
|
||||
class Sanitizer
|
||||
# Returns all attributes not denied by the authorizer.
|
||||
def sanitize(attributes, authorizer)
|
||||
def sanitize(klass, attributes, authorizer)
|
||||
rejected = []
|
||||
sanitized_attributes = attributes.reject do |key, value|
|
||||
rejected << key if authorizer.deny?(key)
|
||||
end
|
||||
process_removed_attributes(rejected) unless rejected.empty?
|
||||
process_removed_attributes(klass, rejected) unless rejected.empty?
|
||||
sanitized_attributes
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def process_removed_attributes(attrs)
|
||||
def process_removed_attributes(klass, attrs)
|
||||
raise NotImplementedError, "#process_removed_attributes(attrs) suppose to be overwritten"
|
||||
end
|
||||
end
|
||||
@ -32,8 +32,21 @@ def logger?
|
||||
@target.respond_to?(:logger) && @target.logger
|
||||
end
|
||||
|
||||
def process_removed_attributes(attrs)
|
||||
logger.warn "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
|
||||
|
||||
@ -42,9 +55,9 @@ def initialize(target = nil)
|
||||
super()
|
||||
end
|
||||
|
||||
def process_removed_attributes(attrs)
|
||||
def process_removed_attributes(klass, attrs)
|
||||
return if (attrs - insensitive_attributes).empty?
|
||||
raise ActiveModel::MassAssignmentSecurity::Error.new(attrs)
|
||||
raise ActiveModel::MassAssignmentSecurity::Error.new(klass, attrs)
|
||||
end
|
||||
|
||||
def insensitive_attributes
|
||||
@ -53,8 +66,8 @@ def insensitive_attributes
|
||||
end
|
||||
|
||||
class Error < StandardError
|
||||
def initialize(attrs)
|
||||
super("Can't mass-assign protected attributes: #{attrs.join(', ')}")
|
||||
def initialize(klass, attrs)
|
||||
super("Can't mass-assign protected attributes for #{klass.name}: #{attrs.join(', ')}")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -19,7 +19,7 @@ def setup
|
||||
|
||||
test "sanitize attributes" do
|
||||
original_attributes = { 'first_name' => 'allowed', 'admin' => 'denied' }
|
||||
attributes = @logger_sanitizer.sanitize(original_attributes, @authorizer)
|
||||
attributes = @logger_sanitizer.sanitize(self.class, original_attributes, @authorizer)
|
||||
|
||||
assert attributes.key?('first_name'), "Allowed key shouldn't be rejected"
|
||||
assert !attributes.key?('admin'), "Denied key should be rejected"
|
||||
@ -29,14 +29,14 @@ def setup
|
||||
original_attributes = { 'first_name' => 'allowed', 'admin' => 'denied' }
|
||||
log = StringIO.new
|
||||
self.logger = ActiveSupport::Logger.new(log)
|
||||
@logger_sanitizer.sanitize(original_attributes, @authorizer)
|
||||
@logger_sanitizer.sanitize(self.class, original_attributes, @authorizer)
|
||||
assert_match(/admin/, log.string, "Should log removed attributes: #{log.string}")
|
||||
end
|
||||
|
||||
test "debug mass assignment removal with StrictSanitizer" do
|
||||
original_attributes = { 'first_name' => 'allowed', 'admin' => 'denied' }
|
||||
assert_raise ActiveModel::MassAssignmentSecurity::Error do
|
||||
@strict_sanitizer.sanitize(original_attributes, @authorizer)
|
||||
@strict_sanitizer.sanitize(self.class, original_attributes, @authorizer)
|
||||
end
|
||||
end
|
||||
|
||||
@ -44,7 +44,7 @@ def setup
|
||||
original_attributes = {'id' => 1, 'first_name' => 'allowed'}
|
||||
|
||||
assert_nothing_raised do
|
||||
@strict_sanitizer.sanitize(original_attributes, @authorizer)
|
||||
@strict_sanitizer.sanitize(self.class, original_attributes, @authorizer)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
class CustomSanitizer < ActiveModel::MassAssignmentSecurity::Sanitizer
|
||||
|
||||
def process_removed_attributes(attrs)
|
||||
def process_removed_attributes(klass, attrs)
|
||||
raise StandardError
|
||||
end
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user