Adds methods to read and check permissions.

This commit is contained in:
Vassyli
2016-10-31 18:31:11 +01:00
parent 3bf23f3ac7
commit 3b8537fab6
10 changed files with 200 additions and 43 deletions
-15
View File
@@ -1,15 +0,0 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
/**
* Extend this class to provide an association between an entity and a permission.
*/
abstract class PermissionAssociation
{
/** @OneToOne(targetEntity="Permission", mappedBy="owner") */
protected $permissionId;
/** @Column(type="int") */
protected $permissionState;
}
@@ -0,0 +1,12 @@
<?php
declare(strict_types=1);
namespace LotGD\Core\Models;
/**
* Extend this class to provide an association between an entity and a permission.
*/
interface PermissionAssociationInterface
{
}
+9 -2
View File
@@ -16,9 +16,16 @@ interface PermissionableInterface
public function hasPermission(string $permissionId): bool;
/**
* Returns the permission
* Returns the permission association.
* @param string $permissionId
* @return PermissionAssociationInterface
*/
public function getPermission(string $permissionId): PermissionAssociationInterface;
/**
* Returns the raw permission entity.
* @param string $permissionId
* @return Permission
*/
public function getPermission(string $permissionId): Permission;
public function getRawPermission(string $permissionId): Permission;
}
+39 -14
View File
@@ -3,21 +3,23 @@ declare(strict_types=1);
namespace LotGD\Core;
use LotGD\Core\Models\PermissionableInterface;
/**
* Permissions can be managed with the PermissionManager.
*
*
* The PermissionManager class provides methods to work with permissions. It can
* be used to create or delete permissions, to remove, allow or deny permissions
* to actors and to check whether an actor has a certain permission or if it is
* explicitely denied from him.
*
*
* The wording used in this class is:
* - allowed, the actor has a certain permission in the allowed state.
* - denied, the actor has a certain permission in the denied state.
*
*
* To make this more clear, the following table summarizes how different methods
* react.
*
*
* Method
* State: | Unset | Allowed | Denied
* -------------------+-------+---------+---------
@@ -29,7 +31,7 @@ class PermissionManager
{
const Allowed = 1;
const Denied = -1;
const Superuser = "lotgd/core/superuser";
const AddScenes = "lotgd/core/scene/add";
const EditScenes = "lotgd/core/scene/edit";
@@ -37,7 +39,18 @@ class PermissionManager
const AddCharacters = "lotgd/core/characters/add";
const EditCharacters = "lotgd/core/characters/edit";
const DeleteCharacters = "lotgd/core/characters/delete";
private $game;
/**
* Construct a permission manager.
* @param Game $g The game.
*/
public function __construct(Game $game)
{
$this->game = $game;
}
/**
* Checks if an actor has a permission set. No assumption can be made if it's allowed or denied.
* @param \LotGD\Core\PermissionableInterface $actor
@@ -45,12 +58,16 @@ class PermissionManager
* @return bool True if the permission has been set, be it allowed or denied.
*/
public function hasPermissionSet(
PermissionableInterface $actor,
PermissionableInterface $actor,
string $permissionId
): bool {
if ($actor->hasPermission($permissionId)) {
return true;
} else {
return false;
}
}
/**
* Checks if an actor is allowed a given permission.
* @param \LotGD\Core\PermissionableInterface $actor
@@ -58,12 +75,16 @@ class PermissionManager
* @return bool True if the actor has the permission set and it's state is allowed.
*/
public function isAllowed(
PermissionableInterface $actor,
PermissionableInterface $actor,
string $permissionId
): bool {
if ($actor->hasPermission($permissionId)) {
return $actor->getPermission($permissionId)->checkState(static::Allowed);
} else {
return false;
}
}
/**
* Checks if an actor is denied a given permission.
* @param \LotGD\Core\PermissionableInterface $actor
@@ -71,9 +92,13 @@ class PermissionManager
* @return bool True if the actor has the permission set and it's state is denied.
*/
public function isDenied(
PermissionableInterface $actor,
PermissionableInterface $actor,
string $permissionId
): bool {
if ($actor->hasPermission($permissionId)) {
return $actor->getPermission($permissionId)->checkState(static::Denied);
} else {
return false;
}
}
}
+26 -1
View File
@@ -11,10 +11,35 @@ use LotGD\Core\Models\Permission;
trait PermissionAssociationable
{
/**
* @ManyToOne(targetEntity="LotGD\Core\Models\Permission", inversedBy="permission")
* @Id @ManyToOne(targetEntity="LotGD\Core\Models\Permission", inversedBy="permission")
* @JoinColumn(name="permission_id", 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 getState(): int
{
return $this->permissionState;
}
public function checkState(int $state): bool
{
return $this->permissionState == $state ? true : false;
}
public function getPermission(): Permission
{
return $this->permission;
}
}
+8 -1
View File
@@ -4,6 +4,7 @@ declare(strict_types=1);
namespace LotGD\Core\Tools\Model;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionAssociationInterface;
/**
* Tools to work with a permission type field.
@@ -29,11 +30,17 @@ trait Permissionable
return isset($this->_permissions[$permissionId]);
}
public function getPermission(string $permissionId): Permission
public function getPermission(string $permissionId): PermissionAssociationInterface
{
$this->loadPermissions();
return $this->_permissions[$permissionId];
}
public function getRawPermission(string $permissionId): Permission
{
$this->loadPermissions();
return $this->_permissions[$permissionId]->getPermission();
}
}
+81 -4
View File
@@ -3,13 +3,18 @@ declare(strict_types=1);
namespace LotGD\Core\Tests\Managers;
use Doctrine\ORM\EntityManagerInterface;
use LotGD\Core\Game;
use LotGD\Core\PermissionManager;
use LotGD\Core\Models\Permission;
use LotGD\Core\Models\PermissionableInterface;
use LotGD\Core\Models\PermissionAssociation;
use LotGD\Core\Models\PermissionAssociationInterface;
use LotGD\Core\Tools\Model\Permissionable;
use LotGD\Core\Tests\CoreModelTestCase;
use LotGD\Core\Tests\Ressources\Models\User;
use LotGD\Core\Tests\Ressources\Models\UserPermissionAssociation;
use LotGD\Core\Tests\Ressources\TestModels\User;
use LotGD\Core\Tests\Ressources\TestModels\UserPermissionAssociation;
/**
* Description of PermissionManagerTest
@@ -18,9 +23,81 @@ class PermissionManagerTest extends CoreModelTestCase
{
protected $dataset = "permission-manager";
public function getPermissionManager(EntityManagerInterface $em): PermissionManager
{
$this->game = $this->getMockBuilder(Game::class)
->disableOriginalConstructor()
->getMock();
$this->game->method('getEntityManager')->willReturn($em);
return new PermissionManager($this->game);
}
public function testUserHasPermission()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$this->assertTrue($user->hasPermission("test/permission_one"));
$this->assertTrue($user->hasPermission("test/permission_two"));
}
public function testUserReturnsPermission()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $user->getRawPermission("test/permission_one");
$this->assertInstanceOf(Permission::class, $permission);
}
public function testUserReturnsPermissionAssociation()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permission = $user->getPermission("test/permission_one");
$this->assertInstanceOf(UserPermissionAssociation::class, $permission);
}
public function testIfHasPermissionSetWorksAsExpected()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->hasPermissionSet($user, "test/permission_one"));
$this->assertTrue($permissionManager->hasPermissionSet($user, "test/permission_two"));
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_tri"));
$this->assertFalse($permissionManager->hasPermissionSet($user, "test/permission_none"));
}
public function testIfIsAllowedSetWorksAsExpected()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertTrue($permissionManager->isAllowed($user, "test/permission_one"));
$this->assertFalse($permissionManager->isAllowed($user, "test/permission_two"));
$this->assertFalse($permissionManager->isAllowed($user, "test/permission_tri"));
$this->assertFalse($permissionManager->isAllowed($user, "test/permission_none"));
}
public function testIfIsDeniedSetWorksAsExpected()
{
$em = $this->getEntityManager();
$user = $em->getRepository(User::class)->find(1);
$permissionManager = $this->getPermissionManager($em);
$this->assertFalse($permissionManager->isDenied($user, "test/permission_one"));
$this->assertTrue($permissionManager->isDenied($user, "test/permission_two"));
$this->assertFalse($permissionManager->isDenied($user, "test/permission_tri"));
$this->assertFalse($permissionManager->isDenied($user, "test/permission_none"));
}
public function testSomething()
{
$this->assertTrue(True);
}
}
+7
View File
@@ -3,12 +3,14 @@ declare(strict_types=1);
namespace LotGD\Core\Tests\Ressources\TestModels;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Models\PermissionableInterface;
use LotGD\Core\Tools\Model\Permissionable;
/**
* @Entity
* @Table("TestUsers")
@@ -23,6 +25,11 @@ class User implements PermissionableInterface {
/** @OneToMany(targetEntity="UserPermissionAssociation", mappedBy="owner", cascade={"persist", "remove"}) */
private $permissions;
public function __construct()
{
$this->permissions = new ArrayCollection();
}
public function getId(): int
{
return $this->id;
@@ -6,18 +6,18 @@ namespace LotGD\Core\Tests\Ressources\TestModels;
use Doctrine\ORM\Mapping\Entity;
use Doctrine\ORM\Mapping\Table;
use LotGD\Core\Models\PermissionAssociation;
use LotGD\Core\Models\PermissionAssociationInterface;
use LotGD\Core\Tools\Model\PermissionAssociationable;
/**
* @Entity
* @Table("TestUserAssociations")
*/
class UserPermissionAssociation {
class UserPermissionAssociation implements PermissionAssociationInterface {
use PermissionAssociationable;
/**
* @Id @ManyToOne(targetEntity="User", inversedBy="permissions")
* @Id @ManyToOne(targetEntity="User", inversedBy="permissions")
*/
private $owner;
}
+15 -3
View File
@@ -6,11 +6,23 @@ testUsers:
testUserAssociations:
-
owner_id: 1
permission_id: "lotgd/core/superuser"
permission_id: "test/permission_one"
permissionState: 1
-
owner_id: 1
permission_id: "test/permission_two"
permissionState: -1
permissions:
-
id: "lotgd/core/superuser"
id: "test/permission_one"
library: "lotgd/core"
name: "Superuser. Superseeds all flags."
name: "Test permission."
-
id: "test/permission_two"
library: "lotgd/core"
name: "Test permission."
-
id: "test/permission_tri"
library: "lotgd/core"
name: "Test permission."