~cytrogen/masto-fe

93e8a15415c35dbe4089b5d20c08161646ba76b3 — Eugen Rochko 2 years ago e4cfe4b
Add forwarding of reported replies to servers being replied to (#25341)

M app/lib/activitypub/activity/flag.rb => app/lib/activitypub/activity/flag.rb +5 -4
@@ 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,

M app/services/report_service.rb => app/services/report_service.rb +9 -5
@@ 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?

M spec/services/report_service_spec.rb => spec/services/report_service_spec.rb +31 -10
@@ 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