Require inbox requests to be signed by the activity actor

This commit is contained in:
Jeremy Dormitzer 2019-01-25 21:15:13 -05:00
parent 3c5dfa9a3d
commit feeea74aea
2 changed files with 51 additions and 18 deletions

View File

@ -51,17 +51,21 @@ class PostController
$object = $results[0];
$inboxField = $object->getReferencingField( 'inbox' );
if ( $inboxField ) {
$actorWithInbox = $inboxField->getObject();
$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, $actorWithInbox ) ) {
! $this->authorized( $request, $activityActor ) ) {
throw new UnauthorizedHttpException(
'Signature realm="ActivityPub",headers="(request-target) host date"'
);
}
$activity = json_decode( $request->getContent(), true );
if ( ! $activity ) {
throw new BadRequestHttpException();
}
$actorWithInbox = $inboxField->getObject();
$event = new InboxActivityEvent( $activity, $actorWithInbox, $request );
$this->eventDispatcher->dispatch( InboxActivityEvent::NAME, $event );
return;
@ -85,6 +89,17 @@ class PostController
throw new MethodNotAllowedHttpException( array( Request::METHOD_GET ) );
}
private function getActivityActor( array $activity )
{
xdebug_break();
$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 );
}
}
private function authorized( Request $request, ActivityPubObject $activityActor )
{
if ( ! $request->attributes->has( 'actor' ) ) {

View File

@ -31,6 +31,9 @@ class PostControllerTest extends TestCase
'id' => 'https://example.com/actor/1/outbox',
),
),
'https://elsewhere.com/actor/1' => array(
'id' => 'https://elsewhere.com/actor/1',
),
);
const REFS = array(
'https://example.com/actor/1/inbox' => array(
@ -67,34 +70,46 @@ class PostControllerTest extends TestCase
}
} )
);
$objectsService->method( 'dereference' )->will(
$this->returnCallback( function( $id ) {
if ( array_key_exists( $id, self::OBJECTS ) ) {
return TestActivityPubObject::fromArray( self::OBJECTS[$id] );
} else {
return null;
}
} )
);
$testCases = array(
array(
'id' => 'basicInboxTest',
'request' => $this->makeRequest(
'https://example.com/actor/1/inbox',
Request::METHOD_POST,
'{"type": "Create"}',
'{"type": "Create", "actor": "https://elsewhere.com/actor/1"}',
array(
'signed' => true,
'actor' => TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
self::OBJECTS['https://elsewhere.com/actor/1']
),
)
),
'expectedEventName' => InboxActivityEvent::NAME,
'expectedEvent' => new InboxActivityEvent(
array( 'type' => 'Create' ),
array(
'type' => 'Create',
'actor' => 'https://elsewhere.com/actor/1'
),
TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
),
$this->makeRequest(
'https://example.com/actor/1/inbox',
Request::METHOD_POST,
'{"type": "Create"}',
'{"type": "Create", "actor": "https://elsewhere.com/actor/1"}',
array(
'signed' => true,
'actor' => TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
self::OBJECTS['https://elsewhere.com/actor/1']
),
)
)
@ -135,10 +150,10 @@ class PostControllerTest extends TestCase
'request' => $this->makeRequest(
'https://example.com/actor/1/inbox',
Request::METHOD_POST,
'{"type": "Create"}',
'{"type": "Create", "actor": "https://elsewhere.com/actor/1"}',
array(
'actor' => TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
self::OBJECTS['https://elsewhere.com/actor/1']
),
)
),
@ -149,7 +164,7 @@ class PostControllerTest extends TestCase
'request' => $this->makeRequest(
'https://example.com/actor/1/inbox',
Request::METHOD_POST,
'{"type": "Create"}',
'{"type": "Create", "actor": "https://elsewhere.com/actor/1"}',
array()
),
'expectedException' => UnauthorizedHttpException::class,
@ -159,10 +174,11 @@ class PostControllerTest extends TestCase
'request' => $this->makeRequest(
'https://example.com/actor/notreal/inbox',
Request::METHOD_POST,
'{"type": "Create"}',
'{"type": "Create", "actor": "https://elsewhere.com/actor/1"}',
array(
'signed' => true,
'actor' => TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
self::OBJECTS['https://elsewhere.com/actor/1']
),
)
),
@ -175,8 +191,9 @@ class PostControllerTest extends TestCase
Request::METHOD_POST,
'',
array(
'signed' => true,
'actor' => TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
self::OBJECTS['https://elsewhere.com/actor/1']
),
)
),
@ -189,8 +206,9 @@ class PostControllerTest extends TestCase
Request::METHOD_POST,
'this is not JSON',
array(
'signed' => 'true',
'actor' => TestActivityPubObject::fromArray(
self::OBJECTS['https://example.com/actor/1']
self::OBJECTS['https://elsewhere.com/actor/1']
),
)
),