Полное руководство по системе прав доступа Cotonti: маски, биты, группы на примере модуля Market
Детальное руководство по системе прав доступа Cotonti: битовые маски, символьные обозначения R, W, 1–5, A, группы пользователей, хранение в БД, функции управления и пример установщика модуля Market.
1. Введение
Cotonti — это гибкая система управления контентом, использующая развитую модель прав доступа. В основе этой модели лежат группы пользователей, объекты доступа и битовые маски разрешений. Понимание этой системы критически важно для разработки модулей, настройки прав и обеспечения безопасности сайта.
В данном руководстве подробно разбирается, как устроена система прав в Cotonti, как формируются символьные маски ('R', 'W', '1'–'5', 'A'), как они преобразуются в числовые значения и обратно, как эти права хранятся в базе данных, и как их использовать на примере установщика модуля Market. Руководство основано на анализе штатного кода Cotonti (файлы functions.php и auth.php) и кода установщика модуля Market. Все утверждения подтверждены кодом, без домыслов.
2. Основы системы прав Cotonti
2.1. Группы пользователей
В Cotonti каждый пользователь принадлежит одной основной группе (main group) и может входить в несколько дополнительных групп. Группы определяют базовые права пользователя. В ядре определены следующие стандартные группы (константы):
| Константа | Числовое значение | Описание |
|---|---|---|
COT_GROUP_DEFAULT | 0 | Шаблон для новых групп (не используется как реальная группа пользователей) |
COT_GROUP_GUESTS | 1 | Гости (неавторизованные посетители) |
COT_GROUP_INACTIVE | 2 | Неактивные пользователи (зарегистрированы, но не активированы) |
COT_GROUP_BANNED | 3 | Забаненные пользователи |
COT_GROUP_MEMBERS | 4 | Обычные зарегистрированные пользователи |
COT_GROUP_SUPERADMINS | 5 | Администраторы (суперадмины) |
COT_GROUP_MODERATORS | 6 | Модераторы (если используется) |
Эти константы объявлены в functions.php:
const COT_GROUP_DEFAULT = 0;
const COT_GROUP_GUESTS = 1;
const COT_GROUP_INACTIVE = 2;
const COT_GROUP_BANNED = 3;
const COT_GROUP_MEMBERS = 4;
const COT_GROUP_SUPERADMINS = 5;
const COT_GROUP_MODERATORS = 6;Пользовательские группы могут иметь идентификаторы больше 6; для них применяются правила, унаследованные от COT_GROUP_DEFAULT (подробнее в разделе о cot_auth_add_item()).
2.2. Объекты доступа: area и option
Права в Cotonti назначаются не глобально, а на конкретные объекты доступа. Объект идентифицируется парой:
area— область или модуль, например'page','forums','market'. Это строка, определяющая контекст прав.option— конкретный элемент внутри области: код категории, идентификатор раздела, или специальный маркер'a'(означает саму область в целом). Для категорий структуры option обычно совпадает с их кодом.
Например, право на чтение категории computers-components модуля Market будет записано как area = 'market', option = 'computers-components'.
При проверке прав функция cot_auth($area, $option, $mask) использует эти два параметра для поиска соответствующих битовых прав.
2.3. Битовые маски прав
Права хранятся в виде целого числа, каждый бит которого соответствует отдельному действию. Это позволяет эффективно упаковывать множество разрешений в одно число и быстро проверять их побитовыми операциями.
Cotonti определяет следующие биты прав (значения из функции cot_auth_getvalue()):
| Символ | Бит (позиция) | Десятичное значение | Описание |
|---|---|---|---|
R | 1 | 1 | Чтение (Read) — просмотр объектов |
W | 2 | 2 | Запись (Write) — добавление/редактирование |
1 | 3 | 4 | Специальное право уровня 1 (назначается модулем) |
2 | 4 | 8 | Специальное право уровня 2 |
3 | 5 | 16 | Специальное право уровня 3 |
4 | 6 | 32 | Специальное право уровня 4 |
5 | 7 | 64 | Специальное право уровня 5 |
A | 8 | 128 | Администрирование (Admin) — управление правами и настройками |
Итоговое числовое значение вычисляется как сумма значений разрешённых битов. Например:
R→ 1RW→ 1 + 2 = 3R1→ 1 + 4 = 5RW1A→ 1 + 2 + 4 + 128 = 135RW12345A→ 1+2+4+8+16+32+64+128 = 255
3. Символьные маски прав
Для удобства человека права записываются в виде строки символов. Каждый символ соответствует одному биту. Состав символов строго определён.
3.1. Символы R, W, 1–5, A
R(Read) — право на чтение или просмотр содержимого объекта.W(Write) — право на запись, создание или изменение объекта.1,2,3,4,5— пять дополнительных уровней прав, интерпретация которых полностью зависит от модуля. В ядре они не имеют фиксированного значения, что даёт разработчикам гибкость. Например, в модуле Market можно назначить:1— право публиковать объявления;2— право редактировать чужие объявления;3— право модерировать (подтверждать/отклонять);4— право управлять категориями;5— право на расширенные настройки.
Эти значения не обязательны; каждый модуль сам решает, как их использовать.
A(Admin) — право администрирования. Обычно подразумевает возможность управления правами доступа к данному объекту, а также выполнение действий, недоступных обычным пользователям.
3.2. Функция cot_auth_getvalue(): маска → число
Функция cot_auth_getvalue($mask) преобразует символьную маску в целое число. Она определена в auth.php:
function cot_auth_getvalue($mask)
{
$mn['0'] = 0;
$mn['R'] = 1;
$mn['W'] = 2;
$mn['1'] = 4;
$mn['2'] = 8;
$mn['3'] = 16;
$mn['4'] = 32;
$mn['5'] = 64;
$mn['A'] = 128;
$res = 0;
$masks = str_split($mask);
foreach ($masks as $k) {
if(isset($mn[$k])) $res += $mn[$k];
}
return $res;
}Как работает:
- Инициализирует массив соответствия символов и значений.
- Разбивает входную строку на отдельные символы.
- Для каждого символа, если он есть в массиве, добавляет его значение к результату.
- Возвращает сумму.
Примеры:
cot_auth_getvalue('R')→ 1cot_auth_getvalue('RW')→ 3cot_auth_getvalue('RW1A')→ 135cot_auth_getvalue('')→ 0cot_auth_getvalue('0')→ 0 (символ '0' добавлен для удобства, значение 0)
3.3. Функция cot_auth_getmask(): число → маска
Обратная функция cot_auth_getmask($rn) преобразует числовое значение в символьную маску. Определена в auth.php:
function cot_auth_getmask($rn)
{
$res = ($rn & 1) ? 'R' : '';
$res .= (($rn & 2) == 2) ? 'W' : '';
$res .= (($rn & 4) == 4) ? '1' : '';
$res .= (($rn & 8) == 8) ? '2' : '';
$res .= (($rn & 16) == 16) ? '3' : '';
$res .= (($rn & 32) == 32) ? '4' : '';
$res .= (($rn & 64) == 64) ? '5' : '';
$res .= (($rn & 128) == 128) ? 'A' : '';
return $res;
}Она проверяет каждый бит и добавляет соответствующий символ. Порядок символов фиксирован: R, W, 1, 2, 3, 4, 5, A.
Примеры:
cot_auth_getmask(1)→'R'cot_auth_getmask(3)→'RW'cot_auth_getmask(135)→'RW1A'cot_auth_getmask(0)→''
4. Хранение прав в базе данных
4.1. Таблица cot_auth
Все права доступа хранятся в таблице cot_auth (обычно $db_auth). Эта таблица связывает группы пользователей, области (area) и объекты (option) с числовыми значениями прав и блокировок.
4.2. Структура записей и ключи
Каждая запись таблицы содержит как минимум следующие поля (на основе использования в коде):
auth_groupid— ID группы пользователей.auth_code— код области (area), например'market'.auth_option— объект (option), например код категории, или'a'для всей области.auth_rights— целочисленное значение разрешённых прав (сумма битов).auth_rights_lock— целочисленное значение заблокированных прав (битовая маска того, что нельзя изменить через интерфейс).auth_setbyuserid— ID пользователя, который установил права (для аудита).
Уникальность записи обеспечивается комбинацией (auth_groupid, auth_code, auth_option). Это означает, что для каждой группы и каждого объекта (в рамках области) существует не более одной строки с правами.
При добавлении прав через cot_auth_add_item() создаётся по одной записи для каждой группы, у которой не установлен флаг skiprights.
5. Функции управления правами
5.1. cot_auth() — проверка прав пользователя
Основная функция проверки прав текущего пользователя:
function cot_auth($area, $option = null, $mask = 'RWA')Параметры:
$area— область (модуль).$option— конкретный объект (код категории) илиnull. Еслиnullили'', то подразумевается'a'(сама область).$mask— строка символов, определяющая, какие права нужно проверить. По умолчанию'RWA', т.е. проверяются чтение, запись и администрирование одновременно (возвращается массив результатов для каждого символа).
Возвращаемое значение:
- Если
$maskсостоит из одного символа — возвращаетbool. - Если
$maskсодержит несколько символов — возвращает массив[symbol => bool].
Как работает:
- Создаёт массив значений битов (
$mn). - Разбивает
$maskна символы. - Для каждого символа проверяет соответствующее право текущего пользователя, используя данные из
Cot::$usr['auth'](кэш прав, построенный при авторизации). - Логирует проверку в
Cot::$sys['auth_log'].
Функция использует побитовую операцию & для проверки, установлен ли нужный бит в сохранённом числовом значении прав.
Пример использования:
if (cot_auth('market', 'computers-components', 'R')) {
// Пользователь может читать эту категорию
}5.2. cot_auth_add_item() — добавление прав для объекта
Функция добавляет записи прав для нового объекта (например, категории). Определена в auth.php.
function cot_auth_add_item($module_name, $item_id, $auth_permit = [], $auth_lock = [])Параметры:
$module_name— область (area).$item_id— код объекта (option), например код категории.$auth_permit— массив разрешённых прав по группам. Формат:[group_id => 'RW1']. Если группа не указана, берётся из$cot_auth_default_permit.$auth_lock— массив блокировок по группам. Аналогично дополняется из$cot_auth_default_lock.
Алгоритм:
- Дополняет
$auth_permitи$auth_lockзначениями по умолчанию (с помощью оператора+, который сохраняет уже заданные ключи). - Для каждой группы из глобального массива
$cot_groups(если у группы не установленskiprights) создаёт запись:- Определяет
$base_grp: если ID группы >COT_GROUP_SUPERADMINS(5), то используетCOT_GROUP_DEFAULT(0), иначе сам ID группы. - Получает символьные маски из
$auth_permit[$base_grp]и$auth_lock[$base_grp]. - Преобразует их в числа через
cot_auth_getvalue(). - Добавляет запись в массив
$ins_array.
- Определяет
- Вставляет все записи одним запросом через
Cot::$db->insert(Cot::$db->auth, $ins_array). - Вызывает
cot_auth_reorder()иcot_auth_clear('all').
Важно: Если какой-то группы нет в $auth_permit, то для неё возьмётся значение из $cot_auth_default_permit. То же для блокировок. Это гарантирует, что все группы получат права.
5.3. cot_auth_remove_item() — удаление прав объекта
function cot_auth_remove_item($module_name, $item_id = null)Удаляет все записи прав для указанного объекта. Если $item_id не указан, удаляются все объекты данной области.
5.4. cot_auth_clear() — очистка кэша прав
function cot_auth_clear($id = 'all')Сбрасывает кэш прав пользователей, чтобы изменения вступили в силу. При 'all' очищает кэш всех пользователей и гостей.
5.5. cot_auth_reorder() — сортировка таблицы прав
Выполняет SQL ALTER TABLE ... ORDER BY ... для физической сортировки записей в таблице cot_auth. Это ускоряет выборки при большом количестве записей.
5.6. cot_auth_add_group() — регистрация новой группы
function cot_auth_add_group($group_id, $base_group_id = COT_GROUP_MEMBERS)Создаёт записи прав для новой группы, копируя их из базовой группы. Используется при динамическом создании групп.
5.7. cot_auth_remove_group() — удаление группы из прав
function cot_auth_remove_group($group_id)Удаляет все записи прав для указанной группы.
6. Права по умолчанию и их значения
6.1. $cot_auth_default_permit — стандартные разрешения
В файле auth.php определён глобальный массив:
$cot_auth_default_permit = [
COT_GROUP_DEFAULT => 'RW',
COT_GROUP_GUESTS => 'R',
COT_GROUP_INACTIVE => 'R',
COT_GROUP_BANNED => '0',
COT_GROUP_MEMBERS => 'RW',
COT_GROUP_SUPERADMINS => 'RW12345A'
];Эти значения используются, если в пользовательском массиве $auth_permit отсутствует та или иная группа. Обратите внимание: для COT_GROUP_BANNED стоит '0' (нет прав), для суперадминов — полный набор.
6.2. $cot_auth_default_lock — стандартные блокировки
$cot_auth_default_lock = [
COT_GROUP_DEFAULT => '0',
COT_GROUP_GUESTS => 'A',
COT_GROUP_INACTIVE => 'A',
COT_GROUP_BANNED => 'RW12345A',
COT_GROUP_MEMBERS => '0',
COT_GROUP_SUPERADMINS => 'RW12345A'
];По умолчанию для гостей и неактивных заблокировано право A (нельзя дать им админ-права через интерфейс). Для забаненных и суперадминов заблокированы все права — их права жёстко фиксированы.
7. Установщик модуля Market: пример использования
Модуль Market при установке создаёт множество категорий и назначает для них права. Рассмотрим ключевые фрагменты его установщика.
7.1. Массив категорий $categories
Категории описаны массивом, каждый элемент содержит:
'code'— уникальный код категории (например,'computers-components').'title'— название.'desc'— описание.'path'— иерархический путь в структуре (например,'001.001').
Пример фрагмента:
$categories = [
[
'code' => 'computers-components',
'title' => 'Computers & Components',
'desc' => 'Desktop computers, components, and peripherals.',
'path' => '001',
],
// ...
];7.2. Массивы $authPermit и $authLock
В установщике заданы собственные права для категорий Market, переопределяющие стандартные:
$authPermit = [
COT_GROUP_DEFAULT => 'RW1',
COT_GROUP_GUESTS => 'R1',
COT_GROUP_INACTIVE => 'R',
COT_GROUP_BANNED => '',
COT_GROUP_MEMBERS => 'RW1',
COT_GROUP_SUPERADMINS => 'RW12345A',
COT_GROUP_MODERATORS => 'RW1A',
];
$authLock = [
COT_GROUP_DEFAULT => '0',
COT_GROUP_GUESTS => 'W2345A',
COT_GROUP_INACTIVE => 'W12345A',
COT_GROUP_BANNED => 'RW12345A',
COT_GROUP_MEMBERS => '0',
COT_GROUP_SUPERADMINS => 'RW12345A',
COT_GROUP_MODERATORS => '0',
];Обратите внимание: для группы COT_GROUP_MODERATORS (6) заданы явные значения, хотя в стандартных массивах её нет. Это гарантирует корректные права для модераторов.
7.3. Цикл установки категорий и прав
Установщик последовательно создаёт каждую категорию с помощью cot_structure_add(), а затем, если категория успешно создана и $useDefaultAuth равен false, добавляет права через cot_auth_add_item().
foreach ($categories as $cat) {
$result = cot_structure_add('market', [...], $useDefaultAuth);
if ($result === true && !$useDefaultAuth) {
cot_auth_add_item('market', $cat['code'], $authPermit, $authLock);
}
}Пояснение: cot_structure_add() может возвращать true при успехе, массив с ошибкой (если категория уже существует) или false. Проверка $result === true предотвращает повторное добавление прав при повторном запуске установщика.
8. Анализ масок, используемых в Market
8.1. Разрешения по группам ($authPermit)
| Группа | Маска | Числовое значение | Пояснение |
|---|---|---|---|
COT_GROUP_DEFAULT | RW1 | 1+2+4 = 7 | Шаблон: новые группы получат чтение, запись, уровень 1 |
COT_GROUP_GUESTS | R1 | 1+4 = 5 | Гости могут читать и использовать уровень 1 (например, просмотр контактов) |
COT_GROUP_INACTIVE | R | 1 | Только чтение |
COT_GROUP_BANNED | '' | 0 | Нет прав |
COT_GROUP_MEMBERS | RW1 | 7 | Пользователи: чтение, запись, уровень 1 |
COT_GROUP_SUPERADMINS | RW12345A | 255 | Полный доступ |
COT_GROUP_MODERATORS | RW1A | 1+2+4+128=135 | Чтение, запись, уровень 1, администрирование |
8.2. Блокировки по группам ($authLock)
| Группа | Маска | Числовое значение | Пояснение |
|---|---|---|---|
COT_GROUP_DEFAULT | 0 | 0 | Ничего не заблокировано |
COT_GROUP_GUESTS | W2345A | 2+8+16+32+64+128=250 | Заблокированы все права, кроме R и 1 |
COT_GROUP_INACTIVE | W12345A | 2+4+8+16+32+64+128=254 | Заблокированы все, кроме R |
COT_GROUP_BANNED | RW12345A | 255 | Все права зафиксированы |
COT_GROUP_MEMBERS | 0 | 0 | Ничего не заблокировано |
COT_GROUP_SUPERADMINS | RW12345A | 255 | Полная блокировка (права суперадминов неизменяемы) |
COT_GROUP_MODERATORS | 0 | 0 | Ничего не заблокировано |
Интерпретация блокировок:
Блокировка (auth_rights_lock) показывает, какие биты нельзя изменить через интерфейс управления правами. Если бит установлен в lock, то соответствующее право фиксируется и не может быть снято или добавлено администратором сайта (кроме как прямым изменением БД). Например, для гостей заблокированы все права, кроме R и 1, что означает, что администратор не может дать гостям права W или A, но может менять R и 1.
9. Типовые комбинации масок и их смысл
На основе битовой системы можно составить множество масок. Приведём часто используемые комбинации:
R— только чтение. Подходит для гостевых групп, которым разрешён просмотр.RW— чтение и запись. Стандарт для зарегистрированных пользователей в большинстве модулей.R1— чтение + уровень 1. Например, гости могут видеть объект и дополнительную информацию, доступную по уровню 1.RW1— чтение, запись и уровень 1. Типичный набор для участников, которые могут добавлять материалы.RW12— чтение, запись, уровни 1 и 2. Расширенные права, например, для доверенных пользователей.RW123— чтение, запись, уровни 1–3. Может использоваться для модераторов без админ-прав.RW1234— ещё более широкие права.RW12345— почти полный доступ, но без администрирования.RW12345A— полный доступ, включая администрирование.A— только администрирование (встречается редко, обычно вместе с другими правами).W— только запись без чтения (нелогично, но возможно).0или пустая строка — отсутствие прав.
Комбинации могут быть произвольными, главное — чтобы они имели смысл для конкретного модуля. Уровни 1–5 могут быть задействованы модулем для градации действий.
10. Блокировки прав (auth_rights_lock)
10.1. Зачем нужны блокировки
Блокировки предотвращают случайное или злонамеренное изменение критических прав через интерфейс администратора. Например, если для гостей заблокировано право A, то администратор не сможет случайно дать гостям административные права, просто отметив галочку. Блокировка фиксирует бит, и изменение этого бита через стандартные средства становится невозможным.
10.2. Примеры блокировок и их эффект
Рассмотрим маску блокировки для гостей в Market: W2345A. Это означает, что биты W, 2, 3, 4, 5, A заблокированы. Администратор может изменять только биты R и 1 (снимать или давать эти права). Но даже если он даст гостям право W, оно не будет работать, потому что при проверке прав Cotonti смотрит только на auth_rights, а блокировка не влияет на фактическое значение прав, а только на возможность их редактирования. Тем не менее, блокировка гарантирует, что после установки права не будут случайно расширены.
Для забаненных и суперадминов блокировка RW12345A означает, что их права полностью фиксированы и не могут быть изменены через интерфейс.
11. Практические рекомендации для разработчиков модулей
- Используйте
cot_auth_add_item()для добавления прав при создании новых объектов. Это гарантирует, что права будут добавлены для всех групп с учётом значений по умолчанию. - Явно задавайте права для групп, если хотите отклониться от стандартных. В примере Market заданы права для всех стандартных групп, включая модераторов.
- Блокируйте критичные права, чтобы предотвратить их изменение. Особенно важно блокировать
Aдля гостей и неактивных, и полностью фиксировать права суперадминов и забаненных. - Помните о значениях по умолчанию: если вы не передадите какую-то группу в
$auth_permit, она получит права из$cot_auth_default_permit. Это может привести к неожиданным результатам, если вы хотели дать группе меньше прав. - Проверяйте права с помощью
cot_auth()в коде модуля. Не следует напрямую обращаться кCot::$usr['auth'], так как функция обеспечивает корректную обработку опции'any'и логирование. - Очищайте кэш прав после программного изменения прав, используя
cot_auth_clear(). - Соблюдайте уникальность пары
(area, option). Если объект уже существует, не добавляйте права повторно без необходимости.
12. Часто задаваемые вопросы (FAQ)
Вопрос: Что означают цифры 1–5 в масках?
Ответ: Это пять дополнительных уровней прав, которые модуль может использовать по своему усмотрению. Ядро не накладывает на них никакой семантики.
Вопрос: Чем отличается R от 1?
Ответ: R — стандартное право чтения, проверяемое ядром для отображения объектов. 1 — дополнительное право, которое может означать что угодно (например, «видеть скрытые поля»). Модуль сам решает, как его интерпретировать.
Вопрос: Можно ли дать пользователю право, которое заблокировано?
Ответ: Через интерфейс — нет, но технически можно изменить значение auth_rights напрямую в базе данных. Блокировка (auth_rights_lock) лишь запрещает изменение через стандартные средства.
Вопрос: Что произойдёт, если не указать блокировку для группы?
Ответ: Возьмётся значение из $cot_auth_default_lock. Если вы не хотите блокировать права, явно укажите '0'.
Вопрос: Как работает проверка прав, если пользователь входит в несколько групп?
Ответ: При построении ACL (cot_auth_build()) права из всех групп пользователя объединяются побитовым ИЛИ. Таким образом, пользователь получает максимум прав из всех своих групп.
Вопрос: Зачем нужна таблица cot_auth и почему не хранить права в группах?
Ответ: Права привязаны не только к группам, но и к конкретным объектам (категориям). Группы определяют общий уровень доступа, а таблица cot_auth позволяет гибко настраивать права для каждой категории отдельно.
13. Заключение
Система прав Cotonti — мощный и гибкий механизм, основанный на битовых масках. Понимание символьных обозначений (R, W, 1–5, A) и умение правильно формировать массивы разрешений и блокировок позволяет разработчикам создавать безопасные и настраиваемые модули. Пример модуля Market демонстрирует, как назначать права на категории при их создании, следуя лучшим практикам Cotonti. Надеемся, данное руководство помогло вам разобраться в тонкостях работы с правами доступа.
Комментарии (0)
Обсуждение страницы в Telegram
Автор контента
Оффлайн
Sodium Carbonate
Последняя авторизация: 28.08.2026 16:59
- Страница размещена: 28.08.2026 16:41
- Последнее обновление: 28.08.2026 16:59
- Язык:
English