Adds methods to read and check permissions.
This commit is contained in:
@@ -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
|
||||
{
|
||||
|
||||
}
|
||||
@@ -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
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
@@ -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."
|
||||
Reference in New Issue
Block a user