debian-mirror-gitlab/app/services/authorized_project_update/project_group_link_create_service.rb

81 lines
2.6 KiB
Ruby
Raw Normal View History

2020-07-28 23:09:34 +05:30
# frozen_string_literal: true
module AuthorizedProjectUpdate
class ProjectGroupLinkCreateService < BaseService
include Gitlab::Utils::StrongMemoize
BATCH_SIZE = 1000
2020-08-18 19:51:02 +05:30
def initialize(project, group, group_access = nil)
2020-07-28 23:09:34 +05:30
@project = project
@group = group
2020-08-18 19:51:02 +05:30
@group_access = group_access
2020-07-28 23:09:34 +05:30
end
def execute
group.members_from_self_and_ancestors_with_effective_access_level
.each_batch(of: BATCH_SIZE, column: :user_id) do |members|
existing_authorizations = existing_project_authorizations(members)
authorizations_to_create = []
user_ids_to_delete = []
members.each do |member|
2020-08-18 19:51:02 +05:30
new_access_level = access_level(member.access_level)
2020-07-28 23:09:34 +05:30
existing_access_level = existing_authorizations[member.user_id]
if existing_access_level
# User might already have access to the project unrelated to the
# current project share
2020-08-18 19:51:02 +05:30
next if existing_access_level >= new_access_level
2020-07-28 23:09:34 +05:30
user_ids_to_delete << member.user_id
end
authorizations_to_create << { user_id: member.user_id,
project_id: project.id,
2020-08-18 19:51:02 +05:30
access_level: new_access_level }
2020-07-28 23:09:34 +05:30
end
update_authorizations(user_ids_to_delete, authorizations_to_create)
end
ServiceResponse.success
end
private
2020-08-18 19:51:02 +05:30
attr_reader :project, :group, :group_access
def access_level(membership_access_level)
return membership_access_level unless group_access
# access level must not be higher than the max access level set when
# creating the project share
[membership_access_level, group_access].min
end
2020-07-28 23:09:34 +05:30
def existing_project_authorizations(members)
user_ids = members.map(&:user_id)
ProjectAuthorization.where(project_id: project.id, user_id: user_ids) # rubocop: disable CodeReuse/ActiveRecord
.select(:user_id, :access_level)
.each_with_object({}) do |authorization, hash|
hash[authorization.user_id] = authorization.access_level
end
end
def update_authorizations(user_ids_to_delete, authorizations_to_create)
ProjectAuthorization.transaction do
if user_ids_to_delete.any?
ProjectAuthorization.where(project_id: project.id, user_id: user_ids_to_delete) # rubocop: disable CodeReuse/ActiveRecord
.delete_all
end
if authorizations_to_create.any?
ProjectAuthorization.insert_all(authorizations_to_create)
end
end
end
end
end