Документация InstantCMS

для администраторов и разработчиков

Инструменты пользователя

Инструменты сайта


dev:controllers:backend:perms

Управление правами доступа

InstantCMS 2 позволяет автоматизировать настройку прав доступа для различных групп пользователей. В админке компонента может быть добавлен специальный экшен, позволяющий определить права. Затем во фронтенде и шаблонах эти права могут быть проверены.

Правила доступа

Правилами доступа называются условия, определяющие возможность зарегистрированного пользователя выполнить какое-либо действие.

Например, так выглядит список правил и форма их настройки в админке компонента «Комментарии»:

Все правила можно разделить на три типа:

flagПравило, имеющее два состояния – включено и выключено. В интерфейсе отображается как чекбокс
listПравило, имеющее несколько предустановленных значений для выбора. В интерфейсе отображается как выпадающий список
numberПравило, представленное в виде числа. В интерфейсе отображается как текстовое поле

Например, вы пишете компонент «Гостевая книга» и хотите сделать настройку прав на три типа действий: добавление записей, редактирование записей и ограничение по репутации, необходимой для добавления записи. Тогда вы можете предусмотреть три правила доступа:

Правило Название Подходящий тип Возможные значения
Добавление записи add_message flag да или нет
Редактирование записей edit_message list own (только свои), all (все записи)
Мин.репутация для добавления karma_limit number Число баллов репутации пользователя, необходимое для возможности добавить запись

Названия правил могут быть любыми, но должны состоять только из латинских букв, цифр и знаков подчеркивания. Названия возможных значений для правил типа list тоже могут быть любыми и формируется по тому же принципу.

Субъекты правил

Один компонент может работать с несколькими сущностями данных. Например, если мы пишем биржу труда, то в ней могут быть два типа сущностей – резюме и вакансии. При этом, допустим, мы хотим иметь возможность отдельно разрешать или запрещать добавление как резюме, так и вакансий.

В этом случае не нужно создавать два отдельных правила («добавление резюме», «добавлений вакансий»). Достаточно создать одно правило (просто «добавление»), а при настройке указывать о каком субъекте (резюме или вакансия) идет речь в данный момент.

То есть, одно правило для одного пользователя может иметь несколько разных значений, в зависимости от текущего субъекта. Выбор текущего субъекта производится при настройке правила и при проверке его значений (когда нужно ограничить доступ).

Ниже будут даны дополнительные подробности.

Создание правил доступа

Перед тем как приступать к созданию формы настроек правил доступа необходимо создать сами правила, добавив их в базу данных и в языковой файл компонента.

База данных

В базе данных правила хранятся в общей таблице perms_rules. Для каждого правила добавляется собственная запись, со следующими полями:

ПолеОписаниеПример
controllerНазвание компонента, который использует данное правилоcomments
nameНазвание правилаadd
typeТип правилаflag
optionsСписок возможных значений, через запятую. Только для правил с типом listown,all,any

Значения каждого правила для каждой группы пользователей хранятся в таблице perms_users. Добавлять вручную в эту таблицу ничего не нужно (кроме случаев, когда вы точно знаете что делаете). Вместо этого, добавлением данных записей будет заниматься специальный экшен настройки, о котором будет рассказано ниже.

Языковой файл

В языковом файле компонента необходимо добавить заголовки для каждого правила. Для правил с типом list также необходимо добавить заголовок каждой опции (кроме own и all).

Имя константы заголовка правила формируется по схеме: LANG_RULE_{КОМПОНЕНТ}_{ПРАВИЛО}. Например, для правила add компонента comments:

define('LANG_RULE_COMMENTS_ADD', 'Добавление комментариев');

Если вам нужно указать пояснение к правилу, то вы можете определить константу по схеме LANG_RULE_{КОМПОНЕНТ}_{ПРАВИЛО}_HINT, например (утрируя, т.к. в данном случае пояснение лишнее) для правила add компонента comments:

define('LANG_RULE_COMMENTS_ADD_HINT', 'Если включено, пользователи смогут добавлять комментарии');

Пояснение будет отображаться под названием правила в списке.

Для опций имена констант формируются по схеме: LANG_PERM_OPTION_{ОПЦИЯ}. Например, если у вас есть правило с типом list и среди его возможных значений есть опция any, то константа будет выглядеть так:

define('LANG_PERM_OPTION_ANY', 'Любой');

В системе есть 2 заранее заданные константы для опций own и all:

define('LANG_PERM_OPTION_OWN', 'Только свои');
define('LANG_PERM_OPTION_ALL', 'Все');

То есть для этих двух опций языковые константы добавлять не нужно.

Настройка правил доступа

После того как правила добавлены в базу, можно приступить к созданию экшена для их настройки в админке компонента.

Этот экшен заранее определен в классе cmsBackend, аналогично экшену для настройки опций. Вам нужно лишь включить его и создать шаблон.

Экшен выводит список правил доступа для данного компонента (см. скриншот в начале статьи) и обрабатывает сохранение их значений в базе.

Включение экшена

Для того, чтобы контроллер админки (backend.php) знал, что вы хотите использовать стандартный экшен для настройки правил доступа, необходимо добавить в описание класса строчку:

public $useDefaultPermissionsAction = true;

После этого экшен станет доступен по URL: /admin/controllers/edit/{компонент}/perms/{субъект}.

В качестве названия субъекта можно использовать любое сочетание латинских букв и цифр. Если компонент работает только с одним типом данных (например, компонент comments управляет только комментариями), то в качестве субъекта можно использовать название самого компонента:

/admin/controllers/edit/comments/perms/comments

Если субъектов должно быть несколько (например, для компонента «Биржа труда» это могут быть резюме и вакансии), то экшен можно разделить на два отдельных:

/admin/controllers/edit/birzha_truda/perms/vakansii
/admin/controllers/edit/birzha_truda/perms/rezume

Физически оба этих URL будут обрабатываться одним экшеном, но, например, ссылок в меню (об этом ниже) может быть уже несколько.

Шаблон экшена опций

Для InstantCMS выше 2.4.0

Для версий InstantCMS выше 2.4.0 прямой необходимости в создании шаблона нет. По умолчанию будет использоваться файл /templates/default/controllers/admin/backend/controllers_perms.tpl.php.

Обратите внимание, если необходимо показать ссылку на документацию, создайте в языковом файле контроллера константу LANG_HELP_URL_COM_ИМЯ-КОНТРОЛЛЕРА, где напишите URL справочной информации. В этом случае на странице правил доступа появится ссылка на нее.

Для InstantCMS 2.4.0 и ниже

До версии 2.4.0 включительно, шаблон необходимо создавать в обязательном порядке.

Свой шаблон вывода правил доступа

Создайте файл /templates/default/controllers/{компонент}/backend/perms.tpl.php со следующим содержимым:

<?php
 
    $this->addBreadcrumb(LANG_PERMISSIONS);
 
    $submit_url = $this->href_to('perms_save', $subject ? $subject : false);
 
    echo $this->renderPermissionsGrid($rules, $groups, $values, $submit_url);

Вы можете модифицировать этот шаблон под собственные нужды.

Добавление экшена в меню

Если кроме настройки правил доступа в админке вашего компонента будут и другие разделы, то имеет смысл создать меню админки.

Для этого в контроллере админки (backend.php) добавьте метод getBackendMenu():

public function getBackendMenu(){
    return array(
 
        // ссылка на экшен "Доступ"
        // третий параметр в href_to - название субъекта
        // если компонент имеет только один субъект, то передаем
        // название самого компонента ($this->name)
        array(
            'title' => LANG_PERMISSIONS,
            'url' => href_to($this->root_url, 'perms', $this->name)
        ),
 
        // ... здесь добавьте ссылки на другие разделы админки ...
 
    );
}

Переадресация на экшен

При переходе к настройкам компонента, админка по-умолчанию отправляет пользователя на экшен index вашего контроллера админки. Поэтому, если в вашей админке такой экшен не нужен, то вы можете из него делать автоматический редирект на другой экшен.

Пример переадресации из экшена index на экшен perms (в компоненте comments):

class backendComments extends cmsBackend{
 
    public $useDefaultPermissionsAction = true;
 
    public function actionIndex(){
        // переадресация на экшен perms для субъекта comments
        $this->redirectToAction('perms', 'comments');
    }
 
}

Проверка прав доступа

В любом месте компонента (в контроллерах, экшенах, шаблонах и модели) можно проверить значение правила доступа для текущего пользователя. Описанные ниже методы работают одинаково во всех местах.

Проверка производится с помощью статических методов класса cmsUser, отвечающего за информацию о текущем пользователе.

Проверка flag и list

Правила типов flag и list проверяются с помощью метода isAllowed($subject, $permission[, $value]), где:

$subjectНазвание субъекта для правила (или название самого компонента, если субъект у него один)
$permissionНазвание правила доступа
$valueЗначение, с которым происходит сравнение. По-умолчанию – true

Метод возвращает результат сравнения (true/false) значения $value со значением, заданным в админке для данного правила и группы текущего пользователя.

Например, так компонент comments проверяет что пользователь имеет право добавлять комментарии:

if ( cmsUser::isAllowed('comments', 'add') ) { ... }

А так, что пользователь может удалять любые комментарии (не только свои):

if ( cmsUser::isAllowed('comments', 'delete', 'all') ) { ... }

Во втором случае правило delete имеет тип list, и среди его возможных значений есть опция all, с которой и происходит сравнение.

Проверка number

Для проверки числовых правил есть два метода, использующих те же самые входящие параметры, что и описанный выше:

isPermittedLimitReachedПроверяет, что указанное в правиле значение достигнуто, т.е. значение $value больше или равно указанному в настройках правила
isPermittedLimitHigherПроверяет, что указанное в правиле значение больше, т.е. значение $value меньше указанного в настройках правила

Первый метод удобно использовать когда речь идет об ограничениях, которые пользователь должен превзойти, например ограничение на минимальный рейтинг:

if ( cmsUser::isPermittedLimitReached('comments', 'min_rating', $user->rating) ) { ... }

Второй метод пригодится для проверки ограничений, которые вероятно еще не наступили, например максимального числа добавленных записей за день:

if ( cmsUser::isPermittedLimitHigher('blog', 'max_posts', $user_posted_today) ) { ... }

Вернуться к оглавлению

dev/controllers/backend/perms.txt · Последние изменения: 14.03.2016 11:21 — fuze