2012-10-11 27 views
7

He configurado una interfaz de administración de sonata que permite a los usuarios crear contenido específico, pero ¿cómo impido a los usuarios editar contenido creado por otros usuarios?Sonata Admin - Permitir solo mostrar qué usuario registrado ha creado

Por razones de argumento, un usuario inicia sesión y crea un blog. En la vista de lista de blogs, solo deben mostrarse los blogs creados por el usuario.

Actualmente, todo se muestra a todos los usuarios. Tengo configuración de grupos/roles para restringir el acceso a las áreas de administración, lo que funciona bien.

La única manera en la que actualmente solo puedo pensar en mostrar un contenido de usuario específico conectado, ¿es anular las plantillas?

Pero, sin duda, esta es una configuración de configuración simple y obvia?

Respuesta

13

hay más opciones de cómo abrir sólo los datos de usuario actualmente conectado:

La primera forma preferida es usar Symfony's ACL, aquí están more informations, how it works and how to do it in Sonata.

Si no desea utilizar ACL, puede cambiar las consultas predeterminadas agregando alguna condición a la consulta SQL (consulta DQL), por ejemplo 'DONDE adminId = 5'. Esto será más trabajo, pero te mostraré un ejemplo básico de cómo hacerlo.

Cambie su definición de sus servicios de administración en services.xml agregando el nuevo setter setSecurityContext. Utilizaré el administrador para enumerar y editar algunos productos.

<service id="acme_demo_admin.product" class="Acme\Bundle\DemoAdminBundle\Admin\ProductAdmin"> 
     <tag name="sonata.admin" manager_type="orm" group="product_group" label_catalogue="admin" label="Products"/> 
     <argument /> 
     <argument>Acme\Bundle\DemoAdminBundle\Entity\Product</argument> 
     <argument>AcmeDemoAdminBundle:ProductAdmin</argument> 

     <call method="setSecurityContext"> 
      <argument type="service" id="security.context" /> 
     </call> 
    </service> 

SecurityContext es el servicio, que contiene información sobre el usuario actualmente registrado.

En Acme/Bundle/DemoAdminBundle/Admin/ProductAdmin.php añadir setSecurityContext colocador y cambiar el método de CreateQuery:

<?php 

namespace Acme\Bundle\DemoAdminBundle\Admin; 

use Symfony\Component\Security\Core\SecurityContextInterface; 
// ... 

class ProductAdmin extends Admin 
{ 
    /** 
    * Security Context 
    * @var \Symfony\Component\Security\Core\SecurityContextInterface 
    */ 
    protected $securityContext; 

    public function setSecurityContext(SecurityContextInterface $securityContext) 
    { 
     $this->securityContext = $securityContext; 
    } 

    protected function configureRoutes(RouteCollection $collection) 
    { 
     //remove all routes except those, you are using in admin and you can secure by yourself 
     $collection 
       ->clearExcept(array(
        'list', 
        'edit', 
       )) 
     ; 
    } 

    public function createQuery($context = 'list') 
    { 
     $queryBuilder = $this->getModelManager()->getEntityManager($this->getClass())->createQueryBuilder(); 

     //if is logged admin, show all data 
     if ($this->securityContext->isGranted('ROLE_ADMIN')) { 
      $queryBuilder->select('p') 
        ->from($this->getClass(), 'p') 
      ; 
     } else { 
      //for other users, show only data, which belongs to them 
      $adminId = $this->securityContext->getToken()->getUser()->getAdminId(); 

      $queryBuilder->select('p') 
        ->from($this->getClass(), 'p') 
        ->where('p.adminId=:adminId') 
        ->setParameter('adminId', $adminId, Type::INTEGER) 
      ; 
     } 

     $proxyQuery = new ProxyQuery($queryBuilder); 
     return $proxyQuery; 
    } 

    //... configureListFields, configureDatagridFilters etc. 
} 

Los usuarios sin papel SONATA_ADMIN no pueden ver todos los registros.

Segundo paso: asegurar algunas rutas especiales, por ejemplo editar - debe comprobar si el administrador actualmente registrado puede editar el producto especificado.

Puede crear su own security voter (solución preferida) o usar un controlador CRUD personalizado.

En el controlador CRUD personalizado: Acme/Bundle/DemoAdminBundle/Controller/ProductController.php sobrecarga editAcción.

<?php 
    namespace Acme\Bundle\DemoAdminBundle\Controller; 

    use Sonata\AdminBundle\Controller\CRUDController as Controller; 
    use Symfony\Component\Security\Core\Exception\AccessDeniedException; 


    class ProductAdminController extends Controller 
    { 
     public function editAction($id = null) 
     { 
      $request = $this->getRequest(); 
      $id = $request->get($this->admin->getIdParameter()); 

      $securityContext = $this->get('security.context'); 
      if (!$securityContext->isGranted('ROLE_ADMIN')) { 

       $adminId = $securityContext->getToken()->getUser()->getId(); 

       $accessGranted = //here you should check if user with adminId can edit product with $id 

       if (!$accessGranted) { 
        throw new AccessDeniedException(sprintf('Admin ID %s has no access to product with id %s', $adminId, $id)); 
       } 
      } 

      return parent::editAction($id); 
     } 

    } 

Como puede ver, puede sobrecargar muchos métodos y rutas para agregar cualquier funcionalidad que necesite. Pero como dije antes, esto es más trabajo, así que en lugar de sobrecargar los métodos, primero compruebe si la ACL de Symfony (o solo crear su propio votante de seguridad) es lo que necesita en su proyecto o no.

+0

Para asegurar el acceso tal vez sería mejor con un [Votante] (http://symfony.com/doc/master/cookbook/security/voters.html). –

+0

De hecho. He actualizado la respuesta. Gracias. – pulzarraider

Cuestiones relacionadas