Change discoverable accounts to only allow followers to feature them if they are locked (#38672)

This commit is contained in:
Claire 2026-04-15 17:05:58 +02:00 committed by GitHub
parent 3a84990780
commit 6b1e1899fd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 62 additions and 7 deletions

View File

@ -473,7 +473,7 @@ class Account < ApplicationRecord
end
def featureable_by?(other_account)
return discoverable? if local?
return discoverable? && (!locked? || followed_by?(other_account)) if local?
feature_policy_for_account(other_account).in?(%i(automatic manual))
end

View File

@ -64,6 +64,6 @@ module Account::InteractionPolicyConcern
def local_feature_policy(kind)
return [] if kind == :manual || !discoverable?
[:public]
[locked? ? :followers : :public]
end
end

View File

@ -176,7 +176,15 @@ class ActivityPub::ActorSerializer < ActivityPub::Serializer
end
def interaction_policy
uri = object.discoverable? ? ActivityPub::TagManager::COLLECTIONS[:public] : ActivityPub::TagManager.instance.uri_for(object)
uri = begin
if !object.discoverable?
ActivityPub::TagManager.instance.uri_for(object)
elsif object.locked?
ActivityPub::TagManager.instance.followers_uri_for(object)
else
ActivityPub::TagManager::COLLECTIONS[:public]
end
end
{
canFeature: {

View File

@ -772,19 +772,42 @@ RSpec.describe Account do
end
describe '#featureable_by?' do
subject { Fabricate.build(:account, domain: (local ? nil : 'example.com'), discoverable:, feature_approval_policy:) }
subject { Fabricate.build(:account, domain: (local ? nil : 'example.com'), discoverable:, locked:, feature_approval_policy:) }
let(:locked) { false }
let(:local_account) { Fabricate(:account) }
context 'when account is local' do
let(:local) { true }
let(:feature_approval_policy) { nil }
let(:feature_approval_policy) { 0 }
context 'when account is discoverable' do
let(:discoverable) { true }
it 'returns `true`' do
expect(subject.featureable_by?(local_account)).to be true
context 'when the account is not locked' do
let(:locked) { false }
it 'returns `true`' do
expect(subject.featureable_by?(local_account)).to be true
end
end
context 'when the account is locked' do
let(:locked) { true }
it 'returns `false`' do
expect(subject.featureable_by?(local_account)).to be false
end
context 'when the other account is a follower' do
before do
local_account.follow!(subject)
end
it 'returns `true`' do
expect(subject.featureable_by?(local_account)).to be true
end
end
end
end

View File

@ -56,6 +56,18 @@ RSpec.describe ActivityPub::ActorSerializer do
},
})
end
context 'when actor is locked' do
let(:record) { Fabricate(:account, locked: true) }
it 'includes an automatic policy allowing followers' do
expect(subject).to include('interactionPolicy' => {
'canFeature' => {
'automaticApproval' => [ActivityPub::TagManager.instance.followers_uri_for(record)],
},
})
end
end
end
context 'when actor is not discoverable' do

View File

@ -93,6 +93,18 @@ RSpec.describe REST::AccountSerializer do
'current_user' => 'automatic',
})
end
context 'when account is locked' do
let(:account) { Fabricate(:account, locked: true) }
it 'includes a policy that allows featuring for followers' do
expect(subject['feature_approval']).to include({
'automatic' => ['followers'],
'manual' => [],
'current_user' => 'automatic',
})
end
end
end
context 'when account is not discoverable' do