Commit b37ca626 authored by Rémy Coutable's avatar Rémy Coutable

Merge branch 'sh-fix-issue-63158' into 'master'

Fix inability to set visibility_level on project via API

Closes #63158

See merge request gitlab-org/gitlab-ce!29578
parents c6cf5291 dcba5279
...@@ -72,7 +72,6 @@ class Project < ApplicationRecord ...@@ -72,7 +72,6 @@ class Project < ApplicationRecord
delegate :no_import?, to: :import_state, allow_nil: true delegate :no_import?, to: :import_state, allow_nil: true
default_value_for :archived, false default_value_for :archived, false
default_value_for(:visibility_level) { Gitlab::CurrentSettings.default_project_visibility }
default_value_for :resolve_outdated_diff_discussions, false default_value_for :resolve_outdated_diff_discussions, false
default_value_for :container_registry_enabled, gitlab_config_features.container_registry default_value_for :container_registry_enabled, gitlab_config_features.container_registry
default_value_for(:repository_storage) { Gitlab::CurrentSettings.pick_repository_storage } default_value_for(:repository_storage) { Gitlab::CurrentSettings.pick_repository_storage }
...@@ -613,6 +612,23 @@ class Project < ApplicationRecord ...@@ -613,6 +612,23 @@ class Project < ApplicationRecord
end end
end end
def initialize(attributes = {})
# We can't use default_value_for because the database has a default
# value of 0 for visibility_level. If someone attempts to create a
# private project, default_value_for will assume that the
# visibility_level hasn't changed and will use the application
# setting default, which could be internal or public. For projects
# inside a private group, those levels are invalid.
#
# To fix the problem, we assign the actual default in the application if
# no explicit visibility has been initialized.
unless visibility_attribute_present?(attributes)
attributes[:visibility_level] = Gitlab::CurrentSettings.default_project_visibility
end
super
end
def all_pipelines def all_pipelines
if builds_enabled? if builds_enabled?
super super
......
---
title: Fix inability to set visibility_level on project via API
merge_request: 29578
author:
type: fixed
...@@ -138,5 +138,18 @@ module Gitlab ...@@ -138,5 +138,18 @@ module Gitlab
def visibility=(level) def visibility=(level)
self[visibility_level_field] = Gitlab::VisibilityLevel.level_value(level) self[visibility_level_field] = Gitlab::VisibilityLevel.level_value(level)
end end
def visibility_attribute_present?(attributes)
visibility_level_attributes.each do |attr|
return true if attributes[attr].present?
end
false
end
def visibility_level_attributes
[visibility_level_field, visibility_level_field.to_s,
:visibility, 'visibility']
end
end end
end end
...@@ -1479,11 +1479,28 @@ describe Project do ...@@ -1479,11 +1479,28 @@ describe Project do
end end
context 'when set to INTERNAL in application settings' do context 'when set to INTERNAL in application settings' do
using RSpec::Parameterized::TableSyntax
before do before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL) stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
end end
it { is_expected.to eq(Gitlab::VisibilityLevel::INTERNAL) } it { is_expected.to eq(Gitlab::VisibilityLevel::INTERNAL) }
where(:attribute_name, :value) do
:visibility | 'public'
:visibility_level | Gitlab::VisibilityLevel::PUBLIC
'visibility' | 'public'
'visibility_level' | Gitlab::VisibilityLevel::PUBLIC
end
with_them do
it 'sets the visibility level' do
proj = described_class.new(attribute_name => value, name: 'test', path: 'test')
expect(proj.visibility_level).to eq(Gitlab::VisibilityLevel::PUBLIC)
end
end
end end
end end
......
...@@ -152,6 +152,33 @@ describe Projects::CreateService, '#execute' do ...@@ -152,6 +152,33 @@ describe Projects::CreateService, '#execute' do
end end
end end
context 'default visibility level' do
let(:group) { create(:group, :private) }
before do
stub_application_setting(default_project_visibility: Gitlab::VisibilityLevel::INTERNAL)
group.add_developer(user)
opts.merge!(
visibility: 'private',
name: 'test',
namespace: group,
path: 'foo'
)
end
it 'creates a private project' do
project = create_project(user, opts)
expect(project).to respond_to(:errors)
expect(project.errors.any?).to be(false)
expect(project.visibility_level).to eq(Gitlab::VisibilityLevel::PRIVATE)
expect(project.saved?).to be(true)
expect(project.valid?).to be(true)
end
end
context 'restricted visibility level' do context 'restricted visibility level' do
before do before do
stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC]) stub_application_setting(restricted_visibility_levels: [Gitlab::VisibilityLevel::PUBLIC])
......
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