Commit 3e73981d authored by Jason Goodman's avatar Jason Goodman Committed by Phil Hughes

Prevent Transfering a Group with a Subscription

parent 7d8e54ba
......@@ -46,6 +46,7 @@ module Groups
def ensure_allowed_transfer
raise_transfer_error(:group_is_already_root) if group_is_already_root?
raise_transfer_error(:same_parent_as_current) if same_parent?
raise_transfer_error(:has_subscription) if has_subscription?
raise_transfer_error(:invalid_policies) unless valid_policies?
raise_transfer_error(:namespace_with_same_path) if namespace_with_same_path?
raise_transfer_error(:group_contains_images) if group_projects_contain_registry_images?
......@@ -73,6 +74,10 @@ module Groups
@new_parent_group && @new_parent_group.id == @group.parent_id
end
def has_subscription?
@group.paid?
end
def transfer_to_subgroup?
@new_parent_group && \
@group.self_and_descendants.pluck_primary_key.include?(@new_parent_group.id)
......
......@@ -24,21 +24,6 @@
"data-bind-in" => "#{'create_chat_team' if Gitlab.config.mattermost.enabled}"
= f.submit s_('GroupSettings|Change group URL'), class: 'btn gl-button btn-warning'
.sub-section
%h4.warning-title= s_('GroupSettings|Transfer group')
= form_for @group, url: transfer_group_path(@group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
.form-group
= dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', data: { data: parent_group_options(@group), qa_selector: 'select_group_dropdown' } })
= hidden_field_tag 'new_parent_group_id'
%ul
- side_effects_link_start = '<a href="https://docs.gitlab.com/ee/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'.html_safe
- warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end: '</a>'.html_safe }
%li= warning_text.html_safe
%li= s_('GroupSettings|You can only transfer the group to a group you manage.')
%li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
%li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
= f.submit s_('GroupSettings|Transfer group'), class: 'btn gl-button btn-warning', data: { qa_selector: "transfer_group_button" }
= render 'groups/settings/transfer', group: @group
= render 'groups/settings/remove', group: @group
= render_if_exists 'groups/settings/restore', group: @group
.sub-section
%h4.warning-title= s_('GroupSettings|Transfer group')
= form_for group, url: transfer_group_path(group), method: :put, html: { class: 'js-group-transfer-form' } do |f|
.form-group
= dropdown_tag('Select parent group', options: { toggle_class: 'js-groups-dropdown', title: 'Parent Group', filter: true, dropdown_class: 'dropdown-open-top dropdown-group-transfer', placeholder: 'Search groups', disabled: group.paid?, data: { data: parent_group_options(group), qa_selector: 'select_group_dropdown' } })
= hidden_field_tag 'new_parent_group_id'
%ul
- side_effects_link_start = '<a href="https://docs.gitlab.com/ee/user/project/index.html#redirects-when-changing-repository-paths" target="_blank">'.html_safe
- warning_text = s_("GroupSettings|Be careful. Changing a group's parent can have unintended %{side_effects_link_start}side effects%{side_effects_link_end}.") % { side_effects_link_start: side_effects_link_start, side_effects_link_end: '</a>'.html_safe }
%li= warning_text.html_safe
%li= s_('GroupSettings|You can only transfer the group to a group you manage.')
%li= s_('GroupSettings|You will need to update your local repositories to point to the new location.')
%li= s_("GroupSettings|If the parent group's visibility is lower than the group current visibility, visibility levels for subgroups and projects will be changed to match the new parent group's visibility.")
- if group.paid?
.gl-alert.gl-alert-info.gl-mb-5{ data: { testid: 'group-to-transfer-has-linked-subscription-alert' } }
= sprite_icon('information-o', size: 16, css_class: 'gl-icon gl-alert-icon gl-alert-icon-no-title')
.gl-alert-body
= html_escape(_("This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group.")) % { linkStart: "<a href=\"#{help_page_path('subscriptions/index', anchor: 'change-the-linked-namespace')}\">".html_safe, linkEnd: '</a>'.html_safe }
= f.submit s_('GroupSettings|Transfer group'), class: 'btn gl-button btn-warning', data: { qa_selector: "transfer_group_button" }
......@@ -335,6 +335,38 @@ RSpec.describe GroupsController, type: :request do
end
end
describe 'PUT #transfer' do
let(:new_parent_group) { create(:group) }
before do
group.add_owner(user)
new_parent_group.add_owner(user)
create(:gitlab_subscription, :ultimate, namespace: group)
login_as(user)
end
it 'does not transfer a group with a gitlab saas subscription' do
put transfer_group_path(group),
params: { new_parent_group_id: new_parent_group.id }
expect(response).to redirect_to(edit_group_path(group))
expect(flash[:alert]).to include('Transfer failed')
expect(group.reload.parent_id).to be_nil
end
it 'transfers a subgroup with a parent group with a gitlab saas subscription' do
subgroup = create(:group, parent: group)
put transfer_group_path(subgroup),
params: { new_parent_group_id: new_parent_group.id }
subgroup.reload
expect(response).to redirect_to(group_path(subgroup))
expect(flash[:alert]).to be_nil
expect(subgroup.parent_id).to eq(new_parent_group.id)
end
end
describe 'DELETE #destroy' do
before do
group.add_owner(user)
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'groups/settings/_transfer.html.haml' do
describe 'render' do
let(:group) { create(:group) }
it 'enables the Select parent group dropdown and does not show an alert for a group' do
render 'groups/settings/transfer', group: group
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"]'
expect(rendered).not_to have_selector '[data-qa-selector="select_group_dropdown"][disabled]'
expect(rendered).not_to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
end
it 'disables the Select parent group dropdown and shows an alert for a group with a paid gitlab.com plan' do
create(:gitlab_subscription, :ultimate, namespace: group)
render 'groups/settings/transfer', group: group
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"][disabled]'
expect(rendered).to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
end
it 'enables the Select parent group dropdown and does not show an alert for a subgroup' do
create(:gitlab_subscription, :ultimate, namespace: group)
subgroup = create(:group, parent: group)
render 'groups/settings/transfer', group: subgroup
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"]'
expect(rendered).not_to have_selector '[data-qa-selector="select_group_dropdown"][disabled]'
expect(rendered).not_to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
end
end
end
......@@ -33480,6 +33480,9 @@ msgstr ""
msgid "This group can't be removed because it is linked to a subscription. To remove this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group can't be transfered because it is linked to a subscription. To transfer this group, %{linkStart}link the subscription%{linkEnd} with a different group."
msgstr ""
msgid "This group cannot be invited to a project inside a group with enforced SSO"
msgstr ""
......
......@@ -38,7 +38,7 @@ module QA
element :project_creation_level_dropdown
end
view 'app/views/groups/settings/_advanced.html.haml' do
view 'app/views/groups/settings/_transfer.html.haml' do
element :select_group_dropdown
element :transfer_group_button
end
......
# frozen_string_literal: true
require 'spec_helper'
RSpec.describe 'groups/settings/_transfer.html.haml' do
describe 'render' do
it 'enables the Select parent group dropdown and does not show an alert for a group' do
group = build(:group)
render 'groups/settings/transfer', group: group
expect(rendered).to have_selector '[data-qa-selector="select_group_dropdown"]'
expect(rendered).not_to have_selector '[data-qa-selector="select_group_dropdown"][disabled]'
expect(rendered).not_to have_selector '[data-testid="group-to-transfer-has-linked-subscription-alert"]'
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