Комментарии 4
В этой реализации, все элементы: и роли и разрешения - безусловные. Т.е. выдано раз - работает всегда. Попробуйте реализовать условную роль владельца, который имеет возможность, скажем, редактировать свою статью, а другие пользователи - нет.
В процессе, вероятно, вы придёте к динамической сборке разрешений и ролей, хранение в json отпадет за ненадобностью. Отдельные проверки на бан - тоже.
И главное помните: rbac - это управление разрешениями, а не запретами. По пытка управлять одновременно и разрешениями т банами - это как пытаться смешать white и black листы - ни к чему хорошему не приведет.
Описанная вами задача по редактированию статьи автором - это как раз "узкое место" RBAC. Оно решается через ABAC. Была идея добавить и такой функционал, но на текущий момент он мне не нужен, так что остановился именно на RBAC.
. По пытка управлять одновременно и разрешениями т банами
Я специально привел альтернативный вариант проверки бана
// Проверить что пользователь не в бане и имеет право на разрешение p1
$rc = !$user->ban() && $user->can('p1'); // TrueВ этом случае флаг бана можно устанавливать вне пакета RBAC и также использовать в условии при проверке. Добавление поддержи бана - это просто "фича", которая, на мой взгляд, органично реализуется внутри пакета работы с RBAC так как есть связь разрешения с баном.
он мне не нужен, так что остановился именно на RBAC
Но вы уже ввели типы статей и бан. Этого уже достаточно динамики, чтобы перейти на условные роли и разрешения - перейти на ABAC.
$rc = !$user->ban() && $user->can('p1'); // True
Думаю вам самому это решение кажется немного странным. И с точки зрения кода: делать двойную проверку почти всегда при проверки ролей; и с точки зрения логики: мы же задаем один вопрос в этом месте кода "можно ли сделать p1", а получаем 2 ответа, причем возможно противоречивых "юзер в бане, можно".
Поэтому и предлагаю вам реализовать что-то вроде схемы "user.active" -> "article.owner" -> "article.edit". И проверять как-то так $access = $user->can('article.edit', $article); - само пройдет цепочку против стрелочек и проверит: в "article.edit" например не прошли ли 5 минут с момента создания или вдруг уже есть комментарии под статьей; Затем авторство в "article.owner"; И затем в "user.active" - наличие бана.
Не ради абстрактного "лучше" - ваш код итак наверняка справляется с поставленной задаче. А ради интересного упражнения в ходе которого, я уверен, станут видны и более изящные решения и взгляд на контроль доступа станет шире.
Для атрибутов нужно реализацию менять. В данном случае я сделал RBAC + добавил то, что легко интегрируется и что мне 100% понадобится.
Чтобы убрать двойную проверку я как раз и сделал привязку разрешения к бану. И всё это в рамках одного пакета чтобы эффективно это дело кешировать.
В данном случае у меня была продуманная схема как сделать RBAC. А вот насчет ABAC такого не было. Поэтому я дал себе указание реализовать то. что уже продумано, а остальное оставить "на потом".
Я себе и так стараюсь "бить по рукам" чтобы исключить лишние упражнения. Иначе у меня получается что я сажусь писать простую страницу на php для вывода данных, а в итоге делаю комбайн который делает ещё много чего :)
Данный пакет - это не конечная цель, а просто промежуточное звено. Если я его начну допиливать до идеала, до цели не дойду.

Пакет управления доступом на основе ролей (RBAC) для PHP