Документация для разработчиков
Темная тема

UserPermissions

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


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

При проектировании публичного API этого сервиса фокус был сделан на ответах на простые вопросы.

Сам этот сервис практически не работает напрямую с хранением настроек и атрибутов прав доступа, это только фасад с удобным API.

Тем не менее, ниже немного описывается структура таблиц и особенности проверки прав доступа.


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

Права доступа в CRM (как во многих других модулях) настраиваются на уровне ролей (таблица b_crm_role).

К каждой роли можно отнести пользователя / группу / подразделение и т.д. (таблица b_crm_role_relation).

На каждую роль настраиваются права доступа (таблица b_crm_role_perms).

Права доступа настраиваются в разрезе "сущности" (колонка ENTITY, это горизонтальная строка в интерфейсе настроек).

Для каждой сущности можно настроить определенный уровень прав (колонка ATTR) для определенного действия (колонка PERM_TYPE).

Хранение атрибутов

Каждый раз при создании / изменении элемента любого типа CRM, его данные, влияющие на права доступа, преобразуются в набор атрибутов и записывается в таблицу b_crm_entity_perms (метод \CCrmPerms::UpdateEntityAttr).

Соответствие между этими данными и получаемыми атрибутами представлено в таблице:


Данные элемента Пример значения атрибута
Поле ОтветственныйU1 1 - идентификатор пользователя
Поле ОтветственныйIU1 1 - идентификатор пользователя как сотрудника
Принадлежность ответственного к подразделениям орг. структурыD2 2 - идентификатор подразделения. Сохраняется как принадлежность к подразделению, так и принадлежность ко всем родительским подразделениям
Поле "Доступна (доступен) для всех"O Если галка в поле установлена, то атрибут есть, а если нет то нет
Является ли компания "моей компанией" (Для компаний)IS_MY_COMPANY Если компания является моей компанией, то атрибут есть и к таким записям доступ на чтение есть всегда, независимо от настроек доступа для остальных компаний
Список наблюдателей (Для лидов и сделок)CU1 1 - идентификатор пользователя. Для каждого наблюдателя добавляется свой атрибут в список
Значение статуса/стадии (Для лидов)STATUS_IDNEW NEW - идентификатор статуса
Значение стадии (Для сделок и коммерческих предложений))STAGE_IDNEW NEW - идентификатор стадии

Далее при проверке прав доступа алгоритм следующий:

  • для пользователя, относительно которого проверяются права доступа, получается список его ролей, из ролей и их разрешений строится карта атрибутов, доступных этому пользователю (метод \CCrmRole::GetUserPerms());
  • карта разрешений сравнивается с текущим набором атрибутов элемента с учетом действия, которое производится (\CCrmPerms::CheckEnityAccess());
  • для списочных запросов строится дополнительное выражение для добавления в WHERE (метод \CCrmPerms::BuildSql()).

В этом сервисе все эти действия спрятаны "под капотом" (по факту вызываются методы старого API).


При написании нового кода рекомендуется использовать именно этот сервис, а не старое API.

Инстанс сервиса следует получать из контейнера, т.к. внутри сервиса данные закешированы.

В методе Service\Container::getUserPermissions() есть аргумент $userId, куда можно передать идентификатор пользователя.

Методы

Метод Описание С версии
public function __construct(int $userId)
  • $userId - идентификатор пользователя, относительно которого будет производиться проверка прав;
Конструктор.

Если $userId = 0, то считается, что действие производится от системного пользователя. Этот пользователь не имеет ни на что доступа.

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

public function getUserId(): int
Вернет идентификатор пользователя.
public function getCrmPermissions(): \CCrmPerms
Вернет объект класса \CCrmPerms, завязанного на текущего пользователя.
public function canWriteConfig(): bool
Вернет true, если пользователь имеет право изменять настройки CRM.
public function canReadConfig(): bool
Вернет true, если пользователь имеет право читать настройки CRM.
public function canReadType(int $entityTypeId, int $categoryId = 0): bool
  • $entityTypeId - идентификатор типа сущности CRM;
  • $categoryId - идентификатор направления.
Вернет true, если пользователь имеет право просматривать элементы типа $entityTypeId хотя бы в одном из направлений типа.
public function canReadTypeInCategory(int $entityTypeId, int $categoryId): bool
  • $entityTypeId - идентификатор типа сущности CRM;
  • $categoryId - идентификатор направления.
Вернет true, если пользователь имеет право имеет право просматривать элементы типа $entityTypeId в направлении $categoryId. crm 22.0.0
public function canAddType(): bool
Вернет true, если пользователь имеет право создать новый смарт-процесс.
public function canUpdateType(): bool
Вернет true, если пользователь имеет право изменить настройки смарт-процесса с идентификатором типа CRM $entityTypeId.
public function canAddItem(Item $item): bool
Вернет true, если пользователь имеет право создать элемент $item в его текущем состоянии.
public function checkAddPermissions
(int $entityTypeId, int $categoryId = 0, 
?string $stageId = null): bool
Вернет true, если пользователь имеет право создать элемент типа $entityTypeId в направлении $categoryId на стадии $stageId.
Здесь и ниже, если направление не указано, то проверка будет произведена для направления по умолчанию.
Если стадия не указана, то проверка прав с учетом стадии производиться не будет.
public function checkUpdatePermissions
(int $entityTypeId, int $id, 
int $categoryId = 0): bool
Вернет true, если пользователь имеет право изменить элемент с идентификатором $id в направлении $categoryId.
public function canUpdateItem(Item $item): bool
Вернет true, если пользователь имеет право изменить элемент $item.
public function checkDeletePermissions
(int $entityTypeId, int $id, int $categoryId = 0): bool
Вернет true, если пользователь имеет право удалить элемент типа $entityTypeId с идентификатором $id в направлении $categoryId.
public function canDeleteItem(Item $item): bool
Вернет true, если пользователь имеет право удалить элемент $item.
public function checkReadPermissions
(int $entityTypeId, int $id = 0, int $categoryId = 0): bool
Вернет true, если пользователь может прочитать элемент типа $entityTypeId с идентификатором $id в направлении $categoryId.
public function canReadItem(Item $item): bool
Вернет true, если пользователь имеет право прочитать элемент $item.
public function canViewItemsInCategory
(Category $category): bool
Вернет true, если пользователь имеет право прочитать элементы $item направления $category.
public function canAddCategory
(Category $category): bool
Вернет true, если пользователь имеет право создать новое направление $category.
public function canUpdateCategory
(Category $category): bool
Вернет true, если пользователь имеет право изменить направление $category.
public function canDeleteCategory
(Category $category): bool
Вернет true, если пользователь имеет право удалить направление $category.
public function filterAvailableForReadingCategories
(array $categories): array
Вернет массив направлений из набора $categories, в которых пользователь может просматривать элементы.
public function getPermissionType
(Item $item, string $operationType = self::OPERATION_READ): 
string
Вернет строковый идентификатор уровня доступа (все / свои и своего отдела / свои / только открытые / нет), который есть у пользователя к элементу $item при выполнении операции $operationType.
public function prepareItemPermissionAttributes
(Item $item): array
Вернет набор атрибутов элемента $item перед его сохранением в таблицу b_crm_entity_perms.
public static function getItemPermissionEntityType
(Item $item): string
Вернет строковый идентификатор сущности для таблицы прав элемента $item.
public static function getPermissionEntityType
(int $entityTypeId, int $categoryId = 0): string
Вернет строковый идентификатор сущности для таблицы прав типа сущности $entityTypeId в направлении $categoryId.
public static function getEntityNameByPermissionEntityType
(string $permissionEntityType): ?string
Вернет строковый идентификатор типа сущности CRM по строковому идентификатору сущности $permissionEntityType для таблицы прав.
public function applyAvailableItemsFilter
(?array $filter, array $permissionEntityTypes, 
?string $operation = self::OPERATION_READ, 
?string $primary = 'ID'): array

  • $filter - текущий фильтр для списка элементов;
  • $permissionEntityTypes - массив строковых идентификаторов для таблицы прав;
  • $operation - тип операции;
  • $primary - код первичного ключа, который будет добавлен в фильтр.
Дополнит $filter дополнительными ключами, которые позволят отобрать только те элементы, к которым пользователь имеет доступ. Вернет новую версию фильтра.
public function getStartStageId(int $entityTypeId, 
EO_Status_Collection $stages, int $categoryId = 0, 
string $operation = self::OPERATION_ADD): ?string

  • $entityTypeId - идентификатор типа сущности CRM;
  • $stages - коллекция стадий;
  • $categoryId - идентификатор направления;
  • $operation - тип операции.
Вернет идентификатор первой стадии из коллекции $stages типа $entityTypeId направления $categoryId, к которой имеет доступ пользователь при выполнении операции типа $operation.
Обычно этот метод используется, чтоб определить, в какую стадию надо поместить создаваемый пользователем элемент.

Примеры


use Bitrix\Crm\Service;

$entityTypeId = 150;
$factory = Service\Container::getInstance()->getFactory($entityTypeId);
if (!$factory)
{
	return;
}

$userPermissions = Service\Container::getInstance()->getUserPermissions();

$canWriteConfig = $userPermissions->canWriteConfig();

$category = $factory->getDefaultCategory ();
$canReadType = $userPermissions->canReadType (
	$factory->getEntityTypeId (),
	$category->getId()
);
$canUpdateCategory = $userPermissions->canUpdateCategory($category);

$item = $factory->getItem(12);
$canDeleteItem = $userPermissions->canDeleteItem($item);
$canAddItemToCategory = $userPermissions->checkAddPermissions(
	$factory->getEntityTypeId (),
	$category->getId()
);

$categories = $factory->getCategories();
$availableForReadItemsCategories = $userPermissions->filterAvailableForReadingCategories($categories);

$filter = [
	'=CATEGORY_ID' => $category->getId(),
	'>ID' => 100,
];

$permissionEntityTypes = [$userPermissions::getPermissionEntityType($factory->getEntityTypeId, $category->getId())];

$filterWithPermissions = $userPermissions->applyAvailableItemsFilter($filter, $permissionEntityTypes);

Пользовательские комментарии

Мы будем рады, если разработчики добавят свои комментарии по практическому использованию методов системы.

Для этого нужно всего лишь авторизоваться на сайте

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

Также Пользовательские комментарии не являются местом для обсуждения функционала. По подобным вопросам обращайтесь на форумы.
© «Битрикс», 2001-2024, «1С-Битрикс», 2024
Наверх