ci sono più opzioni come visualizzare solo i dati di utente attualmente connesso:
Il primo modo preferito è quello di utilizzare Symfony's ACL, qui more informations, how it works and how to do it in Sonata.
Se non si desidera utilizzare ACL, è possibile modificare le query predefinite con l'aggiunta di qualche condizione di query SQL (query DQL), per esempio 'WHERE adminId = 5'. Questo sarà più lavoro, ma ti mostrerò un esempio di base, come farlo.
Modificare la definizione dei servizi di amministrazione in services.xml aggiungendo nuovo setter setSecurityContext. Userò admin per elencare e modificare alcuni prodotti.
<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 è un servizio che contiene informazioni sull'utente attualmente registrato.
In Acme/Bundle/DemoAdminBundle/Amministratore/ProductAdmin.php aggiungere setSecurityContext setter e cambiare metodo 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.
}
Gli utenti senza ruolo SONATA_ADMIN non possono vedere tutti i record.
Secondo passaggio - proteggere alcuni percorsi speciali, per exmaple modificare - è necessario verificare se l'amministratore attualmente loggato può modificare il prodotto specificato.
È possibile creare il own security voter (soluzione preferito) o utilizzare personalizzato CRUD Controller.
Nel controller CRUD personalizzato: Acme/Bundle/DemoAdminBundle/Controller/ProductController.php overload editAction.
<?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);
}
}
Come si può vedere, è possibile sovraccaricare molti metodi e percorsi di aggiungere qualsiasi funzionalità, è necessario. Ma come ho detto prima, questo è più lavoro, così invece di metodi di sovraccarico, controllare prima se Symfony`s ACL (o semplicemente la creazione di propri votanti di sicurezza) è quello che vi serve nel progetto o meno.
Per assicurare l'accesso forse sarebbe meglio con un [Voter] (http://symfony.com/doc/master/cookbook/security/voters.html). –
Infatti. Ho aggiornato la risposta. Grazie. – pulzarraider