Documentation

UserPermissions

Access permissions


Access permissions is always quite a complex section of any application business logic.

Answers to common questions was made when designing public API for this service.

This service practically doesn't operate directly with settings and access permissions attribute storage, serving as facade with convenient API.

Nevertheless, below is a brief description for table structure and access permissions verification specifics.


Access permissions settings

Access permissions in CRM (as in many other modules) are configured at the role level (table b_crm_role).

User / group / department and etc. can have each role (table b_crm_role_relation).

Each role has configured access permissions (table b_crm_role_perms).

Access permissions are configured in the "entities" section (column ENTITY, is a horizontal string in settings UI).

Each entity can have a specifically configured level of access permissions (column ATTR) for a specific action (column PERM_TYPE).

Attribute storage

Each time when creating / updating any CRM element type, its data, affecting access permissions are converted into a set of attributes and written into the table b_crm_entity_perms (method \CCrmPerms::UpdateEntityAttr).

Matching between this data and retrieved attributes is provided in the following table:


Element data Attribute value example
Responsible fieldU1 1 - user identifier
Responsible field IU1 1 - user ID as employee
Association of responsible user to organizational structureD2 2 - department ID. Saved as binding to a department, as well as association to all parent departments
Field "Available for all"O When checkmarked, attribute is available
Is company a "my company" (For companies)IS_MY_COMPANY When checkmarked, attribute is available and read access is always available, independently from access permissions for the rest of companies
List of observers (For leads and deals)CU1 1 - user ID. Each observer adds its own attribute into the list
Status/stage value (for leads)STATUS_IDNEW NEW - status ID
Stage value (For deals and quotes))STAGE_IDNEW NEW - stage ID

Next, the algorithm for verifying access permissions is as follows:

  • access permission check builds map of attributes from list of its roles and permissions for available this user доступных (method \CCrmRole::GetUserPerms());
  • map of permissions is compared with current set of element attributes with account of performed action (\CCrmPerms::CheckEnityAccess());
  • additional expression is built to be added to WHERE for list queries (method \CCrmPerms::BuildSql()).

All actions are hidden "under the hood" in this service (with old API methods called in actuality).


It's recommended to use this service specifically when writing new code and not the old API.

Service instance can be retrieved from container, due the data being cache inside the service.

The method Service\Container::getUserPermissions() has the argument $userId, to pass the user ID.

Methods

Method Description Available from version
public function __construct(int $userId)
  • $userId - user ID to be checked access permissions;
Constructor.

When $userId = 0,its deemed as action performed from the system user. This user doesn't have access permission to anything.

When actions must be performed without checked access permissions, permission check must be disabled in operation.

public function getUserId(): int
Returns user ID.
public function getCrmPermissions(): \CCrmPerms
Returns class object \CCrmPerms, bound to current user.
public function canWriteConfig(): bool
Returns true, when user has permission to change CRM settings.
public function canReadConfig(): bool
Returns true, when user has permission to read CRM settings.
public function canReadType(int $entityTypeId, int $categoryId = 0): bool
  • $entityTypeId - CRM entity type ID;
  • $categoryId - Pipeline ID.
Returns true, when user has permission to view $entityTypeId element type at least in the single type pipeline.
public function canReadTypeInCategory(int $entityTypeId, int $categoryId): bool
  • $entityTypeId -CRM entity type ID;
  • $categoryId - pipeline ID.
Returns true, when user has access permission to view $entityTypeId element type in pipeline $categoryId. crm 22.0.0
public function canAddType(): bool
Returns true, when user has permission to create new SPA.
public function canUpdateType(): bool
Returns true, when user has permission to change settings for SPA with CRM $entityTypeId.
public function canAddItem(Item $item): bool
Returns true, when user has permission to create $item in tis current status.
public function checkAddPermissions
(int $entityTypeId, int $categoryId = 0, 
?string $stageId = null): bool
Returns true, when user has permission to create $entityTypeId in pipeline $categoryId at the stage $stageId.
Here and below, if pipeline is not specified, permission check is performed for default pipeline.
When stage is not specified, access permission with stage is not performed.
public function checkUpdatePermissions
(int $entityTypeId, int $id, 
int $categoryId = 0): bool
Returns true, when user has access permission to edit element with $id in pipeline $categoryId.
public function canUpdateItem(Item $item): bool
Returns true, when user has access permission to edit element $item.
public function checkDeletePermissions
(int $entityTypeId, int $id, int $categoryId = 0): bool
Returns true, when user has access permission to delete element of $entityTypeId with $id in pipeline $categoryId.
public function canDeleteItem(Item $item): bool
Returns true when user has access permission to delete element $item.
public function checkReadPermissions
(int $entityTypeId, int $id = 0, int $categoryId = 0): bool
Returns true when user can read element type $entityTypeId with $id in pipeline $categoryId.
public function canReadItem(Item $item): bool
Returns true, when user has access permission to read element $item.
public function canViewItemsInCategory
(Category $category): bool
Returns true, when user has permission to read elements $item in pipeline $category.
public function canAddCategory
(Category $category): bool
Returns true, when user has access permission to create new pipeline $category.
public function canUpdateCategory
(Category $category): bool
Returns true, when user has access permission to edit pipeline $category.
public function canDeleteCategory
(Category $category): bool
Returns true, when user has access permission to delete pipeline $category.
public function filterAvailableForReadingCategories
(array $categories): array
Returns array with pipeline from the set of $categories with elements the user can view
public function getPermissionType
(Item $item, string $operationType = self::OPERATION_READ): 
string
Returns access level string ID (all / its own and own department / my / opened only / no), for user to $item when executing operation $operationType.
public function prepareItemPermissionAttributes
(Item $item): array
Returns set of $item attributes before saving it to table b_crm_entity_perms.
public static function getItemPermissionEntityType
(Item $item): string
Returns string entity ID for table with entity access permissions $item.
public static function getPermissionEntityType
(int $entityTypeId, int $categoryId = 0): string
Returns string entity ID for table with entity access permissions $entityTypeId in pipeline $categoryId.
public static function getEntityNameByPermissionEntityType
(string $permissionEntityType): ?string
Returns string CRM entity string ID by entity string ID $permissionEntityType for access permission table.
public function applyAvailableItemsFilter
(?array $filter, array $permissionEntityTypes, 
?string $operation = self::OPERATION_READ, 
?string $primary = 'ID'): array

  • $filter - current filter for list of elements;
  • $permissionEntityTypes - array with string IDs for the access permissions table;
  • $operation - operation type;
  • $primary - primary key code to be added to filter.
Adds extra keys to $filter, allowing to select only the elements with user's access. Returns new version of filter.
public function getStartStageId(int $entityTypeId, 
EO_Status_Collection $stages, int $categoryId = 0, 
string $operation = self::OPERATION_ADD): ?string

  • $entityTypeId - CRM entity type ID;
  • $stages - collection of stages;
  • $categoryId - pipeline ID;
  • $operation - operation type.
Returns first stage ID from collection $stages of $entityTypeId in pipeline $categoryId with user having access permission when executing $operation type.
Usually this method is used to determine the stage for the element created by user.

Example


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);
© «Bitrix24», 2001-2024