account_action.rb 3.9 KB

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