Undo notification permissions on individual and domain blocks (#29570)

main-rebase-security-fix
Claire 2024-03-26 15:46:38 +01:00 committed by GitHub
parent 7508472d84
commit 9c24f2d6b1
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 18 additions and 12 deletions

View File

@ -12,6 +12,7 @@ class AfterBlockDomainFromAccountService < BaseService
@domain_block_event = nil @domain_block_event = nil
clear_notifications! clear_notifications!
clear_notification_permissions!
remove_follows! remove_follows!
reject_existing_followers! reject_existing_followers!
reject_pending_follow_requests! reject_pending_follow_requests!
@ -31,6 +32,10 @@ class AfterBlockDomainFromAccountService < BaseService
Notification.where(account: @account).where(from_account: Account.where(domain: @domain)).in_batches.delete_all Notification.where(account: @account).where(from_account: Account.where(domain: @domain)).in_batches.delete_all
end end
def clear_notification_permissions!
NotificationPermission.where(account: @account, from_account: Account.where(domain: @domain)).in_batches.delete_all
end
def reject_existing_followers! def reject_existing_followers!
@account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).in_batches do |follows| @account.passive_relationships.where(account: Account.where(domain: @domain)).includes(:account).reorder(nil).in_batches do |follows|
domain_block_event.import_from_passive_follows!(follows) domain_block_event.import_from_passive_follows!(follows)

View File

@ -10,6 +10,8 @@ class BlockService < BaseService
UnfollowService.new.call(target_account, account) if target_account.following?(account) UnfollowService.new.call(target_account, account) if target_account.following?(account)
RejectFollowService.new.call(target_account, account) if target_account.requested?(account) RejectFollowService.new.call(target_account, account) if target_account.requested?(account)
NotificationPermission.where(account: account, from_account: target_account).destroy_all
block = account.block!(target_account) block = account.block!(target_account)
BlockWorker.perform_async(account.id, target_account.id) BlockWorker.perform_async(account.id, target_account.id)

View File

@ -10,20 +10,17 @@ RSpec.describe AfterBlockDomainFromAccountService do
let(:alice) { Fabricate(:account, username: 'alice') } let(:alice) { Fabricate(:account, username: 'alice') }
before do before do
NotificationPermission.create!(account: alice, from_account: wolf)
wolf.follow!(alice) wolf.follow!(alice)
alice.follow!(dog) alice.follow!(dog)
end end
around do |example| it 'purge followers from blocked domain, remove notification permissions, sends `Reject->Follow`, and records severed relationships', :aggregate_failures do
Sidekiq::Testing.fake! do expect { subject.call(alice, 'evil.org') }
example.run .to change { wolf.following?(alice) }.from(true).to(false)
end .and change { NotificationPermission.exists?(account: alice, from_account: wolf) }.from(true).to(false)
end
it 'purges followers from blocked domain, sends them Reject->Follow, and records severed relationships', :aggregate_failures do
subject.call(alice, 'evil.org')
expect(wolf.following?(alice)).to be false
expect(ActivityPub::DeliveryWorker.jobs.pluck('args')).to contain_exactly( expect(ActivityPub::DeliveryWorker.jobs.pluck('args')).to contain_exactly(
[a_string_including('"type":"Reject"'), alice.id, wolf.inbox_url], [a_string_including('"type":"Reject"'), alice.id, wolf.inbox_url],
[a_string_including('"type":"Undo"'), alice.id, dog.inbox_url] [a_string_including('"type":"Undo"'), alice.id, dog.inbox_url]

View File

@ -11,11 +11,13 @@ RSpec.describe BlockService do
let(:bob) { Fabricate(:account, username: 'bob') } let(:bob) { Fabricate(:account, username: 'bob') }
before do before do
subject.call(sender, bob) NotificationPermission.create!(account: sender, from_account: bob)
end end
it 'creates a blocking relation' do it 'creates a blocking relation and removes notification permissions' do
expect(sender.blocking?(bob)).to be true expect { subject.call(sender, bob) }
.to change { sender.blocking?(bob) }.from(false).to(true)
.and change { NotificationPermission.exists?(account: sender, from_account: bob) }.from(true).to(false)
end end
end end