account_action.rb 3.8 KB

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