Skip to content

Instantly share code, notes, and snippets.

@rantler
Last active December 18, 2015 22:18
Show Gist options
  • Save rantler/5853394 to your computer and use it in GitHub Desktop.
Save rantler/5853394 to your computer and use it in GitHub Desktop.
Sanitizing Decorator
require 'rubygems'
require 'action_controller'
class Sanitizer
def initialize(model)
@delegate = model
end
def method_missing(method_name, *args, &block)
if sanitizable?(method_name)
sanitize(@delegate.send(method_name, *args, &block))
else
@delegate.send(method_name, *args, &block)
end
end
private
def sanitizable?(method_name)
@delegate.columns.select { |c| [:string, :text].include?(c.type) }.map{ |c| c.name.to_sym }.include?(method_name)
end
def sanitize(string)
ActionController::Base.helpers.sanitize(
string || 'No name',
:tags => %w(h3 h4 ul ol li p a strong em br font),
:attributes => %w(class id name rel data-width data-height data-tip data-tip-width data-tip-position size)
)
end
end
class Model
# Emulate AR columns array
def columns
klass = Struct.new(:name, :type)
[
klass.new('name', :string),
klass.new('address', :text),
klass.new('foo', :foo)
]
end
def initialize(name, address)
@name = name
@address = address
end
def name
@name
end
def address
@address
end
def foo
'foo'
end
end
m = Model.new('<strong>My Name</strong><script>alert(1)</script>', '<script>alert("pwned")</script><font size=23>1234</font> <em>Any</em> Street')
s = Sanitizer.new(m)
puts("name = #{m.name}")
puts("sanitized = #{s.name}")
puts("address = #{m.address}")
puts("sanitized = #{s.address}")
puts("foo = #{s.foo.inspect}")
puts("s.class = #{m.class.inspect}")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment