From 1d1d169a5c0d76404012c357dc6ba59d97827a3c Mon Sep 17 00:00:00 2001 From: Diogo Peralta Cordeiro Date: Tue, 28 Dec 2021 16:44:38 +0000 Subject: [PATCH] [PLUGIN][ActivityPub] Support federation of Tombstones --- plugins/ActivityPub/ActivityPub.php | 4 ++-- plugins/ActivityPub/Util/Model.php | 4 ++-- plugins/ActivityPub/Util/Model/Activity.php | 20 +++++++++++++++++--- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/plugins/ActivityPub/ActivityPub.php b/plugins/ActivityPub/ActivityPub.php index efd62fe1dc..902692d579 100644 --- a/plugins/ActivityPub/ActivityPub.php +++ b/plugins/ActivityPub/ActivityPub.php @@ -268,13 +268,13 @@ class ActivityPub extends Plugin } } } catch (Exception $e) { - Log::error('ActivityPub @ freeNetworkDistribute: ' . $e->getMessage()); + Log::error('ActivityPub @ freeNetworkDistribute: ' . $e->getMessage(), [$e]); //$to_failed[$inbox] = $activity; } } if (!empty($errors)) { - Log::error(sizeof($errors) . ' instance/s failed to handle the delete_profile activity!'); + Log::error(sizeof($errors) . ' instance/s failed to handle our activity!'); return false; } diff --git a/plugins/ActivityPub/Util/Model.php b/plugins/ActivityPub/Util/Model.php index 679857d250..2392413607 100644 --- a/plugins/ActivityPub/Util/Model.php +++ b/plugins/ActivityPub/Util/Model.php @@ -124,9 +124,9 @@ abstract class Model public static function toJson(mixed $object, ?int $options = null): string { switch ($object::class) { - case 'App\Entity\Activity': + case \App\Entity\Activity::class: return Activity::toJson($object, $options); - case 'App\Entity\Note': + case \App\Entity\Note::class: return Note::toJson($object, $options); default: $type = self::jsonToType($object); diff --git a/plugins/ActivityPub/Util/Model/Activity.php b/plugins/ActivityPub/Util/Model/Activity.php index ed1423546c..557d27ef3b 100644 --- a/plugins/ActivityPub/Util/Model/Activity.php +++ b/plugins/ActivityPub/Util/Model/Activity.php @@ -40,6 +40,7 @@ use App\Core\Router\Router; use App\Entity\Activity as GSActivity; use App\Util\Exception\ClientException; use App\Util\Exception\NoSuchActorException; +use App\Util\Exception\NotFoundException; use DateTime; use DateTimeInterface; use Exception; @@ -165,11 +166,24 @@ class Activity extends Model 'to' => ['https://www.w3.org/ns/activitystreams#Public'], // TODO: implement proper scope address 'cc' => ['https://www.w3.org/ns/activitystreams#Public'], ]; - $attr['object'] = ($attr['type'] === 'Create') ? self::jsonToType(Model::toJson($object->getObject())) : ActivityPub::getUriByObject($object->getObject()); + try { + $object = $object->getObject(); // Throws NotFoundException + $attr['object'] = ($attr['type'] === 'Create') ? self::jsonToType(Model::toJson($object)) : ActivityPub::getUriByObject($object); + } catch (NotFoundException) { + // It seems this object was deleted, refer to it as a Tombstone + $uri = match ($object->getObjectType()) { + 'note' => Router::url('note_view', ['id' => $object->getObjectId()], type: Router::ABSOLUTE_URL), + 'actor' => Router::url('actor_view_id', ['id' => $object->getObjectId()], type: Router::ABSOLUTE_URL), + default => throw new \App\Util\Exception\NotImplementedException(), + }; + $attr['object'] = Type::create('Tombstone', [ + 'id' => $uri, + ]); + } if (!\is_string($attr['object'])) { - $attr['to'] = array_unique(array_merge($attr['to'], $attr['object']->get('to'))); - $attr['cc'] = array_unique(array_merge($attr['cc'], $attr['object']->get('cc'))); + $attr['to'] = array_unique(array_merge($attr['to'], $attr['object']->get('to') ?? [])); + $attr['cc'] = array_unique(array_merge($attr['cc'], $attr['object']->get('cc') ?? [])); } $type = self::jsonToType($attr);