src/Security/Voters/ApplicationVoter.php line 18

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voters;
  3. use App\Entity\CPSUser;
  4. use App\Entity\OperatoreUser;
  5. use App\Entity\Pratica;
  6. use App\Entity\Servizio;
  7. use App\Entity\User;
  8. use App\Handlers\Servizio\ForbiddenAccessException;
  9. use App\Handlers\Servizio\ServizioHandlerRegistry;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  12. use Symfony\Component\Security\Core\Security;
  13. class ApplicationVoter extends Voter
  14. {
  15.   const EDIT 'edit';
  16.   const VIEW 'view';
  17.   const SUBMIT 'submit';
  18.   const ASSIGN 'assign';
  19.   const ACCEPT_OR_REJECT 'accept_or_reject';
  20.   const WITHDRAW 'withdraw';
  21.   const COMPILE 'compile';
  22.   const DELETE 'delete';
  23.   /**
  24.    * @var ServizioHandlerRegistry
  25.    */
  26.   private $servizioHandlerRegistry;
  27.   /**
  28.    * @var Security
  29.    */
  30.   private $security;
  31.   public function __construct(Security $securityServizioHandlerRegistry $servizioHandlerRegistry)
  32.   {
  33.     $this->security $security;
  34.     $this->servizioHandlerRegistry $servizioHandlerRegistry;
  35.   }
  36.   protected function supports($attribute$subject)
  37.   {
  38.     // if the attribute isn't one we support, return false
  39.     if (!in_array($attribute, [
  40.       self::EDIT,
  41.       self::VIEW,
  42.       self::SUBMIT,
  43.       self::ASSIGN,
  44.       self::ACCEPT_OR_REJECT,
  45.       self::WITHDRAW,
  46.       self::COMPILE,
  47.       self::DELETE
  48.     ])) {
  49.       return false;
  50.     }
  51.     // only vote on `Pratica` objects
  52.     if ($subject && !$subject instanceof Pratica) {
  53.       return false;
  54.     }
  55.     return true;
  56.   }
  57.   protected function voteOnAttribute($attribute$subjectTokenInterface $token)
  58.   {
  59.     $user $token->getUser();
  60.     if (!$user instanceof User) {
  61.       // the user must be logged in; if not, deny access
  62.       return false;
  63.     }
  64.     // you know $subject is a Pratica object, thanks to `supports()`
  65.     /** @var Pratica $pratica */
  66.     $pratica $subject;
  67.     switch ($attribute) {
  68.       case self::EDIT:
  69.         return $this->canEdit($pratica$user);
  70.       case self::VIEW:
  71.         return $this->canView($pratica$user);
  72.       case self::SUBMIT:
  73.         return $this->canSubmit($pratica$user);
  74.       case self::ASSIGN:
  75.         return $this->canAssign($pratica$user);
  76.       case self::ACCEPT_OR_REJECT:
  77.         return $this->canAcceptOrReject($pratica$user);
  78.       case self::WITHDRAW:
  79.         return $this->canWithdraw($pratica$user);
  80.       case self::COMPILE:
  81.         return $this->canCompile($pratica$user);
  82.       case self::DELETE:
  83.         return $this->canDelete($pratica$user);
  84.     }
  85.     throw new \LogicException('This code should not be reached!');
  86.   }
  87.   private function canView(Pratica $praticaUser $user)
  88.   {
  89.     // if they can edit, they can view
  90.     if ($this->canEdit($pratica$user)) {
  91.       return true;
  92.     }
  93.     $isTheOwner $pratica->getUser() === $user;
  94.     $cfs $pratica->getRelatedCFs();
  95.     if (!is_array($cfs)) {
  96.       $cfs = [$cfs];
  97.     }
  98.     $isRelated $user instanceof CPSUser && in_array($user->getCodiceFiscale(), $cfs);
  99.     return $isTheOwner || $isRelated;
  100.   }
  101.   private function canEdit(Pratica $praticaUser $user)
  102.   {
  103.     if ($this->security->isGranted('ROLE_ADMIN')) {
  104.       return true;
  105.     }
  106.     if ($this->security->isGranted('ROLE_OPERATORE')) {
  107.       /** @var OperatoreUser $user */
  108.       if (in_array($pratica->getServizio()->getId(), $user->getServiziAbilitati()->toArray())) {
  109.         return true;
  110.       }
  111.     }
  112.     return false;
  113.   }
  114.   private function canSubmit(Pratica $praticaUser $user)
  115.   {
  116.     // if they can edit, they can submit
  117.     if ($this->canEdit($pratica$user)) {
  118.       return true;
  119.     }
  120.     return $user === $pratica->getUser();
  121.   }
  122.   private function canAssign(Pratica $praticaUser $user)
  123.   {
  124.     if ($this->security->isGranted('ROLE_OPERATORE')) {
  125.       /** @var OperatoreUser $user */
  126.       if (in_array($pratica->getServizio()->getId(), $user->getServiziAbilitati()->toArray())) {
  127.         return true;
  128.       }
  129.     }
  130.     return false;
  131.   }
  132.   private function canAcceptOrReject(Pratica $praticaUser $user)
  133.   {
  134.     if ($this->security->isGranted('ROLE_OPERATORE')) {
  135.       /** @var OperatoreUser $user */
  136.       if ($user === $pratica->getOperatore()) {
  137.         return true;
  138.       }
  139.     }
  140.     return false;
  141.   }
  142.   private function canWithdraw(Pratica $praticaUser $user)
  143.   {
  144.     // Non è possibile ritirare una pratica se non è abilitato il ritiro, se è presente un dovuto di pagamento o se l'utente non è il richiedente
  145.     if (!$pratica->getServizio()->isAllowWithdraw() || !empty($pratica->getPaymentData()) || $pratica->getUser()->getId() !== $user->getId()) {
  146.       return false;
  147.     }
  148.     // Se il servizio ha un workflow di tipo inoltro e la pratica è stata "inoltrata" NON deve comparire il pulsante ritira.
  149.     if ($pratica->getServizio()->getWorkflow() == Servizio::WORKFLOW_FORWARD && $pratica->getStatus() !== Pratica::STATUS_PRE_SUBMIT) {
  150.       return false;
  151.     }
  152.     // Se il servizio ha la protocollazione attiva ed e la pratica è in STATUS_PRE_SUBMIT, altrimenti genera un errore in fase di protocollazzione del documento di ritiro
  153.     if ($pratica->getServizio()->isProtocolRequired() && $pratica->getStatus() === Pratica::STATUS_PRE_SUBMIT) {
  154.       return false;
  155.     }
  156.     return in_array($pratica->getStatus(), [Pratica::STATUS_PRE_SUBMITPratica::STATUS_SUBMITTEDPratica::STATUS_REGISTEREDPratica::STATUS_PENDING]);
  157.   }
  158.   private function canCompile(Pratica $praticaUser $user)
  159.   {
  160.     $canCompile false;
  161.     // se la pratica è in bozza oppure in attesa di creazione del pagamento
  162.     if (in_array($pratica->getStatus(), [Pratica::STATUS_DRAFTPratica::STATUS_DRAFT_FOR_INTEGRATION]) || $pratica->needsPayment() && $pratica->getUser()->getId() == $user->getId()) {
  163.       $handler $this->servizioHandlerRegistry->getByName($pratica->getServizio()->getHandler());
  164.       try {
  165.         $handler->canAccess($pratica->getServizio());
  166.         $canCompile true;
  167.       } catch (ForbiddenAccessException $e) {
  168.         $canCompile false;
  169.       }
  170.     }
  171.     return $canCompile;
  172.   }
  173.   private function canDelete(Pratica $praticaUser $user)
  174.   {
  175.     return $user === $pratica->getUser();
  176.   }
  177. }