Implement and test AuthListener
This commit is contained in:
parent
887ac185ca
commit
88dd8a7b8f
@ -46,8 +46,8 @@ class ActivityPub
|
||||
}
|
||||
|
||||
$dispatcher = new EventDispatcher();
|
||||
$signatureListener = $this->module->get( 'signatureListener' );
|
||||
$dispatcher->addSubscriber( $signatureListener );
|
||||
$dispatcher->addSubscriber( $this->module->get( 'authListener' ) );
|
||||
$dispatcher->addSubscriber( $this->module->get( 'signatureListener' ) );
|
||||
$dispatcher->addSubscriber( new ExceptionListener() );
|
||||
|
||||
$controllerResolver = new ControllerResolver();
|
||||
|
55
src/Auth/AuthListener.php
Normal file
55
src/Auth/AuthListener.php
Normal file
@ -0,0 +1,55 @@
|
||||
<?php
|
||||
namespace ActivityPub\Auth;
|
||||
|
||||
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
|
||||
use Symfony\Component\HttpKernel\KernelEvents;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
|
||||
/**
|
||||
* The AuthListener class answers the question, "is this request authorized
|
||||
* to act on behalf of this Actor?"
|
||||
*
|
||||
* It delegates most of the work to a passed-in Callable to allow library clients to
|
||||
* plug in their own authentication methods.
|
||||
*/
|
||||
class AuthListener implements EventSubscriberInterface
|
||||
{
|
||||
/**
|
||||
* The Callable that is called to determine if a request is authorized for an Actor
|
||||
*
|
||||
* @var Callable
|
||||
*
|
||||
*/
|
||||
private $authFunction;
|
||||
|
||||
public static function getSubscribedEvents()
|
||||
{
|
||||
return array(
|
||||
KernelEvents::REQUEST => 'checkAuth'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new AuthenticationService
|
||||
*
|
||||
* @param Callable $authFunction A Callable that should accept
|
||||
*
|
||||
*/
|
||||
public function __construct( Callable $authFunction )
|
||||
{
|
||||
$this->authFunction = $authFunction;
|
||||
}
|
||||
|
||||
public function checkAuth( GetResponseEvent $event )
|
||||
{
|
||||
$request = $event->getRequest();
|
||||
if ( $request->attributes->has( 'actor' ) ) {
|
||||
return;
|
||||
}
|
||||
$actorId = call_user_func( $this->authFunction );
|
||||
if ( $actorId && ! empty( $actorId ) ) {
|
||||
$request->attributes->set( 'actor', $actorId );
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,32 +0,0 @@
|
||||
<?php
|
||||
namespace ActivityPub\Auth;
|
||||
|
||||
/**
|
||||
* The AuthenticationService class answers the question, "is this request authenticated
|
||||
* to act on behalf of this Actor?"
|
||||
*
|
||||
* It delegates most of the work to a passed-in Callable to allow library clients to
|
||||
* plug in their own authentication methods.
|
||||
*/
|
||||
class AuthenticationService
|
||||
{
|
||||
/**
|
||||
* The Callable that is called to determine if a request is authorized for an Actor
|
||||
*
|
||||
* @var Callable
|
||||
*
|
||||
*/
|
||||
private $authFunction;
|
||||
|
||||
/**
|
||||
* Constructs a new AuthenticationService
|
||||
*
|
||||
* @param Callable $authFunction A Callable that should accept
|
||||
*
|
||||
*/
|
||||
public function __construct( Callable $authFunction )
|
||||
{
|
||||
$this->authFunction = $authFunction;
|
||||
}
|
||||
}
|
||||
?>
|
@ -1,6 +1,8 @@
|
||||
<?php
|
||||
namespace ActivityPub\Config;
|
||||
|
||||
use ActivityPub\Auth\AuthListener;
|
||||
use ActivityPub\Auth\SignatureListener;
|
||||
use ActivityPub\Crypto\HttpSignatureService;
|
||||
use ActivityPub\Database\PrefixNamingStrategy;
|
||||
use ActivityPub\Objects\ObjectsService;
|
||||
@ -26,6 +28,9 @@ class ActivityPubModule
|
||||
$defaults = array(
|
||||
'isDevMode' => false,
|
||||
'dbPrefix' => '',
|
||||
'authFunction' => function() {
|
||||
return false;
|
||||
},
|
||||
);
|
||||
$options = array_merge( $defaults, $options );
|
||||
$this->validateOptions( $options );
|
||||
@ -59,6 +64,9 @@ class ActivityPubModule
|
||||
$this->injector->register( 'signatureListener', SignatureListener::class )
|
||||
->addArgument( new Reference( 'httpSignatureService' ) )
|
||||
->addArgument( new Reference( 'objectsService' ) );
|
||||
|
||||
$this->injector->register( 'authListener', AuthListener::class )
|
||||
->addArgument( $options['authFunction'] );
|
||||
}
|
||||
|
||||
/**
|
||||
|
71
test/Auth/AuthListenerTest.php
Normal file
71
test/Auth/AuthListenerTest.php
Normal file
@ -0,0 +1,71 @@
|
||||
<?php
|
||||
namespace ActivityPub\Test\Auth;
|
||||
|
||||
use ActivityPub\Auth\AuthListener;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\HttpKernel\HttpKernelInterface;
|
||||
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
|
||||
class AuthListenerTest extends TestCase
|
||||
{
|
||||
|
||||
public function getEvent()
|
||||
{
|
||||
$kernel = $this->createMock( HttpKernelInterface::class );
|
||||
$request = Request::create( 'https://example.com/foo', Request::METHOD_GET );
|
||||
return new GetResponseEvent(
|
||||
$kernel, $request, HttpKernelInterface::MASTER_REQUEST
|
||||
);
|
||||
}
|
||||
|
||||
public function testAuthListener()
|
||||
{
|
||||
$testCases = array(
|
||||
array(
|
||||
'id' => 'basicTest',
|
||||
'authFunction' => function() {
|
||||
return 'https://example.com/actor/1';
|
||||
},
|
||||
'expectedAttributes' => array(
|
||||
'actor' => 'https://example.com/actor/1',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'id' => 'existingActorTest',
|
||||
'authFunction' => function() {
|
||||
return 'https://example.com/actor/1';
|
||||
},
|
||||
'requestAttributes' => array(
|
||||
'actor' => 'https://example.com/actor/2',
|
||||
),
|
||||
'expectedAttributes' => array(
|
||||
'actor' => 'https://example.com/actor/2',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'id' => 'defaultAuthTest',
|
||||
'authFunction' => function() {
|
||||
return false;
|
||||
},
|
||||
'expectedAttributes' => array(),
|
||||
),
|
||||
);
|
||||
foreach ( $testCases as $testCase ) {
|
||||
$event = $this->getEvent();
|
||||
if ( array_key_exists( 'requestAttributes', $testCase ) ) {
|
||||
foreach ( $testCase['requestAttributes'] as $attribute => $value ) {
|
||||
$event->getRequest()->attributes->set( $attribute, $value );
|
||||
}
|
||||
}
|
||||
$authListener = new AuthListener( $testCase['authFunction'] );
|
||||
$authListener->checkAuth( $event );
|
||||
$this->assertEquals(
|
||||
$testCase['expectedAttributes'],
|
||||
$event->getRequest()->attributes->all(),
|
||||
"Error on test $testCase[id]"
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
Loading…
Reference in New Issue
Block a user