Add RedactorFilter
This commit is contained in:
parent
454d227b45
commit
7f75300573
|
@ -41,6 +41,7 @@ module Gitlab
|
||||||
autoload :IssueReferenceFilter, 'gitlab/markdown/issue_reference_filter'
|
autoload :IssueReferenceFilter, 'gitlab/markdown/issue_reference_filter'
|
||||||
autoload :LabelReferenceFilter, 'gitlab/markdown/label_reference_filter'
|
autoload :LabelReferenceFilter, 'gitlab/markdown/label_reference_filter'
|
||||||
autoload :MergeRequestReferenceFilter, 'gitlab/markdown/merge_request_reference_filter'
|
autoload :MergeRequestReferenceFilter, 'gitlab/markdown/merge_request_reference_filter'
|
||||||
|
autoload :RedactorFilter, 'gitlab/markdown/redactor_filter'
|
||||||
autoload :RelativeLinkFilter, 'gitlab/markdown/relative_link_filter'
|
autoload :RelativeLinkFilter, 'gitlab/markdown/relative_link_filter'
|
||||||
autoload :SanitizationFilter, 'gitlab/markdown/sanitization_filter'
|
autoload :SanitizationFilter, 'gitlab/markdown/sanitization_filter'
|
||||||
autoload :SnippetReferenceFilter, 'gitlab/markdown/snippet_reference_filter'
|
autoload :SnippetReferenceFilter, 'gitlab/markdown/snippet_reference_filter'
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
require 'gitlab/markdown'
|
||||||
|
require 'html/pipeline/filter'
|
||||||
|
|
||||||
|
module Gitlab
|
||||||
|
module Markdown
|
||||||
|
# HTML filter that removes references to records that the current user does
|
||||||
|
# not have permission to view.
|
||||||
|
#
|
||||||
|
# Expected to be run in its own post-processing pipeline.
|
||||||
|
#
|
||||||
|
class RedactorFilter < HTML::Pipeline::Filter
|
||||||
|
def call
|
||||||
|
doc.css('a.gfm').each do |node|
|
||||||
|
unless user_can_reference?(node)
|
||||||
|
node.replace(node.text)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
doc
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_can_reference?(node)
|
||||||
|
if node.has_attribute?('data-group-id')
|
||||||
|
user_can_reference_group?(node.attr('data-group-id'))
|
||||||
|
elsif node.has_attribute?('data-project-id')
|
||||||
|
user_can_reference_project?(node.attr('data-project-id'))
|
||||||
|
elsif node.has_attribute?('data-user-id')
|
||||||
|
user_can_reference_user?(node.attr('data-user-id'))
|
||||||
|
else
|
||||||
|
false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_can_reference_group?(id)
|
||||||
|
group = Group.find(id)
|
||||||
|
|
||||||
|
group && can?(:read_group, group)
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_can_reference_project?(id)
|
||||||
|
project = Project.find(id)
|
||||||
|
|
||||||
|
project && can?(:read_project, project)
|
||||||
|
end
|
||||||
|
|
||||||
|
def user_can_reference_user?(id)
|
||||||
|
# Permit all user reference links
|
||||||
|
true
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def abilities
|
||||||
|
Ability.abilities
|
||||||
|
end
|
||||||
|
|
||||||
|
def can?(ability, object)
|
||||||
|
abilities.allowed?(current_user, ability, object)
|
||||||
|
end
|
||||||
|
|
||||||
|
def current_user
|
||||||
|
context[:current_user]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -0,0 +1,76 @@
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
module Gitlab::Markdown
|
||||||
|
describe RedactorFilter do
|
||||||
|
include ActionView::Helpers::UrlHelper
|
||||||
|
include FilterSpecHelper
|
||||||
|
|
||||||
|
it 'ignores non-GFM links' do
|
||||||
|
html = %(See <a href="https://google.com/">Google</a>)
|
||||||
|
doc = filter(html, current_user: double)
|
||||||
|
|
||||||
|
expect(doc.css('a').length).to eq 1
|
||||||
|
end
|
||||||
|
|
||||||
|
def reference_link(data)
|
||||||
|
link_to('text', '', class: 'gfm', data: data)
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with data-group-id' do
|
||||||
|
it 'removes unpermitted Group references' do
|
||||||
|
user = create(:user)
|
||||||
|
group = create(:group)
|
||||||
|
|
||||||
|
link = reference_link(group_id: group.id)
|
||||||
|
doc = filter(link, current_user: user)
|
||||||
|
|
||||||
|
expect(doc.css('a').length).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows permitted Group references' do
|
||||||
|
user = create(:user)
|
||||||
|
group = create(:group)
|
||||||
|
group.add_developer(user)
|
||||||
|
|
||||||
|
link = reference_link(group_id: group.id)
|
||||||
|
doc = filter(link, current_user: user)
|
||||||
|
|
||||||
|
expect(doc.css('a').length).to eq 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with data-project-id' do
|
||||||
|
it 'removes unpermitted Project references' do
|
||||||
|
user = create(:user)
|
||||||
|
project = create(:empty_project)
|
||||||
|
|
||||||
|
link = reference_link(project_id: project.id)
|
||||||
|
doc = filter(link, current_user: user)
|
||||||
|
|
||||||
|
expect(doc.css('a').length).to eq 0
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'allows permitted Project references' do
|
||||||
|
user = create(:user)
|
||||||
|
project = create(:empty_project)
|
||||||
|
project.team << [user, :master]
|
||||||
|
|
||||||
|
link = reference_link(project_id: project.id)
|
||||||
|
doc = filter(link, current_user: user)
|
||||||
|
|
||||||
|
expect(doc.css('a').length).to eq 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'with data-user-id' do
|
||||||
|
it 'allows any User reference' do
|
||||||
|
user = create(:user)
|
||||||
|
|
||||||
|
link = reference_link(user_id: user.id)
|
||||||
|
doc = filter(link)
|
||||||
|
|
||||||
|
expect(doc.css('a').length).to eq 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
Loading…
Reference in New Issue