about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--app/lib/activitypub/activity/create.rb34
-rw-r--r--app/services/activitypub/process_collection_service.rb1
-rw-r--r--app/workers/activitypub/processing_worker.rb2
3 files changed, 34 insertions, 3 deletions
diff --git a/app/lib/activitypub/activity/create.rb b/app/lib/activitypub/activity/create.rb
index 9a3db51dd..1b31768d9 100644
--- a/app/lib/activitypub/activity/create.rb
+++ b/app/lib/activitypub/activity/create.rb
@@ -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])
diff --git a/app/services/activitypub/process_collection_service.rb b/app/services/activitypub/process_collection_service.rb
index 5c54aad89..881df478b 100644
--- a/app/services/activitypub/process_collection_service.rb
+++ b/app/services/activitypub/process_collection_service.rb
@@ -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}"
diff --git a/app/workers/activitypub/processing_worker.rb b/app/workers/activitypub/processing_worker.rb
index a8a3ebf0f..a3abe72cf 100644
--- a/app/workers/activitypub/processing_worker.rb
+++ b/app/workers/activitypub/processing_worker.rb
@@ -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