You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

170 lines
3.7 KiB

  1. # frozen_string_literal: true
  2. class Admin::AccountAction
  3. include ActiveModel::Model
  4. include AccountableConcern
  5. include Authorization
  6. TYPES = %w(
  7. none
  8. disable
  9. sensitive
  10. silence
  11. suspend
  12. ).freeze
  13. attr_accessor :target_account,
  14. :current_account,
  15. :type,
  16. :text,
  17. :report_id,
  18. :warning_preset_id
  19. attr_reader :warning, :send_email_notification, :include_statuses
  20. def send_email_notification=(value)
  21. @send_email_notification = ActiveModel::Type::Boolean.new.cast(value)
  22. end
  23. def include_statuses=(value)
  24. @include_statuses = ActiveModel::Type::Boolean.new.cast(value)
  25. end
  26. def save!
  27. ApplicationRecord.transaction do
  28. process_action!
  29. process_warning!
  30. end
  31. process_email!
  32. process_reports!
  33. process_queue!
  34. end
  35. def report
  36. @report ||= Report.find(report_id) if report_id.present?
  37. end
  38. def with_report?
  39. !report.nil?
  40. end
  41. class << self
  42. def types_for_account(account)
  43. if account.local?
  44. TYPES
  45. else
  46. TYPES - %w(none disable)
  47. end
  48. end
  49. end
  50. private
  51. def process_action!
  52. case type
  53. when 'disable'
  54. handle_disable!
  55. when 'sensitive'
  56. handle_sensitive!
  57. when 'silence'
  58. handle_silence!
  59. when 'suspend'
  60. handle_suspend!
  61. end
  62. end
  63. def process_warning!
  64. return unless warnable?
  65. authorize(target_account, :warn?)
  66. @warning = AccountWarning.create!(target_account: target_account,
  67. account: current_account,
  68. action: type,
  69. text: text_for_warning)
  70. # A log entry is only interesting if the warning contains
  71. # custom text from someone. Otherwise it's just noise.
  72. log_action(:create, warning) if warning.text.present?
  73. end
  74. def process_reports!
  75. # If we're doing "mark as resolved" on a single report,
  76. # then we want to keep other reports open in case they
  77. # contain new actionable information.
  78. #
  79. # Otherwise, we will mark all unresolved reports about
  80. # the account as resolved.
  81. reports.each { |report| authorize(report, :update?) }
  82. reports.each do |report|
  83. log_action(:resolve, report)
  84. report.resolve!(current_account)
  85. end
  86. end
  87. def handle_disable!
  88. authorize(target_account.user, :disable?)
  89. log_action(:disable, target_account.user)
  90. target_account.user&.disable!
  91. end
  92. def handle_sensitive!
  93. authorize(target_account, :sensitive?)
  94. log_action(:sensitive, target_account)
  95. target_account.sensitize!
  96. end
  97. def handle_silence!
  98. authorize(target_account, :silence?)
  99. log_action(:silence, target_account)
  100. target_account.silence!
  101. end
  102. def handle_suspend!
  103. authorize(target_account, :suspend?)
  104. log_action(:suspend, target_account)
  105. target_account.suspend!
  106. end
  107. def text_for_warning
  108. [warning_preset&.text, text].compact.join("\n\n")
  109. end
  110. def queue_suspension_worker!
  111. Admin::SuspensionWorker.perform_async(target_account.id)
  112. end
  113. def process_queue!
  114. queue_suspension_worker! if type == 'suspend'
  115. end
  116. def process_email!
  117. UserMailer.warning(target_account.user, warning, status_ids).deliver_later! if warnable?
  118. end
  119. def warnable?
  120. send_email_notification && target_account.local?
  121. end
  122. def status_ids
  123. report.status_ids if report && include_statuses
  124. end
  125. def reports
  126. @reports ||= begin
  127. if type == 'none' && with_report?
  128. [report]
  129. else
  130. Report.where(target_account: target_account).unresolved
  131. end
  132. end
  133. end
  134. def warning_preset
  135. @warning_preset ||= AccountWarningPreset.find(warning_preset_id) if warning_preset_id.present?
  136. end
  137. end