data_privacy_task.rb 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172
  1. # Copyright (C) 2012-2024 Zammad Foundation, https://zammad-foundation.org/
  2. class DataPrivacyTask < ApplicationModel
  3. include HasDefaultModelUserRelations
  4. include DataPrivacyTask::HasActivityStreamLog
  5. include ChecksClientNotification
  6. store :preferences
  7. # optional because related data will get deleted and it would
  8. # cause validation errors if e.g. the created_by_id of the task
  9. # would need to get mapped by a deletion
  10. belongs_to :deletable, polymorphic: true, optional: true
  11. before_create :prepare_deletion_preview
  12. validates_with Validations::DataPrivacyTaskValidator
  13. MAX_PREVIEW_TICKETS = 1000
  14. def perform
  15. perform_deletable
  16. update!(state: 'completed')
  17. rescue => e
  18. handle_exception(e)
  19. end
  20. def self.cleanup(diff = 12.months)
  21. where('created_at < ?', diff.ago).destroy_all
  22. true
  23. end
  24. private
  25. # set user inactive before destroy to prevent
  26. # new online notifications or other events while
  27. # the deletion process is running
  28. # https://github.com/zammad/zammad/issues/3942
  29. def update_inactive(object)
  30. object.update(active: false)
  31. end
  32. def perform_deletable
  33. return if !deletable_type.constantize.exists?(id: deletable_id)
  34. prepare_deletion_preview
  35. save!
  36. case deletable
  37. when User
  38. perform_user_or_organization
  39. when Ticket
  40. perform_ticket
  41. end
  42. end
  43. def perform_user_or_organization
  44. if delete_organization?
  45. perform_organization(deletable.organization)
  46. return
  47. end
  48. perform_user
  49. end
  50. def perform_organization(organization)
  51. update_inactive(organization)
  52. organization.members.find_each { |user| update_inactive(user) }
  53. organization.destroy(associations: true)
  54. end
  55. def perform_user
  56. update_inactive(deletable)
  57. deletable.destroy
  58. end
  59. def perform_ticket
  60. deletable.destroy
  61. end
  62. def handle_exception(e)
  63. Rails.logger.error e
  64. preferences[:error] = "ERROR: #{e.inspect}"
  65. self.state = 'failed'
  66. save!
  67. end
  68. def delete_organization?
  69. return false if preferences[:delete_organization].blank?
  70. return false if preferences[:delete_organization] != 'true'
  71. return false if !deletable.organization
  72. return false if deletable.organization.members.count != 1
  73. true
  74. end
  75. def prepare_deletion_preview
  76. prepare_deletion_preview_tickets
  77. prepare_deletion_preview_user
  78. prepare_deletion_preview_organization
  79. prepare_deletion_preview_anonymize
  80. end
  81. def prepare_deletion_preview_tickets
  82. case deletable
  83. when User
  84. prepare_deletion_preview_user_tickets
  85. when Ticket
  86. prepare_deletion_preview_ticket
  87. end
  88. end
  89. def prepare_deletion_preview_user_tickets
  90. prepare_deletion_preview_owner_tickets
  91. prepare_deletion_preview_customer_tickets
  92. end
  93. def prepare_deletion_preview_owner_tickets
  94. preferences[:owner_tickets] = owner_tickets.limit(MAX_PREVIEW_TICKETS).map(&:number)
  95. preferences[:owner_tickets_count] = owner_tickets.count
  96. end
  97. def prepare_deletion_preview_customer_tickets
  98. preferences[:customer_tickets] = customer_tickets.limit(MAX_PREVIEW_TICKETS).map(&:number)
  99. preferences[:customer_tickets_count] = customer_tickets.count
  100. end
  101. def prepare_deletion_preview_ticket
  102. preferences[:ticket] = {
  103. title: deletable.title,
  104. }
  105. preferences[:customer_tickets] = [deletable.number]
  106. preferences[:customer_tickets_count] = 1
  107. end
  108. def prepare_deletion_preview_user
  109. return if !deletable.is_a?(User)
  110. preferences[:user] = {
  111. firstname: deletable.firstname,
  112. lastname: deletable.lastname,
  113. email: deletable.email,
  114. }
  115. end
  116. def prepare_deletion_preview_organization
  117. return if !deletable.is_a?(User)
  118. return if !deletable.organization
  119. preferences[:user][:organization] = deletable.organization.name
  120. end
  121. def prepare_deletion_preview_anonymize
  122. case deletable
  123. when User
  124. preferences[:user] = Pseudonymisation.of_hash(preferences[:user])
  125. when Ticket
  126. preferences[:ticket] = Pseudonymisation.of_hash(preferences[:ticket])
  127. end
  128. end
  129. def owner_tickets
  130. @owner_tickets ||= deletable.owner_tickets.reorder(id: 'DESC')
  131. end
  132. def customer_tickets
  133. @customer_tickets ||= deletable.customer_tickets.reorder(id: 'DESC')
  134. end
  135. end