2
votes

I'm building a small-scale symfony project, as much for my own edification as anything else.

I have a Network class which extends Entity in a Doctrine ORM setup, and a bunch of users (also entities in a Doctrine setup). I've given some users the CREATE permission on the Network class, and that seems to be working. At least the exception is thrown when I expect it:

    $securityContext = $this->get('security.context');
    $objectId = new ObjectIdentity('class', 'Acme\\AcmeBundle\\Entity\\Network');
    if(false === $securityContext->isGranted('CREATE', $objectId)) {
        throw new AccessDeniedException("You do not have permission.");
    }

But I'd like to check the permission in a twig template, something like this:

        {% if is_granted('CREATE', 'Acme\\AcmeBundle\\Entity\\Network') %}
        <li>
            <a href="{{ path('network_new') }}">
                Create a new entry
            </a>
        </li>
        {% endif %}

My goal here is to only show the link if the user has permission to create a new network. But the is_granted() call seems to be returning true for all the users, not just the ones that I've explicitly granted CREATE to, or at least link is always appearing, even for users that have no ACL/ACE entries for the Network class.

1

1 Answers

4
votes

It turns out that is_granted() expects an object as the second parameter. This is a Twig Extension that provides a classId() function to return an ObjectIdentifier object.

class ClassIdExtension extends \Twig_Extension
{
    public function getFunctions()
    {
        return array(
            'classId' => new \Twig_SimpleFunction('classId', array($this, 'classId'))
        );
    }

    public function classId($class)
    {
        return new ObjectIdentity('class', $class);
    }

    public function getName()
    {
        return 'acme_classidextension';
    }    
}

Once it's registered as a service in Symfony, you can use it in Twig templates like so:

{% if is_granted('CREATE', classId('Acme\\AcmeBundle\\Entity\\Network')) %}
    <li>
        <a href="{{ path('network_new') }}">
            Create a new entry
        </a>
    </li>
{% endif %}

And it works as expected.