Add support for reversible suspensions through ActivityPub (#14989)
This commit is contained in:
@ -73,4 +73,84 @@ RSpec.describe ActivityPub::ProcessAccountService, type: :service do
|
||||
expect(ProofProvider::Keybase::Worker).to have_received(:perform_async)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is not suspended' do
|
||||
let!(:account) { Fabricate(:account, username: 'alice', domain: 'example.com') }
|
||||
|
||||
let(:payload) do
|
||||
{
|
||||
id: 'https://foo.test',
|
||||
type: 'Actor',
|
||||
inbox: 'https://foo.test/inbox',
|
||||
suspended: true,
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Admin::SuspensionWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
subject { described_class.new.call('alice', 'example.com', payload) }
|
||||
|
||||
it 'suspends account remotely' do
|
||||
expect(subject.suspended?).to be true
|
||||
expect(subject.suspension_origin_remote?).to be true
|
||||
end
|
||||
|
||||
it 'queues suspension worker' do
|
||||
subject
|
||||
expect(Admin::SuspensionWorker).to have_received(:perform_async)
|
||||
end
|
||||
end
|
||||
|
||||
context 'when account is suspended' do
|
||||
let!(:account) { Fabricate(:account, username: 'alice', domain: 'example.com', display_name: '') }
|
||||
|
||||
let(:payload) do
|
||||
{
|
||||
id: 'https://foo.test',
|
||||
type: 'Actor',
|
||||
inbox: 'https://foo.test/inbox',
|
||||
suspended: false,
|
||||
name: 'Hoge',
|
||||
}.with_indifferent_access
|
||||
end
|
||||
|
||||
before do
|
||||
allow(Admin::UnsuspensionWorker).to receive(:perform_async)
|
||||
|
||||
account.suspend!(origin: suspension_origin)
|
||||
end
|
||||
|
||||
subject { described_class.new.call('alice', 'example.com', payload) }
|
||||
|
||||
context 'locally' do
|
||||
let(:suspension_origin) { :local }
|
||||
|
||||
it 'does not unsuspend it' do
|
||||
expect(subject.suspended?).to be true
|
||||
end
|
||||
|
||||
it 'does not update any attributes' do
|
||||
expect(subject.display_name).to_not eq 'Hoge'
|
||||
end
|
||||
end
|
||||
|
||||
context 'remotely' do
|
||||
let(:suspension_origin) { :remote }
|
||||
|
||||
it 'unsuspends it' do
|
||||
expect(subject.suspended?).to be false
|
||||
end
|
||||
|
||||
it 'queues unsuspension worker' do
|
||||
subject
|
||||
expect(Admin::UnsuspensionWorker).to have_received(:perform_async)
|
||||
end
|
||||
|
||||
it 'updates attributes' do
|
||||
expect(subject.display_name).to eq 'Hoge'
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -22,7 +22,48 @@ RSpec.describe ActivityPub::ProcessCollectionService, type: :service do
|
||||
subject { described_class.new }
|
||||
|
||||
describe '#call' do
|
||||
context 'when actor is the sender'
|
||||
context 'when actor is suspended' do
|
||||
before do
|
||||
actor.suspend!(origin: :remote)
|
||||
end
|
||||
|
||||
%w(Accept Add Announce Block Create Flag Follow Like Move Remove).each do |activity_type|
|
||||
context "with #{activity_type} activity" do
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: 'foo',
|
||||
type: activity_type,
|
||||
actor: ActivityPub::TagManager.instance.uri_for(actor),
|
||||
}
|
||||
end
|
||||
|
||||
it 'does not process payload' do
|
||||
expect(ActivityPub::Activity).not_to receive(:factory)
|
||||
subject.call(json, actor)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
%w(Delete Reject Undo Update).each do |activity_type|
|
||||
context "with #{activity_type} activity" do
|
||||
let(:payload) do
|
||||
{
|
||||
'@context': 'https://www.w3.org/ns/activitystreams',
|
||||
id: 'foo',
|
||||
type: activity_type,
|
||||
actor: ActivityPub::TagManager.instance.uri_for(actor),
|
||||
}
|
||||
end
|
||||
|
||||
it 'processes the payload' do
|
||||
expect(ActivityPub::Activity).to receive(:factory)
|
||||
subject.call(json, actor)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'when actor differs from sender' do
|
||||
let(:forwarder) { Fabricate(:account, domain: 'example.com', uri: 'http://example.com/other_account') }
|
||||
|
||||
|
@ -13,16 +13,41 @@ RSpec.describe ResolveAccountService, type: :service do
|
||||
stub_request(:get, "https://ap.example.com/users/foo").to_return(request_fixture('activitypub-actor.txt'))
|
||||
stub_request(:get, "https://ap.example.com/users/foo.atom").to_return(request_fixture('activitypub-feed.txt'))
|
||||
stub_request(:get, %r{https://ap.example.com/users/foo/\w+}).to_return(status: 404)
|
||||
stub_request(:get, 'https://example.com/.well-known/webfinger?resource=acct:hoge@example.com').to_return(status: 410)
|
||||
end
|
||||
|
||||
it 'raises error if no such user can be resolved via webfinger' do
|
||||
it 'returns nil if no such user can be resolved via webfinger' do
|
||||
expect(subject.call('catsrgr8@quitter.no')).to be_nil
|
||||
end
|
||||
|
||||
it 'raises error if the domain does not have webfinger' do
|
||||
it 'returns nil if the domain does not have webfinger' do
|
||||
expect(subject.call('catsrgr8@example.com')).to be_nil
|
||||
end
|
||||
|
||||
context 'when webfinger returns http gone' do
|
||||
context 'for a previously known account' do
|
||||
before do
|
||||
Fabricate(:account, username: 'hoge', domain: 'example.com', last_webfingered_at: nil)
|
||||
allow(AccountDeletionWorker).to receive(:perform_async)
|
||||
end
|
||||
|
||||
it 'returns nil' do
|
||||
expect(subject.call('hoge@example.com')).to be_nil
|
||||
end
|
||||
|
||||
it 'queues account deletion worker' do
|
||||
subject.call('hoge@example.com')
|
||||
expect(AccountDeletionWorker).to have_received(:perform_async)
|
||||
end
|
||||
end
|
||||
|
||||
context 'for a previously unknown account' do
|
||||
it 'returns nil' do
|
||||
expect(subject.call('hoge@example.com')).to be_nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
context 'with an ActivityPub account' do
|
||||
it 'returns new remote account' do
|
||||
account = subject.call('foo@ap.example.com')
|
||||
|
Reference in New Issue
Block a user