Commit 67660428 authored by Alex Kalderimis's avatar Alex Kalderimis

Merge branch 'id-fork-developer-groups' into 'master'

Allow developers to fork into group

See merge request gitlab-org/gitlab!78204
parents d26f2fef ddcf1661
...@@ -8,9 +8,9 @@ class ForkTargetsFinder ...@@ -8,9 +8,9 @@ class ForkTargetsFinder
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
def execute(options = {}) def execute(options = {})
return ::Namespace.where(id: user.manageable_namespaces).sort_by_type unless options[:only_groups] return ::Namespace.where(id: user.forkable_namespaces).sort_by_type unless options[:only_groups]
::Group.where(id: user.manageable_groups) ::Group.where(id: user.manageable_groups(include_groups_with_developer_maintainer_access: true))
end end
# rubocop: enable CodeReuse/ActiveRecord # rubocop: enable CodeReuse/ActiveRecord
......
...@@ -1535,8 +1535,8 @@ class User < ApplicationRecord ...@@ -1535,8 +1535,8 @@ class User < ApplicationRecord
end end
end end
def manageable_namespaces def forkable_namespaces
@manageable_namespaces ||= [namespace] + manageable_groups @forkable_namespaces ||= [namespace] + manageable_groups(include_groups_with_developer_maintainer_access: true)
end end
def manageable_groups(include_groups_with_developer_maintainer_access: false) def manageable_groups(include_groups_with_developer_maintainer_access: false)
......
...@@ -9,7 +9,7 @@ class GlobalPolicy < BasePolicy ...@@ -9,7 +9,7 @@ class GlobalPolicy < BasePolicy
with_options scope: :user, score: 0 with_options scope: :user, score: 0
condition(:access_locked) { @user&.access_locked? } condition(:access_locked) { @user&.access_locked? }
condition(:can_create_fork, scope: :user) { @user && @user.manageable_namespaces.any? { |namespace| @user.can?(:create_projects, namespace) } } condition(:can_create_fork, scope: :user) { @user && @user.forkable_namespaces.any? { |namespace| @user.can?(:create_projects, namespace) } }
condition(:required_terms_not_accepted, scope: :user, score: 0) do condition(:required_terms_not_accepted, scope: :user, score: 0) do
@user&.required_terms_not_accepted? @user&.required_terms_not_accepted?
......
- unless @project.empty_repo? - unless @project.empty_repo?
- if current_user - if current_user
.count-badge.btn-group .count-badge.btn-group
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.forkable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'gl-button btn btn-default btn-sm has-tooltip fork-btn' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: s_('ProjectOverview|Go to your fork'), class: 'gl-button btn btn-default btn-sm has-tooltip fork-btn' do
= sprite_icon('fork', css_class: 'icon') = sprite_icon('fork', css_class: 'icon')
%span= s_('ProjectOverview|Fork') %span= s_('ProjectOverview|Fork')
......
...@@ -25,7 +25,7 @@ ...@@ -25,7 +25,7 @@
= forks_sort_direction_button(sort_value) = forks_sort_direction_button(sort_value)
- if current_user && can?(current_user, :fork_project, @project) - if current_user && can?(current_user, :fork_project, @project)
- if current_user.already_forked?(@project) && current_user.manageable_namespaces.size < 2 - if current_user.already_forked?(@project) && current_user.forkable_namespaces.size < 2
= link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm gl-md-ml-3' do = link_to namespace_project_path(current_user, current_user.fork_of(@project)), title: _('Go to your fork'), class: 'btn gl-button btn-confirm gl-md-ml-3' do
= sprite_icon('fork', size: 12) = sprite_icon('fork', size: 12)
%span= _('Fork') %span= _('Fork')
......
...@@ -16,7 +16,9 @@ RSpec.describe ForkTargetsFinder do ...@@ -16,7 +16,9 @@ RSpec.describe ForkTargetsFinder do
end end
let!(:developer_group) do let!(:developer_group) do
create(:group).tap { |g| g.add_developer(user) } create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS).tap do |g|
g.add_developer(user)
end
end end
let!(:reporter_group) do let!(:reporter_group) do
...@@ -33,11 +35,11 @@ RSpec.describe ForkTargetsFinder do ...@@ -33,11 +35,11 @@ RSpec.describe ForkTargetsFinder do
describe '#execute' do describe '#execute' do
it 'returns all user manageable namespaces' do it 'returns all user manageable namespaces' do
expect(finder.execute).to match_array([user.namespace, maintained_group, owned_group, project.namespace]) expect(finder.execute).to match_array([user.namespace, maintained_group, owned_group, project.namespace, developer_group])
end end
it 'returns only groups when only_groups option is passed' do it 'returns only groups when only_groups option is passed' do
expect(finder.execute(only_groups: true)).to match_array([maintained_group, owned_group, project.namespace]) expect(finder.execute(only_groups: true)).to match_array([maintained_group, owned_group, project.namespace, developer_group])
end end
it 'returns groups relation when only_groups option is passed' do it 'returns groups relation when only_groups option is passed' do
......
...@@ -2055,7 +2055,7 @@ RSpec.describe User do ...@@ -2055,7 +2055,7 @@ RSpec.describe User do
it { expect(user.authorized_groups).to eq([group]) } it { expect(user.authorized_groups).to eq([group]) }
it { expect(user.owned_groups).to eq([group]) } it { expect(user.owned_groups).to eq([group]) }
it { expect(user.namespaces).to contain_exactly(user.namespace, group) } it { expect(user.namespaces).to contain_exactly(user.namespace, group) }
it { expect(user.manageable_namespaces).to contain_exactly(user.namespace, group) } it { expect(user.forkable_namespaces).to contain_exactly(user.namespace, group) }
context 'with owned groups only' do context 'with owned groups only' do
before do before do
...@@ -2069,9 +2069,12 @@ RSpec.describe User do ...@@ -2069,9 +2069,12 @@ RSpec.describe User do
context 'with child groups' do context 'with child groups' do
let!(:subgroup) { create(:group, parent: group) } let!(:subgroup) { create(:group, parent: group) }
describe '#manageable_namespaces' do describe '#forkable_namespaces' do
it 'includes all the namespaces the user can manage' do it 'includes all the namespaces the user can fork into' do
expect(user.manageable_namespaces).to contain_exactly(user.namespace, group, subgroup) developer_group = create(:group, project_creation_level: ::Gitlab::Access::DEVELOPER_MAINTAINER_PROJECT_ACCESS)
developer_group.add_developer(user)
expect(user.forkable_namespaces).to contain_exactly(user.namespace, group, subgroup, developer_group)
end end
end end
......
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