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 )
|
public function persistActivityToInbox( InboxActivityEvent $event )
|
||||||
{
|
{
|
||||||
$activity = $event->getActivity();
|
$activity = $event->getActivity();
|
||||||
|
if ( ! $this->objectsService->getObject( $activity['id'] ) ) {
|
||||||
|
$event->getRequest()->attributes->set( 'firstTimeSeen', true );
|
||||||
|
}
|
||||||
$receivingActor = $event->getReceivingActor();
|
$receivingActor = $event->getReceivingActor();
|
||||||
if ( $receivingActor->hasField( 'inbox' ) ) {
|
if ( $receivingActor->hasField( 'inbox' ) ) {
|
||||||
$this->collectionsService->addItem( $receivingActor['inbox'], $activity );
|
$this->collectionsService->addItem( $receivingActor['inbox'], $activity );
|
||||||
|
@ -7,6 +7,7 @@ use ActivityPub\Entities\ActivityPubObject;
|
|||||||
use ActivityPub\Objects\CollectionIterator;
|
use ActivityPub\Objects\CollectionIterator;
|
||||||
use ActivityPub\Objects\ObjectsService;
|
use ActivityPub\Objects\ObjectsService;
|
||||||
use ActivityPub\Utils\DateTimeProvider;
|
use ActivityPub\Utils\DateTimeProvider;
|
||||||
|
use ActivityPub\Utils\Util;
|
||||||
use GuzzleHttp\Client;
|
use GuzzleHttp\Client;
|
||||||
use GuzzleHttp\Psr7\Request;
|
use GuzzleHttp\Psr7\Request;
|
||||||
use Psr\Log\LoggerInterface;
|
use Psr\Log\LoggerInterface;
|
||||||
@ -62,7 +63,52 @@ class DeliveryHandler implements EventSubscriberInterface
|
|||||||
|
|
||||||
public function handleInboxForwarding( InboxActivityEvent $event )
|
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 )
|
public function deliverActivity( OutboxActivityEvent $event )
|
||||||
@ -169,4 +215,19 @@ class DeliveryHandler implements EventSubscriberInterface
|
|||||||
}
|
}
|
||||||
return array();
|
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
|
* 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
|
* @param string $id The object's id
|
||||||
* @return ActivityPubObject|null The object or null
|
* @return ActivityPubObject|null The object or null
|
||||||
* if no object exists with that id
|
* if no object exists with that id
|
||||||
*/
|
*/
|
||||||
protected function getObject( $id )
|
public function getObject( $id )
|
||||||
{
|
{
|
||||||
$results = $this->query( array( 'id' => $id ) );
|
$results = $this->query( array( 'id' => $id ) );
|
||||||
if ( !empty( $results ) ) {
|
if ( !empty( $results ) ) {
|
||||||
|
Loading…
Reference in New Issue
Block a user