Commit 3eb8773d authored by Stan Hu's avatar Stan Hu

Merge branch '5615-non-admins-only-archieve' into 'master'

Resolve "Only allow non-admins to archive projects, not delete them"

Closes #5615

See merge request gitlab-org/gitlab-ee!14002
parents 7961cf35 d3687fd1
......@@ -8,6 +8,7 @@
.form-group
= f.label s_('ProjectCreationLevel|Default project creation protection'), class: 'label-bold'
= f.select :default_project_creation, options_for_select(Gitlab::Access.project_creation_options, @application_setting.default_project_creation), {}, class: 'form-control'
= render_if_exists 'admin/application_settings/default_project_deletion_protection_setting', form: f
.form-group.visibility-level-setting
= f.label :default_project_visibility, class: 'label-bold'
= render('shared/visibility_radios', model_method: :default_project_visibility, form: f, selected_level: @application_setting.default_project_visibility, form_model: Project.new)
......
---
title: Add deletion protection setting column to application_settings table
merge_request: 29268
author:
type: other
......@@ -138,6 +138,7 @@ Settings['issues_tracker'] ||= {}
#
Settings['gitlab'] ||= Settingslogic.new({})
Settings.gitlab['default_project_creation'] ||= ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS
Settings.gitlab['default_project_deletion_protection'] ||= false
Settings.gitlab['default_projects_limit'] ||= 100000
Settings.gitlab['default_branch_protection'] ||= 2
Settings.gitlab['default_can_create_group'] = true if Settings.gitlab['default_can_create_group'].nil?
......
# frozen_string_literal: true
# See http://doc.gitlab.com/ce/development/migration_style_guide.html
# for more information on how to write migrations for GitLab.
class AddDefaultProjectDeletionProtectionToApplicationSettings < ActiveRecord::Migration[5.1]
include Gitlab::Database::MigrationHelpers
DOWNTIME = false
disable_ddl_transaction!
def up
add_column_with_default :application_settings, :default_project_deletion_protection, :boolean, default: false, allow_null: false
end
def down
remove_column :application_settings, :default_project_deletion_protection
end
end
......@@ -226,6 +226,7 @@ ActiveRecord::Schema.define(version: 20190611161641) do
t.text "encrypted_lets_encrypt_private_key"
t.text "encrypted_lets_encrypt_private_key_iv"
t.boolean "dns_rebinding_protection_enabled", default: true, null: false
t.boolean "default_project_deletion_protection", default: false, null: false
t.index ["custom_project_templates_group_id"], name: "index_application_settings_on_custom_project_templates_group_id", using: :btree
t.index ["file_template_project_id"], name: "index_application_settings_on_file_template_project_id", using: :btree
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
......
......@@ -26,6 +26,10 @@ module EE
attrs << :pseudonymizer_enabled
end
if License.feature_available?(:default_project_deletion_protection)
attrs << :default_project_deletion_protection
end
attrs
end
end
......
......@@ -75,6 +75,7 @@ module EE
repository_mirror_attributes + %i[
email_additional_text
file_template_project_id
default_project_deletion_protection
]
end
end
......
......@@ -75,6 +75,7 @@ module EE
def defaults
super.merge(
allow_group_owners_to_manage_ldap: true,
default_project_deletion_protection: false,
elasticsearch_aws: false,
elasticsearch_aws_region: ENV['ELASTIC_REGION'] || 'us-east-1',
elasticsearch_replicas: 1,
......
......@@ -69,6 +69,7 @@ class License < ApplicationRecord
reject_unsigned_commits
commit_committer_check
ci_cd_projects
default_project_deletion_protection
protected_environments
custom_project_templates
group_project_templates
......
......@@ -210,6 +210,8 @@ module EE
rule { owner | reporter }.enable :build_read_project
rule { ~admin & owner & owner_cannot_destroy_project }.prevent :remove_project
rule { archived }.policy do
READONLY_FEATURES_WHEN_ARCHIVED.each do |feature|
prevent(*::ProjectPolicy.create_update_admin_destroy(feature))
......@@ -228,6 +230,11 @@ module EE
::Gitlab::Auth::GroupSaml::SsoEnforcer.group_access_restricted?(subject.group)
end
condition(:owner_cannot_destroy_project) do
::Gitlab::CurrentSettings.current_application_settings
.default_project_deletion_protection
end
rule { web_ide_terminal_available & can?(:create_pipeline) & can?(:maintainer_access) }.enable :create_web_ide_terminal
# Design abilities could also be prevented in the issue policy.
......
- return unless License.feature_available?(:default_project_deletion_protection)
- f = local_assigns.fetch(:form)
.form-group
= f.label s_('Default project deletion protection'), class: 'label-bold'
.form-check
= f.check_box :default_project_deletion_protection, class: 'form-check-input'
= f.label :default_project_deletion_protection, class: 'form-check-label' do
= _('Only admins can delete project')
---
title: Add Admin settings to disable project deletion
merge_request: 14002
author:
type: added
......@@ -158,6 +158,7 @@ module EE
end)
expose :email_additional_text, if: ->(_instance, _opts) { ::License.feature_available?(:email_additional_text) }
expose :file_template_project_id, if: ->(_instance, _opts) { ::License.feature_available?(:custom_file_templates) }
expose :default_project_deletion_protection, if: ->(_instance, _opts) { ::License.feature_available?(:default_project_deletion_protection) }
end
end
......
......@@ -30,6 +30,7 @@ module EE
end
optional :email_additional_text, type: String, desc: 'Additional text added to the bottom of every email for legal/auditing/compliance reasons'
optional :default_project_deletion_protection, type: Grape::API::Boolean, desc: 'Disable project owners ability to delete project'
optional :help_text, type: String, desc: 'GitLab server administrator information'
optional :repository_size_limit, type: Integer, desc: 'Size limit per repository (MB)'
optional :file_template_project_id, type: Integer, desc: 'ID of project where instance-level file templates are stored.'
......
......@@ -24,6 +24,10 @@ module EE
attrs = attrs.except(:file_template_project_id)
end
unless ::License.feature_available?(:default_project_deletion_protection)
attrs = attrs.except(:default_project_deletion_protection)
end
attrs
end
# rubocop: enable CodeReuse/ActiveRecord
......
......@@ -81,6 +81,13 @@ describe Admin::ApplicationSettingsController do
it_behaves_like 'settings for licensed features'
end
context 'default project deletion protection' do
let(:settings) { { default_project_deletion_protection: true } }
let(:feature) { :default_project_deletion_protection }
it_behaves_like 'settings for licensed features'
end
context 'additional email footer' do
let(:settings) { { email_additional_text: 'scary legal footer' } }
let(:feature) { :email_additional_text }
......
......@@ -451,6 +451,31 @@ describe ProjectPolicy do
end
end
describe 'remove_project when default_project_deletion_protection is set to true' do
before do
allow(Gitlab::CurrentSettings.current_application_settings)
.to receive(:default_project_deletion_protection) { true }
end
context 'with admin' do
let(:current_user) { admin }
it { is_expected.to be_allowed(:remove_project) }
context 'who owns the project' do
let(:project) { create(:project, :public, namespace: admin.namespace) }
it { is_expected.to be_allowed(:remove_project) }
end
end
context 'with owner' do
let(:current_user) { owner }
it { is_expected.to be_disallowed(:remove_project) }
end
end
describe 'read_feature_flag' do
context 'with admin' do
let(:current_user) { admin }
......
......@@ -142,6 +142,13 @@ describe API::Settings, 'EE Settings' do
it_behaves_like 'settings for licensed features'
end
context 'default project deletion protection' do
let(:settings) { { default_project_deletion_protection: true } }
let(:feature) { :default_project_deletion_protection }
it_behaves_like 'settings for licensed features'
end
context 'custom file template project' do
let(:settings) { { file_template_project_id: project.id } }
let(:feature) { :custom_file_templates }
......
......@@ -3982,6 +3982,9 @@ msgstr ""
msgid "Default issue template"
msgstr ""
msgid "Default project deletion protection"
msgstr ""
msgid "Default: Directly import the Google Code email address or username"
msgstr ""
......@@ -9059,6 +9062,9 @@ msgstr ""
msgid "Only admins"
msgstr ""
msgid "Only admins can delete project"
msgstr ""
msgid "Only mirror protected branches"
msgstr ""
......
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