Commit 1841bdc2 authored by Yorick Peterse's avatar Yorick Peterse

Merge branch...

Merge branch 'ee-5666-list_groups_with_developer_maintainer_access_on_project_creation' into 'master'

List groups with developer maintainer access on project creation

Closes #5666

See merge request gitlab-org/gitlab-ee!6678
parents 8aaa17f9 a4b2c5ab
module NamespacesHelper module NamespacesHelper
include EE::NamespaceHelper include EE::NamespacesHelper
def namespace_id_from(params) def namespace_id_from(params)
params.dig(:project, :namespace_id) || params[:namespace_id] params.dig(:project, :namespace_id) || params[:namespace_id]
end end
def namespaces_options(selected = :current_user, display_path: false, extra_group: nil, groups_only: false) def namespaces_options(selected = :current_user, display_path: false, groups: nil, extra_group: nil, groups_only: false)
groups = current_user.manageable_groups groups ||= current_user.manageable_groups
.joins(:route) .joins(:route)
.includes(:route) .includes(:route)
.order('routes.path') .order('routes.path')
......
...@@ -12,7 +12,13 @@ ...@@ -12,7 +12,13 @@
.input-group-prepend.has-tooltip{ title: root_url } .input-group-prepend.has-tooltip{ title: root_url }
.input-group-text .input-group-text
= root_url = root_url
= f.select :namespace_id, namespaces_options(namespace_id_from(params) || :current_user, display_path: true, extra_group: namespace_id_from(params)), {}, { class: 'select2 js-select-namespace qa-project-namespace-select', tabindex: 1} - namespace_id = namespace_id_from(params)
= f.select(: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', tabindex: 1})
- else - else
.input-group-prepend.static-namespace.has-tooltip{ title: user_url(current_user.username) + '/' } .input-group-prepend.static-namespace.has-tooltip{ title: user_url(current_user.username) + '/' }
......
module EE module EE
module NamespaceHelper module NamespacesHelper
def namespace_shared_runner_limits_quota(namespace) def namespace_shared_runner_limits_quota(namespace)
used = namespace.shared_runners_minutes.to_i used = namespace.shared_runners_minutes.to_i
...@@ -43,5 +43,14 @@ module EE ...@@ -43,5 +43,14 @@ module EE
content_tag :div, nil, options content_tag :div, nil, options
end end
end end
def namespaces_options_with_developer_maintainer_access(options = {})
selected = options.delete(:selected) || :current_user
options[:groups] = current_user.manageable_groups(include_groups_with_developer_maintainer_access: true)
.eager_load(:route)
.order('routes.path')
namespaces_options(selected, options)
end
end end
end end
...@@ -5,6 +5,8 @@ module EE ...@@ -5,6 +5,8 @@ module EE
# and be prepended in the `User` model # and be prepended in the `User` model
module User module User
extend ActiveSupport::Concern extend ActiveSupport::Concern
extend ::Gitlab::Utils::Override
include AuditorUserHelper include AuditorUserHelper
DEFAULT_ROADMAP_LAYOUT = 'months'.freeze DEFAULT_ROADMAP_LAYOUT = 'months'.freeze
...@@ -31,6 +33,8 @@ module EE ...@@ -31,6 +33,8 @@ module EE
has_many :approvals, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent has_many :approvals, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent
has_many :approvers, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent has_many :approvers, dependent: :destroy # rubocop: disable Cop/ActiveRecordDependent
has_many :developer_groups, -> { where(members: { access_level: ::Gitlab::Access::DEVELOPER }) }, through: :group_members, source: :group
# Protected Branch Access # Protected Branch Access
has_many :protected_branch_merge_access_levels, dependent: :destroy, class_name: ::ProtectedBranch::MergeAccessLevel # rubocop:disable Cop/ActiveRecordDependent has_many :protected_branch_merge_access_levels, dependent: :destroy, class_name: ::ProtectedBranch::MergeAccessLevel # rubocop:disable Cop/ActiveRecordDependent
has_many :protected_branch_push_access_levels, dependent: :destroy, class_name: ::ProtectedBranch::PushAccessLevel # rubocop:disable Cop/ActiveRecordDependent has_many :protected_branch_push_access_levels, dependent: :destroy, class_name: ::ProtectedBranch::PushAccessLevel # rubocop:disable Cop/ActiveRecordDependent
...@@ -110,5 +114,42 @@ module EE ...@@ -110,5 +114,42 @@ module EE
def roadmap_layout def roadmap_layout
super || DEFAULT_ROADMAP_LAYOUT super || DEFAULT_ROADMAP_LAYOUT
end end
override :several_namespaces?
def several_namespaces?
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
override :manageable_groups
def manageable_groups(include_groups_with_developer_maintainer_access: false)
owned_and_maintainer_group_hierarchy = super()
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 groups_with_developer_maintainer_project_access
project_creation_levels = [::EE::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS]
if ::Gitlab::CurrentSettings.default_project_creation == ::EE::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS
project_creation_levels << nil
end
developer_groups_hierarchy = ::Gitlab::GroupHierarchy.new(developer_groups).base_and_descendants
::Group.where(id: developer_groups_hierarchy.select(:id),
project_creation_level: project_creation_levels)
end
end end
end end
---
title: List groups with developer maintainer access on project creation
merge_request: 6678
author:
type: fixed
...@@ -7,6 +7,25 @@ describe 'New project' do ...@@ -7,6 +7,25 @@ describe 'New project' do
sign_in(user) sign_in(user)
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: ::EE::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
context 'repository mirrors' do context 'repository mirrors' do
context 'when licensed' do context 'when licensed' do
before do before do
......
# frozen_string_literal: true
require 'spec_helper'
describe 'User creates a project', :js do
let(:user) { create(:user) }
before do
sign_in(user)
end
context 'in a group with DEVELOPER_MAINTAINER_PROJECT_ACCESS project_creation_level' do
let(:group) { create(:group, project_creation_level: ::EE::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_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
# frozen_string_literal: true
require 'spec_helper'
describe EE::NamespacesHelper, :postgresql do
let!(:admin) { create(:admin) }
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_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: ::EE::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
end
let!(:subgroup3) do
create(:group,
:private,
parent: admin_group,
project_creation_level: ::EE::Gitlab::Access::MAINTAINER_PROJECT_ACCESS)
end
before do
admin_group.add_owner(admin)
user_group.add_owner(user)
end
describe '#namespaces_options' do
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) { ::EE::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: ::EE::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 overriden' do
allow(helper).to receive(:current_user).and_return(user)
stub_application_setting(default_project_creation: ::EE::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
...@@ -10,7 +10,7 @@ module QA ...@@ -10,7 +10,7 @@ module QA
view 'app/views/projects/_new_project_fields.html.haml' do view 'app/views/projects/_new_project_fields.html.haml' do
element :project_namespace_select element :project_namespace_select
element :project_namespace_field, /select :namespace_id.*class: 'select2/ element :project_namespace_field, 'namespaces_options'
element :project_path, 'text_field :path' element :project_path, 'text_field :path'
element :project_description, 'text_area :description' element :project_description, 'text_area :description'
element :project_create_button, "submit 'Create project'" element :project_create_button, "submit 'Create project'"
......
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