Commit fa43f9aa authored by Manoj M J's avatar Manoj M J

Use specialized worker when share_with_group_lock of a group changes

This change makes use of specialized worker
when `share_with_group_lock` attribute
of a group is updated
parent cf6e08a6
......@@ -465,11 +465,35 @@ class Namespace < ApplicationRecord
end
def refresh_access_of_projects_invited_groups
if Feature.enabled?(:specialized_worker_for_group_lock_update_auth_recalculation)
Project
.where(namespace_id: id)
.joins(:project_group_links)
.distinct
.find_each do |project|
AuthorizedProjectUpdate::ProjectRecalculateWorker.perform_async(project.id)
end
# Until we compare the inconsistency rates of the new specialized worker and
# the old approach, we still run AuthorizedProjectsWorker
# but with some delay and lower urgency as a safety net.
Group
.joins(project_group_links: :project)
.where(projects: { namespace_id: id })
.distinct
.find_each do |group|
group.refresh_members_authorized_projects(
blocking: false,
priority: UserProjectAccessChangedService::LOW_PRIORITY
)
end
else
Group
.joins(project_group_links: :project)
.where(projects: { namespace_id: id })
.find_each(&:refresh_members_authorized_projects)
end
end
def nesting_level_allowed
if ancestors.count > Group::NUMBER_OF_ANCESTORS_ALLOWED
......
---
name: specialized_worker_for_group_lock_update_auth_recalculation
introduced_by_url: https://gitlab.com/gitlab-org/gitlab/-/merge_requests/66525
rollout_issue_url: https://gitlab.com/gitlab-org/gitlab/-/issues/336592
milestone: '14.2'
type: development
group: group::access
default_enabled: false
......@@ -1152,6 +1152,68 @@ RSpec.describe Namespace do
end
end
context 'refreshing project access on updating share_with_group_lock' do
let(:group) { create(:group, share_with_group_lock: false) }
let(:project) { create(:project, :private, group: group) }
let_it_be(:shared_with_group_one) { create(:group) }
let_it_be(:shared_with_group_two) { create(:group) }
let_it_be(:group_one_user) { create(:user) }
let_it_be(:group_two_user) { create(:user) }
subject(:execute_update) { group.update!(share_with_group_lock: true) }
before do
shared_with_group_one.add_developer(group_one_user)
shared_with_group_two.add_developer(group_two_user)
create(:project_group_link, group: shared_with_group_one, project: project)
create(:project_group_link, group: shared_with_group_two, project: project)
end
it 'calls AuthorizedProjectUpdate::ProjectRecalculateWorker to update project authorizations' do
expect(AuthorizedProjectUpdate::ProjectRecalculateWorker)
.to receive(:perform_async).with(project.id).once
execute_update
end
it 'updates authorizations leading to users from shared groups losing access', :sidekiq_inline do
expect { execute_update }
.to change { group_one_user.authorized_projects.include?(project) }.from(true).to(false)
.and change { group_two_user.authorized_projects.include?(project) }.from(true).to(false)
end
it 'calls AuthorizedProjectUpdate::UserRefreshFromReplicaWorker with a delay to update project authorizations' do
expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
receive(:bulk_perform_in)
.with(1.hour,
[[group_one_user.id]],
batch_delay: 30.seconds, batch_size: 100)
)
expect(AuthorizedProjectUpdate::UserRefreshFromReplicaWorker).to(
receive(:bulk_perform_in)
.with(1.hour,
[[group_two_user.id]],
batch_delay: 30.seconds, batch_size: 100)
)
execute_update
end
context 'when the feature flag `specialized_worker_for_group_lock_update_auth_recalculation` is disabled' do
before do
stub_feature_flags(specialized_worker_for_group_lock_update_auth_recalculation: false)
end
it 'refreshes the permissions of the members of the old and new namespace' do
expect { execute_update }
.to change { group_one_user.authorized_projects.include?(project) }.from(true).to(false)
.and change { group_two_user.authorized_projects.include?(project) }.from(true).to(false)
end
end
end
describe '#share_with_group_lock with subgroups' do
context 'when creating a subgroup' do
let(:subgroup) { create(:group, parent: root_group )}
......
......@@ -307,7 +307,7 @@ RSpec.describe ProjectTeam do
it { expect(project.team.max_member_access(nonmember.id)).to eq(Gitlab::Access::NO_ACCESS) }
it { expect(project.team.max_member_access(requester.id)).to eq(Gitlab::Access::NO_ACCESS) }
context 'but share_with_group_lock is true' do
context 'but share_with_group_lock is true', :sidekiq_inline do
before do
project.namespace.update!(share_with_group_lock: true)
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