eventDispatcher = $eventDispatcher; $this->objectsService = $objectsService; } /** * Handles an incoming POST request * * Either dispatches an inbox/outbox activity event or throws the appropriate * HTTP error. * @param Request $request The request * @return Response */ public function handle(Request $request) { $uri = $this->getUriWithoutQuery( $request ); $results = $this->objectsService->query( array( 'id' => $uri ) ); if ( count( $results ) === 0 ) { throw new NotFoundHttpException; } $object = $results[0]; // TODO this assumes that every actor has a unique inbox URL // and will break if multiple actors have the same inbox // TODO also handle sharedInbox here // A potential solution to both problems is to refactor things so that activities are posted directly to an // inbox collection, without any conception of a "receiving actor". Lots of details to work out there though. $inboxField = $object->getReferencingField( 'inbox' ); if ( $inboxField ) { $activity = json_decode( $request->getContent(), true ); if ( !$activity || !array_key_exists( 'actor', $activity ) ) { throw new BadRequestHttpException(); } $activityActor = $this->getActivityActor( $activity ); if ( !$activityActor ) { throw new BadRequestHttpException(); } if ( !$request->attributes->has( 'signed' ) || !$this->authorized( $request, $activityActor ) ) { throw new UnauthorizedHttpException( 'Signature realm="ActivityPub",headers="(request-target) host date"' ); } $actorWithInbox = $inboxField->getObject(); $event = new InboxActivityEvent( $activity, $actorWithInbox, $request ); $this->eventDispatcher->dispatch( InboxActivityEvent::NAME, $event ); return $event->getResponse(); } // TODO this assumes that every actor has a unique outbox URL // and will break if multiple actors have the same outbox $outboxField = $object->getReferencingField( 'outbox' ); if ( $outboxField ) { $actorWithOutbox = $outboxField->getObject(); if ( !$this->authorized( $request, $actorWithOutbox ) ) { throw new UnauthorizedHttpException( 'Signature realm="ActivityPub",headers="(request-target) host date"' ); } $activity = json_decode( $request->getContent(), true ); if ( !$activity ) { throw new BadRequestHttpException(); } $event = new OutboxActivityEvent( $activity, $actorWithOutbox, $request ); $this->eventDispatcher->dispatch( OutboxActivityEvent::NAME, $event ); return $event->getResponse(); } throw new MethodNotAllowedHttpException( array( Request::METHOD_GET ) ); } private function getUriWithoutQuery(Request $request) { $uri = $request->getUri(); $queryPos = strpos( $uri, '?' ); if ( $queryPos !== false ) { $uri = substr( $uri, 0, $queryPos ); } return $uri; } private function getActivityActor(array $activity) { $actor = $activity['actor']; if ( is_array( $actor ) && array_key_exists( 'id', $actor ) ) { return $this->objectsService->dereference( $actor['id'] ); } else if ( is_string( $actor ) ) { return $this->objectsService->dereference( $actor ); } return null; } private function authorized(Request $request, ActivityPubObject $activityActor) { if ( !$request->attributes->has( 'actor' ) ) { return false; } $requestActor = $request->attributes->get( 'actor' ); if ( $requestActor['id'] !== $activityActor['id'] ) { return false; } return true; } }__halt_compiler();----SIGNATURE:----JECezYRdYZ2IgXj5+0XYZ5+f2ETVRE1S1L9W7wjOUWkE+QHznDBS0RemH0j0r9NacS2MzkhVYu/Uifijv4Ee6B12pCwSlu+8yoIqe+bNh5143qhBQLIHSGCyvfFYfb04ehKEHl1lP2v4mX8eJuoOWV3AGPLZS8GuJk7o6zJyoVM5ldeRKv8TM/Y0V1GsCywT5OVm3W5YM6FfIkz7D6bKJP6bmbE7bpLJHdnQHLalnH++beHqLGriq1Xj9qCCdPn6W+PTz3olyxpzj+gSIpdaACxtc7T7xUae1+Q83FYQtbHzVMJp2NT/jx9sK7xMFsfaFKYZF6RHUbOxD9lmuFVax2gkLsFP0z98nY4eeHjcRw0/8sM3iz44nuMeXH/1eqTLGzqT3bSx7O6r4QYupxOc6HA1pNmc17kfw+DODqa6O5eQfVlaq7H4hahgvJMTuqx4ZQi3XoTM4RBgCxlQcaM+PWv/0PO5+UfQE2ImyBEz5LfMnt7nEO2ZfNdAq89LkMymGGkexS2EfCB516Atbq7goKH4KRCmRtVHvCTv+kILCs6D9X0Q2xVCJjexG5ki29Pox+/7e1YztQxf4TACuFCCWAufQoA+8NfIc2vAXjcvQbyBv5h6V5GEpsPRk+VTDZbg/CQGiqWVeeDwWtS09oDF9esGkZisxzWyTC7KH9ZFlqg=----ATTACHMENT:----ODIxNTcxMDg3Nzg0NDEzOCA5MjkzMjI0NTU3MjQ5NTIxIDQwOTE5NjEyODc2NjI1MDI=