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.

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