Refactor local-URI-to-account resolving ()

This commit is contained in:
Claire 2025-04-02 16:44:09 +02:00 committed by GitHub
parent 4bbe33e0bd
commit dd23ba9c83
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 50 additions and 16 deletions
app
spec/lib/activitypub

View file

@ -130,12 +130,7 @@ class ActivityPub::Activity
def first_mentioned_local_account
audience = (as_array(@json['to']) + as_array(@json['cc'])).map { |x| value_or_id(x) }.uniq
local_usernames = audience.select { |uri| ActivityPub::TagManager.instance.local_uri?(uri) }
.map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username) }
return if local_usernames.empty?
Account.local.where(username: local_usernames).first
ActivityPub::TagManager.instance.uris_to_local_accounts(audience).first
end
def first_local_follower

View file

@ -412,11 +412,7 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
def addresses_local_accounts?
return true if @options[:delivered_to_account_id]
local_usernames = (audience_to + audience_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.exists?(username: local_usernames)
ActivityPub::TagManager.instance.uris_to_local_accounts((audience_to + audience_cc).uniq).exists?
end
def tombstone_exists?

View file

@ -203,6 +203,19 @@ class ActivityPub::TagManager
path_params[param]
end
def uris_to_local_accounts(uris)
usernames = []
ids = []
uris.each do |uri|
param, value = uri_to_local_account_params(uri)
usernames << value.downcase if param == :username
ids << value if param == :id
end
Account.local.with_username(usernames).or(Account.local.where(id: ids))
end
def uri_to_actor(uri)
uri_to_resource(uri, Account)
end
@ -213,7 +226,7 @@ class ActivityPub::TagManager
if local_uri?(uri)
case klass.name
when 'Account'
klass.find_local(uri_to_local_id(uri, :username))
uris_to_local_accounts([uri]).first
else
StatusFinder.new(uri).status
end
@ -225,4 +238,20 @@ class ActivityPub::TagManager
rescue ActiveRecord::RecordNotFound
nil
end
private
def uri_to_local_account_params(uri)
return unless local_uri?(uri)
path_params = Rails.application.routes.recognize_path(uri)
# TODO: handle numeric IDs
case path_params[:controller]
when 'accounts'
[:username, path_params[:username]]
when 'instance_actors'
[:id, -99]
end
end
end

View file

@ -30,10 +30,7 @@ class ActivityPub::SynchronizeFollowersService < BaseService
# Account record, and should we not do that, we should have sent a Delete.
# In any case there is not much we can do if that occurs.
# TODO: this will need changes when switching to numeric IDs
usernames = items.filter_map { |uri| ActivityPub::TagManager.instance.uri_to_local_id(uri, :username)&.downcase }
Account.local.with_username(usernames)
ActivityPub::TagManager.instance.uris_to_local_accounts(items)
end
def remove_unexpected_local_followers!

View file

@ -187,6 +187,23 @@ RSpec.describe ActivityPub::TagManager do
end
end
describe '#uris_to_local_accounts' do
it 'returns the expected local accounts' do
account = Fabricate(:account)
expect(subject.uris_to_local_accounts([subject.uri_for(account), instance_actor_url])).to contain_exactly(account, Account.representative)
end
it 'does not return remote accounts' do
account = Fabricate(:account, uri: 'https://example.com/123', domain: 'example.com')
expect(subject.uris_to_local_accounts([subject.uri_for(account)])).to be_empty
end
it 'does not return an account for a local post' do
status = Fabricate(:status)
expect(subject.uris_to_local_accounts([subject.uri_for(status)])).to be_empty
end
end
describe '#uri_to_resource' do
it 'returns the local account' do
account = Fabricate(:account)