<?php declare(strict_types=1);namespace App\Security;use App\Entity\LeadInterface;use App\Entity\OrganizationInterface;use App\Entity\PageInterface;use App\Entity\SiteInterface;use App\Entity\UserInterface;use App\Repository\SiteRepository;use Symfony\Component\HttpFoundation\RequestStack;use Symfony\Component\Security\Core\Authorization\Voter\Voter;use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;class AdminEntityAccessVoter extends Voter{ /** * Available voter attribute. * * @see $this->supports() */ const ACCEED = 'ACCEED'; /** * The current site. * * @var SiteInterface */ protected $site; /** * The current toutre name. * * @var string */ protected $routeName; /** * Constructor * * @param RequestStack $requestStack * @param SiteRepository $siteRepository */ public function __construct(RequestStack $requestStack, SiteRepository $siteRepository) { $request = $requestStack->getCurrentRequest(); $this->site = $siteRepository->findOneBy([ 'url' => $request->getSchemeAndHttpHost() ]); $this->routeName = $request->attributes->get('_route'); } /** * {@inheritDoc} */ protected function supports(string $attribute, $subject): bool { if ('admin' !== $this->routeName || self::ACCEED !== $attribute) { return false; } return true; } /** * {@inheritDoc} */ protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool { if (!$this->site) { return true; } $user = $token->getUser(); if (!$user instanceof UserInterface) { // Deny access to anonymous users. return false; } return $this->canAcceed($subject, $user); } /** * Whether the current user can acceed or not. * * @param $subject * @param UserInterface $user * @return boolean */ private function canAcceed($subject, UserInterface $user): bool { if (!$this->site && in_array('ROLE_ADMIN', $user->getRoles())) { // Admin can acceed to create new sites for example. return true; } if ($subject === null) { // $subject is null when creating the entity. return true; } $currentOrganization = $this->site->getOrganization(); if ($subject instanceof OrganizationInterface) { return $currentOrganization === $subject; } if ($subject instanceof SiteInterface) { return $currentOrganization === $subject->getOrganization(); } if ($subject instanceof PageInterface) { return $currentOrganization === $subject->getSite()->getOrganization(); } if ($subject instanceof LeadInterface) { return $currentOrganization === $subject->getFormPage()->getSite()->getOrganization(); } if ($subject instanceof UserInterface) { return $subject->getOrganizations()->contains($subject); } return false; }}