Resend AccountMigration or AccountDeletion for closed recipients

This commit is contained in:
Benjamin Neff
2021-10-24 16:16:14 +02:00
parent 88e2e593a4
commit 3cb1e470a4
9 changed files with 76 additions and 17 deletions

View File

@@ -128,7 +128,7 @@ class AccountMigration < ApplicationRecord
def person_references
references = Person.reflections.reject {|key, _|
%w[profile owner notifications pod account_migration].include?(key)
%w[profile owner notifications pod account_deletion account_migration].include?(key)
}
references.map {|key, value|

View File

@@ -57,6 +57,7 @@ class Person < ApplicationRecord
has_many :mentions, :dependent => :destroy
has_one :account_deletion, dependent: :destroy
has_one :account_migration, foreign_key: :old_person_id, dependent: :nullify, inverse_of: :old_person
validate :owner_xor_pod

View File

@@ -26,6 +26,7 @@ module Workers
DiasporaFederation::Salmon::InvalidEncoding,
Diaspora::Federation::AuthorIgnored,
Diaspora::Federation::InvalidAuthor,
Diaspora::Federation::RecipientClosed,
# TODO: deprecated
DiasporaFederation::Salmon::MissingMagicEnvelope,
DiasporaFederation::Salmon::MissingAuthor,

View File

@@ -103,18 +103,9 @@ DiasporaFederation.configure do |config|
end
on :receive_entity do |entity, sender, recipient_id|
Person.by_account_identifier(sender).pod.try(:schedule_check_if_needed)
unless recipient_id.nil?
User.find_by(id: recipient_id).tap do |user|
next unless user.person.account_migration
Diaspora::Federation::Dispatcher.build(
user,
user.person.account_migration,
subscribers: [Person.by_account_identifier(sender)]
).dispatch
end
end
sender_person = Person.by_account_identifier(sender)
sender_person.pod&.schedule_check_if_needed
Diaspora::Federation::Receive.handle_closed_recipient(sender_person, User.find(recipient_id)) if recipient_id
case entity
when DiasporaFederation::Entities::AccountDeletion

View File

@@ -9,6 +9,10 @@ module Diaspora
# Raised, if the author of the existing object doesn't match the received author
class InvalidAuthor < RuntimeError
end
# Raised, if the recipient account is closed already
class RecipientClosed < RuntimeError
end
end
end

View File

@@ -9,6 +9,15 @@ module Diaspora
public_send(Mappings.receiver_for(entity), entity)
end
def self.handle_closed_recipient(sender, recipient)
return unless recipient.closed_account?
entity = recipient.person.account_migration || recipient.person.account_deletion
Diaspora::Federation::Dispatcher.build(recipient, entity, subscribers: [sender]).dispatch if entity.present?
raise Diaspora::Federation::RecipientClosed
end
def self.account_deletion(entity)
person = author_of(entity)
AccountDeletion.create!(person: person) unless AccountDeletion.where(person: person).exists?

View File

@@ -387,12 +387,13 @@ describe "diaspora federation callbacks" do
it "receives a entity for a recipient" do
received = Fabricate(:status_message_entity, author: remote_person.diaspora_handle)
persisted = FactoryGirl.create(:status_message)
recipient_id = FactoryGirl.create(:user).id
recipient = FactoryGirl.create(:user)
expect(Diaspora::Federation::Receive).to receive(:handle_closed_recipient).with(remote_person, recipient)
expect(Diaspora::Federation::Receive).to receive(:perform).with(received).and_return(persisted)
expect(Workers::ReceiveLocal).to receive(:perform_async).with(persisted.class.to_s, persisted.id, [recipient_id])
expect(Workers::ReceiveLocal).to receive(:perform_async).with(persisted.class.to_s, persisted.id, [recipient.id])
DiasporaFederation.callbacks.trigger(:receive_entity, received, received.author, recipient_id)
DiasporaFederation.callbacks.trigger(:receive_entity, received, received.author, recipient.id)
end
it "does not trigger a ReceiveLocal job if Receive.perform returned nil" do

View File

@@ -200,7 +200,7 @@ describe AccountDeleter do
it "has all person association keys accounted for" do
ignored_or_special_ar_person_associations = %i[comments likes poll_participations contacts notification_actors
notifications owner profile pod conversations messages
account_migration]
account_deletion account_migration]
all_keys = @account_deletion.normal_ar_person_associates_to_delete + ignored_or_special_ar_person_associations
expect(all_keys.sort_by(&:to_s)).to eq(Person.reflections.keys.sort_by(&:to_s).map(&:to_sym))
end

View File

@@ -4,6 +4,58 @@ describe Diaspora::Federation::Receive do
let(:sender) { FactoryGirl.create(:person) }
let(:post) { FactoryGirl.create(:status_message, text: "hello", public: true, author: alice.person) }
describe ".handle_closed_recipient" do
let(:closed_recipient) { FactoryGirl.create(:user).tap {|u| u.person.lock_access! } }
it "does nothing if the recipient isn't closed" do
recipient = FactoryGirl.create(:user)
expect { Diaspora::Federation::Receive.handle_closed_recipient(sender, recipient) }.not_to raise_error
end
it "raises if the recipient is closed, but no AccountMigration and/or AccountDeletion exists" do
expect(Diaspora::Federation::Dispatcher).not_to receive(:build)
expect { Diaspora::Federation::Receive.handle_closed_recipient(sender, closed_recipient) }
.to raise_error(Diaspora::Federation::RecipientClosed)
end
it "resends AccountMigration if the recipient is closed and an AccountMigration exists" do
migration = AccountMigration.create(old_person: closed_recipient.person, new_person: FactoryGirl.create(:person))
dispatcher = double
expect(Diaspora::Federation::Dispatcher).to receive(:build)
.with(closed_recipient, migration, subscribers: [sender]).and_return(dispatcher)
expect(dispatcher).to receive(:dispatch)
expect { Diaspora::Federation::Receive.handle_closed_recipient(sender, closed_recipient) }
.to raise_error(Diaspora::Federation::RecipientClosed)
end
it "resends AccountDeletion if the recipient is closed and an AccountDeletion exists" do
deletion = AccountDeletion.create(person: closed_recipient.person)
dispatcher = double
expect(Diaspora::Federation::Dispatcher).to receive(:build)
.with(closed_recipient, deletion, subscribers: [sender]).and_return(dispatcher)
expect(dispatcher).to receive(:dispatch)
expect { Diaspora::Federation::Receive.handle_closed_recipient(sender, closed_recipient) }
.to raise_error(Diaspora::Federation::RecipientClosed)
end
it "resends AccountMigration if the recipient is closed and both an AccountMigration and AccountDeletion exists" do
AccountDeletion.create(person: closed_recipient.person)
migration = AccountMigration.create(old_person: closed_recipient.person, new_person: FactoryGirl.create(:person))
dispatcher = double
expect(Diaspora::Federation::Dispatcher).to receive(:build)
.with(closed_recipient, migration, subscribers: [sender]).and_return(dispatcher)
expect(dispatcher).to receive(:dispatch)
expect { Diaspora::Federation::Receive.handle_closed_recipient(sender, closed_recipient) }
.to raise_error(Diaspora::Federation::RecipientClosed)
end
end
describe ".account_deletion" do
let(:account_deletion_entity) { Fabricate(:account_deletion_entity, author: sender.diaspora_handle) }