2018-02-28 07:54:55 +02:00
# frozen_string_literal: true
class ReportService < BaseService
2019-06-05 00:11:18 +03:00
include Payloadable
2018-02-28 07:54:55 +02:00
def call ( source_account , target_account , options = { } )
@source_account = source_account
@target_account = target_account
2022-03-02 19:57:08 +02:00
@status_ids = options . delete ( :status_ids ) . presence || [ ]
@comment = options . delete ( :comment ) . presence || ''
2022-11-08 18:28:02 +02:00
@category = options [ :rule_ids ] . present? ? 'violation' : ( options . delete ( :category ) . presence || 'other' )
2022-03-02 19:57:08 +02:00
@rule_ids = options . delete ( :rule_ids ) . presence
2018-02-28 07:54:55 +02:00
@options = options
2021-04-16 23:01:05 +03:00
raise ActiveRecord :: RecordNotFound if @target_account . suspended?
2018-02-28 07:54:55 +02:00
create_report!
notify_staff!
2022-02-10 01:10:16 +02:00
forward_to_origin! if forward?
2018-02-28 07:54:55 +02:00
@report
end
private
def create_report!
@report = @source_account . reports . create! (
target_account : @target_account ,
2022-03-02 19:57:08 +02:00
status_ids : reported_status_ids ,
2019-03-17 16:34:56 +02:00
comment : @comment ,
2020-12-15 05:30:15 +02:00
uri : @options [ :uri ] ,
2022-02-10 01:10:16 +02:00
forwarded : forward? ,
category : @category ,
rule_ids : @rule_ids
2018-02-28 07:54:55 +02:00
)
end
def notify_staff!
2018-09-02 01:11:58 +03:00
return if @report . unresolved_siblings?
2022-07-05 03:41:40 +03:00
User . those_who_can ( :manage_reports ) . includes ( :account ) . each do | u |
2022-06-27 10:30:15 +03: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 07:54:55 +02:00
end
end
def forward_to_origin!
ActivityPub :: DeliveryWorker . perform_async (
payload ,
some_local_account . id ,
@target_account . inbox_url
)
end
2022-02-10 01:10:16 +02:00
def forward?
! @target_account . local? && ActiveModel :: Type :: Boolean . new . cast ( @options [ :forward ] )
end
2022-03-02 19:57:08 +02:00
def reported_status_ids
2022-07-04 12:08:30 +03: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-02 19:57:08 +02:00
end
2018-02-28 07:54:55 +02:00
def payload
2019-06-05 00:11:18 +03:00
Oj . dump ( serialize_payload ( @report , ActivityPub :: FlagSerializer , account : some_local_account ) )
2018-02-28 07:54:55 +02:00
end
def some_local_account
2019-01-05 08:17:12 +02:00
@some_local_account || = Account . representative
2018-02-28 07:54:55 +02:00
end
end