diff options
author | Jarka Kadlecová <jarka@gitlab.com> | 2018-07-16 21:30:17 +0300 |
---|---|---|
committer | Jarka Kadlecová <jarka@gitlab.com> | 2018-07-30 14:29:18 +0300 |
commit | 501fb04ec65cadcd7dddc6376546db8d8f7f123c (patch) | |
tree | 9f984fc2b284239f03f10fa0daa1127c20b3fc59 /app/services/todos | |
parent | 2ca8219a20f16636b7a0ffa899a1a04ab8e84782 (diff) |
Delete todos when users loses target read permissions
Diffstat (limited to 'app/services/todos')
-rw-r--r-- | app/services/todos/destroy/base_service.rb | 33 | ||||
-rw-r--r-- | app/services/todos/destroy/confidential_issue_service.rb | 30 | ||||
-rw-r--r-- | app/services/todos/destroy/entity_leave_service.rb | 49 | ||||
-rw-r--r-- | app/services/todos/destroy/project_private_service.rb | 30 |
4 files changed, 142 insertions, 0 deletions
diff --git a/app/services/todos/destroy/base_service.rb b/app/services/todos/destroy/base_service.rb new file mode 100644 index 00000000000..71cd7921f32 --- /dev/null +++ b/app/services/todos/destroy/base_service.rb @@ -0,0 +1,33 @@ +module Todos + module Destroy + class BaseService + def execute + return unless todos_to_remove? + + without_authorized(todos).delete_all + end + + private + + def without_authorized(items) + items.where('user_id NOT IN (?)', authorized_users) + end + + def authorized_users + ProjectAuthorization.select(:user_id).where(project_id: project_ids) + end + + def todos + # overridden in subclasses + end + + def project_ids + # overridden in subclasses + end + + def todos_to_remove? + # overridden in subclasses + end + end + end +end diff --git a/app/services/todos/destroy/confidential_issue_service.rb b/app/services/todos/destroy/confidential_issue_service.rb new file mode 100644 index 00000000000..06cf308a3cd --- /dev/null +++ b/app/services/todos/destroy/confidential_issue_service.rb @@ -0,0 +1,30 @@ +module Todos + module Destroy + class ConfidentialIssueService < ::Todos::Destroy::BaseService + extend ::Gitlab::Utils::Override + + attr_reader :issue + + def initialize(issue_id) + @issue = Issue.find_by(id: issue_id) + end + + private + + override :todos + def todos + Todo.where(target: issue) + end + + override :todos_to_remove? + def todos_to_remove? + issue&.confidential? + end + + override :project_ids + def project_ids + issue.project_id + end + end + end +end diff --git a/app/services/todos/destroy/entity_leave_service.rb b/app/services/todos/destroy/entity_leave_service.rb new file mode 100644 index 00000000000..328a8b39e7b --- /dev/null +++ b/app/services/todos/destroy/entity_leave_service.rb @@ -0,0 +1,49 @@ +module Todos + module Destroy + class EntityLeaveService < ::Todos::Destroy::BaseService + extend ::Gitlab::Utils::Override + + attr_reader :user_id, :entity + + 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_id = user_id + @entity = entity_type.constantize.find_by(id: entity_id) + end + + private + + override :todos + def todos + if entity.private? + Todo.where(project_id: project_ids, user_id: user_id) + else + Todo.where(target_id: confidential_issues.select(:id), target_type: Issue) + end + end + + override :project_ids + def project_ids + if entity.is_a?(Project) + entity.id + else + Project.select(:id).where(namespace_id: entity.self_and_descendants.select(:id)) + end + end + + override :todos_to_remove? + def todos_to_remove? + return unless entity + + entity.private? || confidential_issues.count > 0 + end + + def confidential_issues + Issue.where(project_id: project_ids, confidential: true) + end + end + end +end diff --git a/app/services/todos/destroy/project_private_service.rb b/app/services/todos/destroy/project_private_service.rb new file mode 100644 index 00000000000..171933e7cbc --- /dev/null +++ b/app/services/todos/destroy/project_private_service.rb @@ -0,0 +1,30 @@ +module Todos + module Destroy + class ProjectPrivateService < ::Todos::Destroy::BaseService + extend ::Gitlab::Utils::Override + + attr_reader :project + + def initialize(project_id) + @project = Project.find_by(id: project_id) + end + + private + + override :todos + def todos + Todo.where(project_id: project_ids) + end + + override :project_ids + def project_ids + project.id + end + + override :todos_to_remove? + def todos_to_remove? + project&.private? + end + end + end +end |