Меню

Создание уровней доступа для модуля при установке (API битрикса)

Битрикс имеет богатые возможности для управления доступом пользователей к тем или иным функциям сайта. Эти права обычно определяются для групп пользователей и назначаются для каждого отдельного модуля. Есть стандартная схема уровней доступа: запрет/чтение/запись (D/R/W). Но при создании модулей рано или поздно возникает ситуация когда этой схемы становится мало. Плюс к этому часто необходимо задавать права для отдельных сущностей внутри модуля. Для этого при его установке создается системы уровней доступа.

Рассмотрим организацию уровней доступа на примере не существующего модуля my.exemple, который имеет набор профилей от имени которых можно запускать какие-либо действия и логирует их. Задачу поставим следующим образом:

Уровни доступа к модулю:
  • D - Доступ запрещен
  • R - Чтение (Просмотр профилей и логов)
  • W - Запись (Изменение и просмотр профилей, просмотр и удаление логов)
  • X - Полный доступ (все действия выше + изменение настроек модуля)

Уровни доступа к профилям (сущность profile)
  • D - Доступ запрещен
  • E - Исполнение (Запуск действий профиля)
  • W - Запись (Создание, редактирование, удаление и запуск действий профиля)

Уровни доступа обозначаются любыми буквами латинского алфавит от D до W. Обычно в порядке возрастания для того чтобы права можно было проверить выражением типа $rights > "R", но это не обязательно, а в некоторых случаях и не выполнимо. 

Обратите внимание, что мы используем букву X. Это не совсем корректно для уровней модуля если работа осуществляется через стандартные методы Битрикс, так как высший уровень имеет группа Администратор и это всегда W. Однако так можно поступить если мы хотим исключить даже администраторов из тех кто имеет полный доступ к модулю. Например дать доступ только одному из них. Или если получение уровней доступа производится через кастомный класс.

Переходим к реализации. В класс главного установочного файла модуля (<директория модуля>/install/index.php) вставляем метод GetModuleTasks() возвращающий массив с описанием уровней доступа.

<?
function GetModuleTasks()
{
	$t = [
		"my_exemple_denied" => [
			"LETTER" => "D",
			"BINDING" => "module",
			"OPERATIONS" => [],
		],
		"my_exemple_read" => [
			"LETTER" => "R",
			"BINDING" => "module",
			"OPERATIONS" => [
				"profiles_read",
				"logs_read",
				"tasks_read",
			],
		],
		"my_exemple_write" => [
			"LETTER" => "W",
			"BINDING" => "module",
			"OPERATIONS" => [
				"profiles_read",
				"profiles_edit",
				"logs_read",
				"logs_edit",
			],
		],
		"my_exemple_full" => [
			"LETTER" => "X",
			"BINDING" => "module",
			"OPERATIONS" => [
				"profiles_read",
				"profiles_edit",
				"logs_read",
				"logs_edit",
				"options_edit",
			],
		],
		"my_exemple_profile_denied" => [
			"LETTER" => "D",
			"BINDING" => "profile",
			"OPERATIONS" => [],
		],
		"my_exemple_profile_execute" => [
			"LETTER" => "R",
			"BINDING" => "profile",
			"OPERATIONS" => [
				"action_execute",
			],
		],
		"my_exemple_profile_write" => [
			"LETTER" => "W",
			"BINDING" => "profile",
			"OPERATIONS" => [
				"action_execute",
				"action_write",
			],
		],
	];
	return $t;
}
?>

Возвращаемый массив состоит из элементов описывающих каждый из уровней доступа. Ключом являются уникальные в системе сайта идентификаторы уровней доступа. Массив уровня состоит из следующих элементов:
  • LETTER - буквенное обозначение уровня
  • BINDING - привязка уровня. Если пустое или module, то привязка к модулю в целом.
  • OPERATIONS - операции доступные уровню. Иногда удобно проверять не уровень доступа пользователя, а возможность выполнения им конкретного действия.
Далее в том же файле в методе DoInstall() или вложенном в него вызвать метод $this->InstallTasks(), а в DoUninstall() $this->UnInstallTasks().

Теперь необходимо привязать языковые описания. Создаем файл <директория модуля>/admin/task_description.php.
<?
if(!defined("B_PROLOG_INCLUDED") || B_PROLOG_INCLUDED !== true) die();

use Bitrix\Main\Localization\Loc;

Loc::loadMessages(__FILE__);

return array(
	"MY_EXEMPLE_DENIED" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_DENIED'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_DENIED'),
	),
	"MY_EXEMPLE_READ" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_READ'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_READ'),
	),
	"MY_EXEMPLE_WRITE" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_WRITE'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_WRITE'),
	),
	"MY_EXEMPLE_FULL" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_FULL'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_FULL'),
	),
	"MY_EXEMPLE_PROFILE_DENIED" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_PROFILE_DENIED'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_PROFILE_DENIED'),
	),
	"MY_EXEMPLE_PROFILE_EXECUTE" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_PROFILE_EXECUTE'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_PROFILE_READ'),
	),
	"MY_EXEMPLE_PROFILE_WRITE" => array(
		"title" => Loc::getMessage('TASK_NAME_MY_EXEMPLE_PROFILE_WRITE'),
		"description" => Loc::getMessage('TASK_DESC_MY_EXEMPLE_PROFILE_WRITE'),
	),
	"MODULE" => array(
		"title" => Loc::getMessage("TASK_BINDING_MODULE"),
	),
	"PROFILE" => array(
		"title" => Loc::getMessage("TASK_BINDING_PROFILE"),
	),
);
?>
Ключи массива совпадают с ключами уровней доступа. 

Далее создаём языковые файлы в дмректории <директория модуля>/lang. Подробно останавливаться не будем, здесь всё стандартно.

Перевод операций производится точно так же в файле <директория модуля>/admin/operation_description.php

Нужно добавить что доступ может быть организован вообще без использования предустановленных уровней доступа, а с описанием только доступных операций. В этом случае администратор сможет создать уровни доступа по своему усмотрению с любым набором операций. Ключи здесь должны быть уникальными. Пример:
<?
function GetModuleTasks()
{
	$t = [
		"" => [
			"OPERATIONS" => [
				"my_exemple_profiles_read",
				"my_exemple_profiles_edit",
				"my_exemple_logs_read",
				"my_exemple_logs_edit",
				"my_exemple_options_edit",
				"my_exemple_action_execute",
				"my_exemple_action_write",
			],
		],
	];
	return $t;
}
?>


Все. Теперь после установки модуля будут созданы все необходимые уровни доступа и операции. Получение уровней доступа модуля производится через стандартные классы Битрикса. Для своих сущностей придется написать отдельные механизмы, так как они могут быть какими угодно и стандартизировать их нельзя.

Некоторые из методов получения прав:
<?
$APPLICATION->GetGroupRight($module_id);                              // уровень доступа к модулю текущего пользователя (буква)
CMain::GetGroupRight($module_id, $group_id);                           // уровень доступа к модулю для группы (буква)
$USER->CanDoOperation('my_exemple_profiles_edit');                 // может ли текущий пользователь выполнять операцию
$USER->CanDoOperation('my_exemple_profiles_edit', 15);           // может ли пользователь с ID 15 выполнять операцию
?>

08.09.2023

Возврат к списку

Оставаясь на этом сайте Вы соглашаетесь с использованием файлов cookie, а также принимаете все пользовательские соглашения данного сайта.