vendor/easycorp/easyadmin-bundle/src/Security/SecurityVoter.php line 19

Open in your IDE?
  1. <?php
  2. namespace EasyCorp\Bundle\EasyAdminBundle\Security;
  3. use EasyCorp\Bundle\EasyAdminBundle\Config\Action;
  4. use EasyCorp\Bundle\EasyAdminBundle\Dto\ActionDto;
  5. use EasyCorp\Bundle\EasyAdminBundle\Dto\CrudDto;
  6. use EasyCorp\Bundle\EasyAdminBundle\Dto\EntityDto;
  7. use EasyCorp\Bundle\EasyAdminBundle\Dto\FieldDto;
  8. use EasyCorp\Bundle\EasyAdminBundle\Dto\MenuItemDto;
  9. use EasyCorp\Bundle\EasyAdminBundle\Provider\AdminContextProvider;
  10. use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
  11. use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface;
  12. use Symfony\Component\Security\Core\Authorization\Voter\Voter;
  13. /**
  14.  * @author Javier Eguiluz <javier.eguiluz@gmail.com>
  15.  */
  16. final class SecurityVoter extends Voter
  17. {
  18.     private $authorizationChecker;
  19.     private $adminContextProvider;
  20.     public function __construct(AuthorizationCheckerInterface $authorizationCheckerAdminContextProvider $adminContextProvider)
  21.     {
  22.         $this->authorizationChecker $authorizationChecker;
  23.         $this->adminContextProvider $adminContextProvider;
  24.     }
  25.     protected function supports($permissionName$subject)
  26.     {
  27.         return Permission::exists($permissionName);
  28.     }
  29.     protected function voteOnAttribute($permissionName$subjectTokenInterface $token)
  30.     {
  31.         if (Permission::EA_VIEW_MENU_ITEM === $permissionName) {
  32.             return $this->voteOnViewMenuItemPermission($subject);
  33.         }
  34.         if (Permission::EA_EXECUTE_ACTION === $permissionName) {
  35.             return $this->voteOnExecuteActionPermission($this->adminContextProvider->getContext()->getCrud(), $subject['action'] ?? null$subject['entity'] ?? null);
  36.         }
  37.         if (Permission::EA_VIEW_FIELD === $permissionName) {
  38.             return $this->voteOnViewPropertyPermission($subject);
  39.         }
  40.         if (Permission::EA_ACCESS_ENTITY === $permissionName) {
  41.             return $this->voteOnViewEntityPermission($subject);
  42.         }
  43.         if (Permission::EA_EXIT_IMPERSONATION === $permissionName) {
  44.             return $this->voteOnExitImpersonationPermission();
  45.         }
  46.         return true;
  47.     }
  48.     private function voteOnViewMenuItemPermission(MenuItemDto $menuItemDto): bool
  49.     {
  50.         // users can see the menu item if they have the permission required by the menu item
  51.         return $this->authorizationChecker->isGranted($menuItemDto->getPermission(), $menuItemDto);
  52.     }
  53.     /**
  54.      * @param string|ActionDto $actionNameOrDto
  55.      */
  56.     private function voteOnExecuteActionPermission(CrudDto $crudDto$actionNameOrDto, ?EntityDto $entityDto): bool
  57.     {
  58.         // users can run the Crud action if:
  59.         // * they have the required permission to execute the action on the given entity instance
  60.         // * the action is not disabled
  61.         if (!\is_string($actionNameOrDto) && !($actionNameOrDto instanceof ActionDto)) {
  62.             throw new \RuntimeException(sprintf('When checking the "%s" permission with the isGranted() method, the value of the "action" parameter passed inside the voter $subject must be a string with the action name or a "%s" object.'Permission::EA_EXECUTE_ACTIONActionDto::class));
  63.         }
  64.         $actionName = \is_string($actionNameOrDto) ? $actionNameOrDto $actionNameOrDto->getName();
  65.         $actionPermission $crudDto->getActionsConfig()->getActionPermissions()[$actionName] ?? null;
  66.         $disabledActionNames $crudDto->getActionsConfig()->getDisabledActions();
  67.         $subject null === $entityDto null $entityDto->getInstance();
  68.         return $this->authorizationChecker->isGranted($actionPermission$subject) && !\in_array($actionName$disabledActionNamestrue);
  69.     }
  70.     private function voteOnViewPropertyPermission(FieldDto $field): bool
  71.     {
  72.         // users can see the field if they have the permission required by the field
  73.         return $this->authorizationChecker->isGranted($field->getPermission(), $field);
  74.     }
  75.     private function voteOnViewEntityPermission(EntityDto $entityDto): bool
  76.     {
  77.         // users can see the entity if they have the required permission on the specific entity instance
  78.         return $this->authorizationChecker->isGranted($entityDto->getPermission(), $entityDto->getInstance());
  79.     }
  80.     private function voteOnExitImpersonationPermission(): bool
  81.     {
  82.         // users can exit impersonation if they are currently impersonating another user.
  83.         // In Symfony, that means that current user has the special impersonator permission
  84.         if (\defined('Symfony\Component\Security\Core\Authorization\Voter\AuthenticatedVoter::IS_IMPERSONATOR')) {
  85.             $impersonatorPermission 'IS_IMPERSONATOR';
  86.         } else {
  87.             $impersonatorPermission 'ROLE_PREVIOUS_ADMIN';
  88.         }
  89.         return $this->authorizationChecker->isGranted($impersonatorPermission);
  90.     }
  91. }