Skip to content

Commit

Permalink
Filter incoming Create activities by relation to local activity (mast…
Browse files Browse the repository at this point in the history
…odon#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
  • Loading branch information
Gargron authored Feb 13, 2019
1 parent 816b855 commit 1870215
Show file tree
Hide file tree
Showing 3 changed files with 34 additions and 3 deletions.
34 changes: 32 additions & 2 deletions app/lib/activitypub/activity/create.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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?
Expand Down Expand Up @@ -337,6 +336,37 @@ def reply_to_local?
!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])
Expand Down
1 change: 1 addition & 0 deletions app/services/activitypub/process_collection_service.rb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ def process_item(item)
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}"
Expand Down
2 changes: 1 addition & 1 deletion app/workers/activitypub/processing_worker.rb
Original file line number Diff line number Diff line change
Expand Up @@ -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

0 comments on commit 1870215

Please sign in to comment.