I find myself in a situation where I have two roles, "Admin" and a "Organizer". The "Admin" accesses the AdminUserController
to update users, while the "Organizer" accesses the UserController
to do so. This is important since the user indexing and input validation is different in both cases: the organizer only indexes a subset of users and can update a subset of fields.
For the controller I am using resource controllers ( https://laravel.com/docs/9.x/controllers#resource-controllers ) and they are the ones managing the input validation, including the different filtering on the index method as well as the input validation.
To authorize actions I am using policies, and with them being a resource-based authorization method, I can only define a single policy to authorize the access / update to the Users table. The problem is that this authorization is different depending on the controller called. I like to encapsulate the Auth logic within policies, but I am not sure what would be a "clean" way to solve this in this case. The only options that came to mind are:
Pass the controller called to the policy: That would make for a controlled-based authorization and not a resource-based authorization and the mix doesn't feel right.
Make a single controller and share authorization logic in it: This would allow to make the correct input validation / filtering depending on the role, but that would be mixing concerns too.
Use a gate in the controller: In this case the authorization logic would stop being encapsulated in the policy methods. Right now I have gates implemented to check for permissions, but the use of these gates is reserved for policies and using them outside doesn't feel right either.
Seems like making two policies would be a possible solution, but that is not an allowed practice in Laravel, so instead of going through a major refactor or mixing authorization philosophies, I am looking for a clean "laravel-way" to solve this issue.
Have any of you face a situation like this in the past? How did you solve it in a clean way?