User permission and Symfony Validator 🔐

18 / 03 / 2020

One of the most powerful things with the Symfony Security component is the Voter System. It allows us to check the permissions of a User for a given Object.

Documentation said :

can this specific user edit the given item?

But how do we check permission on an Object property? 🤓

If you are familiar with API and Api Platform ❤️ you know that you can use the access_control expression but it will only prevent the whole object, not a specific property. If you want to prevent a property you should use serialization groups and a Normalizer to dynamically define the group and the property will (or not) be exposed, depends of your logic.

The API consumer will put information and they will be ignored by our application but it can be “disturbing” for the API consumer to not see these changes despite having sent them. 😢

💡 A more convenient solution is to return an explicit error like: “Sorry but you’re not allowed to do this stuff!

Error rhyme with Validator.

Your mission, if you choose to accept it is to return an error if the User is not allowed to edit a given property. 📼

The Symfony Validator component is a powerful tool to validate an Object, a value, a property... You apply a Constraint (NotBlank, LessThan…) and the validator check if the given item doesn’t violate constraints.

There are many standalone constraints. If you want to add another one your PR is welcome 💻

But in such case these constraints are not enough, thanks to Symfony contributors 💪 you can create a custom constraint with nearly 10 lines of code ! 🚀

Now you see me coming… 🙈

We will create a custom constraint that check if the current User have the good role to edit or create a given property.

Create the Constraint Class 🔧

We call it Role because it’s checks the Role

Create the Validator 🔨

Thanks to autowiring and autoconfigure we can register our RoleValidator class and we can inject in the constructor any available services! 🔥

This class contains the logic to said if there is violation or not. It will check if the User have the allowed role for the given property.

We call it RoleValidator

Apply the Constraint in our Entity in 2 steps 🛠

1- Call our Validator namespace use AppValidator as CustomValidator

2- Apply our Role constraint on the $title property to allow only User with ROLE_ADMIN @CustomValidatorRole(role=ROLE_ADMIN)

From now, only a User with a ROLE_ADMIN can add or edit the title property of our entity 👮

Thanks to Api Platform contributors, The ValidationExceptionListener will converts the throwned ValidationException into a nice Response.

Same test with a User that have a ROLE_ADMIN 🎉

Thanks for reading, I hope you liked it, don't forget to share it !
LinkedIn Twitter