0
votes

I tried to pass a array to is_granted() twig filter but doesn't work, although in the documentation say yes: https://symfony.com/doc/current/reference/twig_reference.html#is-granted

Imagine the app.user has the role ROLE_MANAGER.

Example:

{{ dump(is_granted('ROLE_MANAGER')) }}

This returns: true

{{ dump(is_granted(['ROLE_ADMIN','ROLE_MANAGER'])) }}

This returns: false

The documentations says:

role: type: string, string[]

Returns true if the current user has the given role. If several roles are passed in an array, true is returned if the user has at least one of them.

But this doesn't works... Any idea why?

1

1 Answers

1
votes

I had the same issue. I resolved it by creating a custom Voter. For some reason is_granted function doesn't work as the documentation says. Inspecting the code I noticed that it never finds a voter for this case, which is why I ended up creating one.

Below an example of the voter that I used:

use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;
use Symfony\Component\Security\Core\Security;
use Symfony\Component\Security\Core\User\UserInterface;
    class MenuVoter extends Voter
    {

        /**
         *
         * @var Security
         */
        private $security;

        public function __construct(Security $security)
        {
            $this->security = $security;
        }

        /**
         * {@inheritdoc}
         */
        protected function supports($attribute, $subject): bool
        {
            return $subject === null && \is_array($attribute);
        }

        /**
         * {@inheritdoc}
         */
        protected function voteOnAttribute($attributes, $post, TokenInterface $token): bool
        {
            $user = $token->getUser();
            $r = false;

            if (!($user instanceof UserInterface)) {
                return false;
            }

            foreach ($attributes as $attribute) {
                if ($this->security->isGranted($attribute)) {
                    $r = true;
                    break;
                }
            }

            return $r;
        }

    }

What it basically does is to loop through every role (attribute) and check if access is granted for one of them.

I hope it helps and if someone has a better way I'd love to know.