<?php/** * Created by IntelliJ IDEA. * User: dogukan * Date: 2019-01-27 * Time: 18:21 */namespace App\Security;use App\Entity\Role;use App\Entity\Route;use App\Service\SessionService;use Doctrine\ORM\EntityManagerInterface;use Psr\Cache\CacheItemPoolInterface;use Symfony\Component\HttpFoundation\Request;use Symfony\Component\HttpFoundation\RequestStack;use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;use Symfony\Component\Security\Core\Authorization\Voter\Voter;use Symfony\Component\Security\Core\Security;/** * Class CrudVoter * @package App\Security */class CrudVoter extends Voter{ const ATTR = 'CRUD_VOTER'; /** * @var EntityManagerInterface */ private $entityManager; /** * @var Request|null */ private $request = null; /** * @var Security */ private $security; /** * @var CacheItemPoolInterface */ private $cacheItemPool; /** * @var SessionService */ private $sessionService; /** * CrudVoter constructor. * @param EntityManagerInterface $entityManager * @param RequestStack $requestStack * @param Security $security * @param CacheItemPoolInterface $cacheItemPool * @param SessionService $sessionService */ public function __construct( EntityManagerInterface $entityManager, RequestStack $requestStack, Security $security, CacheItemPoolInterface $cacheItemPool, SessionService $sessionService ) { $this->entityManager = $entityManager; $this->request = $requestStack->getMasterRequest(); $this->security = $security; $this->cacheItemPool = $cacheItemPool; $this->sessionService = $sessionService; } /** * @return EntityManagerInterface */ public function getEntityManager(): EntityManagerInterface { return $this->entityManager; } /** * @return Request|null */ public function getRequest(): ?Request { return $this->request; } /** * @return Security */ public function getSecurity(): Security { return $this->security; } /** * {@inheritdoc} */ protected function supports($attribute, $subject) { return $attribute === self::ATTR && $this->request !== null; } /** * {@inheritdoc} */ protected function voteOnAttribute($attribute, $subject, TokenInterface $token) { // todo: may be we can handle security exceptions to throw more meaningful exceptions $endpoint = $this->request->attributes->get('_route'); $routeRoles = []; $cacheItem = $this->cacheItemPool->getItem($endpoint); if ($cacheItem->isHit()) { $routeRoles = $cacheItem->get(); } else { /** @var Route $route */ $route = $this->entityManager ->getRepository(Route::class) ->findOneBy(['endpoint' => $endpoint]); if ($route !== null) { $routeRoles = $route->getRoles()->map(function (Role $role) { return $role->getIdentifier(); })->toArray(); } } return $this->sessionService->hasOneOfRoles($routeRoles); }}