Change ActivityPub path generation to all happen in ActivityPub::TagManager (#33527)

This commit is contained in:
Claire 2025-01-13 10:39:05 +01:00 committed by GitHub
parent 53885b0fdb
commit d517fa5ab7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
9 changed files with 82 additions and 27 deletions

View File

@ -49,7 +49,7 @@ class ActivityPub::CollectionsController < ActivityPub::BaseController
def collection_presenter def collection_presenter
ActivityPub::CollectionPresenter.new( ActivityPub::CollectionPresenter.new(
id: account_collection_url(@account, params[:id]), id: ActivityPub::TagManager.instance.collection_uri_for(@account, params[:id]),
type: @type, type: @type,
size: @size, size: @size,
items: @items items: @items

View File

@ -41,12 +41,8 @@ class ActivityPub::OutboxesController < ActivityPub::BaseController
end end
end end
def outbox_url(**) def outbox_url(...)
if params[:account_username].present? ActivityPub::TagManager.instance.outbox_uri_for(@account, ...)
account_outbox_url(@account, **)
else
instance_actor_outbox_url(**)
end
end end
def next_page def next_page

View File

@ -46,7 +46,7 @@ class FollowerAccountsController < ApplicationController
end end
def page_url(page) def page_url(page)
account_followers_url(@account, page: page) unless page.nil? ActivityPub::TagManager.instance.followers_uri_for(@account, page: page) unless page.nil?
end end
def next_page_url def next_page_url

View File

@ -86,8 +86,34 @@ class ActivityPub::TagManager
account_status_shares_url(target.account, target) account_status_shares_url(target.account, target)
end end
def followers_uri_for(target) def following_uri_for(target, ...)
target.local? ? account_followers_url(target) : target.followers_url.presence raise ArgumentError, 'target must be a local account' unless target.local?
account_following_index_url(target, ...)
end
def followers_uri_for(target, ...)
return target.followers_url.presence unless target.local?
account_followers_url(target, ...)
end
def collection_uri_for(target, ...)
raise NotImplementedError unless target.local?
account_collection_url(target, ...)
end
def inbox_uri_for(target)
raise NotImplementedError unless target.local?
target.instance_actor? ? instance_actor_inbox_url : account_inbox_url(target)
end
def outbox_uri_for(target, ...)
raise NotImplementedError unless target.local?
target.instance_actor? ? instance_actor_outbox_url(...) : account_outbox_url(target, ...)
end end
# Primary audience of a status # Primary audience of a status
@ -99,7 +125,7 @@ class ActivityPub::TagManager
when 'public' when 'public'
[COLLECTIONS[:public]] [COLLECTIONS[:public]]
when 'unlisted', 'private' when 'unlisted', 'private'
[account_followers_url(status.account)] [followers_uri_for(status.account)]
when 'direct', 'limited' when 'direct', 'limited'
if status.account.silenced? if status.account.silenced?
# Only notify followers if the account is locally silenced # Only notify followers if the account is locally silenced
@ -133,7 +159,7 @@ class ActivityPub::TagManager
case status.visibility case status.visibility
when 'public' when 'public'
cc << account_followers_url(status.account) cc << followers_uri_for(status.account)
when 'unlisted' when 'unlisted'
cc << COLLECTIONS[:public] cc << COLLECTIONS[:public]
end end

View File

@ -44,7 +44,7 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
delegate :suspended?, :instance_actor?, to: :object delegate :suspended?, :instance_actor?, to: :object
def id def id
object.instance_actor? ? instance_actor_url : account_url(object) ActivityPub::TagManager.instance.uri_for(object)
end end
def type def type
@ -60,27 +60,27 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
end end
def following def following
account_following_index_url(object) ActivityPub::TagManager.instance.following_uri_for(object)
end end
def followers def followers
account_followers_url(object) ActivityPub::TagManager.instance.followers_uri_for(object)
end end
def inbox def inbox
object.instance_actor? ? instance_actor_inbox_url : account_inbox_url(object) ActivityPub::TagManager.instance.inbox_uri_for(object)
end end
def outbox def outbox
object.instance_actor? ? instance_actor_outbox_url : account_outbox_url(object) ActivityPub::TagManager.instance.outbox_uri_for(object)
end end
def featured def featured
account_collection_url(object, :featured) ActivityPub::TagManager.instance.collection_uri_for(object, :featured)
end end
def featured_tags def featured_tags
account_collection_url(object, :tags) ActivityPub::TagManager.instance.collection_uri_for(object, :tags)
end end
def endpoints def endpoints

View File

@ -38,6 +38,6 @@ class ActivityPub::AddSerializer < ActivityPub::Serializer
end end
def target def target
account_collection_url(object.account, :featured) ActivityPub::TagManager.instance.collection_uri_for(object.account, :featured)
end end
end end

View File

@ -38,6 +38,6 @@ class ActivityPub::RemoveSerializer < ActivityPub::Serializer
end end
def target def target
account_collection_url(object.account, :featured) ActivityPub::TagManager.instance.collection_uri_for(object.account, :featured)
end end
end end

View File

@ -13,7 +13,7 @@ class WebfingerSerializer < ActiveModel::Serializer
if object.instance_actor? if object.instance_actor?
[instance_actor_url] [instance_actor_url]
else else
[short_account_url(object), account_url(object)] [short_account_url(object), ActivityPub::TagManager.instance.uri_for(object)]
end end
end end
@ -43,6 +43,6 @@ class WebfingerSerializer < ActiveModel::Serializer
end end
def self_href def self_href
object.instance_actor? ? instance_actor_url : account_url(object) ActivityPub::TagManager.instance.uri_for(object)
end end
end end

View File

@ -7,17 +7,50 @@ RSpec.describe ActivityPub::TagManager do
subject { described_class.instance } subject { described_class.instance }
let(:domain) { "#{Rails.configuration.x.use_https ? 'https' : 'http'}://#{Rails.configuration.x.web_domain}" }
describe '#public_collection?' do
it 'returns true for the special public collection and common shorthands' do
expect(subject.public_collection?('https://www.w3.org/ns/activitystreams#Public')).to be true
expect(subject.public_collection?('as:Public')).to be true
expect(subject.public_collection?('Public')).to be true
end
it 'returns false for other URIs' do
expect(subject.public_collection?('https://example.com/foo/bar')).to be false
end
end
describe '#url_for' do describe '#url_for' do
it 'returns a string' do it 'returns a string starting with web domain' do
account = Fabricate(:account) account = Fabricate(:account)
expect(subject.url_for(account)).to be_a String expect(subject.url_for(account)).to be_a(String)
.and start_with(domain)
end end
end end
describe '#uri_for' do describe '#uri_for' do
it 'returns a string' do it 'returns a string starting with web domain' do
account = Fabricate(:account) account = Fabricate(:account)
expect(subject.uri_for(account)).to be_a String expect(subject.uri_for(account)).to be_a(String)
.and start_with(domain)
end
end
describe '#activity_uri_for' do
context 'when given an account' do
it 'raises an exception' do
account = Fabricate(:account)
expect { subject.activity_uri_for(account) }.to raise_error(ArgumentError)
end
end
context 'when given a local activity' do
it 'returns a string starting with web domain' do
status = Fabricate(:status)
expect(subject.uri_for(status)).to be_a(String)
.and start_with(domain)
end
end end
end end