В приложении, над которым я работаю, каждый пользователь может принадлежать к одной или нескольким группам, например, 'guest', 'member', 'admin' и т. д.
Когда пользователь применяет действие, которое меняет модель, например, регистрация аккаунта, редактирование чьих-либо постов и т. д. Мне нужно проверить, разрешено ли это делать пользователю.
Действия, в свою очередь, могут иметь владельца (или субъекта), которому разрешено его выполнять. Например, тема действий при регистрации и входе в систему - guest
, тема выхода из системы - member
(имеется в виду зарегистрированный пользователь), тема редактирования действия поста - owner
.
Прямо сейчас я делаю это в стиле Apache, запрещаю правила:
- у каждого метода есть список ролей пользователей, которым разрешено его использовать
- каждая из этих ролей имеет 3 атрибута:
order
(«разрешить, запретить» или «запретить, разрешить»)
allow
- со списком ролей субъекта (которые могут отличаться от текущего пользователя), например, владелец, гость, участник, администратор и т. д., которым разрешено использовать его
deny
- то же, что и выше, но субъектные роли, которым запрещено использовать его
Функция isAllowed
имеет такую логику:
Получает группы текущего пользователя и темы.
Если текущий идентификатор пользователя = идентификатор субъекта, он добавляет «владельца» в группы как текущего пользователя, так и субъекта.
Если ни одна из групп текущего пользователя не указана в пользовательских ролях метода, функция возвращает false.
Функция «Остальное» продолжает проверять, входят ли группы субъектов в списки разрешений или запретов, и применяет логику порядка (разрешить / запретить).
Если результат более 1 (например, субъект-пользователь является одновременно и членом, и администратором), я применяю логику подчинения (где каждая роль имеет числовое значение важности, поэтому я могу знать, что быть администратором - это более важная позиция, чем постоянный участник) и выберите результат (разрешить или запретить) для наиболее важной роли.
Имеет ли это смысл? Что я должен изменить?