Added Role hierarchy service.

Signed-off-by: Gergely Polonkai <polesz@w00d5t0ck.info>
This commit is contained in:
Polonkai Gergely
2012-08-15 09:59:37 +02:00
parent 3b9788462c
commit b613d6223a
6 changed files with 147 additions and 57 deletions

View File

@@ -0,0 +1,16 @@
<?php
namespace KekRozsak\SecurityBundle\DependencyInjection\Compiler;
use Symfony\Component\DependencyInjection\Compiler\CompilerPassInterface;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use Symfony\Component\DependencyInjection\Reference;
class OverrideServiceCompilerPass implements CompilerPassInterface
{
public function process(ContainerBuilder $container)
{
$definition = $container->getDefinition('security.role_hierarchy');
$definition->setClass('KekRozsak\SecurityBundle\Service\RoleHierarchy');
$definition->setArguments(array(new Reference('doctrine')));
}
}

View File

@@ -78,62 +78,6 @@ class Role implements RoleInterface
return $this;
}
/**
* @var boolean $admin
* @ORM\Column(type="boolean", nullable=false)
*/
protected $admin;
/**
* Set admin
*
* @param boolean $admin
* @return Role
*/
public function setAdmin($admin)
{
$this->admin = $admin;
return $this;
}
/**
* Get admin
*
* @return boolean
*/
public function isAdmin()
{
return $this->admin;
}
/**
* @var boolean $superadmin
* @ORM\Column(type="boolean", nullable=false)
*/
protected $superAdmin;
/**
* Set superadmin
*
* @param boolean $superadmin
* @return Role
*/
public function setSuperadmin($superadmin)
{
$this->superadmin = $superadmin;
return $this;
}
/**
* Get superadmin
*
* @return boolean
*/
public function getSuperadmin()
{
return $this->superadmin;
}
/**
* @var text description
* @ORM\Column(type="string", length=150, nullable=true)
@@ -199,5 +143,27 @@ class Role implements RoleInterface
{
return $this->shortDescription;
}
/**
* List of inherited Roles
*
* @ORM\ManyToMany(targetEntity="Role", fetch="LAZY")
* @ORM\JoinTable(name="role_hierarchy", joinColumns={
* @ORM\JoinColumn(name="parent_role_id", referencedColumnName="id")
* }, inverseJoinColumns={
* @ORM\JoinColumn(name="child_role_id", referencedColumnName="id")
* })
*/
protected $inheritedRoles;
/**
* Get all inherited roles
*
* @return Doctrine\Common\Collections\ArrayCollection
*/
public function getInheritedRoles()
{
return $this->inheritedRoles;
}
}

View File

@@ -323,7 +323,18 @@ class User implements UserInterface, AdvancedUserInterface
}
/**
* Get all roles
* Get all roles as an ArrayCollection
*
* @return Doctrine\Common\Collections\ArrayCollection
*/
public function getRolesCollection()
{
return $this->roles;
}
/**
* Get all roles, for UserInterface implementation. To get the
* collection, use getRolesCollection() instead
*
* @return array
*/

View File

@@ -3,7 +3,15 @@
namespace KekRozsak\SecurityBundle;
use Symfony\Component\HttpKernel\Bundle\Bundle;
use Symfony\Component\DependencyInjection\ContainerBuilder;
use KekRozsak\SecurityBundle\DependencyInjection\Compiler\OverrideServiceCompilerPass;
class KekRozsakSecurityBundle extends Bundle
{
public function build(ContainerBuilder $container)
{
parent::build($container);
$container->addCompilerPass(new OverrideServiceCompilerPass());
}
}

View File

@@ -0,0 +1,57 @@
<?php
namespace KekRozsak\SecurityBundle\Service;
use Symfony\Component\Security\Core\Role\RoleHierarchyInterface;
use Symfony\Bridge\Doctrine\RegistryInterface;
class RoleHierarchy implements RoleHierarchyInterface
{
private $hierarchy;
private $roleRepo;
private $map;
public function __construct(RegistryInterface $doctrine)
{
$this->hierarchy = array();
$this->roleRepo = $doctrine->getRepository('KekRozsakSecurityBundle:Role');
$this->buildRoleMap();
}
public function getReachableRoles(array $roles)
{
$reachableRoles = array();
foreach ($roles as $role) {
if (!isset($this->map[$role->getRole()])) {
continue;
}
foreach ($this->map[$role->getRole()] as $r) {
if (($childRole = $this->roleRepo->findOneByName($r)) !== null) {
$reachableRoles[] = $childRole;
}
}
}
return $reachableRoles;
}
private function buildRoleMap()
{
$this->map = array();
$roles = $this->roleRepo->findAll();
foreach ($roles as $mainRole) {
$main = $mainRole->getRole();
$this->map[$main] = array();
foreach ($mainRole->getInheritedRoles() as $childRole) {
$this->map[$main][] = $childRole->getRole();
// TODO: This is one-level only. Get as deep as possible.
// BEWARE OF RECURSIVE NESTING!
foreach ($childRole->getInheritedRoles() as $grandchildRole) {
$this->map[$main][] = $grandchildRole->getRole();
}
}
}
}
}