Es gibt mehr Möglichkeiten, wie nur Daten von aktuell angemeldeten Benutzer anzuzeigen:
Die erste bevorzugte Art und Weise ist Symfony's ACL zu verwenden, sind hier more informations, how it works and how to do it in Sonata.
Wenn Sie keine ACL verwenden möchten, können Sie die Standardabfragen ändern, indem Sie eine Bedingung zur SQL-Abfrage (DQL-Abfrage) hinzufügen, z. B. 'WHERE adminId = 5'. Das wird mehr Arbeit sein, aber ich werde Ihnen ein einfaches Beispiel zeigen, wie es geht.
Ändern Sie die Definition Ihrer Verwaltungsdienste in services.xml, indem Sie einen neuen Setter hinzufügen setSecurityContext. Ich werde Admin verwenden, um einige Produkte aufzulisten und zu bearbeiten.
<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 ist ein Dienst, der Informationen über den aktuell angemeldeten Benutzer enthält.
In Acme/Bundle/DemoAdminBundle/Admin/ProductAdmin.php Setter setSecurityContext hinzufügen und Create Methode ändern:
<?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.
}
Benutzer ohne Rolle SONATA_ADMIN nicht alle Datensätze sehen können.
Zweiter Schritt - sichere einige spezielle Routen, zum Beispiel bearbeiten - Sie sollten überprüfen, ob der gerade angemeldete Administrator das angegebene Produkt bearbeiten kann.
Sie können Ihre own security voter (bevorzugte Lösung) erstellen oder benutzerdefinierte CRUD-Controller verwenden.
In benutzerdefinierten CRUD-Controller: Acme/Bundle/DemoAdminBundle/Controller/ProductController.php überladen 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);
}
}
Wie Sie sehen können, können Sie viele Methoden und Routen überladen, um jede Funktionalität hinzuzufügen, die Sie benötigen. Aber wie gesagt, das ist mehr Arbeit, also prüfen Sie zuerst, ob Symfony's ACL (oder einfach nur einen eigenen Sicherheitsvoter erstellen) in Ihrem Projekt benötigt wird oder nicht.
Für die Sicherung des Zugangs wäre es vielleicht besser mit einem [Voter] (http://symfony.com/doc/master/cookbook/security/voters.html). –
In der Tat. Ich habe die Antwort aktualisiert. Vielen Dank. – pulzarraider