2012-08-28 16 views
5

Estoy ocupado con una aplicación Symfony2 que necesita algunos permisos de ACL.Acceso a la ACL de Symfony2 a múltiples objetos para múltiples usuarios

Soy un novato con Symfony2, así que no estoy seguro de si estoy viendo esto de la manera correcta.

Tengo varios clientes, cada uno con varias cuentas.

Tengo un súper administrador (ROLE_SUPER_ADMIN) que tiene acceso a todos los clientes y todas las cuentas. Luego tengo una función de administrador (ROLE_ADMIN), que solo se permitirá el acceso a un cliente específico y todas las cuentas para esos clientes. Luego están los agentes (ROLE_AGENT), que solo deberían tener permiso para ciertas cuentas para los clientes.

que vi en la documentación de Symfony que para dar al usuario acceso a un objeto específico, puedo usar el siguiente código:

// creating the ACL 
$aclProvider = $this->get('security.acl.provider'); 
$objectIdentity = ObjectIdentity::fromDomainObject($account); 
$acl = $aclProvider->createAcl($objectIdentity); 

// retrieving the security identity of the currently logged-in user 
$securityContext = $this->get('security.context'); 
$user = $securityContext->getToken()->getUser(); 
$securityIdentity = UserSecurityIdentity::fromAccount($user); 

// grant owner access  
$acl->insertObjectAce($securityIdentity, MaskBuilder::MASK_OWNER); 
$aclProvider->updateAcl($acl); 

Así que cuando se crea una nueva cuenta, puedo dar la sesión actual en acceso de usuario a la cuenta recién creada. ¿Pero cómo otorgo acceso a todos los otros usuarios del acceso de cliente a la cuenta?

No quiero recorrer todos los usuarios y ejecutar el código anterior para cada usuario.

Entonces, por ejemplo, al ver todos los clientes, necesito saber a qué clientes tiene acceso el usuario, o cuando veo las cuentas, necesito saber a qué cuentas tiene acceso el usuario.

También cuando se agrega un nuevo usuario a un cliente, el usuario automáticamente necesita tener acceso a todas las cuentas para ese cliente.

Como nota al margen, solo necesito saber si el usuario tiene acceso a la cuenta/cliente. Si un usuario tiene acceso, entonces se le permite automáticamente ver/editar/eliminar, etc.

+2

Si necesita asignar permisos a cada usuario en un rol específico, debería usar 'ACL' basado en roles ... que se parece mucho a la cuenta. Debería poder escribir algún código de ejemplo (en las próximas horas). Sin embargo, si los roles no son algo que buscas, ** necesitarás ** iterar a través de cada usuario al que quieras asignar permiso ... –

Respuesta

0

Para este caso utilicé un servicio de seguridad personalizado que verifica las relaciones ManyToMany entre entidades. No es la decisión ideal, pero tenga en cuenta.

Primero tenemos que hacer listener que se activará en cada acción del controlador.

class SecurityListener 
{ 
    protected $appSecurity; 

    function __construct(AppSecurity $appSecurity) 
    { 
     $this->appSecurity = $appSecurity; 
    } 

    public function onKernelController(FilterControllerEvent $event) 
    { 
     $c = $event->getController(); 

     /* 
     * $controller passed can be either a class or a Closure. This is not usual in Symfony2 but it may happen. 
     * If it is a class, it comes in array format 
     */ 
     if (!is_array($c)) { 
      return; 
     } 

     $hasAccess = $this->appSecurity->hasAccessToContoller($c[0], $c[1], $event->getRequest()); 

     if(!$hasAccess) { 
      throw new AccessDeniedHttpException('Access denied.'); 
     } 

    } 
} 

En servicio tenemos acceso a solicitud, instancia de controlador y acción llamada. Entonces podemos tomar una decisión tener acceso de usuario o no.

class AppSecurity 
{ 
    protected $em; 
    protected $security; 
    /** @var $user User */ 
    protected $user; 

    public function __construct(EntityManager $em, SecurityContext $security) 
    { 
     $this->em = $em; 
     $this->security = $security; 

     if($security->getToken() !== null && !$security->getToken() instanceof AnonymousToken) { 
      $this->user = $security->getToken()->getUser(); 
     } 
    } 

    /** 
    * @param $controller 
    * @param string $action 
    */ 
    public function hasAccessToContoller($controller, $action, Request $request) 
    { 
     $attrs = $request->attributes->all(); 
     $client = $attrs['client']; 

     /* db query to check link between logged user and request client */ 
    } 
} 

Si está utilizando anotaciones muy desagradables, como ParamConverter se puede extraer fácilmente listo para usar ENTIDADES desde la solicitud.

Cuestiones relacionadas