Security

Управление правами на файлы и каталоги Bitrix

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

  • Управление правами доступа к файлам описано в классе CMain в методах GetFileAccessPermission, SetFileAccessPermission, CopyFileAccessPermission, RemoveFileAccessPermission.
  • Уровень прав хранится в файле .access.php который может быть как один в корне проекта так и для каждого каталога отдельный.
  • Проверка прав идет рекурсивно от корня сайта к конечному каталогу.

Буквенно-символьные коды уровней доступа описывают жестко ограниченный список операций:
    D — доступ запрещён
    R — чтение (право просмотра содержимого файла)
    U — документооборот (право на редактирование файла в режиме документооборота)
    W — запись (право на прямое редактирование)
    X — полный доступ (право на прямое редактирование файла и право на изменение прав доступа на данных файл)
Для более гибкого управление рекомендуется использовать пользовательские уровни доступа.

Установка прав на файл или каталог

CMain:SetFileAccessPermission — задает уровень доступа в буквенно-символьных кодах. Возвращает boolean результат выполнения операции. В методе вызывается событие OnChangePermissions.

Для установки пользовательского уровня доступа вместо стандартных кодов доступа необходимо передать код T_n, где n — идентификатор задачи в таблице b_task.

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

//Установим пользовательский уровень с id 55 для группы с id 5
//Установим права на запись W для пользователя с id 2
//Для всех остальных пользователей запретим доступ D
$APPLICATION->SetFileAccessPermission("/about/", [
    "G5" => "T_55", 
    "U2" => "W", 
    "*" => "D"
]);

В системе есть предопределенные пользовательские уровни доступа аналогичные стандартным:

NAMELETTERMODULE_IDBINDING
fm_folder_access_deniedDmainfile
fm_folder_access_fullXmainfile
fm_folder_access_readRmainfile
fm_folder_access_workflowUmainfile
fm_folder_access_writeWmainfile

Для получения идентификатора задачи можно использовать методы:

/**
 * @var string $letter  - Буквенно-символьный код уровня
 * @var string $module  - Код модуля
 * @var string $binding - Код привязки, file - для уровней доступа к файлам и каталогам
 */
\CTask::GetIdByLetter($letter, $module, $binding='module');

/**
 * @var array $arOrder - Сортировка результатов
 * @var array $arFilter - Фильтр по полям
 */
\CTask::GetList($arOrder = array('MODULE_ID'=>'asc','LETTER'=>'asc'), $arFilter = array());

Примеры поиска уровней доступа:

//Получаем идентификатор уровня чтения для файлов и разделов
$iTaskId = \CTask::GetIdByLetter('R', 'main', 'file');

//Получаем идентификатор уровня чтения по имени уровня
$oTask = \CTask::GetList([], [
    'NAME' => 'fm_folder_access_read',
    'MODULE_ID' => 'main',
    'BINDING' => 'file'
]);
$arTask = $oTask->Fetch();
$iTaskId = $arTask['ID'];

Свои уровни доступа к файлам и каталогам можно создать переопределив метод GetModuleTasks и вызвав в DoInstall метод InstallTasks в классе инсталляции своего модуля.
Также возможно создать уровень прав не прибегая к созданию модуля используя класс \CTask.
Пример создания уровня без модуля:

//Создаем запись нового уровня доступа в таблице b_task
$iTaskId = \CTask::Add([
    'NAME' => 'my_task_name',
    'LETTER' => 'M',
    'MODULE_ID' => 'main',
    'DESCRIPTION' => '',
    'BINDING' => 'file'
]);

//Массив с операциями входящими в состав уровня
$arOperations = [
    [
        'NAME' => 'my_task_name_oper_1',
        'MODULE_ID' => 'main',
        'DESCRIPTION' => '',
        'BINDING' => 'file'
    ],
    [
        'NAME' => 'my_task_name_oper_2',
        'MODULE_ID' => 'main',
        'DESCRIPTION' => '',
        'BINDING' => 'file'
    ],
    [
        'NAME' => 'my_task_name_oper_3',
        'MODULE_ID' => 'main',
        'DESCRIPTION' => '',
        'BINDING' => 'file'
    ]
];

//Cоздаем записи операций в таблице b_operation
foreach ($arOperations as $operation) {
    \Bitrix\Main\OperationTable::add($operation);
}

//Cоздаем записи привязки операций к уровню доступа в таблице
// b_task_operation, последний аргумент ставим в true для привязки 
// по имени операции, иначе необходимо передавать идентификаторы
\CTask::SetOperations($iTaskId, [
    "my_task_name_oper_1",
    "my_task_name_oper_2",
    "my_task_name_oper_3",
], true);

Далее в коде останется только поставить проверки методом GetFileOperations или CanDoFileOperation.
Например:

//Массив всех операций доступных пользователю
$arOperations = $USER->GetFileOperations('/about/', \CUser::GetUserGroup(1));
//Проверка доступности конкретной операции пользователю
$bAssess = $USER->CanDoFileOperation('my_task_name_oper_1', '/about/');

Получение прав на файл или каталог

CMain::GetFileAccessPermission — определяет уровень доступа к файлу или каталогу для массива пользовательских групп. Возвращает буквенно-символьный код уровня доступа или массив доступных операций при работе с пользовательскими уровнями доступа.

/**
 * @var string $path      - Путь относительно корня проекта
 * @var array  $groups    - Массив групп пользователя, в случае отсутствия будут получены группы текущего авторизованного пользователя
 * @var bool   $task_mode - Проверка прав в режиме пользовательских уровней доступа
 */
public function CMain::GetFileAccessPermission(
    $path, 
    $groups=false, 
    $task_mode=false
);

Примеры использования метода:

//Проверка в контексте текущего пользователя
$APPLICATION->GetFileAccessPermission("/about/");
//Проверка для определённого пользователя
$APPLICATION->GetFileAccessPermissionByUser($USER->GetID(), "/about/");
//Проверка для определённой группы
$APPLICATION->GetFileAccessPermission("/about/",[2]);
//Получение массива идентификаторов пользовательских уровней доступа
$arTasks = $APPLICATION->GetFileAccessPermissionByUser($USER->GetID(), "/about/", true);

При работе с пользовательскими уровнями доступа будет возвращен массив идентификаторов именно уровней доступа, а не доступных операций. Для получения списка операций необходимо использовать метод \CTask::GetOperations

//Получаем массив операций уровня доступа
$arOperations = \CTask::GetOperations($iTaskId, true);

Далее можно использовать проверки доступа методами GetFileOperations или CanDoFileOperation описанными выше.

Удаление прав на файл или каталог

CMain::RemoveFileAccessPermission — удаляет записи прав доступа на файл или каталог. Возвращает boolean результат операции.
Примеры использования метода:

//Удаление записей для группы c id 5
$APPLICATION->RemoveFileAccessPermission('/about/', [5]);
//Удаление всех записей прав
$APPLICATION->RemoveFileAccessPermission('/about/', false);

Копирование прав на файл или каталог

CMain::CopyFileAccessPermission — копирует записи прав доступа с файла на файл. Возвращает boolean результат выполнения.

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

$APPLICATION->CopyFileAccessPermission("/about/", "/en/about/", true);

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *