Browse Source

Filter incoming Create activities by relation to local activity (#10005)

Reject those from accounts with no local followers, from relays
that are not enabled, which do not address local accounts and are
not replies to accounts that do have local followers
pull/4/head
Eugen Rochko 5 years ago
committed by GitHub
parent
commit
dad339da6d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 34 additions and 3 deletions
  1. +32
    -2
      app/lib/activitypub/activity/create.rb
  2. +1
    -0
      app/services/activitypub/process_collection_service.rb
  3. +1
    -1
      app/workers/activitypub/processing_worker.rb

+ 32
- 2
app/lib/activitypub/activity/create.rb View File

@ -2,8 +2,7 @@
class ActivityPub::Activity::Create < ActivityPub::Activity
def perform
return if unsupported_object_type? || invalid_origin?(@object['id'])
return if Tombstone.exists?(uri: @object['id'])
return if unsupported_object_type? || invalid_origin?(@object['id']) || Tombstone.exists?(uri: @object['id']) || !related_to_local_activity?
RedisLock.acquire(lock_options) do |lock|
if lock.acquired?
@ -337,6 +336,37 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
!replied_to_status.nil? && replied_to_status.account.local?
end
def related_to_local_activity?
fetch? || followed_by_local_accounts? || requested_through_relay? ||
responds_to_followed_account? || addresses_local_accounts?
end
def fetch?
!@options[:delivery]
end
def followed_by_local_accounts?
@account.passive_relationships.exists?
end
def requested_through_relay?
@options[:relayed_through_account] && Relay.find_by(inbox_url: @options[:relayed_through_account].inbox_url)&.enabled?
end
def responds_to_followed_account?
!replied_to_status.nil? && (replied_to_status.account.local? || replied_to_status.account.passive_relationships.exists?)
end
def addresses_local_accounts?
return true if @options[:delivered_to_account_id]
local_usernames = (as_array(@object['to']) + as_array(@object['cc'])).uniq.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
return false if local_usernames.empty?
Account.local.where(username: local_usernames).exists?
end
def forward_for_reply
return unless @json['signature'].present? && reply_to_local?
ActivityPub::RawDistributionWorker.perform_async(Oj.dump(@json), replied_to_status.account_id, [@account.preferred_inbox_url])

+ 1
- 0
app/services/activitypub/process_collection_service.rb View File

@ -44,6 +44,7 @@ class ActivityPub::ProcessCollectionService < BaseService
end
def verify_account!
@options[:relayed_through_account] = @account
@account = ActivityPub::LinkedDataSignature.new(@json).verify_account!
rescue JSON::LD::JsonLdError => e
Rails.logger.debug "Could not verify LD-Signature for #{value_or_id(@json['actor'])}: #{e.message}"

+ 1
- 1
app/workers/activitypub/processing_worker.rb View File

@ -6,6 +6,6 @@ class ActivityPub::ProcessingWorker
sidekiq_options backtrace: true
def perform(account_id, body, delivered_to_account_id = nil)
ActivityPub::ProcessCollectionService.new.call(body, Account.find(account_id), override_timestamps: true, delivered_to_account_id: delivered_to_account_id)
ActivityPub::ProcessCollectionService.new.call(body, Account.find(account_id), override_timestamps: true, delivered_to_account_id: delivered_to_account_id, delivery: true)
end
end

Loading…
Cancel
Save