Added Role hierarchy service.
Signed-off-by: Gergely Polonkai <polesz@w00d5t0ck.info>
This commit is contained in:
		@@ -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')));
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
@@ -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;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -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
 | 
			
		||||
	 */
 | 
			
		||||
 
 | 
			
		||||
@@ -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());
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										57
									
								
								src/KekRozsak/SecurityBundle/Service/RoleHierarchy.php
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								src/KekRozsak/SecurityBundle/Service/RoleHierarchy.php
									
									
									
									
									
										Normal 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();
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
		Reference in New Issue
	
	Block a user