Commit ffb107ac authored by Oswaldo Ferreira's avatar Oswaldo Ferreira

Keep link when redacting unauthorized object links

parent 565e4ee5
---
title: Keep link when redacting unauthorized object links
merge_request:
author:
type: fixed
...@@ -174,7 +174,9 @@ module Banzai ...@@ -174,7 +174,9 @@ module Banzai
title = object_link_title(object) title = object_link_title(object)
klass = reference_class(object_sym) klass = reference_class(object_sym)
data = data_attributes_for(link_content || match, parent, object, link: !!link_content) data = data_attributes_for(link_content || match, parent, object,
link_content: !!link_content,
link_reference: link_reference)
url = url =
if matches.names.include?("url") && matches[:url] if matches.names.include?("url") && matches[:url]
...@@ -194,10 +196,11 @@ module Banzai ...@@ -194,10 +196,11 @@ module Banzai
end end
end end
def data_attributes_for(text, project, object, link: false) def data_attributes_for(text, project, object, link_content: false, link_reference: false)
data_attribute( data_attribute(
original: text, original: text,
link: link, link: link_content,
link_reference: link_reference,
project: project.id, project: project.id,
object_sym => object.id object_sym => object.id
) )
......
...@@ -42,16 +42,33 @@ module Banzai ...@@ -42,16 +42,33 @@ module Banzai
next if visible.include?(node) next if visible.include?(node)
doc_data[:visible_reference_count] -= 1 doc_data[:visible_reference_count] -= 1
# The reference should be replaced by the original link's content, redacted_content = redacted_node_content(node)
# which is not always the same as the rendered one. node.replace(redacted_content)
content = node.attr('data-original') || node.inner_html
node.replace(content)
end end
end end
metadata metadata
end end
# Return redacted content of given node as either the original link (<a> tag),
# the original content (text), or the inner HTML of the node.
#
def redacted_node_content(node)
original_content = node.attr('data-original')
link_reference = node.attr('data-link-reference')
# Build the raw <a> tag just with a link as href and content if
# it's originally a link pattern. We shouldn't return a plain text href.
original_link =
if link_reference == 'true' && href = original_content
%(<a href="#{href}">#{href}</a>)
end
# The reference should be replaced by the original link's content,
# which is not always the same as the rendered one.
original_link || original_content || node.inner_html
end
def redact_cross_project_references(documents) def redact_cross_project_references(documents)
extractor = Banzai::IssuableExtractor.new(project, user) extractor = Banzai::IssuableExtractor.new(project, user)
issuables = extractor.extract(documents) issuables = extractor.extract(documents)
......
...@@ -40,6 +40,16 @@ describe Banzai::Redactor do ...@@ -40,6 +40,16 @@ describe Banzai::Redactor do
expect(doc.to_html).to eq(original_content) expect(doc.to_html).to eq(original_content)
end end
end end
it 'returns <a> tag with original href if it is originally a link reference' do
href = 'http://localhost:3000'
doc = Nokogiri::HTML
.fragment("<a class='gfm' data-reference-type='issue' data-original=#{href} data-link-reference='true'>#{href}</a>")
redactor.redact([doc])
expect(doc.to_html).to eq('<a href="http://localhost:3000">http://localhost:3000</a>')
end
end end
context 'when project is in pending delete' do context 'when project is in pending delete' do
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment