Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/app
diff options
context:
space:
mode:
Diffstat (limited to 'app')
-rw-r--r--app/controllers/admin/groups_controller.rb3
-rw-r--r--app/controllers/groups_controller.rb3
-rw-r--r--app/helpers/application_settings_helper.rb1
-rw-r--r--app/helpers/namespaces_helper.rb7
-rw-r--r--app/models/application_setting_implementation.rb1
-rw-r--r--app/models/group.rb4
-rw-r--r--app/models/user.rb40
-rw-r--r--app/policies/group_policy.rb11
-rw-r--r--app/views/admin/application_settings/_visibility_and_access.html.haml4
-rw-r--r--app/views/groups/_group_admin_settings.html.haml4
-rw-r--r--app/views/groups/settings/_permissions.html.haml1
-rw-r--r--app/views/groups/settings/_project_creation_level.html.haml3
-rw-r--r--app/views/projects/_new_project_fields.html.haml6
13 files changed, 77 insertions, 11 deletions
diff --git a/app/controllers/admin/groups_controller.rb b/app/controllers/admin/groups_controller.rb
index e0ecdb0c0e9..15f7ef881c8 100644
--- a/app/controllers/admin/groups_controller.rb
+++ b/app/controllers/admin/groups_controller.rb
@@ -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
diff --git a/app/controllers/groups_controller.rb b/app/controllers/groups_controller.rb
index 87b8ef03313..e936d771502 100644
--- a/app/controllers/groups_controller.rb
+++ b/app/controllers/groups_controller.rb
@@ -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
diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb
index e635f608237..e275e4278a4 100644
--- a/app/helpers/application_settings_helper.rb
+++ b/app/helpers/application_settings_helper.rb
@@ -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,
diff --git a/app/helpers/namespaces_helper.rb b/app/helpers/namespaces_helper.rb
index ea3bcfc791a..572d68cb4a3 100644
--- a/app/helpers/namespaces_helper.rb
+++ b/app/helpers/namespaces_helper.rb
@@ -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
diff --git a/app/models/application_setting_implementation.rb b/app/models/application_setting_implementation.rb
index 265aa1d4965..b413ffddb9d 100644
--- a/app/models/application_setting_implementation.rb
+++ b/app/models/application_setting_implementation.rb
@@ -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'],
diff --git a/app/models/group.rb b/app/models/group.rb
index ac66815705c..8bc9b75f0a9 100644
--- a/app/models/group.rb
+++ b/app/models/group.rb
@@ -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
diff --git a/app/models/user.rb b/app/models/user.rb
index 259889995d3..d3524bfd6ae 100644
--- a/app/models/user.rb
+++ b/app/models/user.rb
@@ -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
diff --git a/app/policies/group_policy.rb b/app/policies/group_policy.rb
index db49d3bed9c..eb2e536e8e9 100644
--- a/app/policies/group_policy.rb
+++ b/app/policies/group_policy.rb
@@ -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?
diff --git a/app/views/admin/application_settings/_visibility_and_access.html.haml b/app/views/admin/application_settings/_visibility_and_access.html.haml
index 8122d81f578..03ef2924617 100644
--- a/app/views/admin/application_settings/_visibility_and_access.html.haml
+++ b/app/views/admin/application_settings/_visibility_and_access.html.haml
@@ -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)
diff --git a/app/views/groups/_group_admin_settings.html.haml b/app/views/groups/_group_admin_settings.html.haml
index ff59013ed67..7390c42aba2 100644
--- a/app/views/groups/_group_admin_settings.html.haml
+++ b/app/views/groups/_group_admin_settings.html.haml
@@ -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'
diff --git a/app/views/groups/settings/_permissions.html.haml b/app/views/groups/settings/_permissions.html.haml
index 6b0a6e7ed99..0a14830c666 100644
--- a/app/views/groups/settings/_permissions.html.haml
+++ b/app/views/groups/settings/_permissions.html.haml
@@ -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
diff --git a/app/views/groups/settings/_project_creation_level.html.haml b/app/views/groups/settings/_project_creation_level.html.haml
new file mode 100644
index 00000000000..9f711e6aade
--- /dev/null
+++ b/app/views/groups/settings/_project_creation_level.html.haml
@@ -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'
diff --git a/app/views/projects/_new_project_fields.html.haml b/app/views/projects/_new_project_fields.html.haml
index 5129f11875c..1c1c7d832bd 100644
--- a/app/views/projects/_new_project_fields.html.haml
+++ b/app/views/projects/_new_project_fields.html.haml
@@ -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: "" }})