debian-mirror-gitlab/app/services/todos/destroy/entity_leave_service.rb

152 lines
5 KiB
Ruby
Raw Normal View History

2018-11-20 20:47:30 +05:30
# frozen_string_literal: true
2018-11-18 11:00:15 +05:30
module Todos
module Destroy
class EntityLeaveService < ::Todos::Destroy::BaseService
extend ::Gitlab::Utils::Override
attr_reader :user, :entity
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def initialize(user_id, entity_id, entity_type)
unless %w(Group Project).include?(entity_type)
raise ArgumentError.new("#{entity_type} is not an entity user can leave")
end
@user = User.find_by(id: user_id)
@entity = entity_type.constantize.find_by(id: entity_id)
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def execute
return unless entity && user
# if at least reporter, all entities including confidential issues can be accessed
return if user_has_reporter_access?
2020-12-08 15:28:05 +05:30
remove_confidential_resource_todos
2018-11-18 11:00:15 +05:30
if entity.private?
remove_project_todos
remove_group_todos
else
enqueue_private_features_worker
end
end
private
def enqueue_private_features_worker
2019-07-31 22:56:46 +05:30
projects.each do |project|
TodosDestroyer::PrivateFeaturesWorker.perform_async(project.id, user.id)
2018-11-18 11:00:15 +05:30
end
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2020-12-08 15:28:05 +05:30
def remove_confidential_resource_todos
2018-11-18 11:00:15 +05:30
Todo.where(
2019-02-15 15:39:39 +05:30
target_id: confidential_issues.select(:id), target_type: Issue.name, user_id: user.id
2018-11-18 11:00:15 +05:30
).delete_all
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def remove_project_todos
2020-10-04 03:57:07 +05:30
# Issues are viewable by guests (even in private projects), so remove those todos
# from projects without guest access
Todo.where(project_id: non_authorized_guest_projects, user_id: user.id)
.delete_all
# MRs require reporter access, so remove those todos that are not authorized
Todo.where(project_id: non_authorized_reporter_projects, target_type: MergeRequest.name, user_id: user.id)
.delete_all
2018-11-18 11:00:15 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def remove_group_todos
Todo.where(group_id: non_authorized_groups, user_id: user.id).delete_all
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2019-07-31 22:56:46 +05:30
def projects
2018-11-18 11:00:15 +05:30
condition = case entity
when Project
{ id: entity.id }
when Namespace
2020-10-04 03:57:07 +05:30
{ namespace_id: non_authorized_reporter_groups }
2018-11-18 11:00:15 +05:30
end
2019-07-31 22:56:46 +05:30
Project.where(condition)
2018-11-18 11:00:15 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2020-10-04 03:57:07 +05:30
def authorized_reporter_projects
user.authorized_projects(Gitlab::Access::REPORTER).select(:id)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def authorized_guest_projects
user.authorized_projects(Gitlab::Access::GUEST).select(:id)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def non_authorized_reporter_projects
projects.where('id NOT IN (?)', authorized_reporter_projects)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def non_authorized_guest_projects
projects.where('id NOT IN (?)', authorized_guest_projects)
end
# rubocop: enable CodeReuse/ActiveRecord
# rubocop: disable CodeReuse/ActiveRecord
def authorized_reporter_groups
GroupsFinder.new(user, min_access_level: Gitlab::Access::REPORTER).execute.select(:id)
2018-11-18 11:00:15 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def non_authorized_groups
return [] unless entity.is_a?(Namespace)
entity.self_and_descendants.select(:id)
.where('id NOT IN (?)', GroupsFinder.new(user).execute.select(:id))
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2020-10-04 03:57:07 +05:30
def non_authorized_reporter_groups
2018-11-18 11:00:15 +05:30
entity.self_and_descendants.select(:id)
2020-10-04 03:57:07 +05:30
.where('id NOT IN (?)', authorized_reporter_groups)
2018-11-18 11:00:15 +05:30
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def user_has_reporter_access?
return unless entity.is_a?(Namespace)
entity.member?(User.find(user.id), Gitlab::Access::REPORTER)
end
2018-12-05 23:21:45 +05:30
# rubocop: disable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
def confidential_issues
assigned_ids = IssueAssignee.select(:issue_id).where(user_id: user.id)
2019-07-31 22:56:46 +05:30
Issue.where(project_id: projects, confidential: true)
2018-11-18 11:00:15 +05:30
.where('project_id NOT IN(?)', authorized_reporter_projects)
.where('author_id != ?', user.id)
.where('id NOT IN (?)', assigned_ids)
end
2018-12-05 23:21:45 +05:30
# rubocop: enable CodeReuse/ActiveRecord
2018-11-18 11:00:15 +05:30
end
end
end
2020-12-08 15:28:05 +05:30
Todos::Destroy::EntityLeaveService.prepend_if_ee('EE::Todos::Destroy::EntityLeaveService')