account_action.rb 4.4 KB

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