Группы и разрешения, лучшая практика RBAC в symfony?

Коллеги, приветствую.
Дайте совет.

Как лучше поступить?

Хранить разрешения для каждого пользователя?
Или для групп, в которую входит пользователь?
Мне нужна лучшая практика.

Внутренни перфекционист не даёт покоя.

Для примера.
Ну типа достаю атрибуты из группы в которой состоит юзер.
Соответственно, если не состоит в группе, то и разрешений нет.
Избератель
<?php


namespace App\Security\Administrator\Voter;


use App\Entity\User;
use App\Entity\UserGroup;
use Exception;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authorization\Voter\Voter;

/**
 * Class UserVoter
 * @package App\Security\Administrator\Voters
 */
class UserVoter extends Voter implements IVoter
{

    public const CREATE_USERS = 'create_users';
    public const EDIT_USERS = 'edit_users';
    public const DELETE_USERS = 'delete_users';
    public const VIEW_USERS = 'view_users';
    public const VIEW_CONTACTS = 'view_contacts';
    public const SET_PRIVILEGES_USERS = 'set_privileges_users';


    /**
     * @param string $attribute
     * @param mixed $subject
     * @return bool
     */
    protected function supports($attribute, $subject)
    {
        if (!in_array($attribute, $this->getAttributes())) {
            return false;
        }

        return true;
    }


    /**
     * @param string $attribute
     * @param mixed $subject
     * @param TokenInterface $token
     * @return bool
     */
    protected function voteOnAttribute($attribute, $subject, TokenInterface $token)
    {
        $user = $token->getUser();

        if (!$user instanceof User) {
            return false;
        }

        $permissions = [];
        try {
            if (is_a($user->getGroup(), UserGroup::class)) {
                $permissions = $user->getGroup()->getPermissions();
            }

            foreach ($permissions as $permission) {
                if (in_array($permission, $this->getAttributes())) {
                    return true;
                }
            }

            return false;
        }catch (Exception $exception) {
            return false;
        }
    }


    /**
     * @return string[]
     */
    public function getAttributes()
    {
        return [
            self::CREATE_USERS,
            self::EDIT_USERS,
            self::DELETE_USERS,
            self::VIEW_USERS,
            self::VIEW_CONTACTS,
            self::SET_PRIVILEGES_USERS
        ];
    }
}
  • Вопрос задан
  • 1127 просмотров
Решения вопроса 1
IgorPI
@IgorPI Автор вопроса
Коллеги, решил поступить следующим образом.

Иметь некий стек разрешений для чего-либо, не важно, главное что бы он был статический.
Что я имею в виду когда говорю "статический стек"?

Это обычные атрибуты, которые объявлены заранее
Пример

class UserVoter extends Voter implements IVoter
{

    public const CREATE_USERS = 'create_users';
    public const EDIT_USERS = 'edit_users';
    public const DELETE_USERS = 'delete_users';
    public const VIEW_USERS = 'view_users';
    public const VIEW_CONTACTS = 'view_contacts';
    public const SET_PRIVILEGES_USERS = 'set_privileges_users';
...


Далее проверка в избирателе
...
$permissions = [];
        try {
            if (is_a($user->getGroup(), UserGroup::class)) {
                $permissions = $user->getGroup()->getPermissions();
            }

            foreach ($permissions as $permission) {
                if (in_array($permission, $this->getAttributes())) {
                    return true;
                }
            }

            return false;
        }catch (Exception $exception) {
            return false;
        }
...


Итог, все разрешения принадлежать определённой группе, а в группу уже входит тот или иной пользователь.
Вот и все.
Ответ написан
Комментировать
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы