Общее описание
Система должна обрабатывать множество элементов, организованных во вложенные категории (см. наглядный пример ниже), предоставляя клиентам возможность определять правила разрешений (см. правила разрешений ниже). Он также должен обрабатывать различные общие разрешения, которые не зависят от каких-либо элементов (например, «можно просматривать определенную страницу?» или «можно приглашать новых участников?»).
Все пользователи объединены в группы. У каждого пользователя есть основная группа, к которой он принадлежит, но у него также могут быть дополнительные второстепенные группы.
Несколько пользователей могут быть настроены как суперадминистраторы, и им должно быть разрешено делать что угодно.
При принятии решения о том, разрешено ли пользователю что-то делать, наследование разрешений выглядит следующим образом:
- Начните с разрешений основной группы
- Разрешить все разрешения, разрешенные любой из дополнительных групп пользователя
- Если они определены, проверьте определенные разрешения пользователя (чтобы разрешить или запретить, независимо от вышеперечисленного). Пользовательские разрешения не должны быть определены, если они не определены, пользователь просто наследует разрешение от разрешений группы.
При определении разрешения группы клиент может использовать наследование, чтобы сказать что-то вроде:
- Пользователям разрешено...
- Редакторы имеют все права пользователей + ...
- Модераторы имеют все права редакторов + ... - ...
- Администраторы имеют все права редакторов + модераторов.
ПРИМЕЧАНИЕ. Я должен иметь возможность запрашивать последние 10 элементов из базы данных, которые текущий пользователь может редактировать/просматривать, разрешение для каждого элемента должно определяться базой данных, я не хочу фильтровать элементы для разрешения на уровне приложения, если бы я мог решить это на основе информации, хранящейся в базе данных.
Правила разрешений
Правила могут зависеть от любого свойства элемента (например, основная группа владельца элемента, время создания, категория и т. д.), эта информация хранится в базе данных.
Правила также могут зависеть от любого свойства текущего пользователя (например, дата регистрации, приглашение участников), запрошенного действия (например, просмотр, список, переименование, отмена удаления и т. д.) и другой информации, уже доступной во время выполнения (например, параметры URL-адреса). , лимиты квот, содержимое элемента, загрузка сервера), эта информация доступна для php-скрипта.
См. примеры правил ниже.
Наглядный пример схемы базы данных:
Category 1
Nested Category A
item x
Nested Category B
Deeply Nested Category
item w
item y
Category 2
item z
В настоящее время схема базы данных выглядит следующим образом, но я могу изменить ее, если это необходимо: (конечно, это только часть схемы, есть и другие таблицы и поля)
элементы:
id | title | owner_id | category_id
====================================
1 | item x | 2 | 3
2 | item y | 1 | 4
3 | item z | 3 | 2
4 | item w | 1 | 5
категории:
id | parents | title
=====================================
1 | null | Category 1
2 | null | Category 2
3 | 1 | Nested Category A
4 | 1 | Nested Category B
5 | 1/4 | Deeply Nested Category
пользователи:
id | name | group | all_groups | is_super_admin
===============================================
1 | Tony | 5 | 5 | 1
2 | John | 5 | 5,8,6 | 0
3 | Mike | 4 | 4,7 | 0
4 | Ryan | 6 | 6 | 0
Примеры правил
Следующие правила являются лишь примерами реальных случаев, которые следует реализовать.
- Пользователи могут редактировать свои собственные элементы в течение 5 минут после отправки ()
- Пользователь «Джон» может редактировать все элементы в «Категории 1» и во всех вложенных категориях.
- Редакторы могут редактировать все элементы, кроме тех, владелец которых помечен как суперадминистратор.
Обратите внимание, что эти правила могут быть определены на уровне базы данных, как и большинство правил в моем случае.
Реализация
Я искал документы symfony, stackoverflow и т.д. Есть много интересных статей и вопросов на тему безопасности и ACL, но я не смог найти лучший способ справиться с такой системой.
Понятно, что мне нужен какой-то тип динамического построителя запросов для фильтрации строк на основе информации, хранящейся в базе данных, в соответствии с определенными правилами. Я предполагаю, что второй шаг (который включает информацию, которая не хранится в базе данных, например, текущая загрузка сервера), вероятно, заключается в реализации избирателя (см. пример избирателя в этой статьи или этот вопрос), а иногда и более простое решение (например, правила, зависящие от запрошенного пути). Если решение включает в себя несколько вещей для обработки разрешений, пожалуйста, также опишите, как интегрировать и использовать их вместе.
Вопрос
Я спрашиваю, как реализовать такую систему, пожалуйста, не отвечайте ссылками на документацию symfony или другие ресурсы с общей идеей и типичными простыми случаями. Пожалуйста, прочитайте и поймите мой случай, прежде чем отвечать.