[WIP] Begin implementing block filtering

This commit is contained in:
Jeremy Dormitzer 2019-03-21 23:20:47 -04:00
parent fac4c01f6f
commit 9c7eb01edc
5 changed files with 93 additions and 8 deletions

View File

@ -20,6 +20,7 @@ use ActivityPub\Controllers\PostController;
use ActivityPub\Crypto\HttpSignatureService; use ActivityPub\Crypto\HttpSignatureService;
use ActivityPub\Database\PrefixNamingStrategy; use ActivityPub\Database\PrefixNamingStrategy;
use ActivityPub\Http\Router; use ActivityPub\Http\Router;
use ActivityPub\Objects\BlockService;
use ActivityPub\Objects\CollectionsService; use ActivityPub\Objects\CollectionsService;
use ActivityPub\Objects\ContextProvider; use ActivityPub\Objects\ContextProvider;
use ActivityPub\Objects\IdProvider; use ActivityPub\Objects\IdProvider;
@ -108,10 +109,14 @@ class ActivityPubModule
->addArgument( new Reference( RandomProvider::class ) ) ->addArgument( new Reference( RandomProvider::class ) )
->addArgument( $config->getIdPathPrefix() ); ->addArgument( $config->getIdPathPrefix() );
$this->injector->register( BlockService::class, BlockService::class )
->addArgument( new Reference( ObjectsService::class ) );
$this->injector->register( GetController::class, GetController::class ) $this->injector->register( GetController::class, GetController::class )
->addArgument( new Reference( ObjectsService::class ) ) ->addArgument( new Reference( ObjectsService::class ) )
->addArgument( new Reference( CollectionsService::class ) ) ->addArgument( new Reference( CollectionsService::class ) )
->addArgument( new Reference( AuthService::class ) ); ->addArgument( new Reference( AuthService::class ) )
->addArgument( new Reference( BlockService::class ) );
$this->injector->register( PostController::class, PostController::class ) $this->injector->register( PostController::class, PostController::class )
->addArgument( new Reference( EventDispatcher::class ) ) ->addArgument( new Reference( EventDispatcher::class ) )

View File

@ -3,6 +3,8 @@
namespace ActivityPub\Controllers; namespace ActivityPub\Controllers;
use ActivityPub\Auth\AuthService; use ActivityPub\Auth\AuthService;
use ActivityPub\Entities\ActivityPubObject;
use ActivityPub\Objects\BlockService;
use ActivityPub\Objects\CollectionsService; use ActivityPub\Objects\CollectionsService;
use ActivityPub\Objects\ObjectsService; use ActivityPub\Objects\ObjectsService;
use Symfony\Component\HttpFoundation\JsonResponse; use Symfony\Component\HttpFoundation\JsonResponse;
@ -32,13 +34,20 @@ class GetController
*/ */
private $authService; private $authService;
/**
* @var BlockService
*/
private $blockService;
public function __construct( ObjectsService $objectsService, public function __construct( ObjectsService $objectsService,
CollectionsService $collectionsService, CollectionsService $collectionsService,
AuthService $authService ) AuthService $authService,
BlockService $blockService )
{ {
$this->objectsService = $objectsService; $this->objectsService = $objectsService;
$this->collectionsService = $collectionsService; $this->collectionsService = $collectionsService;
$this->authService = $authService; $this->authService = $authService;
$this->blockService = $blockService;
} }
/** /**
@ -66,7 +75,37 @@ class GetController
if ( $object->hasField( 'type' ) && if ( $object->hasField( 'type' ) &&
( $object['type'] === 'Collection' || ( $object['type'] === 'Collection' ||
$object['type'] === 'OrderedCollection' ) ) { $object['type'] === 'OrderedCollection' ) ) {
$pagedCollection = $this->collectionsService->pageAndFilterCollection( $request, $object ); if ( $object->hasReferencingField( 'inbox' ) ) {
// TODO figure out what to pass in here
$blockedActorIds = $this->blockService->getBlockedActorIds();
$filterFunc = function ( ActivityPubObject $item ) use ( $request, $blockedActorIds ) {
$authorized = $this->authService->isAuthorized( $request, $item );
foreach ( array( 'actor', 'attributedTo' ) as $actorField ) {
if ( $item->hasField( $actorField ) ) {
$actorFieldValue = $item->getFieldValue( $actorField );
if ( ! $actorFieldValue ) {
continue;
}
if ( is_string( $actorFieldValue &&
in_array( $actorFieldValue, $blockedActorIds ) ) ) {
$authorized = false;
break;
} else if ( $actorFieldValue instanceof ActivityPubObject &&
in_array( $actorFieldValue['id'], $blockedActorIds ) ) {
$authorized = false;
break;
}
}
}
return $authorized;
}
} else {
$filterFunc = function ( ActivityPubObject $item ) use ( $request ) {
return $this->authService->isAuthorized( $request, $item );
};
}
$pagedCollection = $this->collectionsService->pageAndFilterCollection( $request, $object, $filterFunc );
return new JsonResponse( $pagedCollection ); return new JsonResponse( $pagedCollection );
} }
$response = new JsonResponse( $object->asArray() ); $response = new JsonResponse( $object->asArray() );

View File

@ -0,0 +1,21 @@
<?php
namespace ActivityPub\Objects;
class BlockService
{
/**
* @var ObjectsService
*/
private $objectsService;
public function __construct( ObjectsService $objectsService )
{
$this->objectsService = $objectsService;
}
public function getBlockedActorIds()
{
// TODO implement me
}
}

View File

@ -8,6 +8,7 @@ use ActivityPub\Auth\AuthService;
use ActivityPub\Entities\ActivityPubObject; use ActivityPub\Entities\ActivityPubObject;
use ActivityPub\Entities\Field; use ActivityPub\Entities\Field;
use ActivityPub\Utils\DateTimeProvider; use ActivityPub\Utils\DateTimeProvider;
use Closure;
use Doctrine\ORM\EntityManager; use Doctrine\ORM\EntityManager;
use Exception; use Exception;
use GuzzleHttp\Client; use GuzzleHttp\Client;
@ -77,14 +78,18 @@ class CollectionsService
* Returns the collection paged and filtered by the request's authorization status * Returns the collection paged and filtered by the request's authorization status
* @param Request $request * @param Request $request
* @param ActivityPubObject $collection * @param ActivityPubObject $collection
* @param Closure $filterFunc The function to filter by. Should be a closure that
* takes an ActivityPubObject and returns a boolean, where
* true means keep the item and false means filter it out
* @return array * @return array
*/ */
public function pageAndFilterCollection( Request $request, public function pageAndFilterCollection( Request $request,
ActivityPubObject $collection ) ActivityPubObject $collection,
Closure $filterFunc )
{ {
if ( $request->query->has( 'offset' ) ) { if ( $request->query->has( 'offset' ) ) {
return $this->getCollectionPage( return $this->getCollectionPage(
$collection, $request, intval( $request->query->get( 'offset' ) ), $this->pageSize $collection, $request, intval( $request->query->get( 'offset' ) ), $this->pageSize, $filterFunc
); );
} }
$colArr = array(); $colArr = array();
@ -98,7 +103,7 @@ class CollectionsService
} }
} }
$firstPage = $this->getCollectionPage( $firstPage = $this->getCollectionPage(
$collection, $request, 0, $this->pageSize $collection, $request, 0, $this->pageSize, $filterFunc
); );
$colArr['first'] = $firstPage; $colArr['first'] = $firstPage;
return $colArr; return $colArr;
@ -107,7 +112,8 @@ class CollectionsService
private function getCollectionPage( ActivityPubObject $collection, private function getCollectionPage( ActivityPubObject $collection,
Request $request, Request $request,
$offset, $offset,
$pageSize ) $pageSize,
Closure $filterFunc )
{ {
$itemsKey = 'items'; $itemsKey = 'items';
$pageType = 'CollectionPage'; $pageType = 'CollectionPage';
@ -133,7 +139,7 @@ class CollectionsService
if ( is_string( $item ) ) { if ( is_string( $item ) ) {
$pageItems[] = $item; $pageItems[] = $item;
$count++; $count++;
} else if ( $this->authService->isAuthorized( $request, $item ) ) { } else if ( call_user_func( $filterFunc, $item ) ) {
$pageItems[] = $item->asArray( 1 ); $pageItems[] = $item->asArray( 1 );
$count++; $count++;
} }

View File

@ -0,0 +1,14 @@
<?php
namespace ActivityPub\Test\Objects;
use ActivityPub\Test\TestConfig\APTestCase;
class BlockServiceTest extends APTestCase
{
public function testGetBlockedActorIds()
{
// TODO implement me
$this->assertTrue( false );
}
}