Chapters
40 Chapters
|
4:19:16
|
Login to bookmark this video
-
Course Code
Subscribe to download the code!
Subscribe to download the code!
-
This Video
Subscribe to download the video!
Subscribe to download the video!
-
Subtitles
Subscribe to download the subtitles!
Subscribe to download the subtitles!
-
Course Script
Subscribe to download the script!
Subscribe to download the script!
28.
Security Voter & Entity Permissions
Scroll down to the script below, click on any sentence (including terminal blocks) to jump to that spot in the video!
Subscribe to jump to this part in the video!
Keep on Learning!
If you liked what you've learned so far, dive in! Subscribe to get access to this tutorial plus video, code and script downloads.
This tutorial is built on Symfony 6 but works great on Symfony 7!
What PHP libraries does this tutorial use?
// composer.json
{
"require": {
"php": ">=8.2.0",
"ext-ctype": "*",
"ext-iconv": "*",
"composer/package-versions-deprecated": "^1.11", // 1.11.99.4
"doctrine/doctrine-bundle": "^2.1", // 2.5.5
"doctrine/doctrine-migrations-bundle": "^3.0", // 3.2.1
"doctrine/orm": "^2.7", // 2.10.4
"easycorp/easyadmin-bundle": "^4.0", // v4.0.2
"handcraftedinthealps/goodby-csv": "^1.4", // 1.4.0
"knplabs/knp-markdown-bundle": "dev-symfony6", // dev-symfony6
"knplabs/knp-time-bundle": "^1.11", // 1.17.0
"sensio/framework-extra-bundle": "^6.0", // v6.2.5
"stof/doctrine-extensions-bundle": "^1.4", // v1.7.0
"symfony/asset": "6.0.*", // v6.0.1
"symfony/console": "6.0.*", // v6.0.2
"symfony/dotenv": "6.0.*", // v6.0.2
"symfony/flex": "^2.0.0", // v2.4.5
"symfony/framework-bundle": "6.0.*", // v6.0.2
"symfony/mime": "6.0.*", // v6.0.2
"symfony/monolog-bundle": "^3.0", // v3.7.1
"symfony/runtime": "6.0.*", // v6.0.0
"symfony/security-bundle": "6.0.*", // v6.0.2
"symfony/stopwatch": "6.0.*", // v6.0.0
"symfony/twig-bundle": "6.0.*", // v6.0.1
"symfony/ux-chartjs": "^2.0", // v2.0.1
"symfony/webpack-encore-bundle": "^1.7", // v1.13.2
"symfony/yaml": "6.0.*", // v6.0.2
"twig/extra-bundle": "^2.12|^3.0", // v3.3.7
"twig/twig": "^2.12|^3.0" // v3.3.7
},
"require-dev": {
"doctrine/doctrine-fixtures-bundle": "^3.3", // 3.4.1
"symfony/debug-bundle": "6.0.*", // v6.0.2
"symfony/maker-bundle": "^1.15", // v1.36.4
"symfony/var-dumper": "6.0.*", // v6.0.2
"symfony/web-profiler-bundle": "6.0.*", // v6.0.2
"zenstruck/foundry": "^1.1" // v1.16.0
}
}
7 Comments
All the functionality described in this section works as described BUT I get an `InsufficientEntityPermissionException` when trying to Add a User using the `Add User` button.
Hey Chris N. !
Hmm. To help with this, click the security part of your web debug toolbar to go into the security part of the profiler. Then check the "access decision log" to see what is denying access. But I think I can track it in the code
And THAT is failing. This is actually handled by this voter: https://github.com/EasyCorp/EasyAdminBundle/blob/321966f365fb809699014d3011d2a40ecb2e2261/src/Security/SecurityVoter.php#L48-L50 - which curiously checks that your "entity permission" returns "true" for the new, empty User object. I didn't realize it did this!
If I'm correct, what you need to do is, in your custom voter, is basically this (before the switch statement):
Let me know if that does the trick :).
Cheers!
Hi Ryan
Thanks for the response.
Unfortunately, your solution doesn't quite work. When creating a new Entity, EasyAdmin first checks for voters on ADMIN_USER_EDIT with a subject of `null`.
My solution requires modifying both the `supports(..)` method and the `voteOnAttribute(..)` methods of the `AdminUserVoter` as so:
```
protected function supports(string $attribute, $subject): bool
{
// replace with your own logic
// https://symfony.com/doc/cur...
return in_array($attribute, ['ADMIN_USER_EDIT']);
}
protected function voteOnAttribute(string $attribute, $subject, TokenInterface $token): bool
{
$user = $token->getUser();
// if the user is anonymous, do not grant access
if (!$user instanceof UserInterface) {
return false;
}
// ... (check conditions and return true to grant permission) ...
// allow NEW objects to be created
switch ($attribute) {
case 'ADMIN_USER_EDIT':
return $user === $subject || $this->security->isGranted('ROLE_SUPER_ADMIN');
}
return false;
}
```
Hey Chris N.!
Sorry for my very slow reply - but thanks for posting this solution! I'm going to add a note to the tutorial about this.
Thanks!
Is there anything wrong with using
in_array('ROLE_SUPER_ADMIN', $user->getRoles())
to check for the super admin role instead of using the security component?
Hey Nick,
Yes, it is... Roles system in Security component is more complex, it allows you to use "roles inheritance". And your example with in_array() won't cover inherited roles. Better always use isGranted() for security checks unless you on purpose want to ignore roles inheritance, though it might just mislead others or even you in the future.
Cheers!
Thanks, I just ran into that exact problem of it not including inherited roles.
Plus, this inheritance structure saves a lot of space in the database by not having to store duplicate roles for everyone.
"Houston: no signs of life"
Start the conversation!