Add a global prefix to generated ids

This commit is contained in:
Jeremy Dormitzer 2019-01-28 09:41:18 -05:00
parent a36e44df58
commit a5796f9e62
5 changed files with 86 additions and 21 deletions

View File

@ -34,6 +34,11 @@ class ActivityPubConfig
*/ */
private $jsonLdContext; private $jsonLdContext;
/**
* @var string
*/
private $idPathPrefix;
/** /**
* Don't call this directly - instead, use * Don't call this directly - instead, use
* ActivityPubConfig->createBuilder()->build() * ActivityPubConfig->createBuilder()->build()
@ -47,6 +52,7 @@ class ActivityPubConfig
$this->dbPrefix = $builder->getDbPrefix(); $this->dbPrefix = $builder->getDbPrefix();
$this->authFunction = $builder->getAuthFunction(); $this->authFunction = $builder->getAuthFunction();
$this->jsonLdContext = $builder->getJsonLdContext(); $this->jsonLdContext = $builder->getJsonLdContext();
$this->idPathPrefix = $builder->getIdPathPrefix();
} }
public function createBuilder() public function createBuilder()
@ -55,7 +61,7 @@ class ActivityPubConfig
} }
/** /**
* @var array * @return array
*/ */
public function getDbConnectionParams() public function getDbConnectionParams()
{ {
@ -63,7 +69,7 @@ class ActivityPubConfig
} }
/** /**
* @var bool * @return bool
*/ */
public function getIsDevMode() public function getIsDevMode()
{ {
@ -71,7 +77,7 @@ class ActivityPubConfig
} }
/** /**
* @var string * @return string
*/ */
public function getDbPrefix() public function getDbPrefix()
{ {
@ -80,7 +86,7 @@ class ActivityPubConfig
} }
/** /**
* @var Callable * @return Callable
*/ */
public function getAuthFunction() public function getAuthFunction()
{ {
@ -88,11 +94,19 @@ class ActivityPubConfig
} }
/** /**
* @var array * @return array
*/ */
public function getJsonLdContext() public function getJsonLdContext()
{ {
return $this->jsonLdContext; return $this->jsonLdContext;
} }
/**
* @return string
*/
public function getIdPathPrefix()
{
return $this->idPathPrefix;
}
} }
?> ?>

View File

@ -3,6 +3,7 @@ namespace ActivityPub\Config;
use ActivityPub\Config\ActivityPubConfig; use ActivityPub\Config\ActivityPubConfig;
use ActivityPub\Objects\ContextProvider; use ActivityPub\Objects\ContextProvider;
use ActivityPub\Objects\IdProvider;
/** /**
* The ActivityPubConfigBuilder is a builder class to create ActivityPub config data * The ActivityPubConfigBuilder is a builder class to create ActivityPub config data
@ -19,6 +20,8 @@ use ActivityPub\Objects\ContextProvider;
*/ */
class ActivityPubConfigBuilder class ActivityPubConfigBuilder
{ {
const DEFAULT_ID_PATH_PREFIX = 'ap';
/** /**
* @var array * @var array
*/ */
@ -44,6 +47,11 @@ class ActivityPubConfigBuilder
*/ */
private $jsonLdContext; private $jsonLdContext;
/**
* @var string
*/
private $idPathPrefix;
/** /**
* Creates a new ActivityPubConfig instance with default values * Creates a new ActivityPubConfig instance with default values
* *
@ -57,6 +65,7 @@ class ActivityPubConfigBuilder
return false; return false;
}; };
$this->jsonLDContext = ContextProvider::DEFAULT_CONTEXT; $this->jsonLDContext = ContextProvider::DEFAULT_CONTEXT;
$this->idPathPrefix = IdProvider::DEFAULT_ID_PATH_PREFIX;
} }
/** /**
@ -191,9 +200,35 @@ class ActivityPubConfigBuilder
return $this; return $this;
} }
/**
* @return array
*/
public function getJsonLdContext() public function getJsonLdContext()
{ {
return $this->jsonLdContext; return $this->jsonLdContext;
} }
/**
* The `idPathPrefix` is a string that is prepended to all ids generated by
* by the ActivityPub library. For example, if the `idPathPrefix` is 'ap',
* the library will generate ids that look like 'https://example.com/ap/note/1'.
*
* Default: 'ap'
* @param string $idPathPrefix The id path prefix
* @return ActivityPubConfigBuilder The builder instance
*/
public function setIdPathPrefix( string $idPathPrefix )
{
$this->idPathPrefix = $idPathPrefix;
return $this;
}
/**
* @return string
*/
public function getIdPathPrefix()
{
return $this->idPathPrefix;
}
} }
?> ?>

View File

@ -88,7 +88,8 @@ class ActivityPubModule
$this->injector->register( IdProvider::class, IdProvider::class ) $this->injector->register( IdProvider::class, IdProvider::class )
->addArgument( new Reference( ObjectsService::class ) ) ->addArgument( new Reference( ObjectsService::class ) )
->addArgument( new Reference( RandomProvider::class ) ); ->addArgument( new Reference( RandomProvider::class ) )
->addArgument( $config->getIdPathPrefix() );
$this->injector->register( GetController::class, GetController::class ) $this->injector->register( GetController::class, GetController::class )
->addArgument( new Reference( ObjectsService::class ) ) ->addArgument( new Reference( ObjectsService::class ) )

View File

@ -10,6 +10,7 @@ use Symfony\Component\HttpFoundation\Request;
*/ */
class IdProvider class IdProvider
{ {
const DEFAULT_ID_PATH_PREFIX = 'ap';
const ID_LENGTH = 12; const ID_LENGTH = 12;
/** /**
@ -22,10 +23,21 @@ class IdProvider
*/ */
private $randomProvider; private $randomProvider;
public function __construct( ObjectsService $objectsService, RandomProvider $randomProvider ) /**
* $pathPrefix gets prepended to all generated id paths
*
* It should not have a leading or a trailing slash.
* @var string
*/
private $pathPrefix;
public function __construct( ObjectsService $objectsService,
RandomProvider $randomProvider,
string $pathPrefix )
{ {
$this->objectsService = $objectsService; $this->objectsService = $objectsService;
$this->randomProvider = $randomProvider; $this->randomProvider = $randomProvider;
$this->pathPrefix = $pathPrefix;
} }
/** /**
@ -34,14 +46,14 @@ class IdProvider
* Ids look like "https://$host/$path/$randomString" * Ids look like "https://$host/$path/$randomString"
* @param Request $request The current request * @param Request $request The current request
* @param string $path The path for the the id URL, just before the random string * @param string $path The path for the the id URL, just before the random string
* Default: "object" * and after the path prefix. Default: "object"
* @return string The new id * @return string The new id
*/ */
public function getId( Request $request, string $path = "objects" ) public function getId( Request $request, string $path = "objects" )
{ {
$baseUri = $request->getSchemeAndHttpHost(); $baseUri = $request->getSchemeAndHttpHost();
if ( ! empty( $path ) ) { if ( ! empty( $path ) ) {
$baseUri = $baseUri . "/$path"; $baseUri = $baseUri . "/{$this->pathPrefix}/$path";
} }
$rnd = $this->randomProvider->randomString( self::ID_LENGTH ); $rnd = $this->randomProvider->randomString( self::ID_LENGTH );
$id = $baseUri . "/$rnd"; $id = $baseUri . "/$rnd";

View File

@ -16,14 +16,17 @@ class IdProviderTest extends TestCase
public function setUp() public function setUp()
{ {
$this->objectsService = $this->createMock( ObjectsService::class ); $this->objectsService = $this->createMock( ObjectsService::class );
$this->objectsService->method( 'query' )->will( $this->returnCallback( function( $query) { $this->objectsService->method( 'query' )
$existsId = sprintf( 'https://example.com/objects/%s', self::EXISTING_ID_STR ); ->will( $this->returnCallback( function( $query) {
if ( array_key_exists( 'id', $query ) && $query['id'] == $existsId ) { $existsId = sprintf(
return array( 'existingObject' ); 'https://example.com/ap/objects/%s', self::EXISTING_ID_STR
} else { );
return array(); if ( array_key_exists( 'id', $query ) && $query['id'] == $existsId ) {
} return array( 'existingObject' );
} ) ); } else {
return array();
}
} ) );
} }
public function testIdProvider() public function testIdProvider()
@ -32,18 +35,18 @@ class IdProviderTest extends TestCase
array( array(
'id' => 'providesId', 'id' => 'providesId',
'providedRnd' => array( 'foo' ), 'providedRnd' => array( 'foo' ),
'expectedId' => 'https://example.com/objects/foo', 'expectedId' => 'https://example.com/ap/objects/foo',
), ),
array( array(
'id' => 'checksForExisting', 'id' => 'checksForExisting',
'providedRnd' => array( self::EXISTING_ID_STR, 'bar' ), 'providedRnd' => array( self::EXISTING_ID_STR, 'bar' ),
'expectedId' => 'https://example.com/objects/bar', 'expectedId' => 'https://example.com/ap/objects/bar',
), ),
array( array(
'id' => 'addsPath', 'id' => 'addsPath',
'providedRnd' => array( 'foo' ), 'providedRnd' => array( 'foo' ),
'path' => 'notes', 'path' => 'notes',
'expectedId' => 'https://example.com/notes/foo', 'expectedId' => 'https://example.com/ap/notes/foo',
), ),
); );
foreach ( $testCases as $testCase ) { foreach ( $testCases as $testCase ) {
@ -52,7 +55,7 @@ class IdProviderTest extends TestCase
array( $randomProvider->method( 'randomString' ), 'willReturnOnConsecutiveCalls' ), array( $randomProvider->method( 'randomString' ), 'willReturnOnConsecutiveCalls' ),
$testCase['providedRnd'] $testCase['providedRnd']
); );
$idProvider = new IdProvider( $this->objectsService, $randomProvider ); $idProvider = new IdProvider( $this->objectsService, $randomProvider, 'ap' );
$request = Request::create( 'https://example.com' ); $request = Request::create( 'https://example.com' );
$id = ''; $id = '';
if ( array_key_exists( 'path', $testCase ) ) { if ( array_key_exists( 'path', $testCase ) ) {