Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 0 additions & 3 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -41,9 +41,6 @@ gem 'rails-html-sanitizer'
# URI replacement
gem 'addressable'

# Converts links in Strings to HTML anchors
gem 'rinku'

# Sanitizes user content
gem 'sanitize'

Expand Down
2 changes: 0 additions & 2 deletions Gemfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,6 @@ GEM
actionpack (>= 5.0)
railties (>= 5.0)
rexml (3.2.5)
rinku (2.0.6)
roar (1.0.3)
representable (>= 2.0.1, <= 3.0.0)
roar-rails (1.0.1)
Expand Down Expand Up @@ -589,7 +588,6 @@ DEPENDENCIES
redis
representable (~> 3.0.0)
request_store
rinku
roar (= 1.0.3)
roo
rspec-instafail
Expand Down
9 changes: 4 additions & 5 deletions lib/user_html.rb
Original file line number Diff line number Diff line change
@@ -1,16 +1,15 @@
module UserHtml
mattr_accessor :sanitize_config

def self.link_and_sanitize(content)
linked_content = Rinku.auto_link(content, :urls)
Sanitize.fragment(linked_content, UserHtml.sanitize_config)
def self.sanitize(content)
Sanitize.fragment(content, UserHtml.sanitize_config)
end

module ActiveRecord
module Base
def user_html(*attributes)
attributes.each do |attribute|
filter_name = :"link_and_sanitize_#{attribute.to_s}"
filter_name = :"sanitize_#{attribute.to_s}"

class_exec do
before_validation filter_name
Expand All @@ -19,7 +18,7 @@ def user_html(*attributes)
content = send(attribute)
return if content.nil?

send("#{attribute}=", UserHtml.link_and_sanitize(content))
send("#{attribute}=", UserHtml.sanitize(content))
end
end
end
Expand Down
25 changes: 11 additions & 14 deletions spec/lib/user_html_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,25 +5,22 @@
expect(ActiveRecord::Base).to respond_to(:user_html)
end

it 'converts url\'s to html anchors with rel="nofollow" and target="_blank"' do
it 'does not auto_link urls' do
content = 'Here is a cool link: http://www.example.com.'
expect(described_class.link_and_sanitize(content)).to(
eq 'Here is a cool link: <a href="http://www.example.com" ' +
'rel="nofollow" target="_blank">http://www.example.com</a>.'
)
expect(described_class.sanitize(content)).to eq content
end

it 'adds rel="nofollow" and target="_blank" to existing html anchors' do
content = 'Here is a cooler link: <a href="https://www.example.com">Example</a>.'
expect(described_class.link_and_sanitize(content)).to(
expect(described_class.sanitize(content)).to(
eq 'Here is a cooler link: <a href="https://www.example.com" ' +
'rel="nofollow" target="_blank">Example</a>.'
)
end

it 'removes script tags' do
content = 'Have a cup of <script>1337 $cr1pt</script>.'
expect(described_class.link_and_sanitize(content)).to eq 'Have a cup of .'
expect(described_class.sanitize(content)).to eq 'Have a cup of .'
end

it 'allows iframes to whitelisted domains' do
Expand All @@ -34,7 +31,7 @@
'src="https://www.youtube.com/embed/Xp6V_lO1ZKA" frameborder="0" ' +
'allowfullscreen=""></iframe>'

expect(described_class.link_and_sanitize(youtube_content)).to eq expected_youtube_content
expect(described_class.sanitize(youtube_content)).to eq expected_youtube_content

khan_content = \
"<a style=\"color: #111; font-family: helvetica;\" target=\"_blank\" " +
Expand All @@ -57,7 +54,7 @@
"src=\"https://www.khanacademy.org/embed_video?v=Xp6V_lO1ZKA\" allowfullscreen=\"\" " +
"webkitallowfullscreen=\"\" mozallowfullscreen=\"\"></iframe>"

expect(described_class.link_and_sanitize(khan_content)).to eq expected_khan_content
expect(described_class.sanitize(khan_content)).to eq expected_khan_content

end

Expand All @@ -68,33 +65,33 @@
https://server2.cnx.org/content
}
valid_urls.each do | url |
expect(described_class.link_and_sanitize(
expect(described_class.sanitize(
"<iframe src='#{url}' />"
)).to eq "<iframe src=\"#{url}\"></iframe>"
end
end

it 'removes iframes to non-whitelisted domains' do
content = "Funny cat videos: <iframe src=\"http://mal.icio.us\">"
expect(described_class.link_and_sanitize(content)).to eq 'Funny cat videos: '
expect(described_class.sanitize(content)).to eq 'Funny cat videos: '
end

describe 'data-math attribute' do
let (:formula){ %-\lim_{x\to\infty}f(x)=0- }

it 'is allowed on divs' do
content = "as a block: <div data-math='#{formula}'/>"
expect(described_class.link_and_sanitize(content)).to eq "as a block: <div data-math=\"#{formula}\"></div>"
expect(described_class.sanitize(content)).to eq "as a block: <div data-math=\"#{formula}\"></div>"
end

it 'is allowed on spans' do
content = "as inline: <span data-math='#{formula}'/>"
expect(described_class.link_and_sanitize(content)).to eq "as inline: <span data-math=\"#{formula}\"></span>"
expect(described_class.sanitize(content)).to eq "as inline: <span data-math=\"#{formula}\"></span>"
end

it 'is removed from other elements' do
content = "also: <p data-math='#{formula}'/>"
expect(described_class.link_and_sanitize(content)).to eq 'also: <p></p>'
expect(described_class.sanitize(content)).to eq 'also: <p></p>'
end

end
Expand Down