In the Symfony security feature, the access control part decides if a user
can access some resource (a URL, a model object, a method call, etc.). This is
configured with roles and checked using the #[IsGranted]
attribute, the
isGranted()
PHP method, and the is_granted()
Twig function.
For example, checking if a user has permissions inside a service:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
// src/Reports/SalesReportGenerator.php
// ...
use Symfony\Bundle\SecurityBundle\Security;
class SalesReportGenerator
{
public function __construct(
private Security $security,
) {
}
public function generate(): void
{
if ($this->security->isGranted('ROLE_SALES_EXECUTIVE')) {
// ...
}
// ...
}
}
The isGranted()
method always checks the permissions of the currently logged
in user. This is fine most of the times, but falls short in scenarios like commands,
offline tasks, message queues, etc. That's why in Symfony 7.3 we're introducing
isGrantedForUser()
, a new method to check permissions of arbitrary users:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
// ...
use Symfony\Bundle\SecurityBundle\Security;
class SalesReportGenerator
{
public function __construct(
private Security $security,
) {
}
public function generate(): void
{
// get somehow all users that will receive the report...
/** @var UserInterface[] $users */
$users = ...
// you can now check permissions of all users while generating reports
foreach ($users as $user) {
if ($this->security->isGrantedForUser($user, 'ROLE_SALES_EXECUTIVE')) {
// ...
}
// ...
}
}
}
In Twig templates, use the new is_granted_for_user()
function to check
permissions for any arbitrary user:
1 2 3 4 5 6 7
{% if is_granted('ROLE_SALES_EXECUTIVE') %}
<a href="..."> Download report </a>
{% endif %}
{% if is_granted_for_user(another_user, 'ROLE_SALES_EXECUTIVE') %}
<a href="..."> Send the sales report to {{ another_user }} </a>
{% endif %}
Lovely!!
As someone who uses role hierarchy a lot, anytime you had to do a check that is not for the current user , doing the hierarchy lookup and such felt like I was doing something wrong!
(Yes, it was a hassle... But it was one one or two lines extra, and you could abstract it in a service , but still... Not going through the whole voter system and checking roles yourself didn't feel right).
Awesome, Great work on this ❤️
Awesome, great work