Reduce usage of LD signatures (#9659)
* Do not LDS-sign Follow, Accept, Reject, Undo, Block * Do not use LDS for Create activities of private toots * Minor cleanup * Ignore unsigned activities instead of misattributing them * Use status.distributable? instead of querying visibility directly
This commit is contained in:
		@@ -28,7 +28,7 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def reject_follow_request!(target_account)
 | 
			
		||||
    json = Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(FollowRequest.new(account: @account, target_account: target_account, uri: @json['id']), serializer: ActivityPub::RejectFollowSerializer, adapter: ActivityPub::Adapter).as_json).sign!(target_account))
 | 
			
		||||
    json = ActiveModelSerializers::SerializableResource.new(FollowRequest.new(account: @account, target_account: target_account, uri: @json['id']), serializer: ActivityPub::RejectFollowSerializer, adapter: ActivityPub::Adapter).to_json
 | 
			
		||||
    ActivityPub::DeliveryWorker.perform_async(json, target_account.id, @account.inbox_url)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -27,7 +27,7 @@ class ActivityPub::ProcessCollectionService < BaseService
 | 
			
		||||
  private
 | 
			
		||||
 | 
			
		||||
  def different_actor?
 | 
			
		||||
    @json['actor'].present? && value_or_id(@json['actor']) != @account.uri && @json['signature'].present?
 | 
			
		||||
    @json['actor'].present? && value_or_id(@json['actor']) != @account.uri
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def process_items(items)
 | 
			
		||||
 
 | 
			
		||||
@@ -31,11 +31,11 @@ class AfterBlockDomainFromAccountService < BaseService
 | 
			
		||||
 | 
			
		||||
    return unless follow.account.activitypub?
 | 
			
		||||
 | 
			
		||||
    json = Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    json = ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      follow,
 | 
			
		||||
      serializer: ActivityPub::RejectFollowSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(@account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
 | 
			
		||||
    ActivityPub::DeliveryWorker.perform_async(json, @account.id, follow.account.inbox_url)
 | 
			
		||||
  end
 | 
			
		||||
 
 | 
			
		||||
@@ -24,11 +24,11 @@ class AuthorizeFollowService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_json(follow_request)
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      follow_request,
 | 
			
		||||
      serializer: ActivityPub::AcceptFollowSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(follow_request.target_account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_xml(follow_request)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class BlockService < BaseService
 | 
			
		||||
  include StreamEntryRenderer
 | 
			
		||||
 | 
			
		||||
  def call(account, target_account)
 | 
			
		||||
    return if account.id == target_account.id
 | 
			
		||||
 | 
			
		||||
@@ -27,11 +25,11 @@ class BlockService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_json(block)
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      block,
 | 
			
		||||
      serializer: ActivityPub::BlockSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(block.account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_xml(block)
 | 
			
		||||
 
 | 
			
		||||
@@ -1,8 +1,6 @@
 | 
			
		||||
# frozen_string_literal: true
 | 
			
		||||
 | 
			
		||||
class FollowService < BaseService
 | 
			
		||||
  include StreamEntryRenderer
 | 
			
		||||
 | 
			
		||||
  # Follow a remote user, notify remote user about the follow
 | 
			
		||||
  # @param [Account] source_account From which to follow
 | 
			
		||||
  # @param [String, Account] uri User URI to follow in the form of username@domain (or account record)
 | 
			
		||||
@@ -82,10 +80,10 @@ class FollowService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_json(follow_request)
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      follow_request,
 | 
			
		||||
      serializer: ActivityPub::FollowSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(follow_request.account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -60,11 +60,13 @@ class ProcessMentionsService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def activitypub_json
 | 
			
		||||
    @activitypub_json ||= Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    return @activitypub_json if defined?(@activitypub_json)
 | 
			
		||||
    payload = ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      @status,
 | 
			
		||||
      serializer: ActivityPub::ActivitySerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(@status.account))
 | 
			
		||||
    ).as_json
 | 
			
		||||
    @activitypub_json = Oj.dump(@status.distributable? ? ActivityPub::LinkedDataSignature.new(payload).sign!(@status.account) : payload)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def resolve_account_service
 | 
			
		||||
 
 | 
			
		||||
@@ -19,11 +19,11 @@ class RejectFollowService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_json(follow_request)
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      follow_request,
 | 
			
		||||
      serializer: ActivityPub::RejectFollowSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(follow_request.target_account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_xml(follow_request)
 | 
			
		||||
 
 | 
			
		||||
@@ -20,11 +20,11 @@ class UnblockService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_json(unblock)
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      unblock,
 | 
			
		||||
      serializer: ActivityPub::UndoBlockSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(unblock.account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_xml(block)
 | 
			
		||||
 
 | 
			
		||||
@@ -43,11 +43,11 @@ class UnfollowService < BaseService
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_json(follow)
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      follow,
 | 
			
		||||
      serializer: ActivityPub::UndoFollowSerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json).sign!(follow.account))
 | 
			
		||||
    ).to_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def build_xml(follow)
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ class ActivityPub::DistributionWorker
 | 
			
		||||
    return if skip_distribution?
 | 
			
		||||
 | 
			
		||||
    ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
 | 
			
		||||
      [signed_payload, @account.id, inbox_url]
 | 
			
		||||
      [payload, @account.id, inbox_url]
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    relay! if relayable?
 | 
			
		||||
@@ -35,20 +35,24 @@ class ActivityPub::DistributionWorker
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def signed_payload
 | 
			
		||||
    @signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@account))
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(unsigned_payload).sign!(@account))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def payload
 | 
			
		||||
    @payload ||= ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
  def unsigned_payload
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      @status,
 | 
			
		||||
      serializer: ActivityPub::ActivitySerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def payload
 | 
			
		||||
    @payload ||= @status.distributable? ? signed_payload : Oj.dump(unsigned_payload)
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def relay!
 | 
			
		||||
    ActivityPub::DeliveryWorker.push_bulk(Relay.enabled.pluck(:inbox_url)) do |inbox_url|
 | 
			
		||||
      [signed_payload, @account.id, inbox_url]
 | 
			
		||||
      [payload, @account.id, inbox_url]
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -12,7 +12,7 @@ class ActivityPub::ReplyDistributionWorker
 | 
			
		||||
    return unless @account.present? && @status.distributable?
 | 
			
		||||
 | 
			
		||||
    ActivityPub::DeliveryWorker.push_bulk(inboxes) do |inbox_url|
 | 
			
		||||
      [signed_payload, @status.account_id, inbox_url]
 | 
			
		||||
      [payload, @status.account_id, inbox_url]
 | 
			
		||||
    end
 | 
			
		||||
  rescue ActiveRecord::RecordNotFound
 | 
			
		||||
    true
 | 
			
		||||
@@ -25,14 +25,18 @@ class ActivityPub::ReplyDistributionWorker
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def signed_payload
 | 
			
		||||
    @signed_payload ||= Oj.dump(ActivityPub::LinkedDataSignature.new(payload).sign!(@status.account))
 | 
			
		||||
    Oj.dump(ActivityPub::LinkedDataSignature.new(unsigned_payload).sign!(@status.account))
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def payload
 | 
			
		||||
    @payload ||= ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
  def unsigned_payload
 | 
			
		||||
    ActiveModelSerializers::SerializableResource.new(
 | 
			
		||||
      @status,
 | 
			
		||||
      serializer: ActivityPub::ActivitySerializer,
 | 
			
		||||
      adapter: ActivityPub::Adapter
 | 
			
		||||
    ).as_json
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  def payload
 | 
			
		||||
    @payload ||= @status.distributable? ? signed_payload : Oj.dump(unsigned_payload)
 | 
			
		||||
  end
 | 
			
		||||
end
 | 
			
		||||
 
 | 
			
		||||
@@ -26,9 +26,9 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
 | 
			
		||||
    context 'when actor differs from sender' do
 | 
			
		||||
      let(:forwarder) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/other_account') }
 | 
			
		||||
 | 
			
		||||
      it 'processes payload with sender if no signature exists' do
 | 
			
		||||
        expect_any_instance_of(ActivityPub::LinkedDataSignature).not_to receive(:verify_account!)
 | 
			
		||||
        expect(ActivityPub::Activity).to receive(:factory).with(instance_of(Hash), forwarder, instance_of(Hash))
 | 
			
		||||
      it 'does not process payload if no signature exists' do
 | 
			
		||||
        expect_any_instance_of(ActivityPub::LinkedDataSignature).to receive(:verify_account!).and_return(nil)
 | 
			
		||||
        expect(ActivityPub::Activity).not_to receive(:factory)
 | 
			
		||||
 | 
			
		||||
        subject.call(json, forwarder)
 | 
			
		||||
      end
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user