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 field | U1 | 1 - user identifier |
Responsible field | IU1 | 1 - user ID as employee |
Association of responsible user to organizational structure | D2 | 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).
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)
|
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
|
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
|
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
|
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
|
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);