diff --git a/src/Component/AuthManager.php b/src/Component/AuthManager.php index d3a9abb..adcc406 100644 --- a/src/Component/AuthManager.php +++ b/src/Component/AuthManager.php @@ -4,6 +4,7 @@ use Doctrine\DBAL\Exception\UniqueConstraintViolationException; use Potievdev\SlimRbac\Exception\CyclicException; +use Potievdev\SlimRbac\Exception\DatabaseException; use Potievdev\SlimRbac\Exception\NotUniqueException; use Potievdev\SlimRbac\Models\Entity\Permission; use Potievdev\SlimRbac\Models\Entity\Role; @@ -23,6 +24,7 @@ class AuthManager extends BaseComponent * @param integer $parentRoleId * @param integer $childRoleId * @throws CyclicException + * @throws \Doctrine\ORM\Query\QueryException */ private function checkForCyclicHierarchy($parentRoleId, $childRoleId) { @@ -37,6 +39,7 @@ private function checkForCyclicHierarchy($parentRoleId, $childRoleId) /** * Truncates all tables + * @throws DatabaseException */ public function removeAll() { @@ -51,13 +54,13 @@ public function removeAll() $pdo->exec('TRUNCATE role'); $pdo->exec('TRUNCATE permission'); $pdo->exec('TRUNCATE user_role'); - $pdo->exec('SET FOREIGN_KEY_CHECKS=0'); + $pdo->exec('SET FOREIGN_KEY_CHECKS=1'); $pdo->commit(); } catch (\Exception $e) { $pdo->rollBack(); - throw new \Exception($e->getMessage()); + throw new DatabaseException($e->getMessage()); } } @@ -91,12 +94,12 @@ public function createRole($roleName) * Save permission in database * @param Permission $permission * @throws NotUniqueException + * @throws DatabaseException */ public function addPermission(Permission $permission) { try { - $this->entityManager->persist($permission); - $this->entityManager->flush(); + $this->saveEntity($permission); } catch (UniqueConstraintViolationException $e) { throw new NotUniqueException('Permission with name ' . $permission->getName() . ' already created'); } @@ -106,12 +109,12 @@ public function addPermission(Permission $permission) * Save role in database * @param Role $role * @throws NotUniqueException + * @throws DatabaseException */ public function addRole(Role $role) { try { - $this->entityManager->persist($role); - $this->entityManager->flush(); + $this->saveEntity($role); } catch (UniqueConstraintViolationException $e) { throw new NotUniqueException('Role with name ' . $role->getName() . ' already created'); } @@ -121,6 +124,7 @@ public function addRole(Role $role) * Add permission to role * @param Role $role * @param Permission $permission + * @throws DatabaseException * @throws NotUniqueException */ public function addChildPermission(Role $role, Permission $permission) @@ -131,8 +135,7 @@ public function addChildPermission(Role $role, Permission $permission) $rolePermission->setRole($role); try { - $this->entityManager->persist($rolePermission); - $this->entityManager->flush(); + $this->saveEntity($rolePermission); } catch (UniqueConstraintViolationException $e) { throw new NotUniqueException('Permission ' . $permission->getName() . ' is already assigned to role ' . $role->getName()); } @@ -142,7 +145,10 @@ public function addChildPermission(Role $role, Permission $permission) * Add child role to role * @param Role $parentRole * @param Role $childRole + * @throws CyclicException + * @throws DatabaseException * @throws NotUniqueException + * @throws \Doctrine\ORM\Query\QueryException */ public function addChildRole(Role $parentRole, Role $childRole) { @@ -154,8 +160,7 @@ public function addChildRole(Role $parentRole, Role $childRole) $this->checkForCyclicHierarchy($childRole->getId(), $parentRole->getId()); try { - $this->entityManager->persist($roleHierarchy); - $this->entityManager->flush(); + $this->saveEntity($roleHierarchy); } catch (UniqueConstraintViolationException $e) { throw new NotUniqueException('Child role ' . $childRole->getName() . ' is already has parent role ' . $parentRole->getName()); } @@ -166,6 +171,7 @@ public function addChildRole(Role $parentRole, Role $childRole) * @param Role $role * @param integer $userId * @throws NotUniqueException + * @throws DatabaseException */ public function assign(Role $role, $userId) { @@ -175,10 +181,9 @@ public function assign(Role $role, $userId) $userRole->setRole($role); try { - $this->entityManager->persist($userRole); - $this->entityManager->flush(); + $this->saveEntity($userRole); } catch (UniqueConstraintViolationException $e) { throw new NotUniqueException('Role ' . $role->getName() . 'is already assigned to user with identifier ' . $userId); } } -} \ No newline at end of file +} diff --git a/src/Component/AuthMiddleware.php b/src/Component/AuthMiddleware.php index 998b3e0..3366e69 100644 --- a/src/Component/AuthMiddleware.php +++ b/src/Component/AuthMiddleware.php @@ -15,11 +15,13 @@ class AuthMiddleware extends BaseComponent { /** * Check access - * @param ServerRequestInterface $request PSR7 request - * @param ResponseInterface $response PSR7 response - * @param callable $next Next middleware + * @param ServerRequestInterface $request PSR7 request + * @param ResponseInterface $response PSR7 response + * @param callable $next Next middleware * * @return \Psr\Http\Message\ResponseInterface + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException */ public function __invoke($request, $response, $next) { @@ -30,16 +32,16 @@ public function __invoke($request, $response, $next) switch ($storageType) { case AuthOptions::ATTRIBUTE_STORAGE_TYPE: - $userId = $request->getAttribute($variableName); + $userId = intval($request->getAttribute($variableName)); break; case AuthOptions::HEADER_STORAGE_TYPE: - $userId = $request->getHeaderLine($variableName); + $userId = intval($request->getHeaderLine($variableName)); break; case AuthOptions::COOKIE_STORAGE_TYPE: $params = $request->getCookieParams(); - $userId = $params[$variableName]; + $userId = intval($params[$variableName]); break; } @@ -58,4 +60,4 @@ public function __invoke($request, $response, $next) return $response; } -} \ No newline at end of file +} diff --git a/src/Component/BaseComponent.php b/src/Component/BaseComponent.php index a886a75..15edf0c 100644 --- a/src/Component/BaseComponent.php +++ b/src/Component/BaseComponent.php @@ -3,6 +3,8 @@ namespace Potievdev\SlimRbac\Component; use Doctrine\ORM\EntityManager; +use Doctrine\ORM\OptimisticLockException; +use Potievdev\SlimRbac\Exception\DatabaseException; use Potievdev\SlimRbac\Exception\InvalidArgumentException; use Potievdev\SlimRbac\Helper\ValidatorHelper; use Potievdev\SlimRbac\Models\RepositoryRegistry; @@ -34,12 +36,30 @@ public function __construct(AuthOptions $authOptions) $this->repositoryRegistry = new RepositoryRegistry($this->entityManager); } + /** + * Insert or update entity + * @param object $entity + * @return object + * @throws DatabaseException + */ + protected function saveEntity($entity) + { + try { + $this->entityManager->persist($entity); + $this->entityManager->flush($entity); + return $entity; + } catch (OptimisticLockException $e) { + throw new DatabaseException($e->getMessage()); + } + } + /** * Checks access status * @param integer $userId * @param string $permissionName * @return bool - * @throws \Exception + * @throws InvalidArgumentException + * @throws \Doctrine\ORM\Query\QueryException */ public function checkAccess($userId, $permissionName) { @@ -74,4 +94,4 @@ public function checkAccess($userId, $permissionName) return false; } -} \ No newline at end of file +} diff --git a/src/Console/Command/BaseDatabaseCommand.php b/src/Console/Command/BaseDatabaseCommand.php index 3649e78..c71e313 100644 --- a/src/Console/Command/BaseDatabaseCommand.php +++ b/src/Console/Command/BaseDatabaseCommand.php @@ -86,4 +86,4 @@ public function execute(InputInterface $input, OutputInterface $output) $this->config = new Config($configArray); } -} \ No newline at end of file +} diff --git a/src/Console/Command/CreateConfigCommand.php b/src/Console/Command/CreateConfigCommand.php index 8a8358c..d273780 100644 --- a/src/Console/Command/CreateConfigCommand.php +++ b/src/Console/Command/CreateConfigCommand.php @@ -31,4 +31,4 @@ public function execute(InputInterface $input, OutputInterface $output) file_put_contents($currentDir . '/sr-config.php', $configFile); $output->writeln("File sr-config.php created in directory: $currentDir"); } -} \ No newline at end of file +} diff --git a/src/Console/Command/MigrateDatabaseCommand.php b/src/Console/Command/MigrateDatabaseCommand.php index 0422229..3334ce2 100644 --- a/src/Console/Command/MigrateDatabaseCommand.php +++ b/src/Console/Command/MigrateDatabaseCommand.php @@ -34,4 +34,4 @@ public function execute(InputInterface $input, OutputInterface $output) $manager = new Manager($this->config, $input, $output); $manager->migrate($this->config->getDefaultEnvironment()); } -} \ No newline at end of file +} diff --git a/src/Console/Command/RollbackDatabaseCommand.php b/src/Console/Command/RollbackDatabaseCommand.php index af25e91..67c1c94 100644 --- a/src/Console/Command/RollbackDatabaseCommand.php +++ b/src/Console/Command/RollbackDatabaseCommand.php @@ -34,4 +34,4 @@ public function execute(InputInterface $input, OutputInterface $output) $manager = new Manager($this->config, $input, $output); $manager->rollback($this->config->getDefaultEnvironment()); } -} \ No newline at end of file +} diff --git a/src/Console/SlimRbacConsoleApplication.php b/src/Console/SlimRbacConsoleApplication.php index 6636cd8..ee6db16 100644 --- a/src/Console/SlimRbacConsoleApplication.php +++ b/src/Console/SlimRbacConsoleApplication.php @@ -32,6 +32,7 @@ public function __construct($version = '1.0.0') * @param InputInterface $input An Input instance * @param OutputInterface $output An Output instance * @return integer 0 if everything went fine, or an error code + * @throws \Throwable */ public function doRun(InputInterface $input, OutputInterface $output) { @@ -45,4 +46,4 @@ public function doRun(InputInterface $input, OutputInterface $output) return parent::doRun($input, $output); } -} \ No newline at end of file +} diff --git a/src/Exception/CyclicException.php b/src/Exception/CyclicException.php index 9866384..617e03e 100644 --- a/src/Exception/CyclicException.php +++ b/src/Exception/CyclicException.php @@ -3,11 +3,11 @@ namespace Potievdev\SlimRbac\Exception; /** - * This throws when cyclic line detected + * This throws when cyclic line detected in roles hierarchy * Class CyclicException * @package Potievdev\SlimRbac\Exception */ class CyclicException extends \Exception { protected $message = 'Cyclic role three detected'; -} \ No newline at end of file +} diff --git a/src/Exception/DatabaseException.php b/src/Exception/DatabaseException.php new file mode 100644 index 0000000..4ce48a6 --- /dev/null +++ b/src/Exception/DatabaseException.php @@ -0,0 +1,12 @@ +description = $description; } - /** @ORM\PrePersist */ + /** @ORM\PrePersist + * @throws \Exception + */ public function prePersist() { $this->createdAt = new \DateTime(); } - /** @ORM\PreUpdate */ + /** @ORM\PreUpdate + * @throws \Exception + */ public function preUpdate() { $this->updatedAt = new \DateTime(); } -} \ No newline at end of file +} diff --git a/src/Models/Entity/Role.php b/src/Models/Entity/Role.php index ad3496b..5e95cd5 100644 --- a/src/Models/Entity/Role.php +++ b/src/Models/Entity/Role.php @@ -153,15 +153,19 @@ public function setDescription($description) $this->description = $description; } - /** @ORM\PrePersist */ + /** @ORM\PrePersist + * @throws \Exception + */ public function prePersist() { $this->createdAt = new \DateTime(); } - /** @ORM\PreUpdate */ + /** @ORM\PreUpdate + * @throws \Exception + */ public function preUpdate() { $this->updatedAt = new \DateTime(); } -} \ No newline at end of file +} diff --git a/src/Models/Entity/RoleHierarchy.php b/src/Models/Entity/RoleHierarchy.php index aef0b3f..57281e5 100644 --- a/src/Models/Entity/RoleHierarchy.php +++ b/src/Models/Entity/RoleHierarchy.php @@ -127,9 +127,11 @@ public function setParentRole($parentRole) $this->parentRole = $parentRole; } - /** @ORM\PrePersist */ + /** @ORM\PrePersist + * @throws \Exception + */ public function prePersist() { $this->createdAt = new \DateTime(); } -} \ No newline at end of file +} diff --git a/src/Models/Entity/RolePermission.php b/src/Models/Entity/RolePermission.php index 7fbfa26..dd1378c 100644 --- a/src/Models/Entity/RolePermission.php +++ b/src/Models/Entity/RolePermission.php @@ -159,9 +159,11 @@ public function setRole($role) $this->role = $role; } - /** @ORM\PrePersist */ + /** @ORM\PrePersist + * @throws \Exception + */ public function prePersist() { $this->createdAt = new \DateTime(); } -} \ No newline at end of file +} diff --git a/src/Models/Entity/UserRole.php b/src/Models/Entity/UserRole.php index b7ba5a5..9114fec 100644 --- a/src/Models/Entity/UserRole.php +++ b/src/Models/Entity/UserRole.php @@ -133,9 +133,11 @@ public function setRole($role) $this->role = $role; } - /** @ORM\PrePersist */ + /** @ORM\PrePersist + * @throws \Exception + */ public function prePersist() { $this->createdAt = new \DateTime(); } -} \ No newline at end of file +} diff --git a/src/Models/Repository/RoleHierarchyRepository.php b/src/Models/Repository/RoleHierarchyRepository.php index a3fd8a1..00df1de 100644 --- a/src/Models/Repository/RoleHierarchyRepository.php +++ b/src/Models/Repository/RoleHierarchyRepository.php @@ -17,6 +17,7 @@ class RoleHierarchyRepository extends EntityRepository * Returns array of child role ids for given parent role ids * @param integer[] $parentIds * @return integer[] + * @throws \Doctrine\ORM\Query\QueryException */ private function getChildIds($parentIds) { @@ -36,6 +37,7 @@ private function getChildIds($parentIds) * @param integer $parentRoleId * @param integer $findingChildId * @return bool + * @throws \Doctrine\ORM\Query\QueryException */ public function hasChildRoleId($parentRoleId, $findingChildId) { @@ -62,6 +64,7 @@ public function hasChildRoleId($parentRoleId, $findingChildId) * Returns all child role ids for given parent role ids * @param integer[] $parentIds * @return integer[] + * @throws \Doctrine\ORM\Query\QueryException */ private function getAllChildRoleIds($parentIds) { @@ -78,6 +81,7 @@ private function getAllChildRoleIds($parentIds) /** * @param integer[] $rootRoleIds * @return integer[] + * @throws \Doctrine\ORM\Query\QueryException */ public function getAllRoleIdsHierarchy($rootRoleIds) { @@ -85,4 +89,4 @@ public function getAllRoleIdsHierarchy($rootRoleIds) return ArrayHelper::merge($rootRoleIds, $childRoleIds); } -} \ No newline at end of file +} diff --git a/src/Models/Repository/UserRoleRepository.php b/src/Models/Repository/UserRoleRepository.php index db35992..a8108f5 100644 --- a/src/Models/Repository/UserRoleRepository.php +++ b/src/Models/Repository/UserRoleRepository.php @@ -15,6 +15,7 @@ class UserRoleRepository extends EntityRepository /** * @param integer $userId * @return array + * @throws \Doctrine\ORM\Query\QueryException */ public function getUserRoleIds($userId) { diff --git a/src/Structure/AuthOptions.php b/src/Structure/AuthOptions.php index 523dd37..0625801 100644 --- a/src/Structure/AuthOptions.php +++ b/src/Structure/AuthOptions.php @@ -74,4 +74,4 @@ public function setVariableStorageType($variableStorageType) { $this->variableStorageType = $variableStorageType; } -} \ No newline at end of file +} diff --git a/tests/unit/AuthManagerTest.php b/tests/unit/AuthManagerTest.php index a258b37..5868173 100644 --- a/tests/unit/AuthManagerTest.php +++ b/tests/unit/AuthManagerTest.php @@ -2,16 +2,34 @@ namespace Tests\Unit; +use Potievdev\SlimRbac\Component\AuthManager; use Potievdev\SlimRbac\Models\Entity\Permission; use Potievdev\SlimRbac\Models\Entity\Role; +/** + * Class AuthManagerTest + * @package Tests\Unit + */ class AuthManagerTest extends BaseTestCase { + + /** @var AuthManager $authManager */ + protected $authManager; + /** - * Testing has permission cases + * @throws \Potievdev\SlimRbac\Exception\CyclicException + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException + * @throws \Doctrine\ORM\Query\QueryException */ - public function testAccessTrue() + public function setUp() { + parent::setUp(); + + $authOptions = $this->createAuthOptions(); + $this->authManager = new AuthManager($authOptions); + $this->authManager->removeAll(); + $edit = $this->authManager->createPermission('edit'); $this->authManager->addPermission($edit); @@ -30,70 +48,89 @@ public function testAccessTrue() $this->authManager->assign($moderator, self::MODERATOR_USER_ID); $this->authManager->assign($admin, self::ADMIN_USER_ID); + } + + public function successCasesProvider() + { - $this->assertTrue($this->authManager->checkAccess(self::MODERATOR_USER_ID, 'edit')); - $this->assertTrue($this->authManager->checkAccess(self::ADMIN_USER_ID, 'edit')); - $this->assertTrue($this->authManager->checkAccess(self::ADMIN_USER_ID, 'write')); + return [ + 'moderator can edit' => [self::MODERATOR_USER_ID, 'edit'], + 'admin can edit' => [self::ADMIN_USER_ID, 'edit'], + 'admin can write' => [self::ADMIN_USER_ID, 'write'], + ]; } /** - * Testing not have permission cases + * Testing has permission cases + * @param integer $userId user id + * @param string $roleOrPermission role or permission name + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException + * @dataProvider successCasesProvider */ - public function testAccessFalse() + public function testCheckAccessSuccessCases($userId, $roleOrPermission) { - $edit = $this->authManager->createPermission('edit'); - $this->authManager->addPermission($edit); - - $write = $this->authManager->createPermission('write'); - $this->authManager->addPermission($write); - - $moderator = $this->authManager->createRole('moderator'); - $this->authManager->addRole($moderator); - - $admin = $this->authManager->createRole('admin'); - $this->authManager->addRole($admin); + $this->assertTrue($this->authManager->checkAccess($userId, $roleOrPermission)); + } - $this->authManager->addChildPermission($moderator, $edit); - $this->authManager->addChildPermission($admin, $write); - $this->authManager->addChildRole($admin, $moderator); + /** + * @return array + */ + public function failCasesProvider() + { + return [ + 'moderator has no write permission' => [self::MODERATOR_USER_ID, 'write'], + 'not existing permission' => [self::ADMIN_USER_ID, 'none_permission'], + 'not existing user id not has permission' => [self::NOT_USER_ID, 'edit'], + 'not existing user id not has role' => [self::NOT_USER_ID, 'admin'] + ]; + } - $this->assertFalse($this->authManager->checkAccess(self::MODERATOR_USER_ID, 'write')); - $this->assertFalse($this->authManager->checkAccess(self::ADMIN_USER_ID, 'none_permission')); - $this->assertFalse($this->authManager->checkAccess(self::NOT_USER_ID, 'edit')); - $this->assertFalse($this->authManager->checkAccess(self::NOT_USER_ID, 'admin')); - $this->assertFalse($this->authManager->checkAccess(self::NOT_USER_ID, 'moderator')); + /** + * Testing not have permission cases + * @param integer $userId user id + * @param string $roleOrPermission role or permission name + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException + * @dataProvider failCasesProvider + */ + public function testCheckAccessFailureCases($userId, $roleOrPermission) + { + $this->assertFalse($this->authManager->checkAccess($userId, $roleOrPermission)); } /** * Testing adding not unique permission * @expectedException \Potievdev\SlimRbac\Exception\NotUniqueException + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException */ - public function testNotUniquePermission() + public function testCheckAddingNotUniquePermission() { $edit = $this->authManager->createPermission('edit'); $this->authManager->addPermission($edit); - - $edit = $this->authManager->createPermission('edit'); - $this->authManager->addPermission($edit); } /** * Testing adding not unique role * @expectedException \Potievdev\SlimRbac\Exception\NotUniqueException + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException */ - public function testNonUniqueRole() + public function testCheckAddingNonUniqueRole() { $moderator = $this->authManager->createRole('moderator'); $this->authManager->addRole($moderator); - - $moderator = $this->authManager->createRole('moderator'); - $this->authManager->addRole($moderator); } /** * @expectedException \Potievdev\SlimRbac\Exception\CyclicException + * @throws \Potievdev\SlimRbac\Exception\CyclicException + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException + * @throws \Doctrine\ORM\Query\QueryException */ - public function testCyclicException() + public function testCheckCyclicException() { $a = $this->authManager->createRole('a'); $b = $this->authManager->createRole('b'); @@ -108,16 +145,12 @@ public function testCyclicException() /** * Testing creating permission */ - public function testCreatingPermission() + public function testCheckCreatingPermission() { - $permissionName = 'edit'; - - $edit = $this->authManager->createPermission($permissionName); - $this->authManager->addPermission($edit); - - $permission = $this->repositoryRegistry + $repositoryRegistry = $this->createRepositoryRegistry(); + $permission = $repositoryRegistry ->getPermissionRepository() - ->findOneBy(['name' => $permissionName]); + ->findOneBy(['name' => 'edit']); $this->assertTrue($permission instanceof Permission); } @@ -125,17 +158,60 @@ public function testCreatingPermission() /** * Testing creating role */ - public function testCreatingRole() + public function testCheckCreatingRole() { - $roleName = 'admin'; + $repositoryRegistry = $this->createRepositoryRegistry(); - $admin = $this->authManager->createRole($roleName); - $this->authManager->addRole($admin); - - $role = $this->repositoryRegistry + $role = $repositoryRegistry ->getRoleRepository() - ->findOneBy(['name' => $roleName]); + ->findOneBy(['name' => 'admin']); $this->assertTrue($role instanceof Role); } -} \ No newline at end of file + + /** + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException + * @expectedException \Potievdev\SlimRbac\Exception\NotUniqueException + */ + public function testCheckDoubleAssigningPermissionToSameRole() + { + $repositoryRegistry = $this->createRepositoryRegistry(); + + /** @var Role $role */ + $role = $repositoryRegistry + ->getRoleRepository() + ->findOneBy(['name' => 'admin']); + + /** @var Permission $permission */ + $permission = $repositoryRegistry + ->getPermissionRepository() + ->findOneBy(['name' => 'write']); + + $this->authManager->addChildPermission($role, $permission); + } + + /** + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\CyclicException + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException + * @expectedException \Potievdev\SlimRbac\Exception\NotUniqueException + */ + public function testCheckAddingSameChildRoleDoubleTime() + { + $repositoryRegistry = $this->createRepositoryRegistry(); + + /** @var Role $parent */ + $parent = $repositoryRegistry + ->getRoleRepository() + ->findOneBy(['name' => 'admin']); + + /** @var Role $child */ + $child = $repositoryRegistry + ->getRoleRepository() + ->findOneBy(['name' => 'moderator']); + + $this->authManager->addChildRole($parent, $child); + } +} diff --git a/tests/unit/AuthMiddlewareTest.php b/tests/unit/AuthMiddlewareTest.php index 4b247e2..13ea93b 100644 --- a/tests/unit/AuthMiddlewareTest.php +++ b/tests/unit/AuthMiddlewareTest.php @@ -5,8 +5,9 @@ use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; use GuzzleHttp\Psr7\ServerRequest; -use Psr\Http\Message\ServerRequestInterface; -use Psr\Http\Message\ResponseInterface; +use Potievdev\SlimRbac\Component\AuthManager; +use Potievdev\SlimRbac\Component\AuthMiddleware; +use Potievdev\SlimRbac\Structure\AuthOptions; /** * Class for testing AuthMiddleware @@ -15,44 +16,113 @@ */ class AuthMiddlewareTest extends BaseTestCase { + /** @var AuthOptions $authOptions */ + protected $authOptions; - public function testInvoke() + /** @var callable $callable */ + protected $callable; + + /** @var ServerRequest $request */ + protected $request; + + /** @var Response $response */ + protected $response; + + /** + * @throws \Potievdev\SlimRbac\Exception\CyclicException + * @throws \Potievdev\SlimRbac\Exception\DatabaseException + * @throws \Potievdev\SlimRbac\Exception\NotUniqueException + * @throws \Doctrine\ORM\Query\QueryException + */ + public function setUp() { - $edit = $this->authManager->createPermission('edit'); + parent::setUp(); + + $this->authOptions = $this->createAuthOptions(); + + $authManager = new AuthManager($this->authOptions); + $authManager->removeAll(); + + $edit = $authManager->createPermission('edit'); $edit->setDescription('Edit permission'); - $this->authManager->addPermission($edit); + $authManager->addPermission($edit); - $write = $this->authManager->createPermission('write'); + $write = $authManager->createPermission('write'); $write->setDescription('Write permission'); - $this->authManager->addPermission($write); + $authManager->addPermission($write); - $moderator = $this->authManager->createRole('moderator'); + $moderator = $authManager->createRole('moderator'); $moderator->setDescription('Moderator role'); - $this->authManager->addRole($moderator); + $authManager->addRole($moderator); - $admin = $this->authManager->createRole('admin'); + $admin = $authManager->createRole('admin'); $admin->setDescription('Admin role'); - $this->authManager->addRole($admin); - - $this->authManager->addChildPermission($moderator, $edit); - $this->authManager->addChildPermission($admin, $write); - $this->authManager->addChildRole($admin, $moderator); + $authManager->addRole($admin); - $this->authManager->assign($moderator, self::MODERATOR_USER_ID); - $this->authManager->assign($admin, self::ADMIN_USER_ID); + $authManager->addChildPermission($moderator, $edit); + $authManager->addChildPermission($admin, $write); + $authManager->addChildRole($admin, $moderator); - $middleware = $this->authMiddleware; - $callable = function (Request $request, Response $response) { return $response; }; + $authManager->assign($moderator, self::MODERATOR_USER_ID); + $authManager->assign($admin, self::ADMIN_USER_ID); - $request = new ServerRequest('GET', 'write'); - $response = new Response(); + $this->callable = function (Request $request, Response $response) { + return $response; + }; + $this->request = new ServerRequest('GET', 'write'); + $this->response = new Response(); + } - $request = $request->withAttribute('userId', self::ADMIN_USER_ID); - $response = $middleware->__invoke($request, $response, $callable); + /** + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException + */ + public function testCheckAccessSuccessCase() + { + $middleware = new AuthMiddleware($this->authOptions); + $request = $this->request->withAttribute($this->authOptions->getVariableName(), self::ADMIN_USER_ID); + $response = $middleware->__invoke($request, $this->response, $this->callable); $this->assertEquals(200, $response->getStatusCode()); + } - $request = $request->withAttribute('userId', self::MODERATOR_USER_ID); - $response = $middleware->__invoke($request, $response, $callable); + /** + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException + */ + public function testCheckAccessDeniedCase() + { + $middleware = new AuthMiddleware($this->authOptions); + $request = $this->request->withAttribute($this->authOptions->getVariableName(), self::MODERATOR_USER_ID); + $response = $middleware->__invoke($request, $this->response, $this->callable); $this->assertEquals(403, $response->getStatusCode()); } -} \ No newline at end of file + + /** + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException + */ + public function testCheckReadingUserIdFromHeader() + { + $authOptions = $this->authOptions; + $authOptions->setVariableStorageType(AuthOptions::HEADER_STORAGE_TYPE); + $middleware = new AuthMiddleware($authOptions); + $request = $this->request->withHeader($authOptions->getVariableName(), self::ADMIN_USER_ID); + $response = $middleware->__invoke($request, $this->response, $this->callable); + $this->assertEquals(200, $response->getStatusCode()); + } + + /** + * @throws \Doctrine\ORM\Query\QueryException + * @throws \Potievdev\SlimRbac\Exception\InvalidArgumentException + */ + public function testCheckReadingUserIdFromCookie() + { + $authOptions = $this->authOptions; + $authOptions->setVariableStorageType(AuthOptions::COOKIE_STORAGE_TYPE); + $middleware = new AuthMiddleware($authOptions); + $request = $this->request->withCookieParams([$authOptions->getVariableName() => self::ADMIN_USER_ID]); + $response = $middleware->__invoke($request, $this->response, $this->callable); + $this->assertEquals(200, $response->getStatusCode()); + } + +} diff --git a/tests/unit/AuthOptionsTest.php b/tests/unit/AuthOptionsTest.php index 4383a39..42c8cca 100644 --- a/tests/unit/AuthOptionsTest.php +++ b/tests/unit/AuthOptionsTest.php @@ -8,11 +8,14 @@ * Class AuthOptionsTest * @package Tests\Unit */ -class AuthOptionsTest extends \PHPUnit_Framework_TestCase +class AuthOptionsTest extends BaseTestCase { - public function testAuthOptions() + /** + * Testing AuthOptionsComponent + */ + public function testCheckSetAndGetMethods() { - $authOptions = new AuthOptions(); + $authOptions = $this->createAuthOptions(); $this->assertEquals(AuthOptions::DEFAULT_VARIABLE_NAME, $authOptions->getVariableName()); $this->assertEquals(AuthOptions::ATTRIBUTE_STORAGE_TYPE, $authOptions->getVariableStorageType()); @@ -23,4 +26,4 @@ public function testAuthOptions() $authOptions->setVariableStorageType(AuthOptions::COOKIE_STORAGE_TYPE); $this->assertEquals(AuthOptions::COOKIE_STORAGE_TYPE, $authOptions->getVariableStorageType()); } -} \ No newline at end of file +} diff --git a/tests/unit/BaseTestCase.php b/tests/unit/BaseTestCase.php index e89fe35..dbcb56b 100644 --- a/tests/unit/BaseTestCase.php +++ b/tests/unit/BaseTestCase.php @@ -2,11 +2,13 @@ namespace Tests\Unit; -use Potievdev\SlimRbac\Component\AuthManager; -use Potievdev\SlimRbac\Component\AuthMiddleware; use Potievdev\SlimRbac\Models\RepositoryRegistry; use Potievdev\SlimRbac\Structure\AuthOptions; +/** + * Class BaseTestCase + * @package Tests\Unit + */ class BaseTestCase extends \PHPUnit_Framework_TestCase { /** Moderator user identifier */ @@ -17,20 +19,25 @@ class BaseTestCase extends \PHPUnit_Framework_TestCase const NOT_USER_ID = 3; /** @var \Doctrine\ORM\EntityManager $entityManager */ - protected $entityManager; + private $entityManager; - /** @var RepositoryRegistry $entityManager */ - protected $repositoryRegistry; - - /** @var AuthOptions $authOptions */ - protected $authOptions; - - /** @var AuthManager $authManager */ - protected $authManager; - - /** @var AuthMiddleware $authMiddleware */ - protected $authMiddleware; + /** + * @return RepositoryRegistry + */ + protected function createRepositoryRegistry() + { + return new RepositoryRegistry($this->entityManager); + } + /** + * @return AuthOptions + */ + protected function createAuthOptions() + { + $authOptions = new AuthOptions(); + $authOptions->setEntityManager($this->entityManager); + return $authOptions; + } /** * Initializing AuthOptions, AuthManager and AuthOptions @@ -38,17 +45,5 @@ class BaseTestCase extends \PHPUnit_Framework_TestCase public function setUp() { $this->entityManager = require __DIR__ . '/../../config/sr-config.php'; - - $this->repositoryRegistry = new RepositoryRegistry($this->entityManager); - - $this->authOptions = new AuthOptions(); - - $this->authOptions->setEntityManager($this->entityManager); - - $this->authMiddleware = new AuthMiddleware($this->authOptions); - - $this->authManager = new AuthManager($this->authOptions); - - $this->authManager->removeAll(); } -} \ No newline at end of file +}