Предполагая следующую структуру базы данных (изменяемая при необходимости) ...
Я ищу хороший способ определить «эффективные разрешения» для данного пользователя на данной странице таким образом, чтобы я мог вернуть строку, содержащую страницу и действующие разрешения.
Я думаю, что идеальное решение может включать в себя функцию, которая использует CTE для выполнения рекурсии, необходимой для оценки «эффективных разрешений» для данной строки страницы для текущего пользователя.
Предпосылки и детали реализации
Приведенная выше схема представляет собой отправную точку для системы управления контентом, в которой пользователям могут быть предоставлены разрешения путем добавления и удаления из ролей.
Ресурсы в системе (например, страницы) связаны с ролями, чтобы предоставить группе пользователей, связанных с этой ролью, разрешения, которые она предоставляет.
Идея состоит в том, чтобы иметь возможность легко заблокировать пользователя, просто запретив роль и добавив страницу корневого уровня в дереве к этой роли, а затем добавив пользователя в эту роль.
Это позволит структуре разрешений оставаться на месте, когда (например) подрядчик, работающий на компанию, недоступен в течение длительных периодов времени, и это также позволит обеспечить такое же предоставление исходных разрешений путем простого удаления пользователя из этой одной роли. ,
Разрешения основаны на типичных правилах типа ACL, которые могут применяться к файловой системе при соблюдении этих правил.
Разрешения CRUD должны быть обнуляемыми битами, поэтому доступные значения - это истина, ложь, не определены, если верно следующее:
- ложь + что-нибудь = ложь
- верно + не определено = верно
- правда + правда = правда
- не определено + не определено = не определено
Если какое-либо из разрешений ложно -> ложно Иначе, если есть правда -> правда Остальное (все не определено) -> ложь
Другими словами, вы не получаете никаких разрешений ни на что, если вы не получили их через членство в роли, а правило запрета отменяет правило разрешения.
«Набор» разрешений, к которому это относится, - это все разрешения, применяемые к дереву, включая текущую страницу, иными словами, если ложно в любой роли, примененной к любой странице дерева в этой странице, то результатом является ложь. , но если целое дерево до этого не определено, то текущая страница содержит истинное правило, результат здесь истинен, но будет родительским.
Я хотел бы по возможности свободно сохранить структуру базы данных, а также помнить, что моя цель здесь заключается в том, чтобы иметь возможность делать что-то вроде этого: select * from pages where effective permissions (read = true) and user = ?
поэтому любое решение должно позволить мне иметь набор запросов с действующими разрешениями в них. каким-либо образом (возвращать их необязательно, если критерии могут быть указаны).
Предполагая, что существуют 2 страницы, где 1 является дочерним по отношению к другому, и существуют 2 роли, одна для пользователей-администраторов и 1 для пользователей только для чтения, обе связаны только с страницей корневого уровня. Я ожидаю увидеть что-то вроде этого в качестве ожидаемого результата:
Admin user:
Id, Parent, Name, Create, Read, Update, Delete
1, null, Root, True , True, True , True
2, 1, Child,True , True, True , True
Read only user:
Id, Parent, Name, Create, Read, Update, Delete
1, null, Root, False , True, False , False
2, 1, Child,False , True, False , False
Дальнейшее обсуждение этого вопроса можно найти в главном чате на сайте, начиная с этой страницы .