@@ 4,13 4,14 @@ class ActivityPub::Activity::Flag < ActivityPub::Activity
def perform
return if skip_reports?
- target_accounts = object_uris.filter_map { |uri| account_from_uri(uri) }.select(&:local?)
- target_statuses_by_account = object_uris.filter_map { |uri| status_from_uri(uri) }.select(&:local?).group_by(&:account_id)
+ target_accounts = object_uris.filter_map { |uri| account_from_uri(uri) }
+ target_statuses_by_account = object_uris.filter_map { |uri| status_from_uri(uri) }.group_by(&:account_id)
target_accounts.each do |target_account|
- target_statuses = target_statuses_by_account[target_account.id]
+ target_statuses = target_statuses_by_account[target_account.id]
+ replied_to_accounts = Account.local.where(id: target_statuses.filter_map(&:in_reply_to_account_id))
- next if target_account.suspended?
+ next if target_account.suspended? || (!target_account.local? && replied_to_accounts.none?)
ReportService.new.call(
@account,
@@ 45,11 45,15 @@ class ReportService < BaseService
end
def forward_to_origin!
- ActivityPub::DeliveryWorker.perform_async(
- payload,
- some_local_account.id,
- @target_account.inbox_url
- )
+ # Send report to the server where the account originates from
+ ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, @target_account.inbox_url)
+
+ # Send report to servers to which the account was replying to, so they also have a chance to act
+ inbox_urls = Account.remote.where(id: Status.where(id: reported_status_ids).where.not(in_reply_to_account_id: nil).select(:in_reply_to_account_id)).inboxes - [@target_account.inbox_url]
+
+ inbox_urls.each do |inbox_url|
+ ActivityPub::DeliveryWorker.perform_async(payload, some_local_account.id, inbox_url)
+ end
end
def forward?
@@ 17,24 17,45 @@ RSpec.describe ReportService, type: :service do
context 'with a remote account' do
let(:remote_account) { Fabricate(:account, domain: 'example.com', protocol: :activitypub, inbox_url: 'http://example.com/inbox') }
+ let(:forward) { false }
before do
stub_request(:post, 'http://example.com/inbox').to_return(status: 200)
end
- it 'sends ActivityPub payload when forward is true' do
- subject.call(source_account, remote_account, forward: true)
- expect(a_request(:post, 'http://example.com/inbox')).to have_been_made
- end
+ context 'when forward is true' do
+ let(:forward) { true }
+
+ it 'sends ActivityPub payload when forward is true' do
+ subject.call(source_account, remote_account, forward: forward)
+ expect(a_request(:post, 'http://example.com/inbox')).to have_been_made
+ end
- it 'does not send anything when forward is false' do
- subject.call(source_account, remote_account, forward: false)
- expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
+ it 'has an uri' do
+ report = subject.call(source_account, remote_account, forward: forward)
+ expect(report.uri).to_not be_nil
+ end
+
+ context 'when reporting a reply' do
+ let(:remote_thread_account) { Fabricate(:account, domain: 'foo.com', protocol: :activitypub, inbox_url: 'http://foo.com/inbox') }
+ let(:reported_status) { Fabricate(:status, account: remote_account, thread: Fabricate(:status, account: remote_thread_account)) }
+
+ before do
+ stub_request(:post, 'http://foo.com/inbox').to_return(status: 200)
+ end
+
+ it 'sends ActivityPub payload to the author of the replied-to post' do
+ subject.call(source_account, remote_account, status_ids: [reported_status.id], forward: forward)
+ expect(a_request(:post, 'http://foo.com/inbox')).to have_been_made
+ end
+ end
end
- it 'has an uri' do
- report = subject.call(source_account, remote_account, forward: true)
- expect(report.uri).to_not be_nil
+ context 'when forward is false' do
+ it 'does not send anything' do
+ subject.call(source_account, remote_account, forward: forward)
+ expect(a_request(:post, 'http://example.com/inbox')).to_not have_been_made
+ end
end
end