Commit f8d93b24 authored by Stan Hu's avatar Stan Hu

Set project default visibility to max allowed

If the default, instance-wide visibility were set to internal but a
group were private, the radio button would be set on internal even
though that setting were not allowed. We now consider the allowed
visibility setting for the group in determining what the default should
be.

Closes https://gitlab.com/gitlab-org/gitlab-ce/issues/62298
parent e6a88b02
...@@ -165,8 +165,46 @@ module VisibilityLevelHelper ...@@ -165,8 +165,46 @@ module VisibilityLevelHelper
!form_model.visibility_level_allowed?(level) !form_model.visibility_level_allowed?(level)
end end
# Visibility level can be restricted in two ways:
#
# 1. The group permissions (e.g. a subgroup is private, which requires
# all projects to be private)
# 2. The global allowed visibility settinngs, set by the admin
def selected_visibility_level(form_model, requested_level)
requested_level =
if requested_level.present?
requested_level.to_i
else
default_project_visibility
end
[requested_level, max_allowed_visibility_level(form_model)].min
end
private private
def max_allowed_visibility_level(form_model)
# First obtain the maximum visibility for the project or group
current_level = max_allowed_visibility_level_by_model(form_model)
# Now limit this by the global setting
Gitlab::VisibilityLevel.closest_allowed_level(current_level)
end
def max_allowed_visibility_level_by_model(form_model)
current_level = Gitlab::VisibilityLevel::PRIVATE
Gitlab::VisibilityLevel.values.sort.each do |value|
if disallowed_visibility_level?(form_model, value)
break
else
current_level = value
end
end
current_level
end
def visibility_level_errors_for_group(group, level_name) def visibility_level_errors_for_group(group, level_name)
group_name = link_to group.name, group_path(group) group_name = link_to group.name, group_path(group)
change_visiblity = link_to 'change the visibility', edit_group_path(group) change_visiblity = link_to 'change the visibility', edit_group_path(group)
......
- visibility_level = params.dig(:project, :visibility_level) || default_project_visibility - visibility_level = selected_visibility_level(@project, params.dig(:project, :visibility_level))
- ci_cd_only = local_assigns.fetch(:ci_cd_only, false) - ci_cd_only = local_assigns.fetch(:ci_cd_only, false)
- hide_init_with_readme = local_assigns.fetch(:hide_init_with_readme, false) - hide_init_with_readme = local_assigns.fetch(:hide_init_with_readme, false)
- track_label = local_assigns.fetch(:track_label, 'blank_project') - track_label = local_assigns.fetch(:track_label, 'blank_project')
......
---
title: Set project default visibility to max allowed
merge_request: 28754
author:
type: fixed
...@@ -63,6 +63,36 @@ describe 'New project' do ...@@ -63,6 +63,36 @@ describe 'New project' do
end end
end end
end end
context 'when group visibility is private but default is internal' do
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PRIVATE)
visit new_project_path(namespace_id: group.id)
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
context 'when group visibility is public but user requests private' do
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end
it 'has private selected' do
group = create(:group, visibility_level: Gitlab::VisibilityLevel::PUBLIC)
visit new_project_path(namespace_id: group.id, project: { visibility_level: Gitlab::VisibilityLevel::PRIVATE })
page.within('#blank-project-pane') do
expect(find_field("project_visibility_level_#{Gitlab::VisibilityLevel::PRIVATE}")).to be_checked
end
end
end
end end
context 'Readme selector' do context 'Readme selector' do
......
...@@ -162,4 +162,49 @@ describe VisibilityLevelHelper do ...@@ -162,4 +162,49 @@ describe VisibilityLevelHelper do
end end
end end
end end
describe "selected_visibility_level" do
let(:group) { create(:group, :public) }
let!(:project) { create(:project, :internal, group: group) }
let!(:forked_project) { fork_project(project) }
using RSpec::Parameterized::TableSyntax
PUBLIC = Gitlab::VisibilityLevel::PUBLIC
INTERNAL = Gitlab::VisibilityLevel::INTERNAL
PRIVATE = Gitlab::VisibilityLevel::PRIVATE
# This is a subset of all the permutations
where(:requested_level, :max_allowed, :global_default_level, :restricted_levels, :expected) do
PUBLIC | PUBLIC | PUBLIC | [] | PUBLIC
PUBLIC | PUBLIC | PUBLIC | [PUBLIC] | INTERNAL
INTERNAL | PUBLIC | PUBLIC | [] | INTERNAL
INTERNAL | PRIVATE | PRIVATE | [] | PRIVATE
PRIVATE | PUBLIC | PUBLIC | [] | PRIVATE
PUBLIC | PRIVATE | INTERNAL | [] | PRIVATE
PUBLIC | INTERNAL | PUBLIC | [] | INTERNAL
PUBLIC | PRIVATE | PUBLIC | [] | PRIVATE
PUBLIC | INTERNAL | INTERNAL | [] | INTERNAL
PUBLIC | PUBLIC | INTERNAL | [] | PUBLIC
end
before do
stub_application_setting(restricted_visibility_levels: restricted_levels,
default_project_visibility: global_default_level)
end
with_them do
it "provides correct visibility level for forked project" do
project.update(visibility_level: max_allowed)
expect(selected_visibility_level(forked_project, requested_level)).to eq(expected)
end
it "provides correct visibiility level for project in group" do
project.group.update(visibility_level: max_allowed)
expect(selected_visibility_level(project, requested_level)).to eq(expected)
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