src/Security/Voter/TokenVoter.php line 17
<?php
namespace App\Security\Voter;
use App\Entity\Action;
use App\Entity\UserRole;
use App\Entity\EntityName;
use App\Entity\Permission;
use App\Entity\Refill;
use Doctrine\ORM\EntityManagerInterface;
use Doctrine\Persistence\ManagerRegistry;
use Symfony\Bundle\SecurityBundle\Security;
use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
class TokenVoter extends Voter
{
private $security, $actions, $doctrine, $em;
public function __construct(Security $security, ManagerRegistry $doctrine)
{
$this->em = $doctrine->getManager();
// TODO: (whole project) only use $doctrine->getRepository or $em->getRepository, not both!!! Make cleaner!!!!!
$actionObjectList = $this->em->getRepository(Action::class)->findAll();
$this->actions = array(); // [NEW, EDIT, ...]. It was CRUD_*action* but this is better
$this->security = $security;
$this->doctrine = $doctrine;
foreach ($actionObjectList as $action)
{
array_push($this->actions, $action->getName());
}
}
protected function supports(string $attribute, $subject): bool
{
return in_array($attribute, $this->actions);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
return true;
// TODO review code for user without control of refill
$user = $token->getUser();
if (in_array('ROLE_ADMIN', $user->getRoles())) return true;
// Need to get the EntityName ID from $subject (new CategoryReport())
// Need to get the Action's ID from $attribute ("LIST")
// Need to check the right refill object, given the user ID (channel ID taken from user), the entity it's trying to access and what action they want to do...
// I can get the entity AND action from denyAccessUnlessGranted in the controller, user from $token->getUser. I've got everything!!
$refillRepo = $this->em->getRepository(Refill::class);
$entityNameRepo = $this->em->getRepository(EntityName::class);
$actionRepo = $this->em->getRepository(Action::class);
$userID = $user->getId();
$entityID = $entityNameRepo->findOneBy(['name' => $subject->getEntityName()])->getId();
$actionID = $actionRepo->findOneBy(['name' => $attribute])->getId();
$refill = $refillRepo->findRefillToUse($entityID, $actionID, $userID);
// If I don't find a user-specific refill and the user is in a channel
if (!$refill && $user->getChannel())
{
$refill = $refillRepo->findRefillToUse($entityID, $actionID, null, $user->getChannel()->getId());
}
if ($refill)
{
$refill->setUsed($refill->getUsed() + 1);
$this->em->persist($refill);
$this->em->flush();
return true;
}
return false;
}
}