Skip to content

Instantly share code, notes, and snippets.

@ivan-kolmychek
Last active April 20, 2023 19:33
Show Gist options
  • Star 2 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save ivan-kolmychek/ee2fdc53f3e2c637271d to your computer and use it in GitHub Desktop.
Save ivan-kolmychek/ee2fdc53f3e2c637271d to your computer and use it in GitHub Desktop.
Rails 4: scrubber with customizeable lists of allowed tags and attributes, based on :strip from Loofah gem
# place this file to app/scrubbers/ directory
#
# This scrubber is analog of :strip build-in scrubber
# (http://rubydoc.info/github/flavorjones/loofah/master/Loofah/Scrubbers/Strip)
# with allowed @tags and @attributes lists.
# Fallback to default :strip behavior included.
class AllowedTagsScrubber < Loofah::Scrubber
def initialize(options={})
@direction = :bottom_up
@tags = options[:tags]
@attributes = options[:attributes]
end
def scrub(node)
scrub_node_attributes(node) and return CONTINUE if node_allowed?(node)
node.before node.children
node.remove
end
private
def scrub_node_attributes(node)
fallback_scrub_node_attributes(node) and return true unless @attributes.present? && @attributes.respond_to?(:include?)
node.attribute_nodes.each do |attr_node|
attr_node.remove unless @attributes.include?(attr_node.name)
end
end
def allowed_not_element_node_types
[ Nokogiri::XML::Node::TEXT_NODE, Nokogiri::XML::Node::CDATA_SECTION_NODE ]
end
def fallback_scrub_node_attributes(node)
Loofah::HTML5::Scrub.scrub_attributes(node)
end
def fallback_allowed_element_detection(node)
Loofah::HTML5::Scrub.allowed_element?(node.name)
end
def node_allowed?(node)
return fallback_allowed_element_detection(node) unless @tags.present? && @tags.respond_to?(:include?)
return true if allowed_not_element_node_types.include?(node.type)
return false unless node.type == Nokogiri::XML::Node::ELEMENT_NODE
@tags.include? node.name
end
end
module ApplicationHelper
...
def sanitize(string, options)
Loofah.fragment(string).scrub!(AllowedTagsScrubber.new(options)).to_s
end
...
end
# place this file to config/initializers/ directory
Rails.application.config.autoload_paths += [ Rails.root.join('app', 'scrubbers') ]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment