Add part of needed code
Add columns to store project creation settings Add project creation level column in groups and default project creation column in application settings Remove obsolete line from schema Update migration with project_creation_level column existence check Rename migrations to avoid conflicts Update migration methods Update migration method
This commit is contained in:
parent
8cdda8f79a
commit
64858317ad
33 changed files with 447 additions and 16 deletions
|
@ -89,7 +89,8 @@ class Admin::GroupsController < Admin::ApplicationController
|
|||
:request_access_enabled,
|
||||
:visibility_level,
|
||||
:require_two_factor_authentication,
|
||||
:two_factor_grace_period
|
||||
:two_factor_grace_period,
|
||||
:project_creation_level
|
||||
]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -187,7 +187,8 @@ class GroupsController < Groups::ApplicationController
|
|||
:create_chat_team,
|
||||
:chat_team_name,
|
||||
:require_two_factor_authentication,
|
||||
:two_factor_grace_period
|
||||
:two_factor_grace_period,
|
||||
:project_creation_level
|
||||
]
|
||||
end
|
||||
|
||||
|
|
|
@ -137,6 +137,7 @@ module ApplicationSettingsHelper
|
|||
:default_artifacts_expire_in,
|
||||
:default_branch_protection,
|
||||
:default_group_visibility,
|
||||
:default_project_creation,
|
||||
:default_project_visibility,
|
||||
:default_projects_limit,
|
||||
:default_snippet_visibility,
|
||||
|
|
|
@ -49,6 +49,13 @@ module NamespacesHelper
|
|||
end
|
||||
end
|
||||
|
||||
def namespaces_options_with_developer_maintainer_access(options = {})
|
||||
selected = options.delete(:selected) || :current_user
|
||||
options[:groups] = current_user.manageable_groups_with_routes(include_groups_with_developer_maintainer_access: true)
|
||||
|
||||
namespaces_options(selected, options)
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# Many importers create a temporary Group, so use the real
|
||||
|
|
|
@ -26,6 +26,7 @@ module ApplicationSettingImplementation
|
|||
default_artifacts_expire_in: '30 days',
|
||||
default_branch_protection: Settings.gitlab['default_branch_protection'],
|
||||
default_group_visibility: Settings.gitlab.default_projects_features['visibility_level'],
|
||||
default_project_creation: Settings.gitlab['default_project_creation'],
|
||||
default_project_visibility: Settings.gitlab.default_projects_features['visibility_level'],
|
||||
default_projects_limit: Settings.gitlab['default_projects_limit'],
|
||||
default_snippet_visibility: Settings.gitlab.default_projects_features['visibility_level'],
|
||||
|
|
|
@ -404,6 +404,10 @@ class Group < Namespace
|
|||
Feature.enabled?(:group_clusters, root_ancestor, default_enabled: true)
|
||||
end
|
||||
|
||||
def project_creation_level
|
||||
super || ::Gitlab::CurrentSettings.default_project_creation
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def update_two_factor_requirement
|
||||
|
|
|
@ -105,6 +105,7 @@ class User < ApplicationRecord
|
|||
has_many :groups, through: :group_members
|
||||
has_many :owned_groups, -> { where(members: { access_level: Gitlab::Access::OWNER }) }, through: :group_members, source: :group
|
||||
has_many :maintainers_groups, -> { where(members: { access_level: Gitlab::Access::MAINTAINER }) }, through: :group_members, source: :group
|
||||
has_many :developer_groups, -> { where(members: { access_level: ::Gitlab::Access::DEVELOPER }) }, through: :group_members, source: :group
|
||||
has_many :owned_or_maintainers_groups,
|
||||
-> { where(members: { access_level: [Gitlab::Access::MAINTAINER, Gitlab::Access::OWNER] }) },
|
||||
through: :group_members,
|
||||
|
@ -883,7 +884,12 @@ class User < ApplicationRecord
|
|||
# rubocop: enable CodeReuse/ServiceClass
|
||||
|
||||
def several_namespaces?
|
||||
owned_groups.any? || maintainers_groups.any?
|
||||
union_sql = ::Gitlab::SQL::Union.new(
|
||||
[owned_groups,
|
||||
maintainers_groups,
|
||||
groups_with_developer_maintainer_project_access]).to_sql
|
||||
|
||||
::Group.from("(#{union_sql}) #{::Group.table_name}").any?
|
||||
end
|
||||
|
||||
def namespace_id
|
||||
|
@ -1169,12 +1175,24 @@ class User < ApplicationRecord
|
|||
@manageable_namespaces ||= [namespace] + manageable_groups
|
||||
end
|
||||
|
||||
def manageable_groups
|
||||
Gitlab::ObjectHierarchy.new(owned_or_maintainers_groups).base_and_descendants
|
||||
def manageable_groups(include_groups_with_developer_maintainer_access: false)
|
||||
owned_and_maintainer_group_hierarchy = Gitlab::ObjectHierarchy.new(owned_or_maintainers_groups).base_and_descendants
|
||||
|
||||
if include_groups_with_developer_maintainer_access
|
||||
union_sql = ::Gitlab::SQL::Union.new(
|
||||
[owned_and_maintainer_group_hierarchy,
|
||||
groups_with_developer_maintainer_project_access]).to_sql
|
||||
|
||||
::Group.from("(#{union_sql}) #{::Group.table_name}")
|
||||
else
|
||||
owned_and_maintainer_group_hierarchy
|
||||
end
|
||||
end
|
||||
|
||||
def manageable_groups_with_routes
|
||||
manageable_groups.eager_load(:route).order('routes.path')
|
||||
def manageable_groups_with_routes(include_groups_with_developer_maintainer_access: false)
|
||||
manageable_groups(include_groups_with_developer_maintainer_access: include_groups_with_developer_maintainer_access)
|
||||
.eager_load(:route)
|
||||
.order('routes.path')
|
||||
end
|
||||
|
||||
def namespaces
|
||||
|
@ -1573,4 +1591,16 @@ class User < ApplicationRecord
|
|||
ensure
|
||||
Gitlab::ExclusiveLease.cancel(lease_key, uuid)
|
||||
end
|
||||
|
||||
def groups_with_developer_maintainer_project_access
|
||||
project_creation_levels = [::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS]
|
||||
|
||||
if ::Gitlab::CurrentSettings.default_project_creation == ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS
|
||||
project_creation_levels << nil
|
||||
end
|
||||
|
||||
developer_groups_hierarchy = ::Gitlab::ObjectHierarchy.new(developer_groups).base_and_descendants
|
||||
::Group.where(id: developer_groups_hierarchy.select(:id),
|
||||
project_creation_level: project_creation_levels)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -35,6 +35,14 @@ class GroupPolicy < BasePolicy
|
|||
with_options scope: :subject, score: 0
|
||||
condition(:request_access_enabled) { @subject.request_access_enabled }
|
||||
|
||||
condition(:create_projects_disabled) do
|
||||
@subject.project_creation_level == ::Gitlab::Access::NO_ONE_PROJECT_ACCESS
|
||||
end
|
||||
|
||||
condition(:developer_maintainer_access) do
|
||||
@subject.project_creation_level == ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS
|
||||
end
|
||||
|
||||
rule { public_group }.policy do
|
||||
enable :read_group
|
||||
enable :read_list
|
||||
|
@ -115,6 +123,9 @@ class GroupPolicy < BasePolicy
|
|||
|
||||
rule { ~can_have_multiple_clusters & has_clusters }.prevent :add_cluster
|
||||
|
||||
rule { developer & developer_maintainer_access }.enable :create_projects
|
||||
rule { create_projects_disabled }.prevent :create_projects
|
||||
|
||||
def access_level
|
||||
return GroupMember::NO_ACCESS if @user.nil?
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
.form-group
|
||||
= f.label :default_branch_protection, class: 'label-bold'
|
||||
= f.select :default_branch_protection, options_for_select(Gitlab::Access.protection_options, @application_setting.default_branch_protection), {}, class: 'form-control'
|
||||
= render_if_exists 'admin/application_settings/project_creation_level', form: f, application_setting: @application_setting
|
||||
.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'
|
||||
.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)
|
||||
|
|
|
@ -9,6 +9,10 @@
|
|||
= link_to icon('question-circle'), help_page_path('workflow/lfs/manage_large_binaries_with_git_lfs')
|
||||
%br/
|
||||
%span.descr This setting can be overridden in each project.
|
||||
.form-group.row
|
||||
= f.label s_('ProjectCreationLevel|Allowed to create projects'), class: 'col-form-label col-sm-2'
|
||||
.col-sm-10
|
||||
= f.select :project_creation_level, options_for_select(::Gitlab::Access.project_creation_options, @group.project_creation_level), {}, class: 'form-control'
|
||||
|
||||
.form-group.row
|
||||
= f.label :require_two_factor_authentication, 'Two-factor authentication', class: 'col-form-label col-sm-2 pt-0'
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
%span.descr.text-muted= share_with_group_lock_help_text(@group)
|
||||
|
||||
= render 'groups/settings/lfs', f: f
|
||||
= render 'groups/settings/project_creation_level', f: f, group: @group
|
||||
= render 'groups/settings/two_factor_auth', f: f
|
||||
= render_if_exists 'groups/member_lock_setting', f: f, group: @group
|
||||
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
.form-group
|
||||
= f.label s_('ProjectCreationLevel|Allowed to create projects'), class: 'label-bold'
|
||||
= f.select :project_creation_level, options_for_select(::Gitlab::Access.project_creation_options, group.project_creation_level), {}, class: 'form-control'
|
|
@ -19,9 +19,9 @@
|
|||
= root_url
|
||||
- namespace_id = namespace_id_from(params)
|
||||
= f.select(:namespace_id,
|
||||
namespaces_options(namespace_id || :current_user,
|
||||
display_path: true,
|
||||
extra_group: namespace_id),
|
||||
namespaces_options_with_developer_maintainer_access(selected: namespace_id,
|
||||
display_path: true,
|
||||
extra_group: namespace_id),
|
||||
{},
|
||||
{ class: 'select2 js-select-namespace qa-project-namespace-select block-truncated', tabindex: 1, data: { track_label: "#{track_label}", track_event: "activate_form_input", track_property: "project_path", track_value: "" }})
|
||||
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
---
|
||||
title: Move allow developers to create projects in groups to Core
|
||||
merge_request: 25975
|
||||
author:
|
||||
type: added
|
|
@ -126,6 +126,7 @@ Settings['issues_tracker'] ||= {}
|
|||
# GitLab
|
||||
#
|
||||
Settings['gitlab'] ||= Settingslogic.new({})
|
||||
Settings.gitlab['default_project_creation'] ||= ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS
|
||||
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?
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
# 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 AddDefaultProjectCreationApplicationSetting < ActiveRecord::Migration[5.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
unless column_exists?(:application_settings, :default_project_creation)
|
||||
add_column(:application_settings, :default_project_creation, :integer, default: 2, null: false)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
if column_exists?(:application_settings, :default_project_creation)
|
||||
remove_column(:application_settings, :default_project_creation)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -0,0 +1,22 @@
|
|||
# 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 AddProjectCreationLevelToNamespaces < ActiveRecord::Migration[5.0]
|
||||
include Gitlab::Database::MigrationHelpers
|
||||
|
||||
DOWNTIME = false
|
||||
|
||||
def up
|
||||
unless column_exists?(:namespaces, :project_creation_level)
|
||||
add_column :namespaces, :project_creation_level, :integer
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
unless column_exists?(:namespaces, :project_creation_level)
|
||||
remove_column :namespaces, :project_creation_level, :integer
|
||||
end
|
||||
end
|
||||
end
|
|
@ -177,6 +177,7 @@ ActiveRecord::Schema.define(version: 20190325165127) do
|
|||
t.string "runners_registration_token_encrypted"
|
||||
t.integer "local_markdown_version", default: 0, null: false
|
||||
t.integer "first_day_of_week", default: 0, null: false
|
||||
t.integer "default_project_creation", default: 2, null: false
|
||||
t.index ["usage_stats_set_by_user_id"], name: "index_application_settings_on_usage_stats_set_by_user_id", using: :btree
|
||||
end
|
||||
|
||||
|
@ -1391,6 +1392,7 @@ ActiveRecord::Schema.define(version: 20190325165127) do
|
|||
t.integer "cached_markdown_version"
|
||||
t.string "runners_token"
|
||||
t.string "runners_token_encrypted"
|
||||
t.integer "project_creation_level"
|
||||
t.boolean "auto_devops_enabled"
|
||||
t.index ["created_at"], name: "index_namespaces_on_created_at", using: :btree
|
||||
t.index ["name", "parent_id"], name: "index_namespaces_on_name_and_parent_id", unique: true, using: :btree
|
||||
|
|
|
@ -151,6 +151,17 @@ There are two different ways to add a new project to a group:
|
|||
|
||||
![Select group](img/select_group_dropdown.png)
|
||||
|
||||
### Default project creation level
|
||||
|
||||
Group owners or administrators can allow users with the
|
||||
Developer role to create projects under groups.
|
||||
|
||||
By default, [Developers and Maintainers](../permissions.md##group-members-permissions) can create projects under agroup, but this can be changed either within the group settings for a group, or
|
||||
be set globally by a GitLab administrator in the Admin area
|
||||
at **Settings > General > Visibility and access controls**.
|
||||
|
||||
Available settings are `No one`, `Maintainers`, or `Developers + Maintainers`.
|
||||
|
||||
## Transfer projects into groups
|
||||
|
||||
Learn how to [transfer a project into a group](../project/settings/index.md#transferring-an-existing-project-into-another-namespace).
|
||||
|
|
|
@ -40,7 +40,8 @@ module API
|
|||
end
|
||||
optional :container_registry_token_expire_delay, type: Integer, desc: 'Authorization token duration (minutes)'
|
||||
optional :default_artifacts_expire_in, type: String, desc: "Set the default expiration time for each job's artifacts"
|
||||
optional :default_branch_protection, type: Integer, values: Gitlab::Access.protection_values, desc: 'Determine if developers can push to master'
|
||||
optional :default_project_creation, type: Integer, values: ::Gitlab::Access.project_creation_values, desc: 'Determine if developers can create projects in the group'
|
||||
optional :default_branch_protection, type: Integer, values: ::Gitlab::Access.protection_values, desc: 'Determine if developers can push to master'
|
||||
optional :default_group_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default group visibility'
|
||||
optional :default_project_visibility, type: String, values: Gitlab::VisibilityLevel.string_values, desc: 'The default project visibility'
|
||||
optional :default_projects_limit, type: Integer, desc: 'The maximum number of personal projects'
|
||||
|
|
|
@ -24,6 +24,11 @@ module Gitlab
|
|||
PROTECTION_FULL = 2
|
||||
PROTECTION_DEV_CAN_MERGE = 3
|
||||
|
||||
# Default project creation level
|
||||
NO_ONE_PROJECT_ACCESS = 0
|
||||
MAINTAINER_PROJECT_ACCESS = 1
|
||||
DEVELOPER_MAINTAINER_PROJECT_ACCESS = 2
|
||||
|
||||
class << self
|
||||
delegate :values, to: :options
|
||||
|
||||
|
@ -85,6 +90,22 @@ module Gitlab
|
|||
def human_access_with_none(access)
|
||||
options_with_none.key(access)
|
||||
end
|
||||
|
||||
def project_creation_options
|
||||
{
|
||||
s_('ProjectCreationLevel|No one') => NO_ONE_PROJECT_ACCESS,
|
||||
s_('ProjectCreationLevel|Maintainers') => MAINTAINER_PROJECT_ACCESS,
|
||||
s_('ProjectCreationLevel|Developers + Maintainers') => DEVELOPER_MAINTAINER_PROJECT_ACCESS
|
||||
}
|
||||
end
|
||||
|
||||
def project_creation_values
|
||||
project_creation_options.values
|
||||
end
|
||||
|
||||
def project_creation_level_name(name)
|
||||
project_creation_options.key(name)
|
||||
end
|
||||
end
|
||||
|
||||
def human_access
|
||||
|
|
|
@ -6418,6 +6418,21 @@ msgstr ""
|
|||
msgid "ProjectActivityRSS|Subscribe"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectCreationLevel|Allowed to create projects"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectCreationLevel|Default project creation protection"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectCreationLevel|Developers + Maintainers"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectCreationLevel|Maintainers"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectCreationLevel|No one"
|
||||
msgstr ""
|
||||
|
||||
msgid "ProjectFileTree|Name"
|
||||
msgstr ""
|
||||
|
||||
|
|
|
@ -85,6 +85,13 @@ describe Admin::ApplicationSettingsController do
|
|||
expect(response).to redirect_to(admin_application_settings_path)
|
||||
expect(ApplicationSetting.current.receive_max_input_size).to eq(1024)
|
||||
end
|
||||
|
||||
it 'updates the default_project_creation for string value' do
|
||||
put :update, params: { application_setting: { default_project_creation: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS } }
|
||||
|
||||
expect(response).to redirect_to(admin_application_settings_path)
|
||||
expect(ApplicationSetting.current.default_project_creation).to eq(::Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
|
||||
end
|
||||
end
|
||||
|
||||
describe 'PUT #reset_registration_token' do
|
||||
|
|
|
@ -60,5 +60,11 @@ describe Admin::GroupsController do
|
|||
expect(response).to redirect_to(admin_group_path(group))
|
||||
expect(group.users).not_to include group_user
|
||||
end
|
||||
|
||||
it 'updates the project_creation_level successfully' do
|
||||
expect do
|
||||
post :update, params: { id: group.to_param, group: { project_creation_level: ::Gitlab::Access::NO_ONE_PROJECT_ACCESS } }
|
||||
end.to change { group.reload.project_creation_level }.to(::Gitlab::Access::NO_ONE_PROJECT_ACCESS)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -349,6 +349,13 @@ describe GroupsController do
|
|||
expect(assigns(:group).errors).not_to be_empty
|
||||
expect(assigns(:group).path).not_to eq('new_path')
|
||||
end
|
||||
|
||||
it 'updates the project_creation_level successfully' do
|
||||
post :update, params: { id: group.to_param, group: { project_creation_level: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS } }
|
||||
|
||||
expect(response).to have_gitlab_http_status(302)
|
||||
expect(group.reload.project_creation_level).to eq(::Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
|
||||
end
|
||||
end
|
||||
|
||||
describe '#ensure_canonical_path' do
|
||||
|
|
|
@ -4,6 +4,7 @@ FactoryBot.define do
|
|||
path { name.downcase.gsub(/\s/, '_') }
|
||||
type 'Group'
|
||||
owner nil
|
||||
project_creation_level ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS
|
||||
|
||||
after(:create) do |group|
|
||||
if group.owner
|
||||
|
|
|
@ -77,6 +77,14 @@ describe 'Edit group settings' do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'project creation level menu' do
|
||||
it 'shows the selection menu' do
|
||||
visit edit_group_path(group)
|
||||
|
||||
expect(page).to have_content('Allowed to create projects')
|
||||
end
|
||||
end
|
||||
|
||||
describe 'edit group avatar' do
|
||||
before do
|
||||
visit edit_group_path(group)
|
||||
|
|
|
@ -252,4 +252,23 @@ describe 'New project' do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'Namespace selector' do
|
||||
context 'with group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
|
||||
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
|
||||
|
||||
before do
|
||||
group.add_developer(user)
|
||||
visit new_project_path(namespace_id: group.id)
|
||||
end
|
||||
|
||||
it 'selects the group namespace' do
|
||||
page.within('#blank-project-pane') do
|
||||
namespace = find('#project_namespace_id option[selected]')
|
||||
|
||||
expect(namespace.text).to eq group.full_path
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -54,4 +54,31 @@ describe 'User creates a project', :js do
|
|||
expect(project.namespace).to eq(subgroup)
|
||||
end
|
||||
end
|
||||
|
||||
context 'in a group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
|
||||
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
|
||||
|
||||
before do
|
||||
group.add_developer(user)
|
||||
end
|
||||
|
||||
it 'creates a new project' do
|
||||
visit(new_project_path)
|
||||
|
||||
fill_in :project_name, with: 'a-new-project'
|
||||
fill_in :project_path, with: 'a-new-project'
|
||||
|
||||
page.find('.js-select-namespace').click
|
||||
page.find("div[role='option']", text: group.full_path).click
|
||||
|
||||
page.within('#content-body') do
|
||||
click_button('Create project')
|
||||
end
|
||||
|
||||
expect(page).to have_content("Project 'a-new-project' was successfully created")
|
||||
|
||||
project = Project.find_by(name: 'a-new-project')
|
||||
expect(project.namespace).to eq(group)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,10 +1,38 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe NamespacesHelper do
|
||||
describe NamespacesHelper, :postgresql do
|
||||
let!(:admin) { create(:admin) }
|
||||
let!(:admin_group) { create(:group, :private) }
|
||||
let!(:admin_project_creation_level) { nil }
|
||||
let!(:admin_group) do
|
||||
create(:group,
|
||||
:private,
|
||||
project_creation_level: admin_project_creation_level)
|
||||
end
|
||||
let!(:user) { create(:user) }
|
||||
let!(:user_group) { create(:group, :private) }
|
||||
let!(:user_project_creation_level) { nil }
|
||||
let!(:user_group) do
|
||||
create(:group,
|
||||
:private,
|
||||
project_creation_level: user_project_creation_level)
|
||||
end
|
||||
let!(:subgroup1) do
|
||||
create(:group,
|
||||
:private,
|
||||
parent: admin_group,
|
||||
project_creation_level: nil)
|
||||
end
|
||||
let!(:subgroup2) do
|
||||
create(:group,
|
||||
:private,
|
||||
parent: admin_group,
|
||||
project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
|
||||
end
|
||||
let!(:subgroup3) do
|
||||
create(:group,
|
||||
:private,
|
||||
parent: admin_group,
|
||||
project_creation_level: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
|
||||
end
|
||||
|
||||
before do
|
||||
admin_group.add_owner(admin)
|
||||
|
@ -105,5 +133,43 @@ describe NamespacesHelper do
|
|||
helper.namespaces_options
|
||||
end
|
||||
end
|
||||
|
||||
describe 'include_groups_with_developer_maintainer_access parameter' do
|
||||
context 'when DEVELOPER_MAINTAINER_PROJECT_ACCESS is set for a project' do
|
||||
let!(:admin_project_creation_level) { ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS }
|
||||
|
||||
it 'returns groups where user is a developer' do
|
||||
allow(helper).to receive(:current_user).and_return(user)
|
||||
stub_application_setting(default_project_creation: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
|
||||
admin_group.add_user(user, GroupMember::DEVELOPER)
|
||||
|
||||
options = helper.namespaces_options_with_developer_maintainer_access
|
||||
|
||||
expect(options).to include(admin_group.name)
|
||||
expect(options).not_to include(subgroup1.name)
|
||||
expect(options).to include(subgroup2.name)
|
||||
expect(options).not_to include(subgroup3.name)
|
||||
expect(options).to include(user_group.name)
|
||||
expect(options).to include(user.name)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when DEVELOPER_MAINTAINER_PROJECT_ACCESS is set globally' do
|
||||
it 'return groups where default is not overridden' do
|
||||
allow(helper).to receive(:current_user).and_return(user)
|
||||
stub_application_setting(default_project_creation: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
|
||||
admin_group.add_user(user, GroupMember::DEVELOPER)
|
||||
|
||||
options = helper.namespaces_options_with_developer_maintainer_access
|
||||
|
||||
expect(options).to include(admin_group.name)
|
||||
expect(options).to include(subgroup1.name)
|
||||
expect(options).to include(subgroup2.name)
|
||||
expect(options).not_to include(subgroup3.name)
|
||||
expect(options).to include(user_group.name)
|
||||
expect(options).to include(user.name)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -959,4 +959,12 @@ describe Group do
|
|||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe 'project_creation_level' do
|
||||
it 'outputs the default one if it is nil' do
|
||||
group = create(:group, project_creation_level: nil)
|
||||
|
||||
expect(group.project_creation_level).to eq(Gitlab::CurrentSettings.default_project_creation)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -347,6 +347,120 @@ describe GroupPolicy do
|
|||
end
|
||||
end
|
||||
|
||||
context "create_projects" do
|
||||
context 'when group has no project creation level set' do
|
||||
let(:group) { create(:group, project_creation_level: nil) }
|
||||
|
||||
context 'reporter' do
|
||||
let(:current_user) { reporter }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'developer' do
|
||||
let(:current_user) { developer }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'maintainer' do
|
||||
let(:current_user) { maintainer }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'owner' do
|
||||
let(:current_user) { owner }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when group has project creation level set to no one' do
|
||||
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::NO_ONE_PROJECT_ACCESS) }
|
||||
|
||||
context 'reporter' do
|
||||
let(:current_user) { reporter }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'developer' do
|
||||
let(:current_user) { developer }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'maintainer' do
|
||||
let(:current_user) { maintainer }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'owner' do
|
||||
let(:current_user) { owner }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when group has project creation level set to maintainer only' do
|
||||
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::MAINTAINER_PROJECT_ACCESS) }
|
||||
|
||||
context 'reporter' do
|
||||
let(:current_user) { reporter }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'developer' do
|
||||
let(:current_user) { developer }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'maintainer' do
|
||||
let(:current_user) { maintainer }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'owner' do
|
||||
let(:current_user) { owner }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
end
|
||||
|
||||
context 'when group has project creation level set to developers + maintainer' do
|
||||
let(:group) { create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS) }
|
||||
|
||||
context 'reporter' do
|
||||
let(:current_user) { reporter }
|
||||
|
||||
it { is_expected.to be_disallowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'developer' do
|
||||
let(:current_user) { developer }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'maintainer' do
|
||||
let(:current_user) { maintainer }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
|
||||
context 'owner' do
|
||||
let(:current_user) { owner }
|
||||
|
||||
it { is_expected.to be_allowed(:create_projects) }
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
it_behaves_like 'clusterable policies' do
|
||||
let(:clusterable) { create(:group) }
|
||||
let(:cluster) do
|
||||
|
|
|
@ -44,6 +44,7 @@ describe API::Settings, 'Settings' do
|
|||
put api("/application/settings", admin),
|
||||
params: {
|
||||
default_projects_limit: 3,
|
||||
default_project_creation: 2,
|
||||
password_authentication_enabled_for_web: false,
|
||||
repository_storages: ['custom'],
|
||||
plantuml_enabled: true,
|
||||
|
@ -64,12 +65,13 @@ describe API::Settings, 'Settings' do
|
|||
performance_bar_allowed_group_path: group.full_path,
|
||||
instance_statistics_visibility_private: true,
|
||||
diff_max_patch_bytes: 150_000,
|
||||
default_branch_protection: Gitlab::Access::PROTECTION_DEV_CAN_MERGE,
|
||||
default_branch_protection: ::Gitlab::Access::PROTECTION_DEV_CAN_MERGE,
|
||||
local_markdown_version: 3
|
||||
}
|
||||
|
||||
expect(response).to have_gitlab_http_status(200)
|
||||
expect(json_response['default_projects_limit']).to eq(3)
|
||||
expect(json_response['default_project_creation']).to eq(::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
|
||||
expect(json_response['password_authentication_enabled_for_web']).to be_falsey
|
||||
expect(json_response['repository_storages']).to eq(['custom'])
|
||||
expect(json_response['plantuml_enabled']).to be_truthy
|
||||
|
|
Loading…
Reference in a new issue