Forking a project to a namespace with lower visibility.
In this case the project will get the minimum between both visibilities. If that visibility is restricted, then a lower level will be picked.
This commit is contained in:
parent
723d788fbe
commit
0618487906
5 changed files with 64 additions and 13 deletions
|
@ -26,7 +26,7 @@ module Projects
|
||||||
name: @project.name,
|
name: @project.name,
|
||||||
path: @project.path,
|
path: @project.path,
|
||||||
shared_runners_enabled: @project.shared_runners_enabled,
|
shared_runners_enabled: @project.shared_runners_enabled,
|
||||||
namespace_id: @params[:namespace].try(:id) || current_user.namespace.id
|
namespace_id: target_namespace.id
|
||||||
}
|
}
|
||||||
|
|
||||||
if @project.avatar.present? && @project.avatar.image?
|
if @project.avatar.present? && @project.avatar.image?
|
||||||
|
@ -74,14 +74,14 @@ module Projects
|
||||||
Projects::ForksCountService.new(@project).refresh_cache
|
Projects::ForksCountService.new(@project).refresh_cache
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed_visibility_level
|
def target_namespace
|
||||||
project_level = @project.visibility_level
|
@target_namespace ||= @params[:namespace] || current_user.namespace
|
||||||
|
end
|
||||||
|
|
||||||
if Gitlab::VisibilityLevel.non_restricted_level?(project_level)
|
def allowed_visibility_level
|
||||||
project_level
|
target_level = [@project.visibility_level, target_namespace.visibility_level].min
|
||||||
else
|
|
||||||
Gitlab::VisibilityLevel.highest_allowed_level
|
Gitlab::VisibilityLevel.closest_allowed_level(target_level)
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,5 @@
|
||||||
|
---
|
||||||
|
title: Allow forking a public project to a private group
|
||||||
|
merge_request: 16050
|
||||||
|
author:
|
||||||
|
type: changed
|
|
@ -57,11 +57,17 @@ module Gitlab
|
||||||
}
|
}
|
||||||
end
|
end
|
||||||
|
|
||||||
def highest_allowed_level
|
def allowed_levels
|
||||||
restricted_levels = current_application_settings.restricted_visibility_levels
|
restricted_levels = current_application_settings.restricted_visibility_levels
|
||||||
|
|
||||||
allowed_levels = self.values - restricted_levels
|
self.values - restricted_levels
|
||||||
allowed_levels.max || PRIVATE
|
end
|
||||||
|
|
||||||
|
def closest_allowed_level(target_level)
|
||||||
|
highest_allowed_level = allowed_levels.select { |level| level <= target_level }.max
|
||||||
|
|
||||||
|
# If all levels are restricted, fall back to PRIVATE
|
||||||
|
highest_allowed_level || PRIVATE
|
||||||
end
|
end
|
||||||
|
|
||||||
def allowed_for?(user, level)
|
def allowed_for?(user, level)
|
||||||
|
|
|
@ -49,4 +49,31 @@ describe Gitlab::VisibilityLevel do
|
||||||
.to eq([Gitlab::VisibilityLevel::PUBLIC])
|
.to eq([Gitlab::VisibilityLevel::PUBLIC])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe '.allowed_levels' do
|
||||||
|
it 'only includes the levels that arent restricted' do
|
||||||
|
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
|
||||||
|
|
||||||
|
expect(described_class.allowed_levels)
|
||||||
|
.to contain_exactly(described_class::PRIVATE, described_class::PUBLIC)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '.closest_allowed_level' do
|
||||||
|
it 'picks INTERNAL instead of PUBLIC if public is restricted' do
|
||||||
|
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
|
||||||
|
|
||||||
|
expect(described_class.closest_allowed_level(described_class::PUBLIC))
|
||||||
|
.to eq(described_class::INTERNAL)
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'picks PRIVATE if nothing is available' do
|
||||||
|
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC,
|
||||||
|
Gitlab::VisibilityLevel::INTERNAL,
|
||||||
|
Gitlab::VisibilityLevel::PRIVATE])
|
||||||
|
|
||||||
|
expect(described_class.closest_allowed_level(described_class::PUBLIC))
|
||||||
|
.to eq(described_class::PRIVATE)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -139,10 +139,10 @@ describe Projects::ForkService do
|
||||||
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
|
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::INTERNAL])
|
||||||
end
|
end
|
||||||
|
|
||||||
it "creates fork with highest allowed level" do
|
it "creates fork with lowest level" do
|
||||||
forked_project = fork_project(@from_project, @to_user)
|
forked_project = fork_project(@from_project, @to_user)
|
||||||
|
|
||||||
expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC)
|
expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -209,6 +209,19 @@ describe Projects::ForkService do
|
||||||
expect(to_project.errors[:path]).to eq(['has already been taken'])
|
expect(to_project.errors[:path]).to eq(['has already been taken'])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
context 'when the namespace has a lower visibility level than the project' do
|
||||||
|
it 'creates the project with the lower visibility level' do
|
||||||
|
public_project = create(:project, :public)
|
||||||
|
private_group = create(:group, :private)
|
||||||
|
group_owner = create(:user)
|
||||||
|
private_group.add_owner(group_owner)
|
||||||
|
|
||||||
|
forked_project = fork_project(public_project, group_owner, namespace: private_group)
|
||||||
|
|
||||||
|
expect(forked_project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue