src/Security/Voter/OnlineShop/ProductSecurityVoter.php line 17

Open in your IDE?
  1. <?php
  2. namespace App\Security\Voter\OnlineShop;
  3. use App\Entity\OnlineShop\Product;
  4. use App\Entity\User;
  5. use App\Enum\MenuRolesAssociatedEnum;
  6. use App\Enum\MenuRolesManagerEnum;
  7. use App\Enum\UserRolesEnum;
  8. use App\Enum\VotersEnum;
  9. use App\Manager\ProvidersManager;
  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. use Symfony\Component\Security\Core\User\UserInterface;
  14. final class ProductSecurityVoter extends Voter
  15. {
  16.     private Security $security;
  17.     private array $voters;
  18.     private ProvidersManager $providersManager;
  19.     public function __construct(Security $securityProvidersManager $providersManager)
  20.     {
  21.         $this->security $security;
  22.         $this->voters = [
  23.             VotersEnum::LIST_PRODUCT,
  24.             VotersEnum::CREATE_PRODUCT,
  25.             VotersEnum::READ,
  26.             VotersEnum::UPDATE,
  27.             VotersEnum::DELETE,
  28.             VotersEnum::EXPORT_PRODUCT,
  29.             VotersEnum::IMPORT_PRODUCT,
  30.             VotersEnum::REMOVE_MULTIPLE_PRODUCT,
  31.             VotersEnum::LIST_PRODUCTS_META_CATALOG,
  32.         ];
  33.         $this->providersManager $providersManager;
  34.     }
  35.     protected function supports(string $attribute$subject): bool
  36.     {
  37.         // first check the $subject and last if the $attribute is supported,
  38.         // because there are attributes (with subject) used as well by other voters (like UPDATE, ...)
  39.         if ($subject && !$subject instanceof Product) {
  40.             // only vote on these objects
  41.             return false;
  42.         }
  43.         if (in_array($attribute$this->voters)) {
  44.             // if the attribute is one we support
  45.             return true;
  46.         }
  47.         return false;
  48.     }
  49.     protected function voteOnAttribute(string $attribute$subjectTokenInterface $token): bool
  50.     {
  51.         $user $token->getUser();
  52.         if (!$user instanceof User) {
  53.             // the user must be logged in; if not, deny access
  54.             return false;
  55.         }
  56.         switch ($attribute) {
  57.             case VotersEnum::LIST_PRODUCT:
  58.                 return $this->canList();
  59.             case VotersEnum::CREATE_PRODUCT:
  60.                 return $this->canCreate();
  61.             case VotersEnum::READ:
  62.                 return $this->canRead($subject$user);
  63.             case VotersEnum::UPDATE:
  64.                 return $this->canUpdate($subject$user);
  65.             case VotersEnum::DELETE:
  66.                 return $this->canDelete($subject$user);
  67.             case VotersEnum::EXPORT_PRODUCT:
  68.                 return $this->canExport();
  69.             case VotersEnum::IMPORT_PRODUCT:
  70.                 return $this->canImport();
  71.             case VotersEnum::REMOVE_MULTIPLE_PRODUCT:
  72.                 return $this->canRemoveMultiple();
  73.             case VotersEnum::LIST_PRODUCTS_META_CATALOG:
  74.                 return $this->canListProductsMetaCatalog();
  75.         }
  76.         throw new \LogicException('This code should not be reached!');
  77.     }
  78.     private function canList(): bool
  79.     {
  80.         return $this->isAdminUser()
  81.             || $this->security->isGranted(UserRolesEnum::ROLE_PROVIDER_LONG)
  82.             ;
  83.     }
  84.     private function canCreate(): bool
  85.     {
  86.         return $this->isAdminUser()
  87.             || $this->security->isGranted(UserRolesEnum::ROLE_PROVIDER_LONG)
  88.             ;
  89.     }
  90.     private function canRead(Product $productUserInterface $user): bool
  91.     {
  92.         return $this->isAdminUser()
  93.             || ($this->security->isGranted(UserRolesEnum::ROLE_PROVIDER_LONG) && $this->providersManager->isProductAvailableForProvider($product$user))
  94.             || ($this->security->isGranted(UserRolesEnum::ROLE_COORDINATOR_LONG) && $product->userHasAccess($user))
  95.             || ($this->security->isGranted(MenuRolesAssociatedEnum::ROLE_MENU_ONLINE_SHOP_ASSOCIATED) && $product->userHasAccess($user))
  96.             ;
  97.     }
  98.     private function canUpdate(Product $productUserInterface $user): bool
  99.     {
  100.         return $this->isAdminUser()
  101.             || ($this->security->isGranted(UserRolesEnum::ROLE_PROVIDER_LONG) && $this->providersManager->isProductAvailableForProvider($product$user))
  102.             ;
  103.     }
  104.     private function canDelete(Product $productUserInterface $user): bool
  105.     {
  106.         return $this->isAdminUser()
  107.             || ($this->security->isGranted(UserRolesEnum::ROLE_PROVIDER_LONG) && $this->providersManager->isProductAvailableForProvider($product$user))
  108.             ;
  109.     }
  110.     private function canExport(): bool
  111.     {
  112.         return $this->isAdminUser();
  113.     }
  114.     private function canImport(): bool
  115.     {
  116.         return $this->isAdminUser();
  117.     }
  118.     private function canRemoveMultiple(): bool
  119.     {
  120.         return $this->isAdminUser();
  121.     }
  122.     private function canListProductsMetaCatalog(): bool
  123.     {
  124.         return $this->isAdminUser();
  125.     }
  126.     private function isAdminUser(): bool
  127.     {
  128.         return $this->security->isGranted(MenuRolesManagerEnum::ROLE_MENU_ONLINE_SHOP);
  129.     }
  130. }