2018-02-28 16:54:55 +11:00
# frozen_string_literal: true
class ReportService < BaseService
2019-06-05 07:11:18 +10:00
include Payloadable
2018-02-28 16:54:55 +11:00
def call ( source_account , target_account , options = { } )
@source_account = source_account
@target_account = target_account
2022-03-03 04:57:08 +11:00
@status_ids = options . delete ( :status_ids ) . presence || [ ]
@comment = options . delete ( :comment ) . presence || ''
2022-11-09 03:28:02 +11:00
@category = options [ :rule_ids ] . present? ? 'violation' : ( options . delete ( :category ) . presence || 'other' )
2022-03-03 04:57:08 +11:00
@rule_ids = options . delete ( :rule_ids ) . presence
2018-02-28 16:54:55 +11:00
@options = options
2021-04-17 06:01:05 +10:00
raise ActiveRecord :: RecordNotFound if @target_account . suspended?
2018-02-28 16:54:55 +11:00
create_report!
notify_staff!
2022-02-10 10:10:16 +11:00
forward_to_origin! if forward?
2018-02-28 16:54:55 +11:00
@report
end
private
def create_report!
@report = @source_account . reports . create! (
target_account : @target_account ,
2022-03-03 04:57:08 +11:00
status_ids : reported_status_ids ,
2019-03-18 01:34:56 +11:00
comment : @comment ,
2020-12-15 14:30:15 +11:00
uri : @options [ :uri ] ,
2022-02-10 10:10:16 +11:00
forwarded : forward? ,
category : @category ,
rule_ids : @rule_ids
2018-02-28 16:54:55 +11:00
)
end
def notify_staff!
2018-09-02 08:11:58 +10:00
return if @report . unresolved_siblings?
2022-07-05 10:41:40 +10:00
User . those_who_can ( :manage_reports ) . includes ( :account ) . each do | u |
2022-06-27 17:30:15 +10:00
LocalNotificationWorker . perform_async ( u . account_id , @report . id , 'Report' , 'admin.report' )
AdminMailer . new_report ( u . account , @report ) . deliver_later if u . allows_report_emails?
2018-02-28 16:54:55 +11:00
end
end
def forward_to_origin!
ActivityPub :: DeliveryWorker . perform_async (
payload ,
some_local_account . id ,
@target_account . inbox_url
)
end
2022-02-10 10:10:16 +11:00
def forward?
! @target_account . local? && ActiveModel :: Type :: Boolean . new . cast ( @options [ :forward ] )
end
2022-03-03 04:57:08 +11:00
def reported_status_ids
2022-07-04 19:08:30 +10:00
return AccountStatusesFilter . new ( @target_account , @source_account ) . results . with_discarded . find ( Array ( @status_ids ) ) . pluck ( :id ) if @source_account . local?
# If the account making reports is remote, it is likely anonymized so we have to relax the requirements for attaching statuses.
domain = @source_account . domain . to_s . downcase
has_followers = @target_account . followers . where ( Account . arel_table [ :domain ] . lower . eq ( domain ) ) . exists?
visibility = has_followers ? % i ( public unlisted private ) : % i ( public unlisted )
scope = @target_account . statuses . with_discarded
scope . merge! ( scope . where ( visibility : visibility ) . or ( scope . where ( 'EXISTS (SELECT 1 FROM mentions m JOIN accounts a ON m.account_id = a.id WHERE lower(a.domain) = ?)' , domain ) ) )
# Allow missing posts to not drop reports that include e.g. a deleted post
scope . where ( id : Array ( @status_ids ) ) . pluck ( :id )
2022-03-03 04:57:08 +11:00
end
2018-02-28 16:54:55 +11:00
def payload
2019-06-05 07:11:18 +10:00
Oj . dump ( serialize_payload ( @report , ActivityPub :: FlagSerializer , account : some_local_account ) )
2018-02-28 16:54:55 +11:00
end
def some_local_account
2019-01-05 17:17:12 +11:00
@some_local_account || = Account . representative
2018-02-28 16:54:55 +11:00
end
end