mirror of
https://github.com/mastodon/mastodon.git
synced 2026-08-28 09:05:46 -05:00
Delete remote accounts when fetching their URI leads to a 410 (#39865)
This commit is contained in:
@@ -233,7 +233,7 @@ module JsonLdHelper
|
||||
# If an error is raised, it contains the response and can be captured for handling like
|
||||
#
|
||||
# begin
|
||||
# fetch_resource_without_id_validation(uri, nil, true)
|
||||
# fetch_resource_without_id_validation(uri, raise_on_error: :all)
|
||||
# rescue Mastodon::UnexpectedResponseError => e
|
||||
# e.response
|
||||
# end
|
||||
|
||||
@@ -15,10 +15,14 @@ class ActivityPub::FetchRemoteActorService < BaseService
|
||||
|
||||
@json = begin
|
||||
if prefetched_body.nil?
|
||||
fetch_resource(uri, true)
|
||||
fetch_resource(uri, true, raise_on_error: :all)
|
||||
else
|
||||
body_to_json(prefetched_body, compare_id: uri)
|
||||
end
|
||||
rescue Mastodon::UnexpectedResponseError => e
|
||||
queue_deletion!(uri) if e.response.code == 410
|
||||
|
||||
raise Error, "Error fetching actor JSON at #{uri} (HTTP #{e.response.code})"
|
||||
rescue JSON::ParserError
|
||||
raise Error, "Error parsing JSON-LD document #{uri}"
|
||||
end
|
||||
@@ -39,6 +43,16 @@ class ActivityPub::FetchRemoteActorService < BaseService
|
||||
|
||||
private
|
||||
|
||||
def queue_deletion!(uri)
|
||||
account = Account.find_by(uri:)
|
||||
return unless account&.remote?
|
||||
|
||||
Rails.logger.debug { "Deleting actor #{uri} because of HTTP 410 response" }
|
||||
|
||||
account.suspend!(origin: :remote)
|
||||
AccountDeletionWorker.perform_async(account.id, { 'reserve_username' => false, 'skip_activitypub' => true })
|
||||
end
|
||||
|
||||
def supported_context?
|
||||
super(@json)
|
||||
end
|
||||
|
||||
@@ -32,6 +32,51 @@ RSpec.describe ActivityPub::FetchRemoteActorService do
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the account is already known and the actor document returns a temporary error' do
|
||||
let!(:known_account) { Fabricate(:remote_account, uri: 'https://example.com/alice') }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(status: 500)
|
||||
end
|
||||
|
||||
it 'returns nil but keeps the existing account intact' do
|
||||
expect(account).to be_nil
|
||||
expect(known_account.reload.suspended?).to be false
|
||||
expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
|
||||
expect(AccountDeletionWorker).to_not have_enqueued_sidekiq_job
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the account is already known and the actor document returns a 404 not found error' do
|
||||
let!(:known_account) { Fabricate(:remote_account, uri: 'https://example.com/alice') }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(status: 404)
|
||||
end
|
||||
|
||||
it 'returns nil but keeps the existing account intact' do
|
||||
expect(account).to be_nil
|
||||
expect(known_account.reload.suspended?).to be false
|
||||
expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
|
||||
expect(AccountDeletionWorker).to_not have_enqueued_sidekiq_job
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the account is already known and the actor document returns a 410 gone error' do
|
||||
let!(:known_account) { Fabricate(:remote_account, uri: 'https://example.com/alice') }
|
||||
|
||||
before do
|
||||
stub_request(:get, 'https://example.com/alice').to_return(status: 410)
|
||||
end
|
||||
|
||||
it 'returns nil and marks the known account for deletion' do
|
||||
expect(account).to be_nil
|
||||
expect(known_account.reload.suspended?).to be true
|
||||
expect(a_request(:get, 'https://example.com/alice')).to have_been_made.once
|
||||
expect(AccountDeletionWorker).to have_enqueued_sidekiq_job(known_account.id, { 'reserve_username' => false, 'skip_activitypub' => true })
|
||||
end
|
||||
end
|
||||
|
||||
context 'when the account does not have a inbox' do
|
||||
before do
|
||||
actor[:inbox] = nil
|
||||
|
||||
Reference in New Issue
Block a user