D
D
Danbka2018-09-18 14:54:58
Laravel
Danbka, 2018-09-18 14:54:58

How to resolve access rights depending on the user's role?

Hello.
I'll start with a simple example to make it easier to formulate questions.
So, there is an entity Contract with fields:

- number
- date
- manager_id

manager_id - binding to the user to whom the contract is assigned.
There are roles (groups) of users:
- Директор (видит все контракты)
- Менеджер (видит только "свои" контракты)

Obviously, when selecting contracts, you need to get the role of the current user, and depending on it, select the necessary contracts. However, various best practices suggest that you work with permissions in your code, not with user roles. In this case, you can create the following permissions:
- доступ ко всем контрактам (назначить это разрешение для роли "Директор")
- доступ к "своим" контрактам (назначить это разрешение для роли "Менеджер")

Then it seems that everything is not bad and in the code there will be something like:
if (User::hasPermission('all_contracts')) {
    Contract::all();
} elseif (User::hasPermission('own_contracts')) {
    Contract::getByManager(User::getId());
}

Suppose now that we have a certain "Regional Director" in our system, who should see contracts in his region. Apparently, in this case, a field will be added to the contract,
- region_id
according to which a selection will be made for the regional director.
How would the code change in this case?
if (User::hasPermission('all_contracts')) {
    Contract::all();
} elseif (User::hasPermission('own_contracts')) {
    if (User::hasRole('manager')) {
        Contract::getByManager($managerId);
    } elseif (User::hasRole('region_manager')) {
        Contract::getByRegion(User::getRegionId());
    }
}

One way or another, a check of user roles appears in the code.
Is it correct? If not, how do you implement?
And a follow-up question, specifically about Laravel: do I understand correctly that this resolution of rights must be transferred to the service provider? It seems that controllers / models / repositories are not intended for such things.

Answer the question

In order to leave comments, you need to log in

5 answer(s)
D
Dmitry, 2018-09-18
@Danbka

In order not to fence a bunch of methods for sampling for every case of life, I would make a scope that would take the user as an argument and filter the records depending on the permissions. Then the selection of contracts will always be "clean", such as
In the scope, you will already have to prescribe filters for permissions.
Yes, it may not be the best practice, but it works. Theoretically, of course, this has not yet been implemented.

A
Andrey, 2018-09-18
@andreybold

I would advise you to use ready -made packages for such purposes. Then you will have the opportunity to check the rights in the controller methods, and get models that correspond to the rights that you specify (through scopes)

V
Vadim, 2018-09-18
@kylt_lichnosti

Voters should help you - https://symfony.com/doc/current/security/voters.html

E
Evgeny Svirsky, 2018-09-18
@e_svirsky

Symfony ACLs

D
Dmitry, 2018-09-27
@dlnsk

Here is my article just on this topic: Laravel 5. Hierarchical RBAC for the smallest
The package in question allows you not to change the application code at all when adding new roles, create and modify roles very flexibly and use standard Laravel features, including , and in templates.

Didn't find what you were looking for?

Ask your question

Ask a Question

731 491 924 answers to any question