src/Security/DeviceVoter.php line 18

Open in your IDE?
  1. <?php
  2. /**
  3.  * @license SILK SOFTWARE HOUSE SP Z O O
  4.  */
  5. namespace App\Security;
  6. use App\Entity\Customer;
  7. use App\Entity\Device;
  8. use App\Entity\User;
  9. use App\Repository\LicenseRepository;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  12. /**
  13.  * Class DeviceVoter.
  14.  */
  15. class DeviceVoter extends Voter
  16. {
  17.     const SHOW 'show';
  18.     const NEW = 'new';
  19.     const EDIT 'edit';
  20.     const DELETE 'delete';
  21.     /**
  22.      * License repository.
  23.      *
  24.      * @var LicenseRepository
  25.      */
  26.     private $licenseRepository;
  27.     /**
  28.      * DeviceVoter constructor.
  29.      *
  30.      * @param LicenseRepository $licenseRepository
  31.      */
  32.     public function __construct(LicenseRepository $licenseRepository)
  33.     {
  34.         $this->licenseRepository $licenseRepository;
  35.     }
  36.     /**
  37.      * Supports.
  38.      *
  39.      * @param string $attribute
  40.      * @param object $subject
  41.      *
  42.      * @return bool
  43.      */
  44.     protected function supports($attribute$subject)
  45.     {
  46.         // if the attribute isn't one we support, return false
  47.         if (!in_array($attribute, [self::SHOWself::NEW, self::EDITself::DELETE])) {
  48.             return false;
  49.         }
  50.         if ($subject && !$subject instanceof Device) {
  51.             return false;
  52.         }
  53.         return true;
  54.     }
  55.     /**
  56.      * Vote on attribute.
  57.      *
  58.      * @param string         $attribute
  59.      * @param object         $subject
  60.      * @param TokenInterface $token
  61.      *
  62.      * @return bool
  63.      */
  64.     protected function voteOnAttribute($attribute$subjectTokenInterface $token)
  65.     {
  66.         $user $token->getUser();
  67.         if (!$user instanceof User) {
  68.             // the user must be logged in; if not, deny access
  69.             return false;
  70.         }
  71.         if (!$subject instanceof Device && self::NEW !== $attribute) {
  72.             return false;
  73.         }
  74.         // you know $subject is a Device object, thanks to `supports()`
  75.         /** @var Device $device */
  76.         $device $subject;
  77.         if (in_array($attribute, [self::NEW, self::DELETE])) {
  78.             return $user->hasRole('ROLE_ADMIN');
  79.         }
  80.         if (self::EDIT === $attribute) {
  81.             return $this->canEdit($device$user);
  82.         }
  83.         return $this->canView($device$user);
  84.     }
  85.     /**
  86.      * Can view.
  87.      *
  88.      * @param Device $device
  89.      * @param User   $user
  90.      *
  91.      * @return bool
  92.      */
  93.     private function canView(Device $deviceUser $user)
  94.     {
  95.         if ($user->hasRole('ROLE_ADMIN') || $this->canEdit($device$user)) {
  96.             return true;
  97.         }
  98.         $deviceHasCustomersMeasurement $this->hasMeasurement($device$user->getCustomer());
  99.         return null !== $this->licenseRepository->findOneBy([
  100.                 'device' => $device,
  101.                 'customer' => $user->getActiveCustomer(),
  102.             ]) || $deviceHasCustomersMeasurement;
  103.     }
  104.     /**
  105.      * Can edit.
  106.      *
  107.      * @param Device $device
  108.      * @param User   $user
  109.      *
  110.      * @return bool
  111.      */
  112.     private function canEdit(Device $deviceUser $user)
  113.     {
  114.         if ($user->hasRole('ROLE_ADMIN')) {
  115.             return true;
  116.         }
  117.         $deviceCustomer $device->getCustomer();
  118.         $userCustomer $user->getActiveCustomer();
  119.         return ($deviceCustomer && $userCustomer && $deviceCustomer->getId() === $userCustomer->getId());
  120.     }
  121.     /**
  122.      * @param Device        $device
  123.      * @param Customer|null $customer
  124.      *
  125.      * @return bool
  126.      */
  127.     private function hasMeasurement(Device $device, ?Customer $customer): bool
  128.     {
  129.         foreach ($device->getMeasurements() ?? [] as $measurement) {
  130.             return $measurement->getCustomer() === $customer;
  131.         }
  132.         return false;
  133.     }
  134. }