Implement activity forwarding
This commit is contained in:
parent
e4a8e84dcc
commit
cb3abbdc3c
@ -45,6 +45,9 @@ class ActivityPersister implements EventSubscriberInterface
|
||||
public function persistActivityToInbox( InboxActivityEvent $event )
|
||||
{
|
||||
$activity = $event->getActivity();
|
||||
if ( ! $this->objectsService->getObject( $activity['id'] ) ) {
|
||||
$event->getRequest()->attributes->set( 'firstTimeSeen', true );
|
||||
}
|
||||
$receivingActor = $event->getReceivingActor();
|
||||
if ( $receivingActor->hasField( 'inbox' ) ) {
|
||||
$this->collectionsService->addItem( $receivingActor['inbox'], $activity );
|
||||
|
@ -7,6 +7,7 @@ use ActivityPub\Entities\ActivityPubObject;
|
||||
use ActivityPub\Objects\CollectionIterator;
|
||||
use ActivityPub\Objects\ObjectsService;
|
||||
use ActivityPub\Utils\DateTimeProvider;
|
||||
use ActivityPub\Utils\Util;
|
||||
use GuzzleHttp\Client;
|
||||
use GuzzleHttp\Psr7\Request;
|
||||
use Psr\Log\LoggerInterface;
|
||||
@ -62,7 +63,52 @@ class DeliveryHandler implements EventSubscriberInterface
|
||||
|
||||
public function handleInboxForwarding( InboxActivityEvent $event )
|
||||
{
|
||||
|
||||
// Forward the activity if:
|
||||
// - this is the first time we've seen the activity
|
||||
// - AND the values of to, cc, or audience contain a Collection that we own
|
||||
// - AND (according to Kaninii) if the 'object' of the activity is NOT an actor
|
||||
// - AND the values of inReplyTo, object, target, or tag are objects that we own, recursing through
|
||||
// the objects in these value chains up to some reasonable limit
|
||||
$activity = $event->getActivity();
|
||||
if ( ! $event->getRequest()->attributes->get( 'firstTimeSeen' ) ) {
|
||||
$this->logger->debug(
|
||||
'Not forwarding activity because we\'ve seen it before', array( 'activity' => $activity )
|
||||
);
|
||||
return;
|
||||
}
|
||||
if ( array_key_exists( 'object', $activity ) && $this->isActor( $activity['object'] ) ) {
|
||||
$this->logger->debug(
|
||||
'Not forwarding activity with an actor as its object', array( 'activity' => $activity )
|
||||
);
|
||||
return;
|
||||
}
|
||||
$forwardingTargets = array();
|
||||
$recipients = array_intersect( $activity, array_flip( array( 'to', 'cc', 'audience' ) ) );
|
||||
foreach ( $recipients as $recip ) {
|
||||
$recipId = $recip;
|
||||
if ( is_array( $recipId ) && array_key_exists( 'id', $recipId ) ) {
|
||||
$recipId = $recipId['id'];
|
||||
}
|
||||
if ( is_string( $recipId ) ) {
|
||||
$recipient = $this->objectsService->dereference( $recipId );
|
||||
if (
|
||||
$recipient->hasField( 'type' ) &&
|
||||
in_array( $recipient['type'], array( 'Collection', 'OrderedCollection') ) &&
|
||||
Util::isLocalUri( $recipient['id'] )
|
||||
) {
|
||||
$forwardingTargets = array_unique( array_merge(
|
||||
$forwardingTargets, $this->resolveRecipient( $recipient )
|
||||
) );
|
||||
}
|
||||
}
|
||||
}
|
||||
if ( count( $forwardingTargets ) === 0 ) {
|
||||
$this->logger->debug(
|
||||
'No collections we own in recipients, not forwarding', array( 'activity' => $activity )
|
||||
);
|
||||
return;
|
||||
}
|
||||
// TODO recurse through inReplyTo, object, target, and tags looking for object we own
|
||||
}
|
||||
|
||||
public function deliverActivity( OutboxActivityEvent $event )
|
||||
@ -169,4 +215,19 @@ class DeliveryHandler implements EventSubscriberInterface
|
||||
}
|
||||
return array();
|
||||
}
|
||||
|
||||
private function isActor( $objectId )
|
||||
{
|
||||
if ( is_array( $objectId ) && array_key_exists( 'id', $objectId ) ) {
|
||||
$objectId = $objectId['id'];
|
||||
}
|
||||
if ( ! is_string( $objectId ) ) {
|
||||
return false;
|
||||
}
|
||||
$object = $this->objectsService->dereference( $objectId );
|
||||
if ( ! $object ) {
|
||||
return false;
|
||||
}
|
||||
return $object->hasField( 'inbox' ) && $object->hasField( 'outbox' );
|
||||
}
|
||||
}
|
@ -68,13 +68,13 @@ class ObjectsService
|
||||
/**
|
||||
* Gets an object from the DB by its ActivityPub id
|
||||
*
|
||||
* For internal use only - external callers should use dereference()
|
||||
* You probably want dereference() instead of this.
|
||||
*
|
||||
* @param string $id The object's id
|
||||
* @return ActivityPubObject|null The object or null
|
||||
* if no object exists with that id
|
||||
*/
|
||||
protected function getObject( $id )
|
||||
public function getObject( $id )
|
||||
{
|
||||
$results = $this->query( array( 'id' => $id ) );
|
||||
if ( !empty( $results ) ) {
|
||||
|
Loading…
Reference in New Issue
Block a user