Commit 60fd4217 authored by Grzegorz Bizon's avatar Grzegorz Bizon

Merge branch '66803-fix-uploads-relative-link-filter' into 'master'

Fix permissions check in `RelativeLinkFilter`

See merge request gitlab-org/gitlab-ce!32448
parents 305260df be0f039d
---
title: Fix upload URLs in Markdown for users without access to project repository
merge_request: 32448
author:
type: fixed
...@@ -19,7 +19,6 @@ module Banzai ...@@ -19,7 +19,6 @@ module Banzai
def call def call
return doc if context[:system_note] return doc if context[:system_note]
return doc unless visible_to_user?
@uri_types = {} @uri_types = {}
clear_memoization(:linkable_files) clear_memoization(:linkable_files)
...@@ -50,7 +49,7 @@ module Banzai ...@@ -50,7 +49,7 @@ module Banzai
if html_attr.value.start_with?('/uploads/') if html_attr.value.start_with?('/uploads/')
process_link_to_upload_attr(html_attr) process_link_to_upload_attr(html_attr)
elsif linkable_files? elsif linkable_files? && repo_visible_to_user?
process_link_to_repository_attr(html_attr) process_link_to_repository_attr(html_attr)
end end
end end
...@@ -168,14 +167,8 @@ module Banzai ...@@ -168,14 +167,8 @@ module Banzai
Gitlab.config.gitlab.relative_url_root.presence || '/' Gitlab.config.gitlab.relative_url_root.presence || '/'
end end
def visible_to_user? def repo_visible_to_user?
if project project && Ability.allowed?(current_user, :download_code, project)
Ability.allowed?(current_user, :download_code, project)
elsif group
Ability.allowed?(current_user, :read_group, group)
else # Objects detached from projects or groups, e.g. Personal Snippets.
true
end
end end
def ref def ref
......
...@@ -65,9 +65,6 @@ describe MarkupHelper do ...@@ -65,9 +65,6 @@ describe MarkupHelper do
describe 'inside a group' do describe 'inside a group' do
before do before do
# Ensure the generated reference links aren't redacted
group.add_maintainer(user)
helper.instance_variable_set(:@group, group) helper.instance_variable_set(:@group, group)
helper.instance_variable_set(:@project, nil) helper.instance_variable_set(:@project, nil)
end end
...@@ -81,9 +78,6 @@ describe MarkupHelper do ...@@ -81,9 +78,6 @@ describe MarkupHelper do
let(:project_in_group) { create(:project, group: group) } let(:project_in_group) { create(:project, group: group) }
before do before do
# Ensure the generated reference links aren't redacted
project_in_group.add_maintainer(user)
helper.instance_variable_set(:@group, group) helper.instance_variable_set(:@group, group)
helper.instance_variable_set(:@project, project_in_group) helper.instance_variable_set(:@project, project_in_group)
end end
......
...@@ -289,121 +289,72 @@ describe Banzai::Filter::RelativeLinkFilter do ...@@ -289,121 +289,72 @@ describe Banzai::Filter::RelativeLinkFilter do
let(:relative_path) { "/#{project.full_path}#{upload_path}" } let(:relative_path) { "/#{project.full_path}#{upload_path}" }
context 'to a project upload' do context 'to a project upload' do
context 'without project repository access' do shared_examples 'rewrite project uploads' do
let(:project) { create(:project, :repository, repository_access_level: ProjectFeature::PRIVATE) }
it 'does not rebuild relative URL for a link' do
doc = filter(link(upload_path))
expect(doc.at_css('a')['href']).to eq(upload_path)
doc = filter(nested(link(upload_path)))
expect(doc.at_css('a')['href']).to eq(upload_path)
end
it 'does not rebuild relative URL for an image' do
doc = filter(image(upload_path))
expect(doc.at_css('img')['src']).to eq(upload_path)
doc = filter(nested(image(upload_path)))
expect(doc.at_css('img')['src']).to eq(upload_path)
end
context 'with an absolute URL' do context 'with an absolute URL' do
let(:absolute_path) { Gitlab.config.gitlab.url + relative_path } let(:absolute_path) { Gitlab.config.gitlab.url + relative_path }
let(:only_path) { false } let(:only_path) { false }
it 'does not rewrite the link' do it 'rewrites the link correctly' do
doc = filter(link(upload_path)) doc = filter(link(upload_path))
expect(doc.at_css('a')['href']).to eq(upload_path) expect(doc.at_css('a')['href']).to eq(absolute_path)
end end
end end
end
context 'with an absolute URL' do it 'rebuilds relative URL for a link' do
let(:absolute_path) { Gitlab.config.gitlab.url + relative_path }
let(:only_path) { false }
it 'rewrites the link correctly' do
doc = filter(link(upload_path)) doc = filter(link(upload_path))
expect(doc.at_css('a')['href']).to eq(relative_path)
expect(doc.at_css('a')['href']).to eq(absolute_path) doc = filter(nested(link(upload_path)))
expect(doc.at_css('a')['href']).to eq(relative_path)
end end
end
it 'rebuilds relative URL for a link' do it 'rebuilds relative URL for an image' do
doc = filter(link(upload_path)) doc = filter(image(upload_path))
expect(doc.at_css('a')['href']).to eq(relative_path) expect(doc.at_css('img')['src']).to eq(relative_path)
doc = filter(nested(link(upload_path))) doc = filter(nested(image(upload_path)))
expect(doc.at_css('a')['href']).to eq(relative_path) expect(doc.at_css('img')['src']).to eq(relative_path)
end end
it 'rebuilds relative URL for an image' do it 'does not modify absolute URL' do
doc = filter(image(upload_path)) doc = filter(link('http://example.com'))
expect(doc.at_css('img')['src']).to eq(relative_path) expect(doc.at_css('a')['href']).to eq 'http://example.com'
end
doc = filter(nested(image(upload_path))) it 'supports unescaped Unicode filenames' do
expect(doc.at_css('img')['src']).to eq(relative_path) path = '/uploads/한글.png'
end doc = filter(link(path))
it 'does not modify absolute URL' do expect(doc.at_css('a')['href']).to eq("/#{project.full_path}/uploads/%ED%95%9C%EA%B8%80.png")
doc = filter(link('http://example.com')) end
expect(doc.at_css('a')['href']).to eq 'http://example.com'
end
it 'supports unescaped Unicode filenames' do it 'supports escaped Unicode filenames' do
path = '/uploads/한글.png' path = '/uploads/한글.png'
doc = filter(link(path)) escaped = Addressable::URI.escape(path)
doc = filter(image(escaped))
expect(doc.at_css('a')['href']).to eq("/#{project.full_path}/uploads/%ED%95%9C%EA%B8%80.png") expect(doc.at_css('img')['src']).to eq("/#{project.full_path}/uploads/%ED%95%9C%EA%B8%80.png")
end
end end
it 'supports escaped Unicode filenames' do context 'without project repository access' do
path = '/uploads/한글.png' let(:project) { create(:project, :repository, repository_access_level: ProjectFeature::PRIVATE) }
escaped = Addressable::URI.escape(path)
doc = filter(image(escaped)) it_behaves_like 'rewrite project uploads'
end
expect(doc.at_css('img')['src']).to eq("/#{project.full_path}/uploads/%ED%95%9C%EA%B8%80.png") context 'with project repository access' do
it_behaves_like 'rewrite project uploads'
end end
end end
context 'to a group upload' do context 'to a group upload' do
let(:upload_path) { '/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg' } let(:upload_link) { link('/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg') }
let(:upload_link) { link(upload_path) }
let(:group) { create(:group) } let(:group) { create(:group) }
let(:project) { nil } let(:project) { nil }
let(:relative_path) { "/groups/#{group.full_path}/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" } let(:relative_path) { "/groups/#{group.full_path}/-/uploads/e90decf88d8f96fe9e1389afc2e4a91f/test.jpg" }
context 'without group read access' do
let(:group) { create(:group, :private) }
it 'does not rewrite the link' do
doc = filter(upload_link)
expect(doc.at_css('a')['href']).to eq(upload_path)
end
it 'does not rewrite the link for subgroup' do
group.update!(parent: create(:group))
doc = filter(upload_link)
expect(doc.at_css('a')['href']).to eq(upload_path)
end
context 'with an absolute URL' do
let(:absolute_path) { Gitlab.config.gitlab.url + relative_path }
let(:only_path) { false }
it 'does not rewrite the link' do
doc = filter(upload_link)
expect(doc.at_css('a')['href']).to eq(upload_path)
end
end
end
context 'with an absolute URL' do context 'with an absolute URL' do
let(:absolute_path) { Gitlab.config.gitlab.url + relative_path } let(:absolute_path) { Gitlab.config.gitlab.url + relative_path }
let(:only_path) { false } let(:only_path) { false }
......
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