Commit 54d97d39 authored by Robert Speicher's avatar Robert Speicher

Fork MRs target least visible project

Previously, if a user forked a Public project and made their fork
Private, opening a merge request in the fork would target the source
project (the Public one) by default, potentially exposing private code.

Now, when the fork project is less visible than its source, we default
to targeting the fork.
parent a0686586
......@@ -2071,10 +2071,16 @@ class Project < ApplicationRecord
end
def default_merge_request_target
if forked_from_project&.merge_requests_enabled?
forked_from_project
else
return self unless forked_from_project
return self unless forked_from_project.merge_requests_enabled?
# When our current visibility is more restrictive than the source project,
# (e.g., the fork is `private` but the parent is `public`), target the less
# permissive project
if visibility_level_value < forked_from_project.visibility_level_value
self
else
forked_from_project
end
end
......
---
title: 'When a forked project is less visible than its source, merge requests now target the less visible project by default.'
merge_request: 21517
author:
type: changed
......@@ -3269,6 +3269,54 @@ describe Project do
it { expect(project.parent_changed?).to be_truthy }
end
describe '#default_merge_request_target' do
context 'when forked from a more visible project' do
it 'returns the more restrictive project' do
project = create(:project, :public)
forked = fork_project(project)
forked.visibility = Gitlab::VisibilityLevel::PRIVATE
forked.save!
expect(project.visibility).to eq 'public'
expect(forked.visibility).to eq 'private'
expect(forked.default_merge_request_target).to eq(forked)
end
end
context 'when forked from a project with disabled merge requests' do
it 'returns the current project' do
project = create(:project, :merge_requests_disabled)
forked = fork_project(project)
expect(forked.forked_from_project).to receive(:merge_requests_enabled?)
.and_call_original
expect(forked.default_merge_request_target).to eq(forked)
end
end
context 'when forked from a project with enabled merge requests' do
it 'returns the source project' do
project = create(:project, :public)
forked = fork_project(project)
expect(project.visibility).to eq 'public'
expect(forked.visibility).to eq 'public'
expect(forked.default_merge_request_target).to eq(project)
end
end
context 'when not forked' do
it 'returns the current project' do
project = build_stubbed(:project)
expect(project.default_merge_request_target).to eq(project)
end
end
end
def enable_lfs
allow(Gitlab.config.lfs).to receive(:enabled).and_return(true)
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