From f00878df8dc0ae6495eeaa8667f0881f96c7f003 Mon Sep 17 00:00:00 2001 From: Nate Wiebe Date: Wed, 9 Nov 2022 11:16:55 -0500 Subject: [PATCH] Add is_granted_for_user() function to twig --- src/Symfony/Bridge/Twig/CHANGELOG.md | 5 +++++ .../Bridge/Twig/Extension/SecurityExtension.php | 17 +++++++++++++++++ .../Bridge/Twig/UndefinedCallableHandler.php | 1 + .../Resources/config/templating_twig.php | 1 + 4 files changed, 24 insertions(+) diff --git a/src/Symfony/Bridge/Twig/CHANGELOG.md b/src/Symfony/Bridge/Twig/CHANGELOG.md index b18e2745915e..156b29ab4190 100644 --- a/src/Symfony/Bridge/Twig/CHANGELOG.md +++ b/src/Symfony/Bridge/Twig/CHANGELOG.md @@ -1,6 +1,11 @@ CHANGELOG ========= +7.3 +--- + + * Add `is_granted_for_user()` Twig function + 7.2 --- diff --git a/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php b/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php index 863df1560673..0def2e85ad35 100644 --- a/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php +++ b/src/Symfony/Bridge/Twig/Extension/SecurityExtension.php @@ -13,7 +13,9 @@ use Symfony\Component\Security\Acl\Voter\FieldVote; use Symfony\Component\Security\Core\Authorization\AuthorizationCheckerInterface; +use Symfony\Component\Security\Core\Authorization\UserAuthorizationCheckerInterface; use Symfony\Component\Security\Core\Exception\AuthenticationCredentialsNotFoundException; +use Symfony\Component\Security\Core\User\UserInterface; use Symfony\Component\Security\Http\Impersonate\ImpersonateUrlGenerator; use Twig\Extension\AbstractExtension; use Twig\TwigFunction; @@ -28,6 +30,7 @@ final class SecurityExtension extends AbstractExtension public function __construct( private ?AuthorizationCheckerInterface $securityChecker = null, private ?ImpersonateUrlGenerator $impersonateUrlGenerator = null, + private ?UserAuthorizationCheckerInterface $userSecurityChecker = null, ) { } @@ -48,6 +51,19 @@ public function isGranted(mixed $role, mixed $object = null, ?string $field = nu } } + public function isGrantedForUser(UserInterface $user, mixed $attribute, mixed $subject = null, ?string $field = null): bool + { + if (!$this->userSecurityChecker) { + return false; + } + + if (!$field) { + $subject = new FieldVote($subject, $field); + } + + return $this->userSecurityChecker->isGrantedForUser($user, $attribute, $subject); + } + public function getImpersonateExitUrl(?string $exitTo = null): string { if (null === $this->impersonateUrlGenerator) { @@ -88,6 +104,7 @@ public function getFunctions(): array { return [ new TwigFunction('is_granted', $this->isGranted(...)), + new TwigFunction('is_granted_for_user', $this->isGrantedForUser(...)), new TwigFunction('impersonation_exit_url', $this->getImpersonateExitUrl(...)), new TwigFunction('impersonation_exit_path', $this->getImpersonateExitPath(...)), new TwigFunction('impersonation_url', $this->getImpersonateUrl(...)), diff --git a/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php b/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php index 5da9a1484ac9..16421eaf504d 100644 --- a/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php +++ b/src/Symfony/Bridge/Twig/UndefinedCallableHandler.php @@ -61,6 +61,7 @@ class UndefinedCallableHandler 'logout_url' => 'security-http', 'logout_path' => 'security-http', 'is_granted' => 'security-core', + 'is_granted_for_user' => 'security-core', 'impersonation_path' => 'security-http', 'impersonation_url' => 'security-http', 'impersonation_exit_path' => 'security-http', diff --git a/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.php b/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.php index 05a74d086e82..96a7a2833a44 100644 --- a/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.php +++ b/src/Symfony/Bundle/SecurityBundle/Resources/config/templating_twig.php @@ -26,6 +26,7 @@ ->args([ service('security.authorization_checker')->ignoreOnInvalid(), service('security.impersonate_url_generator')->ignoreOnInvalid(), + service('security.user_authorization_checker')->ignoreOnInvalid(), ]) ->tag('twig.extension') ;