123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174 |
- # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
- class DataPrivacyTask < ApplicationModel
- include HasDefaultModelUserRelations
- include DataPrivacyTask::HasActivityStreamLog
- include ChecksClientNotification
- store :preferences
- # optional because related data will get deleted and it would
- # cause validation errors if e.g. the created_by_id of the task
- # would need to get mapped by a deletion
- belongs_to :deletable, polymorphic: true, optional: true
- before_create :prepare_deletion_preview
- validates_with Validations::DataPrivacyTaskValidator
- MAX_PREVIEW_TICKETS = 1000
- def perform
- perform_deletable
- update!(state: 'completed')
- rescue => e
- handle_exception(e)
- end
- def self.cleanup(diff = 12.months)
- where(created_at: ...diff.ago)
- .destroy_all
- true
- end
- private
- # set user inactive before destroy to prevent
- # new online notifications or other events while
- # the deletion process is running
- # https://github.com/zammad/zammad/issues/3942
- def update_inactive(object)
- object.update(active: false)
- end
- def perform_deletable
- return if !deletable_type.constantize.exists?(id: deletable_id)
- prepare_deletion_preview
- save!
- case deletable
- when User
- perform_user_or_organization
- when Ticket
- perform_ticket
- end
- end
- def perform_user_or_organization
- if delete_organization?
- perform_organization(deletable.organization)
- return
- end
- perform_user
- end
- def perform_organization(organization)
- update_inactive(organization)
- organization.members.find_each { |user| update_inactive(user) }
- organization.destroy(associations: true)
- end
- def perform_user
- update_inactive(deletable)
- deletable.destroy
- end
- def perform_ticket
- deletable.destroy
- end
- def handle_exception(e)
- Rails.logger.error e
- preferences[:error] = "ERROR: #{e.inspect}"
- self.state = 'failed'
- save!
- end
- def delete_organization?
- return false if preferences[:delete_organization].blank?
- return false if preferences[:delete_organization] != 'true'
- return false if !deletable.organization
- return false if deletable.organization.members.count != 1
- true
- end
- def prepare_deletion_preview
- prepare_deletion_preview_tickets
- prepare_deletion_preview_user
- prepare_deletion_preview_organization
- prepare_deletion_preview_anonymize
- end
- def prepare_deletion_preview_tickets
- case deletable
- when User
- prepare_deletion_preview_user_tickets
- when Ticket
- prepare_deletion_preview_ticket
- end
- end
- def prepare_deletion_preview_user_tickets
- prepare_deletion_preview_owner_tickets
- prepare_deletion_preview_customer_tickets
- end
- def prepare_deletion_preview_owner_tickets
- preferences[:owner_tickets] = owner_tickets.limit(MAX_PREVIEW_TICKETS).map(&:number)
- preferences[:owner_tickets_count] = owner_tickets.count
- end
- def prepare_deletion_preview_customer_tickets
- preferences[:customer_tickets] = customer_tickets.limit(MAX_PREVIEW_TICKETS).map(&:number)
- preferences[:customer_tickets_count] = customer_tickets.count
- end
- def prepare_deletion_preview_ticket
- preferences[:ticket] = {
- title: deletable.title,
- }
- preferences[:customer_tickets] = [deletable.number]
- preferences[:customer_tickets_count] = 1
- end
- def prepare_deletion_preview_user
- return if !deletable.is_a?(User)
- preferences[:user] = {
- firstname: deletable.firstname,
- lastname: deletable.lastname,
- email: deletable.email,
- }
- end
- def prepare_deletion_preview_organization
- return if !deletable.is_a?(User)
- return if !deletable.organization
- preferences[:user][:organization] = deletable.organization.name
- end
- def prepare_deletion_preview_anonymize
- case deletable
- when User
- preferences[:user] = Pseudonymisation.of_hash(preferences[:user])
- when Ticket
- preferences[:ticket] = Pseudonymisation.of_hash(preferences[:ticket])
- end
- end
- def owner_tickets
- @owner_tickets ||= deletable.owner_tickets.reorder(id: 'DESC')
- end
- def customer_tickets
- @customer_tickets ||= deletable.customer_tickets.reorder(id: 'DESC')
- end
- end
|