Adds removal of exceptions as well as error handling.

This commit is contained in:
Vassyli
2016-11-01 10:36:12 +01:00
parent 3b8537fab6
commit 1c89d8f204
14 changed files with 438 additions and 14 deletions
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if an existing entity is tried to create again.
*/
class EntityAlreadyExistsException extends EntityException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a non-existing entity is requested.
*/
class EntityDoesNotExistException extends EntityException
{
}
+12
View File
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* A basic entity exception
*/
class EntityException extends CoreException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if an existing entity is tried to create again.
*/
class PermissionAlreadyExistsException extends EntityAlreadyExistsException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if an existing entity is tried to create again.
*/
class PermissionDoesNotExistException extends EntityDoesNotExistException
{
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Exceptions;
/**
* Exception if a requested permission id has not been found.
*/
class PermissionIdNotFoundException extends EntityDoesNotExistException
{
}
+12
View File
@@ -28,4 +28,16 @@ interface PermissionableInterface
* @return Permission
*/
public function getRawPermission(string $permissionId): Permission;
/**
* Adds a permission with a set state.
* @param \LotGD\Core\Models\Permission $permission
*/
public function addPermission(Permission $permission, int $state);
/**
* Removes a permission with a given id.
* @param string $permissionId
*/
public function removePermission(string $permissionId);
}
+75
View File
@@ -3,7 +3,9 @@ declare(strict_types=1);
namespace LotGD\Core;
use LotGD\Core\Exceptions\PermissionIdNotFoundException;
use LotGD\Core\Models\PermissionableInterface;
use LotGD\Core\Models\Permission;
/**
* Permissions can be managed with the PermissionManager.
@@ -101,4 +103,77 @@ class PermissionManager
return false;
}
}
/**
* Retrieves a permission entity from the database by a permission id.
* @param string $permissionId
* @return Permission
* @throws PermissionIdNotFoundException
*/
private function findPermission(string $permissionId): Permission
{
$em = $this->game->getEntityManager();
$result = $em->getRepository(Permission::class)->find($permissionId);
if ($result) {
return $result;
} else {
throw new PermissionIdNotFoundException("Permission {$permissionId} was not found.");
}
}
/**
* Allows an actor a permission given by the permission id.
* @param PermissionableInterface $actor
* @param string $permissionId
*/
public function allow(
PermissionableInterface $actor,
string $permissionId
) {
if ($actor->hasPermission($permissionId)) {
if ($this->isAllowed($actor, $permissionId) == false) {
$permission = $actor->getPermission($permissionId);
$permission->setState(static::Allowed);
}
} else {
$permission = $this->findPermission($permissionId);
$actor->addPermission($permission, static::Allowed);
}
}
/**
* Denies an actor a permission given by the permission id.
* @param PermissionableInterface $actor
* @param string $permissionId
*/
public function deny(
PermissionableInterface $actor,
string $permissionId
) {
if ($actor->hasPermission($permissionId)) {
if ($this->isDenied($actor, $permissionId) == false) {
$permission = $actor->getPermission($permissionId);
$permission->setState(static::Denied);
}
} else {
$permission = $this->findPermission($permissionId);
$actor->addPermission($permission, static::Denied);
}
}
/**
* Removes a permission from an actor.
* @param PermissionableInterface $actor
* @param string $permissionId
*/
public function remove(
PermissionableInterface $actor,
string $permissionId
) {
if ($actor->hasPermission($permissionId)) {
$permissionAssoc = $actor->getPermission($permissionId);
$actor->removePermission($permissionId);
}
}
}
+48 -9
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core\Tools\Model;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionableInterface;
/**
* Tools to work with a permission type field.
@@ -12,32 +13,70 @@ trait PermissionAssociationable
{
/**
* @Id @ManyToOne(targetEntity="LotGD\Core\Models\Permission", inversedBy="permission")
* @JoinColumn(name="permission_id", referencedColumnName="id")
* @JoinColumn(name="permission", referencedColumnName="id")
*/
protected $permission;
/** @Column(type="integer") */
protected $permissionState;
public function getId(): string
{
return $this->permission->getId();
}
public function getLibrary(): string
{
return $this->permission->getLibrary();
public function __construct(PermissionableInterface $owner, Permission $permission, int $state) {
$this->owner = $owner;
$this->permission = $permission;
$this->permissionState = $state;
}
/**
* Returns the current state of the permission.
* @return int
*/
public function getState(): int
{
return $this->permissionState;
}
/**
* Sets the current state of the permission.
* @param int $state
*/
public function setState(int $state)
{
$this->permissionState = $state;
}
/**
* Checks if this permission is set to a given state.
* @param int $state
* @return bool
*/
public function checkState(int $state): bool
{
return $this->permissionState == $state ? true : false;
}
/**
* Returns the permission id.
* @see Permission->getId()
* @return string
*/
public function getId(): string
{
return $this->permission->getId();
}
/**
* Returns the permission library.
* @see Permission->getLibrary()
* @return string
*/
public function getLibrary(): string
{
return $this->permission->getLibrary();
}
/**
* Returns the Permission entity.
* @return Permission
*/
public function getPermission(): Permission
{
return $this->permission;
+36
View File
@@ -3,9 +3,12 @@ declare(strict_types=1);
namespace LotGD\Core\Tools\Model;
use LotGD\Core\Exceptions\PermissionAlreadyExistsException;
use LotGD\Core\Exceptions\PermissionDoesNotExistException;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionAssociationInterface;
/**
* Tools to work with a permission type field.
*/
@@ -16,6 +19,12 @@ trait Permissionable
protected function loadPermissions()
{
if (empty($this->permissionAssociationEntity)) {
throw new PermissionAssociationEntityMissingException(
"The permissionable entity does not have the property permissionAssociationEntity set."
);
}
if (empty($this->_permissions)) {
foreach ($this->permissions as $permission) {
$this->_permissions[$permission->getId()] = $permission;
@@ -43,4 +52,31 @@ trait Permissionable
return $this->_permissions[$permissionId]->getPermission();
}
public function addPermission(Permission $permission, int $state)
{
$this->loadPermissions();
if ($this->hasPermission($permission->getId())) {
$permissionId = $permission->getId();
throw new PermissionAlreadyExistsException("The permission with the id {$permissionId} has already been set on this actor.");
} else {
$permissionAssoc = new $this->permissionAssociationEntity($this, $permission, $state);
$this->permissions->add($permissionAssoc);
$this->_permissions[$permissionAssoc->getId()] = $permissionAssoc;
}
}
public function removePermission(string $permissionId)
{
$this->loadPermissions();
if ($this->hasPermission($permissionId)) {
$permissionAssoc = $this->getPermission($permissionId);
$this->permissions->removeElement($permissionAssoc);
unset($this->_permissions[$permissionId]);
} else {
throw new PermissionDoesNotExistException("The permission with the id {$permissionId} has not been set on this actor.");
}
}
}
+187
View File
@@ -7,6 +7,9 @@ use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Game;
use LotGD\Core\PermissionManager;
use LotGD\Core\Exceptions\PermissionAlreadyExistsException;
use LotGD\Core\Exceptions\PermissionDoesNotExistException;
use LotGD\Core\Exceptions\PermissionIdNotFoundException;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionableInterface;
use LotGD\Core\Models\PermissionAssociationInterface;
@@ -60,6 +63,26 @@ class PermissionManagerTest extends CoreModelTestCase
$this->assertInstanceOf(UserPermissionAssociation::class, $permission);
}
public function testIfAddingAnAlreadySetPermissionToAnUserResultsInException()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $em->getRepository(Permission::class)->find("test/permission_two");
$this->expectException(PermissionAlreadyExistsException::class);
$user->addPermission($permission, PermissionManager::Denied);
}
public function testIfRemovingANotSetPermissionFromAnUserResultsInException()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $em->getRepository(Permission::class)->find("test/permission_tri");
$this->expectException(PermissionDoesNotExistException::class);
$user->removePermission("test/permission_tri");
}
public function testIfHasPermissionSetWorksAsExpected()
{
$em = $this->getEntityManager();
@@ -96,6 +119,170 @@ class PermissionManagerTest extends CoreModelTestCase
$this->assertFalse($permissionManager->isDenied($user, "test/permission_none"));
}
public function testIfAllowingAnAllowedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->allow($user, "test/permission_one");
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
}
public function testIfAllowingAnDeniedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$permissionManager->allow($user, "test/permission_two");
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_two"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_two"));
}
public function testIfAllowingANonExistingPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->allow($user, "test/permission_tri");
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_tri"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_tri"));
}
public function testIfDenyingAnAllowedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$permissionManager->deny($user, "test/permission_one");
$this->assertTrue($permissionManager->isDenied($user, "test/permission_one"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_one"));
}
public function testIfDenyingAnDeniedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$permissionManager->deny($user, "test/permission_two");
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
}
public function testIfDenyingANonExistingPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->deny($user, "test/permission_tri");
$this->assertTrue($permissionManager->isDenied($user, "test/permission_tri"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_tri"));
}
public function testIfRemovingAnAllowedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$permissionManager->remove($user, "test/permission_one");
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_one"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_one"));
}
public function testIfRemovingADeniedPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$permissionManager->remove($user, "test/permission_two");
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_two"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_two"));
}
public function testIfRemovingANonExistingPermissionWorks()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$permissionManager->remove($user, "test/permission_tri");
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$em->flush();
$em->clear();
$user = $em->getRepository(User::class)->find(1);
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
}
public function testIfRequestingANonExistingPermissionThrowsAnException()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->expectException(PermissionIdNotFoundException::class);
$permissionManager->allow($user, "test/non_existing_permission");
}
public function testSomething()
{
$this->assertTrue(True);
+3 -1
View File
@@ -22,9 +22,11 @@ class User implements PermissionableInterface {
private $id;
/** @Column(type="string", length=50); */
private $name;
/** @OneToMany(targetEntity="UserPermissionAssociation", mappedBy="owner", cascade={"persist", "remove"}) */
/** @OneToMany(targetEntity="UserPermissionAssociation", mappedBy="owner", cascade={"persist", "remove"}, orphanRemoval=true) */
private $permissions;
private $permissionAssociationEntity = UserPermissionAssociation::class;
public function __construct()
{
$this->permissions = new ArrayCollection();
@@ -18,6 +18,7 @@ class UserPermissionAssociation implements PermissionAssociationInterface {
/**
* @Id @ManyToOne(targetEntity="User", inversedBy="permissions")
* @JoinColumn(name="owner", referencedColumnName="id")
*/
private $owner;
}
+4 -4
View File
@@ -5,12 +5,12 @@ testUsers:
name: "Test User 1"
testUserAssociations:
-
owner_id: 1
permission_id: "test/permission_one"
owner: 1
permission: "test/permission_one"
permissionState: 1
-
owner_id: 1
permission_id: "test/permission_two"
owner: 1
permission: "test/permission_two"
permissionState: -1
permissions: