From 125c38db3c281adb89871de2ea2259ad342d8aee Mon Sep 17 00:00:00 2001 From: Jeremy Dormitzer Date: Sat, 23 Mar 2019 12:57:51 -0400 Subject: [PATCH] [WIP] Implement and test filtering out blocked actors from inboxes --- src/Controllers/GetController.php | 14 +- src/Objects/BlockService.php | 29 +++- test/Controllers/GetControllerTest.php | 10 +- test/Objects/BlockServiceTest.php | 178 +++++++++++++++++++++++- test/Objects/CollectionsServiceTest.php | 15 +- 5 files changed, 229 insertions(+), 17 deletions(-) diff --git a/src/Controllers/GetController.php b/src/Controllers/GetController.php index bc32220..3188b06 100644 --- a/src/Controllers/GetController.php +++ b/src/Controllers/GetController.php @@ -76,10 +76,10 @@ class GetController ( $object['type'] === 'Collection' || $object['type'] === 'OrderedCollection' ) ) { if ( $object->hasReferencingField( 'inbox' ) ) { - // TODO figure out what to pass in here - $blockedActorIds = $this->blockService->getBlockedActorIds(); + $inboxActor = $object->getReferencingField( 'inbox' )->getObject(); + $blockedActorIds = $this->blockService->getBlockedActorIds( $inboxActor['id'] ); $filterFunc = function ( ActivityPubObject $item ) use ( $request, $blockedActorIds ) { - $authorized = $this->authService->isAuthorized( $request, $item ); + $shouldShow = $this->authService->isAuthorized( $request, $item ); foreach ( array( 'actor', 'attributedTo' ) as $actorField ) { if ( $item->hasField( $actorField ) ) { $actorFieldValue = $item->getFieldValue( $actorField ); @@ -88,17 +88,17 @@ class GetController } if ( is_string( $actorFieldValue && in_array( $actorFieldValue, $blockedActorIds ) ) ) { - $authorized = false; + $shouldShow = false; break; } else if ( $actorFieldValue instanceof ActivityPubObject && in_array( $actorFieldValue['id'], $blockedActorIds ) ) { - $authorized = false; + $shouldShow = false; break; } } } - return $authorized; - } + return $shouldShow; + }; } else { $filterFunc = function ( ActivityPubObject $item ) use ( $request ) { return $this->authService->isAuthorized( $request, $item ); diff --git a/src/Objects/BlockService.php b/src/Objects/BlockService.php index dcd791d..d810020 100644 --- a/src/Objects/BlockService.php +++ b/src/Objects/BlockService.php @@ -14,8 +14,33 @@ class BlockService $this->objectsService = $objectsService; } - public function getBlockedActorIds() + /** + * Returns an array of actorIds that are the object of a block activity + * by $blockingActorId + * + * @param string $blockingActorId + * @return array + */ + public function getBlockedActorIds( $blockingActorId ) { - // TODO implement me + $q = array( + 'type' => 'Block', + 'actor' => array( + 'id' => $blockingActorId, + ), + ); + $blocks = $this->objectsService->query( $q ); + $blockedIds = array(); + foreach ( $blocks as $block ) { + if ( $block->hasField( 'object' ) ) { + $blockedActor = $block['object']; + if ( is_string( $blockedActor ) ) { + $blockedIds[] = $blockedActor; + } else { + $blockedIds[] = $blockedActor['id']; + } + } + } + return $blockedIds; } } \ No newline at end of file diff --git a/test/Controllers/GetControllerTest.php b/test/Controllers/GetControllerTest.php index e81813e..4c10590 100644 --- a/test/Controllers/GetControllerTest.php +++ b/test/Controllers/GetControllerTest.php @@ -4,6 +4,7 @@ namespace ActivityPub\Test\Controllers; use ActivityPub\Auth\AuthService; use ActivityPub\Controllers\GetController; +use ActivityPub\Objects\BlockService; use ActivityPub\Objects\CollectionsService; use ActivityPub\Objects\ContextProvider; use ActivityPub\Objects\ObjectsService; @@ -51,8 +52,9 @@ class GetControllerTest extends APTestCase $this->getMock( EntityManager::class ), $objectsService ); + $blockService = $this->getMock( BlockService::class ); $this->getController = new GetController( - $objectsService, $collectionsService, $authService + $objectsService, $collectionsService, $authService, $blockService ); } @@ -186,5 +188,11 @@ class GetControllerTest extends APTestCase $this->assertEquals( 'application/json', $response->headers->get( 'Content-Type' ) ); $this->assertEquals( 410, $response->getStatusCode() ); } + + public function testItFiltersInboxForBlockedActors() + { + // TODO implement me + $this->assertTrue( false ); + } } diff --git a/test/Objects/BlockServiceTest.php b/test/Objects/BlockServiceTest.php index 2e3dd74..2ea59fe 100644 --- a/test/Objects/BlockServiceTest.php +++ b/test/Objects/BlockServiceTest.php @@ -2,13 +2,183 @@ namespace ActivityPub\Test\Objects; -use ActivityPub\Test\TestConfig\APTestCase; +use ActivityPub\Database\PrefixNamingStrategy; +use ActivityPub\Objects\BlockService; +use ActivityPub\Objects\ObjectsService; +use ActivityPub\Test\TestConfig\ArrayDataSet; +use ActivityPub\Test\TestConfig\SQLiteTestCase; +use ActivityPub\Test\TestUtils\TestDateTimeProvider; +use DateTime; +use Doctrine\ORM\EntityManager; +use Doctrine\ORM\Tools\Setup; +use GuzzleHttp\Client; +use GuzzleHttp\Psr7\Response; +use PHPUnit_Extensions_Database_DataSet_IDataSet; -class BlockServiceTest extends APTestCase +class BlockServiceTest extends SQLiteTestCase { + /** + * @var ObjectsService + */ + private $objectsService; + + /** + * @var BlockService + */ + private $blockService; + + protected function setUp() + { + parent::setUp(); + $dbConfig = Setup::createAnnotationMetadataConfiguration( + array( __DIR__ . '/../../src/Entities' ), true + ); + $namingStrategy = new PrefixNamingStrategy( '' ); + $dbConfig->setNamingStrategy( $namingStrategy ); + $dbParams = array( + 'driver' => 'pdo_sqlite', + 'path' => self::getDbPath(), + ); + $entityManager = EntityManager::create( $dbParams, $dbConfig ); + $dateTimeProvider = new TestDateTimeProvider( array( + 'objects-service.create' => new DateTime( "12:00" ), + 'objects-service.update' => new DateTime( "12:01" ), + ) ); + $httpClient = $this->getMock( Client::class ); + $httpClient->method( 'send' )->willReturn( new Response( 404 ) ); + $this->objectsService = new ObjectsService( $entityManager, $dateTimeProvider, $httpClient ); + $this->blockService = new BlockService( $this->objectsService ); + } + public function testGetBlockedActorIds() { - // TODO implement me - $this->assertTrue( false ); + $testCases = array( + array( + 'id' => 'blocksExist', + 'initialData' => array( + array( + 'id' => 'https://example.com/blocks/1', + 'type' => 'Block', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/1', + ), + ), + ), + 'blockingActorId' => 'https://example.com/actors/1', + 'expectedBlockedActorIds' => array( 'https://elsewhere.com/actors/1' ), + ), + array( + 'id' => 'noBlocksExist', + 'blockingActorId' => 'https://example.com/actors/1', + 'expectedBlockedActorIds' => array(), + ), + array( + 'id' => 'multipleBlocksExist', + 'initialData' => array( + array( + 'id' => 'https://example.com/blocks/1', + 'type' => 'Block', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/1', + ), + ), + array( + 'id' => 'https://example.com/blocks/2', + 'type' => 'Block', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/2', + ), + ), + ), + 'blockingActorId' => 'https://example.com/actors/1', + 'expectedBlockedActorIds' => array( 'https://elsewhere.com/actors/1', 'https://elsewhere.com/actors/2' ), + ), + array( + 'id' => 'blocksExistsFromDifferentActor', + 'initialData' => array( + array( + 'id' => 'https://example.com/blocks/1', + 'type' => 'Block', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/1', + ), + ), + array( + 'id' => 'https://example.com/blocks/2', + 'type' => 'Block', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/2', + ), + ), + ), + 'blockingActorId' => 'https://example.com/actors/2', + 'expectedBlockedActorIds' => array(), + ), + array( + 'id' => 'differentTypesOfActivitiesExistWithSameObjectAndActor', + 'initialData' => array( + array( + 'id' => 'https://example.com/follows/1', + 'type' => 'Follow', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/1', + ), + ), + array( + 'id' => 'https://example.com/blocks/1', + 'type' => 'Block', + 'actor' => array( + 'id' => 'https://example.com/actors/1', + ), + 'object' => array( + 'id' => 'https://elsewhere.com/actors/2', + ), + ), + ), + 'blockingActorId' => 'https://example.com/actors/1', + 'expectedBlockedActorIds' => array( 'https://elsewhere.com/actors/2' ), + ), + ); + foreach ( $testCases as $testCase ) { + self::setUp(); + if ( array_key_exists( 'initialData', $testCase ) ) { + foreach ( $testCase['initialData'] as $object ) { + $this->objectsService->persist( $object ); + } + } + $blockedActorIds = $this->blockService->getBlockedActorIds( $testCase['blockingActorId'] ); + $this->assertEquals( + $testCase['expectedBlockedActorIds'], $blockedActorIds, "Error on test $testCase[id]" + ); + self::tearDown(); + } + } + + /** + * Returns the test dataset. + * + * @return PHPUnit_Extensions_Database_DataSet_IDataSet + */ + protected function getDataSet() + { + return new ArrayDataSet( array() ); } } \ No newline at end of file diff --git a/test/Objects/CollectionsServiceTest.php b/test/Objects/CollectionsServiceTest.php index 5d9b289..a5c8dca 100644 --- a/test/Objects/CollectionsServiceTest.php +++ b/test/Objects/CollectionsServiceTest.php @@ -3,6 +3,7 @@ namespace ActivityPub\Test\Objects; use ActivityPub\Auth\AuthService; +use ActivityPub\Entities\ActivityPubObject; use ActivityPub\Objects\CollectionsService; use ActivityPub\Objects\ContextProvider; use ActivityPub\Objects\ObjectsService; @@ -22,9 +23,14 @@ class CollectionsServiceTest extends APTestCase */ private $collectionsService; + /** + * @var AuthService + */ + private $authService; + public function setUp() { - $authService = new AuthService(); + $this->authService = new AuthService(); $contextProvider = new ContextProvider(); $httpClient = $this->getMock( Client::class ); $httpClient->method( 'send' )->willReturn( @@ -40,7 +46,7 @@ class CollectionsServiceTest extends APTestCase $objectsService = $this->getMock( ObjectsService::class ); $this->collectionsService = new CollectionsService( 4, - $authService, + $this->authService, $contextProvider, $httpClient, new SimpleDateTimeProvider(), @@ -397,7 +403,10 @@ class CollectionsServiceTest extends APTestCase } $actual = $this->collectionsService->pageAndFilterCollection( $testCase['request'], - TestActivityPubObject::fromArray( $testCase['collection'] ) + TestActivityPubObject::fromArray( $testCase['collection'] ), + function( ActivityPubObject $item ) use ( $testCase ) { + return $this->authService->isAuthorized( $testCase['request'], $item ); + } ); $this->assertEquals( $testCase['expectedResult'], $actual, "Error on test $testCase[id]"