Некоторые мысли относительно контроля прав в Cogear
Что мы имеем, и как сделать лучше?
На данный момент в движке Cogear существует следующая система контроля прав:субъект права:[множество пользователей (группа)] -> (право на действие) {объект права зависит от acl-записи}
Такая система проста, но не очень гибка — на каждое действие приходится придумывать отдельное право. Кроме того, на некоторые типы субъектов (к примеру, владельца (автора) публикации или комментария) тоже приходится придумывать отдельные acl, и, более того, реализовывать их поддержку в коде модуля.
Разрешение на действие:
[множество субъектов разрешения] -> (действие) -> [множество объектов разрешения]
Запрет на действие:
[множество субъектов запрета] -> (действие) -> [множество объектов запрет]
Теперь, поясню множества субъектов и объектов:
Множеством субъектов может быть:
- Все пользователи вообще
- Все незарегистрированные пользователи
- Все зарегистрированные пользователи
- Пользователи, принадлежащие к какой-либо отдельной группе (входит в предыдущее множество)
- Какой-то конкретный пользователь (входит в предыдущее множество, является множеством из одного элемента)
- Владелец объекта (входит во множество пользователей в группах, является множеством из одного элемента)
Множеством объектов может быть:
- Любой объект (запись, комментарий, сообщество,право доступа, etc)
- Объект конкретного типа (запись, комментарий, сообщество,право доступа, etc)
- Конкретный объект
- Дочерний объект конкретного объекта (для сообщества или блога это будет публикация, для публикации — комментарий, для комментария — ответ на комментарий и т.д.)
А, в свою очередь, действия могут быть таковыми:
- Любое действие
- Видимость (объект выводится в списке, к примеру запись в дайджесте блога)
- Просмотр (можно просмотреть, т.е. открыть запись)
- Редактирование
- Создание
- Удаление
- Оценка
- Отсутсвие капчи для совершения действия
- Присвоение (то есть изменение принадлежности на принадлежность конечному субъекту)
Теперь, про множества пользователей:
Пользователь может быть членом нескольких множеств, к примеру таких, как:
- Группы, определенные администратором
- Подписчики какого-либо блога
- Множество всех модераторов
- Множество модераторов конкретного блога
- и т.д.
Наверняка, у вас появился вопрос, зачем так сложно?
А вот зачем: Фишка разрешения комментирования любой записи добавляется так:разрешение:[множество всех пользователй] (создание) [объект типа комментарий]
Фишка ввода капчи для любого действия для провинившихся:
запрет:[монжество провинившихся] (отсутствие капчи) [множество всех объектов]
Фишка блокировки забаненых:
запрет:[множество забаненых] (любое действие) [множество всех объектов]
Фишка «прострелить себе коленку»:
запрет:[все пользователи вообще] (любое действие) [множество всех объектов]
Обработка на стороне сервера
По умолчанию прав нет. Ни на что.
При запросе (функции передается id пользователя, id и тип объекта, тип дочернего объекта (если есть) и действие, которое должно быть совершено) права доступа происходит следующее:
1. Будет вычеслено в какие множества входить пользователь
2. Будет вычеслен родитель объекта
3. Будет установленно, является ли пользователь владельцем объекта
4. Будет сделан запрос типа
запрет:[все пользователи или {все зарегистрированные} или {множества, в которые входит пользователь} или {владелец?} или пользователь] (действие) [все объекты или объект типа {тип} или {предок} или объект]
Если вернется хотя бы одна запись, доступ будет отклонен
5. Будет сделан запрос типа
разрешени:[все пользователи или {все зарегистрированные} или {множества, в которые входит пользователь} или {владелец?} или пользователь] (действие) [все объекты или объект типа {тип} или {предок} или объект]
Если вернется хотя бы одна запись, доступ будет разрешен.
К сожалению, у этой концепции есть и недостатки: сложность реализации, необходимость правки ВСЕГО кода движка и высокая нагрузка на сервер (в принципе может быть решено за счет кэша). Если подобная идея получит поддержку сообщества, и Дмитрий будет не против помочь с ее реализацией — можно будет заняться воплощением системы в действительность.
Хочется верить, что я достаточно подробно и внятно описал эту идею. Очень надеюсь на ваши комментарии.


С использованием кеша система приемлема, без кеша — слишком требовательна.
Я уже забыл, как реализован кеш в Cogear: если есть возможность для каких-то конкретных записей задавать время жизни infinite, то такую систему можно даже сделать :) если же нет, то придется редактировать еще и кеш.
есть таблица прав пользователя, есть таблица прав группы, есть таблица модулей(у меня — права на доступ к модулю.), есть 3 статуса — по умолчанию, запрещен, разрешен
если права заданы в группе пользователя то они действуют для ползователя у которого установлено «по умолчанию», но не действуют если у пользователя стоит «запрещен». Если у группы нету доступа но у пользователя есть — то итоговый статус доступа к модулю — разрешен.