Мучаюсь вопросом, а какие есть общепринятые подходы к реализации разграничения прав в приложении, в случаях когда права на объекты распространяются вверх по иерархии?
Например, что-то типа - начальник подразделения может управлять (читать, удалять, менять) задачи всех отделов этого подразделения?
На практике я натыкался на два способа. Первый,
это, по сути, линеаризация иерархических отношений. В БД явно лежат связи: данный человек, имеет данное право, на данную группу объектов (задачи конкретного отдела, в нашем случае).
Особенно хорошо такая реализации подходит для параноидальной модели управления правами. Не принес служебную записку от вышестоящего начальства, доступа к задачам нового отела не получишь.
Зато если хочеться сделать все автоматически, то дописывается огромная куча кода, по синхронизации собсно прав и иерархии. Добавление объекта, удаление объекта.. все это требует изменения в нашем лианеризованном отношении.
Вариант два - хардкод. Все права в системе сводятся к простой табличке. По горизонтали описываются действия: Добавить задачу, удалить задачу, внести дополнения к задаче, по вертикали роли тех кто этим будет заниматься: Владелец задачи, начальник отдела, начальник подразделения. Таблицу окидывают мудрым взором, и приступают к реализации.
Действия по горизонтали превращаются в имена методов: can_create_task, can_drop_task, can_read_task. Из вертикали вытаскиваются параметры методов и собсно реализация через набор if'ов.
Для полного счаться необходимо еще добавить метод get_available_tasks, который на первых порах жизни проекта можно реализовать просто фильтруя все задачи через can_read_task.
А потом ad-hoc, не стеснясь этот интерфейс используют в коде. Что-то типа:
drop_task(task_id):
task = Task.get(task_id)
user = UserNamager.getCurrentUser()
if can_drop_task(user, task):
...
Есть мнение что второй подход, несмотря на то что кода в нем на порядок меньше, есть зло, вне зависимости от ситуации