роли, которые я могу придумать
Система прав наконец получила последний кусочек, которого мне не хватало. После переделки RBAC на сайте появилась матрица возможностей, которую я могу редактировать: какая роль может модерировать комментарии, какая может видеть список пользователей, всё это можно включать и выключать. Но сами роли были высечены в камне: user, moderator, dev, admin, и точка. Хочешь «junior moderator»? Не выйдет, иди пиши код.

Лестница ролей на странице прав. user и admin закреплены.
Теперь роли стали просто данными. Страница прав показывает их в виде лестницы: user закреплён внизу, admin закреплён наверху, а я могу создать новую роль в любом месте между ними, переименовать её, подвинуть вверх или вниз или удалить. Позиция на лестнице определяет ранг, а ранг решает, кто может действовать в отношении кого, так что перетащить роль выше moderator буквально значит, что moderator больше не сможет трогать тех, у кого она есть. Новая роль начинается совсем без прав, пока я сам не включу нужные: это показалось мне единственным разумным вариантом по умолчанию.
Часть, в которую я вложил больше всего внимания, это удаление. При удалении роли, которая у кого-то есть, система просит меня подтвердить действие, показывая точное число людей, у которых она есть, а затем возвращает их всех обратно в обычный user. А что с токенами, с которыми эти люди продолжают ходить? Токен сессии, в котором указана роль, которой больше не существует, не даёт вообще ничего: вся система считает неизвестные роли рангом ноль без каких-либо прав. Я проверил именно этот случай: создал роль, выдал кому-то токен с ней, удалил роль, повторно отправил токен: 403. Это тот скучный вид теста, после которого я могу спокойно спать.
Всё правило «по умолчанию запрещено» умещается в одну функцию:
func (c *Cache) RankOf(ctx context.Context, name string) (int, error) {
list, err := c.List(ctx)
if err != nil {
return 0, err
}
for i, r := range list {
if r.Name == name {
return i, nil
}
}
return 0, nil // unknown role: bottom of the ladder, no privileges
}Заодно по мелочи поправил кое-что: правило, что редактировать имена пользователей и почту могут только более высокие ранги, раньше проверяло роль, буквально называющуюся «dev». Раз dev теперь можно переименовать, эта проверка теперь сравнивает позиции на лестнице, а не имена. Теперь имена служат просто ярлыками, а правду задаёт лестница.