diff --git a/src/Exception/UnauthorizedException.php b/src/Exception/UnauthorizedException.php index bb042f86..524d8d0d 100644 --- a/src/Exception/UnauthorizedException.php +++ b/src/Exception/UnauthorizedException.php @@ -1,4 +1,7 @@ - * @license MIT */ -class UnauthorizedException implements UnauthorizedExceptionInterface +class UnauthorizedException extends RuntimeException implements UnauthorizedExceptionInterface { + /** @var string */ + protected $message = 'You are not authorized to access this resource'; } diff --git a/src/Exception/UnauthorizedExceptionInterface.php b/src/Exception/UnauthorizedExceptionInterface.php index b3e1f335..3d5f4374 100644 --- a/src/Exception/UnauthorizedExceptionInterface.php +++ b/src/Exception/UnauthorizedExceptionInterface.php @@ -1,4 +1,7 @@ - * @license MIT */ -interface UnauthorizedExceptionInterface extends \Lmc\Rbac\Exception\ExceptionInterface +interface UnauthorizedExceptionInterface extends ExceptionInterface { } diff --git a/src/Guard/GuardPluginManagerFactory.php b/src/Guard/GuardPluginManagerFactory.php index 7a66d491..5bd18896 100644 --- a/src/Guard/GuardPluginManagerFactory.php +++ b/src/Guard/GuardPluginManagerFactory.php @@ -36,6 +36,6 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o /** @var ModuleOptions $options */ $options = $container->get(ModuleOptions::class); - return new GuardPluginManager($container, $options->getGuards()); + return new GuardPluginManager($container, $options->getGuardManager()); } } diff --git a/src/Options/ModuleOptions.php b/src/Options/ModuleOptions.php index 2d0dbb5f..6b7f3a92 100644 --- a/src/Options/ModuleOptions.php +++ b/src/Options/ModuleOptions.php @@ -19,8 +19,8 @@ namespace Lmc\Rbac\Mvc\Options; use Lmc\Rbac\Exception; -use Lmc\Rbac\Options\ModuleOptions as BaseModuleOptions; use Lmc\Rbac\Mvc\Guard\GuardInterface; +use Lmc\Rbac\Options\ModuleOptions as BaseModuleOptions; /** * Options for LmcRbacMvc module @@ -56,6 +56,11 @@ class ModuleOptions extends BaseModuleOptions */ protected ?RedirectStrategyOptions $redirectStrategyOptions = null; + /** + * Guard Plugin Manager configuration + */ + protected array $guardManager = []; + /** * Constructor * @@ -71,7 +76,6 @@ public function __construct($options = null) * Set the guards options * * @param array $guards - * @return void */ public function setGuards(array $guards): void { @@ -91,9 +95,7 @@ public function getGuards(): array /** * Set the protection policy for guards * - * @param string $protectionPolicy - * @return void - *@throws Exception\RuntimeException + * @throws Exception\RuntimeException */ public function setProtectionPolicy(string $protectionPolicy): void { @@ -110,7 +112,6 @@ public function setProtectionPolicy(string $protectionPolicy): void /** * Get the protection policy for guards * - * @return string */ public function getProtectionPolicy(): string { @@ -186,4 +187,13 @@ public function getIdentityProvider(): string return $this->identityProvider; } + public function setGuardManager(array $config = []): void + { + $this->guardManager = $config; + } + + public function getGuardManager(): array + { + return $this->guardManager; + } } diff --git a/tests/Asset/TestGuard.php b/tests/Asset/TestGuard.php new file mode 100644 index 00000000..719704dd --- /dev/null +++ b/tests/Asset/TestGuard.php @@ -0,0 +1,19 @@ +expectException(UnauthorizedException::class); + $this->expectExceptionMessage('You are not authorized to access this resource'); + throw new UnauthorizedException(); + } + + public function testUnauthorizedExceptionMessage(): void + { + $this->expectExceptionMessage('foo'); + throw new UnauthorizedException('foo'); + } +} diff --git a/tests/Guard/GuardPluginManagerFactoryTest.php b/tests/Guard/GuardPluginManagerFactoryTest.php index dc0bd3f6..d339ee39 100644 --- a/tests/Guard/GuardPluginManagerFactoryTest.php +++ b/tests/Guard/GuardPluginManagerFactoryTest.php @@ -1,4 +1,7 @@ []]); + $moduleOptions = new ModuleOptions(); $serviceManager = new ServiceManager(); $serviceManager->setService(ModuleOptions::class, $moduleOptions); diff --git a/tests/Guard/GuardPluginManagerTest.php b/tests/Guard/GuardPluginManagerTest.php index c928a46d..0cd7ae79 100644 --- a/tests/Guard/GuardPluginManagerTest.php +++ b/tests/Guard/GuardPluginManagerTest.php @@ -1,4 +1,7 @@ 'foo' - ] + 'admin/*' => 'foo', + ], ], [ - 'Lmc\Rbac\Mvc\Guard\RoutePermissionsGuard', + RoutePermissionsGuard::class, [ - 'post/delete' => 'post.delete' - ] + 'post/delete' => 'post.delete', + ], ], [ - 'Lmc\Rbac\Mvc\Guard\ControllerGuard', + ControllerGuard::class, [ [ 'controller' => 'Foo', 'actions' => 'bar', - 'roles' => 'baz' - ] - ] + 'roles' => 'baz', + ], + ], ], [ - 'Lmc\Rbac\Mvc\Guard\ControllerPermissionsGuard', + ControllerPermissionsGuard::class, [ [ 'controller' => 'Foo', 'actions' => 'bar', - 'permissions' => 'baz' - ] - ] + 'permissions' => 'baz', + ], + ], ], ]; } #[DataProvider('guardProvider')] - public function testCanCreateDefaultGuards($type, $options) + public function testCanCreateDefaultGuards(string $type, array $options): void { $serviceManager = new ServiceManager(); - $serviceManager->setService('Lmc\Rbac\Mvc\Options\ModuleOptions', new ModuleOptions()); + $serviceManager->setService(ModuleOptions::class, new ModuleOptions()); $serviceManager->setService( - 'Lmc\Rbac\Mvc\Service\RoleService', - $this->createMock('Lmc\Rbac\Mvc\Service\RoleService') + RoleService::class, + $this->createMock(RoleService::class) ); $serviceManager->setService( - 'Lmc\Rbac\Mvc\Service\AuthorizationService', - $this->createMock('Lmc\Rbac\Mvc\Service\AuthorizationService') + AuthorizationService::class, + $this->createMock(AuthorizationService::class) ); $pluginManager = new GuardPluginManager($serviceManager); @@ -87,11 +100,43 @@ public function testCanCreateDefaultGuards($type, $options) $this->assertInstanceOf($type, $guard); } - public function testThrowExceptionForInvalidPlugin() + public function testThrowExceptionForInvalidPlugin(): void { - $this->expectException('Lmc\Rbac\Exception\RuntimeException'); + $this->expectException(RuntimeException::class); $pluginManager = new GuardPluginManager(new ServiceManager()); - $pluginManager->setService('foo', new \stdClass()); + $pluginManager->setService('foo', new stdClass()); + } + + public function testCanCreateNewGuard(): void + { + $moduleOptions = new ModuleOptions([ + 'guards' => [ + TestGuard::class => [], + ], + 'guard_manager' => [ + 'factories' => [ + TestGuard::class => function () { + return new TestGuard(); + }, + ], + ], + ]); + $serviceManager = new ServiceManager(); + $serviceManager->setService(ModuleOptions::class, $moduleOptions); + $serviceManager->setService( + RoleService::class, + $this->createMock(RoleService::class) + ); + $serviceManager->setService( + AuthorizationService::class, + $this->createMock(AuthorizationService::class) + ); + + $pluginManager = new GuardPluginManager($serviceManager, $moduleOptions->getGuardManager()); + + $guard = $pluginManager->get(TestGuard::class); + + $this->assertInstanceOf(TestGuard::class, $guard); } } diff --git a/tests/Options/ModuleOptionsFactoryTest.php b/tests/Options/ModuleOptionsFactoryTest.php index 7407305d..d03976bd 100644 --- a/tests/Options/ModuleOptionsFactoryTest.php +++ b/tests/Options/ModuleOptionsFactoryTest.php @@ -1,4 +1,7 @@ []]; @@ -35,12 +40,12 @@ public function testFactory() $serviceManager->setService('Config', $config); $factory = new ModuleOptionsFactory(); - $options = $factory($serviceManager, 'Lmc\Rbac\Mvc\Options\ModuleOptions' ); + $options = $factory($serviceManager, ModuleOptions::class); - $this->assertInstanceOf('Lmc\Rbac\Mvc\Options\ModuleOptions', $options); + $this->assertInstanceOf(ModuleOptions::class, $options); } - public function testFactoryNotCreatedException() + public function testFactoryNotCreatedException(): void { $config = []; @@ -49,6 +54,6 @@ public function testFactoryNotCreatedException() $this->expectException(ServiceNotCreatedException::class); $factory = new ModuleOptionsFactory(); - $options = $factory($serviceManager, 'Lmc\Rbac\Mvc\Options\ModuleOptions' ); + $options = $factory($serviceManager, ModuleOptions::class); } } diff --git a/tests/Options/ModuleOptionsTest.php b/tests/Options/ModuleOptionsTest.php index e44e46da..2b79e783 100644 --- a/tests/Options/ModuleOptionsTest.php +++ b/tests/Options/ModuleOptionsTest.php @@ -18,51 +18,58 @@ namespace LmcTest\Rbac\Mvc\Options; +use Lmc\Rbac\Exception\RuntimeException; +use Lmc\Rbac\Mvc\Identity\AuthenticationIdentityProvider; use Lmc\Rbac\Mvc\Options\ModuleOptions; +use Lmc\Rbac\Mvc\Options\RedirectStrategyOptions; +use Lmc\Rbac\Mvc\Options\UnauthorizedStrategyOptions; use LmcTest\Rbac\Mvc\Util\ServiceManagerFactory; +use PHPUnit\Framework\TestCase; /** * @covers \Lmc\Rbac\Mvc\Options\ModuleOptions */ -class ModuleOptionsTest extends \PHPUnit\Framework\TestCase +class ModuleOptionsTest extends TestCase { - public function testAssertModuleDefaultOptions() + public function testAssertModuleDefaultOptions(): void { /** @var ModuleOptions $moduleOptions */ - $moduleOptions = ServiceManagerFactory::getServiceManager()->get('Lmc\Rbac\Mvc\Options\ModuleOptions'); + $moduleOptions = ServiceManagerFactory::getServiceManager()->get(ModuleOptions::class); $this->assertEquals('allow', $moduleOptions->getProtectionPolicy()); $this->assertIsArray($moduleOptions->getGuards()); - $this->assertInstanceOf('Lmc\Rbac\Mvc\Options\UnauthorizedStrategyOptions', $moduleOptions->getUnauthorizedStrategy()); - $this->assertInstanceOf('Lmc\Rbac\Mvc\Options\RedirectStrategyOptions', $moduleOptions->getRedirectStrategy()); - $this->assertEquals('Lmc\Rbac\Mvc\Identity\AuthenticationIdentityProvider', $moduleOptions->getIdentityProvider()); + $this->assertInstanceOf(UnauthorizedStrategyOptions::class, $moduleOptions->getUnauthorizedStrategy()); + $this->assertInstanceOf(RedirectStrategyOptions::class, $moduleOptions->getRedirectStrategy()); + $this->assertEquals(AuthenticationIdentityProvider::class, $moduleOptions->getIdentityProvider()); } - public function testSettersAndGetters() + public function testSettersAndGetters(): void { $moduleOptions = new ModuleOptions([ - 'identity_provider' => 'foo', + 'identity_provider' => 'foo', 'guards' => [], 'protection_policy' => 'deny', 'unauthorized_strategy' => [ - 'template' => 'error/unauthorized' + 'template' => 'error/unauthorized', ], - 'redirect_strategy' => [ + 'redirect_strategy' => [ 'redirect_to_route_connected' => 'home', - 'redirect_to_route_disconnected' => 'login' - ] + 'redirect_to_route_disconnected' => 'login', + ], + 'guard_manager' => [], ]); $this->assertEquals([], $moduleOptions->getGuards()); $this->assertEquals('foo', $moduleOptions->getIdentityProvider()); $this->assertEquals('deny', $moduleOptions->getProtectionPolicy()); - $this->assertInstanceOf('Lmc\Rbac\Mvc\Options\UnauthorizedStrategyOptions', $moduleOptions->getUnauthorizedStrategy()); - $this->assertInstanceOf('Lmc\Rbac\Mvc\Options\RedirectStrategyOptions', $moduleOptions->getRedirectStrategy()); + $this->assertInstanceOf(UnauthorizedStrategyOptions::class, $moduleOptions->getUnauthorizedStrategy()); + $this->assertInstanceOf(RedirectStrategyOptions::class, $moduleOptions->getRedirectStrategy()); + $this->assertEquals([], $moduleOptions->getGuardManager()); } - public function testThrowExceptionForInvalidProtectionPolicy() + public function testThrowExceptionForInvalidProtectionPolicy(): void { - $this->expectException(\Lmc\Rbac\Exception\RuntimeException::class); + $this->expectException(RuntimeException::class); $moduleOptions = new ModuleOptions(); $moduleOptions->setProtectionPolicy('invalid');