Re-check suspension status on remote accounts on incoming activity

This commit is contained in:
Claire 2025-03-12 16:46:59 +01:00
parent 966b816382
commit 649d5fa194
6 changed files with 22 additions and 9 deletions

View File

@ -26,6 +26,9 @@ class ActivityPub::Activity::Announce < ActivityPub::Activity
Trends.register!(@status)
# If we got a new reblog, the account is probably not suspended at origin anymore
@account.schedule_suspension_recheck!(interaction_time: @status.created_at)
distribute
end

View File

@ -50,6 +50,9 @@ class ActivityPub::Activity::Create < ActivityPub::Activity
process_tags
process_audience
# If we got a new status, the account is probably not suspended at origin anymore
@account.schedule_suspension_recheck!(interaction_time: @params[:created_at])
ApplicationRecord.transaction do
@status = Status.create!(@params)
attach_tags(@status)

View File

@ -8,6 +8,8 @@ class ActivityPub::Activity::Follow < ActivityPub::Activity
return if target_account.nil? || !target_account.local? || delete_arrived_first?(@json['id'])
@account.schedule_suspension_recheck!
# Update id of already-existing follow requests
existing_follow_request = ::FollowRequest.find_by(account: @account, target_account: target_account)
unless existing_follow_request.nil?

View File

@ -6,6 +6,8 @@ class ActivityPub::Activity::Like < ActivityPub::Activity
return if original_status.nil? || !original_status.account.local? || delete_arrived_first?(@json['id']) || @account.favourited?(original_status)
@account.schedule_suspension_recheck!
favourite = original_status.favourites.create!(account: @account)
LocalNotificationWorker.perform_async(original_status.account_id, favourite.id, 'Favourite', 'favourite')

View File

@ -64,6 +64,7 @@ class Account < ApplicationRecord
trust_level
)
SUSPENSION_REFRESH_INTERVAL = 1.day.freeze
BACKGROUND_REFRESH_INTERVAL = 1.week.freeze
REFRESH_DEADLINE = 6.hours
STALE_THRESHOLD = 1.day
@ -250,6 +251,14 @@ class Account < ApplicationRecord
AccountRefreshWorker.perform_in(rand(REFRESH_DEADLINE), id)
end
def schedule_suspension_recheck!(interaction_time: nil)
return unless suspended? && suspension_origin_remote?
return if last_webfingered_at.present? && last_webfingered_at >= SUSPENSION_REFRESH_INTERVAL.ago
return if interaction_time.present? && interaction_time < suspended_at
RemoteAccountRefreshWorker.perform_async(id)
end
def refresh!
ResolveAccountService.new.call(acct) unless local?
end

View File

@ -8,17 +8,11 @@ class RemoteAccountRefreshWorker
sidekiq_options queue: 'pull', retry: 3
def perform(id)
account = Account.find_by(id: id)
return if account.nil? || account.local?
account = Account.remote.find_by(id: id)
return if account.nil?
ActivityPub::FetchRemoteAccountService.new.call(account.uri)
rescue Mastodon::UnexpectedResponseError => e
response = e.response
if response_error_unsalvageable?(response)
# Give up
else
raise e
end
raise e unless response_error_unsalvageable?(e.response)
end
end