mirror of
https://github.com/openfoodfoundation/openfoodnetwork
synced 2026-02-15 23:57:48 +00:00
Merge pull request #22 from Matt-Yorkley/sanitizer-service
Content Sanitizer
This commit is contained in:
@@ -1,8 +1,6 @@
|
||||
require "open_food_network/scope_variant_to_hub"
|
||||
|
||||
class Api::ProductSerializer < ActiveModel::Serializer
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
|
||||
attributes :id, :name, :permalink, :meta_keywords
|
||||
attributes :group_buy, :notes, :description, :description_html
|
||||
attributes :properties_with_values, :price
|
||||
@@ -18,17 +16,12 @@ class Api::ProductSerializer < ActiveModel::Serializer
|
||||
|
||||
# return an unformatted descripton
|
||||
def description
|
||||
return unless d = strip_tags(object.description&.strip)
|
||||
|
||||
ProductDescriptionFilter.filter(d)
|
||||
sanitizer.strip_content(object.description)
|
||||
end
|
||||
|
||||
# return a sanitized html description
|
||||
def description_html
|
||||
ProductDescriptionFilter.filter(
|
||||
sanitize(object.description, tags: ["p", "b", "strong", "em", "i", "a", "u"],
|
||||
attributes: ["href", "target"]).to_s.html_safe
|
||||
)
|
||||
sanitizer.sanitize_content(object.description).html_safe
|
||||
end
|
||||
|
||||
def properties_with_values
|
||||
@@ -50,4 +43,10 @@ class Api::ProductSerializer < ActiveModel::Serializer
|
||||
object.master.price_with_fees(options[:current_distributor], options[:current_order_cycle])
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def sanitizer
|
||||
@sanitizer ||= ContentSanitizer.new
|
||||
end
|
||||
end
|
||||
|
||||
36
app/services/content_sanitizer.rb
Normal file
36
app/services/content_sanitizer.rb
Normal file
@@ -0,0 +1,36 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
# Sanitizes and cleans up user-provided content that may contain tags, special characters, etc.
|
||||
|
||||
class ContentSanitizer
|
||||
include ActionView::Helpers::SanitizeHelper
|
||||
|
||||
ALLOWED_TAGS = ["p", "b", "strong", "em", "i", "a", "u"].freeze
|
||||
ALLOWED_ATTRIBUTES = ["href", "target"].freeze
|
||||
FILTERED_CHARACTERS = {
|
||||
"&amp;" => "&",
|
||||
"&" => "&",
|
||||
" " => " "
|
||||
}.freeze
|
||||
|
||||
def strip_content(content)
|
||||
content = strip_tags(content.to_s.strip)
|
||||
|
||||
filter_characters(content) if content.length
|
||||
end
|
||||
|
||||
def sanitize_content(content)
|
||||
content = sanitize(content.to_s, tags: ALLOWED_TAGS, attributes: ALLOWED_ATTRIBUTES)
|
||||
|
||||
filter_characters(content) if content.length
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def filter_characters(content)
|
||||
FILTERED_CHARACTERS.each do |character, sub|
|
||||
content = content.gsub(character, sub)
|
||||
end
|
||||
content
|
||||
end
|
||||
end
|
||||
@@ -1,16 +0,0 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class ProductDescriptionFilter
|
||||
FILTERED_CHARACTERS = {
|
||||
"&amp;" => "&",
|
||||
"&" => "&",
|
||||
" " => " "
|
||||
}.freeze
|
||||
|
||||
def self.filter(descripton)
|
||||
FILTERED_CHARACTERS.each do |character, sub|
|
||||
descripton = descripton.gsub(character, sub)
|
||||
end
|
||||
descripton
|
||||
end
|
||||
end
|
||||
Reference in New Issue
Block a user