Commit a803cd51 authored by Robert Speicher's avatar Robert Speicher

Check for project read permissions in cross-references

parent 470b0c25
...@@ -8,18 +8,28 @@ module Gitlab ...@@ -8,18 +8,28 @@ module Gitlab
# Given a cross-project reference string, get the Project record # Given a cross-project reference string, get the Project record
# #
# If no valid reference is given, returns the `:project` value for the # Defaults to value of `context[:project]` if:
# current context. # - No reference is given
# - Reference given doesn't exist
# - Reference given can't be read by the current user
# #
# ref - String reference. # ref - String reference.
# #
# Returns a Project # Returns a Project
def project_from_ref(ref) def project_from_ref(ref)
if ref && other = Project.find_with_namespace(ref) if ref && other = Project.find_with_namespace(ref)
if user_can_reference_project?(other)
other other
else else
context[:project] context[:project]
end end
else
context[:project]
end
end
def user_can_reference_project?(project, user = context[:current_user])
user && Ability.abilities.allowed?(user, :read_project, project)
end end
end end
end end
......
...@@ -2,21 +2,48 @@ require 'spec_helper' ...@@ -2,21 +2,48 @@ require 'spec_helper'
module Gitlab::Markdown module Gitlab::Markdown
describe CrossProjectReference do describe CrossProjectReference do
include CrossProjectReference # context in the html-pipeline sense, not in the rspec sense
let(:context) do
{
current_user: double('user'),
project: double('project')
}
end
include described_class
describe '#project_from_ref' do describe '#project_from_ref' do
let(:project) { double('project') } context 'when referenced project does not exist' do
it 'returns the project from context' do
expect(project_from_ref('invalid/reference')).to eq context[:project]
end
end
context 'when referenced project exists' do
let(:project2) { double('referenced project') }
it 'returns a project from a valid reference' do before do
expect(Project).to receive(:find_with_namespace).with('cross-reference/foo').and_return(project) expect(Project).to receive(:find_with_namespace).
with('cross/reference').and_return(project2)
end
context 'and the user has permission to read it' do
it 'returns the referenced project' do
expect(self).to receive(:user_can_reference_project?).
with(project2).and_return(true)
expect(project_from_ref('cross-reference/foo')).to eq project expect(project_from_ref('cross/reference')).to eq project2
end
end end
it 'returns the project from context when reference is invalid' do context 'and the user does not have permission to read it' do
expect(self).to receive(:context).and_return({project: project}) it 'returns the project from context' do
expect(self).to receive(:user_can_reference_project?).
with(project2).and_return(false)
expect(project_from_ref('invalid/reference')).to eq project expect(project_from_ref('cross/reference')).to eq context[:project]
end
end
end end
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