Commit 465a4f6e authored by Małgorzata Ksionek's avatar Małgorzata Ksionek Committed by Małgorzata Ksionek

Add refreshing projects to transfering groups

Add changelog entry

Add cr remarks

Add cr remarks

Add cr remarks

Add specs for multiple users in group
parent f9ef6bc7
...@@ -37,6 +37,7 @@ module Groups ...@@ -37,6 +37,7 @@ module Groups
# Overridden in EE # Overridden in EE
def post_update_hooks(updated_project_ids) def post_update_hooks(updated_project_ids)
refresh_project_authorizations
end end
def ensure_allowed_transfer def ensure_allowed_transfer
...@@ -136,6 +137,16 @@ module Groups ...@@ -136,6 +137,16 @@ module Groups
@group.add_owner(current_user) @group.add_owner(current_user)
end end
def refresh_project_authorizations
ProjectAuthorization.where(project_id: @group.all_projects.select(:id)).delete_all # rubocop: disable CodeReuse/ActiveRecord
# refresh authorized projects for current_user immediately
current_user.refresh_authorized_projects
# schedule refreshing projects for all the members of the group
@group.refresh_members_authorized_projects
end
def raise_transfer_error(message) def raise_transfer_error(message)
raise TransferError, localized_error_messages[message] raise TransferError, localized_error_messages[message]
end end
......
...@@ -16,6 +16,9 @@ class AuthorizedProjectsWorker ...@@ -16,6 +16,9 @@ class AuthorizedProjectsWorker
if Rails.env.test? if Rails.env.test?
def self.bulk_perform_and_wait(args_list, timeout: 10) def self.bulk_perform_and_wait(args_list, timeout: 10)
end end
def self.bulk_perform_inline(args_list)
end
end end
# rubocop: disable CodeReuse/ActiveRecord # rubocop: disable CodeReuse/ActiveRecord
......
---
title: Refresh project authorizations when transferring groups
merge_request:
author:
type: security
...@@ -18,6 +18,7 @@ module EE ...@@ -18,6 +18,7 @@ module EE
::Project.id_in(updated_project_ids).find_each do |project| ::Project.id_in(updated_project_ids).find_each do |project|
project.maintain_elasticsearch_update if project.maintaining_elasticsearch? project.maintain_elasticsearch_update if project.maintaining_elasticsearch?
end end
super
end end
def lost_groups def lost_groups
......
...@@ -414,44 +414,117 @@ RSpec.describe Groups::TransferService do ...@@ -414,44 +414,117 @@ RSpec.describe Groups::TransferService do
end end
context 'when transferring a group with nested groups and projects' do context 'when transferring a group with nested groups and projects' do
let!(:group) { create(:group, :public) } let(:subgroup1) { create(:group, :private, parent: group) }
let!(:project1) { create(:project, :repository, :private, namespace: group) } let!(:project1) { create(:project, :repository, :private, namespace: group) }
let!(:subgroup1) { create(:group, :private, parent: group) }
let!(:nested_subgroup) { create(:group, :private, parent: subgroup1) } let!(:nested_subgroup) { create(:group, :private, parent: subgroup1) }
let!(:nested_project) { create(:project, :repository, :private, namespace: subgroup1) } let!(:nested_project) { create(:project, :repository, :private, namespace: subgroup1) }
before do before do
TestEnv.clean_test_path TestEnv.clean_test_path
create(:group_member, :owner, group: new_parent_group, user: user) create(:group_member, :owner, group: new_parent_group, user: user)
transfer_service.execute(new_parent_group)
end end
it 'updates subgroups path' do context 'updated paths' do
new_base_path = "#{new_parent_group.path}/#{group.path}" let(:group) { create(:group, :public) }
group.children.each do |children|
expect(children.full_path).to eq("#{new_base_path}/#{children.path}") before do
transfer_service.execute(new_parent_group)
end end
new_base_path = "#{new_parent_group.path}/#{group.path}/#{subgroup1.path}" it 'updates subgroups path' do
subgroup1.children.each do |children| new_base_path = "#{new_parent_group.path}/#{group.path}"
expect(children.full_path).to eq("#{new_base_path}/#{children.path}") group.children.each do |children|
expect(children.full_path).to eq("#{new_base_path}/#{children.path}")
end
new_base_path = "#{new_parent_group.path}/#{group.path}/#{subgroup1.path}"
subgroup1.children.each do |children|
expect(children.full_path).to eq("#{new_base_path}/#{children.path}")
end
end end
end
it 'updates projects path' do it 'updates projects path' do
new_parent_path = "#{new_parent_group.path}/#{group.path}" new_parent_path = "#{new_parent_group.path}/#{group.path}"
subgroup1.projects.each do |project| subgroup1.projects.each do |project|
project_full_path = "#{new_parent_path}/#{project.namespace.path}/#{project.name}" project_full_path = "#{new_parent_path}/#{project.namespace.path}/#{project.name}"
expect(project.full_path).to eq(project_full_path) expect(project.full_path).to eq(project_full_path)
end
end
it 'creates redirect for the subgroups and projects' do
expect(group.redirect_routes.count).to eq(1)
expect(project1.redirect_routes.count).to eq(1)
expect(subgroup1.redirect_routes.count).to eq(1)
expect(nested_subgroup.redirect_routes.count).to eq(1)
expect(nested_project.redirect_routes.count).to eq(1)
end end
end end
it 'creates redirect for the subgroups and projects' do context 'resets project authorizations' do
expect(group.redirect_routes.count).to eq(1) let(:old_parent_group) { create(:group) }
expect(project1.redirect_routes.count).to eq(1) let(:group) { create(:group, :private, parent: old_parent_group) }
expect(subgroup1.redirect_routes.count).to eq(1) let(:new_group_member) { create(:user) }
expect(nested_subgroup.redirect_routes.count).to eq(1) let(:old_group_member) { create(:user) }
expect(nested_project.redirect_routes.count).to eq(1)
before do
new_parent_group.add_maintainer(new_group_member)
old_parent_group.add_maintainer(old_group_member)
group.refresh_members_authorized_projects
end
it 'removes old project authorizations' do
expect { transfer_service.execute(new_parent_group) }.to change {
ProjectAuthorization.where(project_id: project1.id, user_id: old_group_member.id).size
}.from(1).to(0)
end
it 'adds new project authorizations' do
expect { transfer_service.execute(new_parent_group) }.to change {
ProjectAuthorization.where(project_id: project1.id, user_id: new_group_member.id).size
}.from(0).to(1)
end
it 'performs authorizations job immediately' do
expect(AuthorizedProjectsWorker).to receive(:bulk_perform_inline)
transfer_service.execute(new_parent_group)
end
context 'for nested projects' do
it 'removes old project authorizations' do
expect { transfer_service.execute(new_parent_group) }.to change {
ProjectAuthorization.where(project_id: nested_project.id, user_id: old_group_member.id).size
}.from(1).to(0)
end
it 'adds new project authorizations' do
expect { transfer_service.execute(new_parent_group) }.to change {
ProjectAuthorization.where(project_id: nested_project.id, user_id: new_group_member.id).size
}.from(0).to(1)
end
end
context 'for groups with many members' do
before do
11.times do
new_parent_group.add_maintainer(create(:user))
end
end
it 'adds new project authorizations for the user which makes a transfer' do
transfer_service.execute(new_parent_group)
expect(ProjectAuthorization.where(project_id: project1.id, user_id: user.id).size).to eq(1)
expect(ProjectAuthorization.where(project_id: nested_project.id, user_id: user.id).size).to eq(1)
end
it 'schedules authorizations job' do
expect(AuthorizedProjectsWorker).to receive(:bulk_perform_async)
.with(array_including(new_parent_group.members_with_parents.pluck(:user_id).map {|id| [id, anything] }))
transfer_service.execute(new_parent_group)
end
end
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