Skip to content

Commit

Permalink
Merge pull request #140 from visto9259/fix-138-139
Browse files Browse the repository at this point in the history
Fixed UnauthorizedException to be a throwable exception. Fixed GuardPluginManager factory to use 'guard_manager' config
  • Loading branch information
visto9259 authored Sep 17, 2024
2 parents d301142 + 38ce3ab commit 85fa90b
Show file tree
Hide file tree
Showing 10 changed files with 189 additions and 65 deletions.
12 changes: 8 additions & 4 deletions src/Exception/UnauthorizedException.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Expand All @@ -18,12 +21,13 @@

namespace Lmc\Rbac\Mvc\Exception;

use Lmc\Rbac\Exception\RuntimeException;

/**
* Unauthorized exception
*
* @author Michaël Gallego <mic.gallego@gmail.com>
* @license MIT
*/
class UnauthorizedException implements UnauthorizedExceptionInterface
class UnauthorizedException extends RuntimeException implements UnauthorizedExceptionInterface
{
/** @var string */
protected $message = 'You are not authorized to access this resource';
}
10 changes: 6 additions & 4 deletions src/Exception/UnauthorizedExceptionInterface.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Expand All @@ -18,12 +21,11 @@

namespace Lmc\Rbac\Mvc\Exception;

use Lmc\Rbac\Exception\ExceptionInterface;

/**
* Interface for an unauthorized exception
*
* @author Michaël Gallego <mic.gallego@gmail.com>
* @license MIT
*/
interface UnauthorizedExceptionInterface extends \Lmc\Rbac\Exception\ExceptionInterface
interface UnauthorizedExceptionInterface extends ExceptionInterface
{
}
2 changes: 1 addition & 1 deletion src/Guard/GuardPluginManagerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}
}
22 changes: 16 additions & 6 deletions src/Options/ModuleOptions.php
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -56,6 +56,11 @@ class ModuleOptions extends BaseModuleOptions
*/
protected ?RedirectStrategyOptions $redirectStrategyOptions = null;

/**
* Guard Plugin Manager configuration
*/
protected array $guardManager = [];

/**
* Constructor
*
Expand All @@ -71,7 +76,6 @@ public function __construct($options = null)
* Set the guards options
*
* @param array $guards
* @return void
*/
public function setGuards(array $guards): void
{
Expand All @@ -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
{
Expand All @@ -110,7 +112,6 @@ public function setProtectionPolicy(string $protectionPolicy): void
/**
* Get the protection policy for guards
*
* @return string
*/
public function getProtectionPolicy(): string
{
Expand Down Expand Up @@ -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;
}
}
19 changes: 19 additions & 0 deletions tests/Asset/TestGuard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

namespace LmcTest\Rbac\Mvc\Asset;

use Laminas\EventManager\EventManagerInterface;
use Laminas\Mvc\MvcEvent;
use Lmc\Rbac\Mvc\Guard\AbstractGuard;

class TestGuard extends AbstractGuard
{

/**
* @inheritDoc
*/
public function isGranted(MvcEvent $event): bool
{
return true;
}
}
24 changes: 24 additions & 0 deletions tests/Exception/UnauthorizedExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<?php

declare(strict_types=1);

namespace LmcTest\Rbac\Mvc\Exception;

use Lmc\Rbac\Mvc\Exception\UnauthorizedException;
use PHPUnit\Framework\TestCase;

class UnauthorizedExceptionTest extends TestCase
{
public function testUnauthorizedException(): void
{
$this->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');
}
}
16 changes: 12 additions & 4 deletions tests/Guard/GuardPluginManagerFactoryTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Expand All @@ -19,18 +22,23 @@
namespace LmcTest\Rbac\Mvc\Guard;

use Laminas\ServiceManager\ServiceManager;
use Lmc\Rbac\Mvc\Guard\GuardPluginManagerFactory;
use Lmc\Rbac\Mvc\Guard\GuardPluginManager;
use Lmc\Rbac\Mvc\Guard\GuardPluginManagerFactory;
use Lmc\Rbac\Mvc\Options\ModuleOptions;
use PHPUnit\Framework\TestCase;
use Psr\Container\ContainerExceptionInterface;

/**
* @covers \Lmc\Rbac\Mvc\Guard\GuardPluginManagerFactory
*/
class GuardPluginManagerFactoryTest extends \PHPUnit\Framework\TestCase
class GuardPluginManagerFactoryTest extends TestCase
{
public function testFactory()
/**
* @throws ContainerExceptionInterface
*/
public function testFactory(): void
{
$moduleOptions = new ModuleOptions(['guard_manager' => []]);
$moduleOptions = new ModuleOptions();
$serviceManager = new ServiceManager();
$serviceManager->setService(ModuleOptions::class, $moduleOptions);

Expand Down
93 changes: 69 additions & 24 deletions tests/Guard/GuardPluginManagerTest.php
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
<?php

declare(strict_types=1);

/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
Expand All @@ -19,65 +22,75 @@
namespace LmcTest\Rbac\Mvc\Guard;

use Laminas\ServiceManager\ServiceManager;
use Lmc\Rbac\Exception\RuntimeException;
use Lmc\Rbac\Mvc\Guard\ControllerGuard;
use Lmc\Rbac\Mvc\Guard\ControllerPermissionsGuard;
use Lmc\Rbac\Mvc\Guard\GuardPluginManager;
use Lmc\Rbac\Mvc\Guard\RouteGuard;
use Lmc\Rbac\Mvc\Guard\RoutePermissionsGuard;
use Lmc\Rbac\Mvc\Options\ModuleOptions;
use Lmc\Rbac\Mvc\Service\AuthorizationService;
use Lmc\Rbac\Mvc\Service\RoleService;
use LmcTest\Rbac\Mvc\Asset\TestGuard;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
use stdClass;

/**
* @covers \Lmc\Rbac\Mvc\Guard\GuardPluginManager
*/
class GuardPluginManagerTest extends \PHPUnit\Framework\TestCase
class GuardPluginManagerTest extends TestCase
{
public static function guardProvider(): array
{
return [
[
'Lmc\Rbac\Mvc\Guard\RouteGuard',
RouteGuard::class,
[
'admin/*' => '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);
Expand All @@ -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);
}
}
Loading

0 comments on commit 85fa90b

Please sign in to comment.