I
I
IsaevDev2017-02-09 21:27:30
Software design
IsaevDev, 2017-02-09 21:27:30

Where is it better to check user rights - model/controller/%else%?

Let's say the user has a certain set of rights - editing, moderation, etc.
These rights affect the fields that can be updated in the model or that can be searched.
Where to check user permissions in the model or in the controller? The validation logic is quite complex and validation in the controller will result in duplication if different controllers hook the same model method from different situations. But it is difficult to take into account all scenarios in the model.
What do you advise?

Answer the question

In order to leave comments, you need to log in

1 answer(s)
I
Ivan Tomilov, 2017-02-16
@IsaevDev

The rights system is always difficult to work with and you always need to look at the specific implementation and take into account how it will change in the future. In any case, I am now a bit involved in a similar task in our company and will try to give some useful answer.
In the controller, it’s really worth checking only simple cases and the disadvantage of checking in the controller is precisely that if, for example, you implemented a check in one HTTP controller and suddenly a CLI controller appears, then you want the domain logic calls to be the same from anywhere, including validation. Accordingly, we will try to take the access check to another place.
I don't want to take everything into the model either. Observing the principle of SoC and the layering of the application, domain models in the general case should not know anything about the user who performs an action on them. Accordingly, there is a proposal to introduce a third component, which is responsible for checking whether the user has access to a specific action. Plus, I'm sure that sometimes you want to perform some action on the model without checking the rights.
As you wrote, you have a certain set of rights and certain actions (moderation, editing) with some parameters (editing fields) that can be performed on the model. Accordingly, we formulate a solution. It may not suit you at all, this is just a simple option with a finger to the sky, which illustrates the approach. Let's introduce a PolicyChecker with methods like canCreatePost(user, createPostRequest) bool, where each method corresponds to checking a specific action with specific request parameters for a specific user. This PolicyChecker knows everything about authorized users, about roles, groups and whatever they have, and if it needs additional dependencies to check, they are passed to it in the constructor or whatever your approach to dependency management is.
Thus, in each controller, based on PolicyChecker, you can check that this user is authorized for this action. If another controller appears, then this check will have to be written again, and I think that this is correct, i.e. PolicyCheckers may again be different for different controllers, and the rules for checking them may differ. Or there may be a need to perform an action on the model without an authorized user at all, as I wrote above, and then you can not check any rights and just forget about PolicyChecker.
The specific implementation again depends on your specific user case, and the rights system needs to be well designed in connection with the needs of the business, because it tends to grow like an avalanche and lead to difficulties in maintaining code and vulnerabilities in general.
I hope my thoughts have been helpful to you.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question