Commit 7f753005 authored by Robert Speicher's avatar Robert Speicher

Add RedactorFilter

parent 454d227b
...@@ -41,6 +41,7 @@ module Gitlab ...@@ -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'
......
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
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
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