Согласно общей концепции анализа модели предоставления прав в информационной системе квадрига «роль — условия — разрешения — объект» в Tessa является квантом модели предоставления прав, и правило доступа должно быть логичным кластером подобных квантовых объектов в общей модели предоставления прав в системе. Далее предпринята попытка анализа подобных кластеров-правил доступа.
Выгрузка данных из БД Tessa¶
Далее представлен код MS SQL, предназначенный для выгрузки данных из базы данных (далее БД) Tessa, которые требуются для кластерного анализа модели предоставления прав в Tessa. Однако, в целях обеспечения безопасности эксплуатационных данных для разработки кластерного анализа предлагается использовать тестовые данные, сгенерированные с помощью генератора датафреймов, разработанного в Microsegment.ru.
-- Все правила доступа с русским переводом параметров
SELECT kp.ID AS [ID правила доступа],
kp.Caption AS [Название правила доступа],
CASE WHEN kp.IsDisabled ='1' THEN 'True' ELSE 'False' END AS [Правило отключено],
CASE WHEN kp.IsRequired ='1' THEN 'True' ELSE 'False' END AS [Всегда проверять правило],
CASE WHEN kp.IsExtended ='1' THEN 'True'ELSE 'False' END AS [РПД],
CASE WHEN kp.Conditions LIKE '%ConditionTypeID%' THEN 'True' ELSE 'False' END AS [Типы условий],
-- Разрешения из правил доступа
CASE WHEN kp.CanCreateCard ='1' THEN 'True' ELSE 'False' END AS [Создание карточки],
CASE WHEN kp.CanReadCard ='1' THEN 'True' ELSE 'False' END AS [Чтение карточки],
CASE WHEN kp.CanEditCard ='1' THEN 'True' ELSE 'False' END AS [Редактирование карточки],
CASE WHEN kp.CanEditFiles ='1' THEN 'True' ELSE 'False' END AS [Редактирование файлов],
CASE WHEN kp.CanAddFiles ='1' THEN 'True' ELSE 'False' END AS [Добавление файлов],
CASE WHEN kp.CanEditRoute ='1' THEN 'True' ELSE 'False' END AS [Редактирование маршрута],
CASE WHEN kp.CanDeleteCard ='1' THEN 'True' ELSE 'False' END AS [Удаление карточки],
CASE WHEN kp.CanStartProcess ='1' THEN 'True' ELSE 'False' END AS [Инициация типового процесса отправки задач],
CASE WHEN kp.CanEditNumber ='1' THEN 'True' ELSE 'False' END AS [Ручное редактирование номера],
CASE WHEN kp.CanCreateResolutions ='1' THEN 'True' ELSE 'False' END AS [Создание резолюций],
CASE WHEN kp.CanDeleteFiles ='1' THEN 'True' ELSE 'False' END AS [Удаление всех файлов],
CASE WHEN kp.CanEditOwnFiles ='1' THEN 'True' ELSE 'False' END AS [Редактирование собственных файлов].
CASE WHEN kp.CanDeleteownFiles ='1' THEN 'True'ELSE 'False' END AS [Удаление собственных файлов],
CASE WHEN kp.CansignFiles ='1' THEN 'True' ELSE 'False' END AS [Подписание файлов],
CASE WHEN kp.CanAddTopics ='1' THEN 'True'ELSE 'False'END AS [Создание обсуждений].
CASE WHEN kp.CanSuperModeratorMode ='1' THEN 'True'ELSE 'False' END AS [Права супермодератора],
CASE WHEN kp.CanSubscribeForNotifications = '1' THEN 'True' ELSE 'False' END AS [Подписка на уведомления],
CASE WHEN kp.CanCreateTemplateAndCopy ='1' THEN 'True' ELSE 'False' END AS [Создание шаблона и копирование],
CASE WHEN kp.CanSkipStages ='1' THEN 'True' ELSE 'False' END AS [Пропуск этапов],
CASE WHEN kp.CanFullRecalcRoute ='1' THEN 'True' ELSE 'False' END AS [Полный пересчет маршрута].
CASE WHEN kp.CanEditMyMessages ='1' THEN 'True' ELSE 'False' END AS [Редактирование своих сообщений],
CASE WHEN kp.CanEditAllMessages ='1' THEN 'True' ELSE 'False' END AS [Редактирование всех сообщений],
CASE WHEN kp.CanReadAllTopics ='1' THEN 'True' ELSE 'False' END AS [Чтение обсуждений],
CASE WHEN kp.CanReadAndSendMessageInAllTopics ='1' THEN 'True' ELSE 'False' END AS [Чтение и отправка сообщений]
FROM KrPermissions (NOLOCK) kp;
-- Обогащение правил доступа дополнительными данными о ролях
SELECT DISTINCT
-- Правила доступа
kpr.ID AS [ID правила доступа],
-- Роли
kpr.RoleID AS [ID роли],
kpr.RoleName AS [Название роли]
FROM krPermissionRoles (NOLOCK) kpr;
-- Обогащение правил доступа дополнительными данными о типах документов
SELECT DISTINCT
-- Правила доступа
kpt.ID AS [ID правила доступа],
-- Тип карточки
kpt.TypeCaption AS [ID ЛФО типа карточки]
dbo.Localize(kpt.TypeCaption, 25) AS [Тип карточки]
FROM KrPermissionTypes (NOLOCK) kpt;
-- Обогащение правил доступа дополнительными данными о состояниях документов
SELECT DISTINCT
-- Правила доступа
kpt.ID AS [ID правила доступа],
-- Состояние карточки
kps.StateName AS [ID ЛФО состояния карточки]
dbo.Localize(kps.StateName, 25) AS [Состояние карточки]
FROM KrPermissionStates (NOLOCK) kps
-- Расширенные правила доступа (РПД)
SELECT
DISTINCT
-- Правила доступа
kp.ID AS [ID правила доступа],
-- Параметры РПД
kpecr.SectionName AS [РПД. Секция карточки].
kpecrf.FieldName AS [РПД. Поле карточки],
kpecr.AccessSettingName AS [РПД. Разрешение],
dbo.Localize(kpecr.AccesssettingName, 25) AS [РПД. Разрешение (рус)]
FROM KrPermissions AS kp
LEFT JOIN KrPermissionExtendedcardRules (NOLOCK) kpecr ON kpecr.ID = kp. ID
LEFT JOIN KrPermissionExtendedcardRulefields (NOLOCK) kpecrf ON kpecrf. ID = kp.ID;
-- Вхождение PersonalRoles в любые Roles, кроме ContextRoles
SELECT pr.ID AS [ID пользователя],
pr.Name AS [Имя пользователя],
pr.Position AS [Должность пользователя],
pr.AccessLevelID AS [Уровень доступа пользователя],
pr.LoginTypeID AS [Тип учетной записи пользователя],
pr.Login AS [Логин пользователя],
CASE WHEN pr.Blocked ='1' THEN 'True' END AS [Блокировка учетной записи пользователя],
r.ID AS [ID роли],
r.Name AS [Название роли],
r.TypeID AS [Тип роли]
FROM Roles (NOLOCK)r
LEFT JOIN RoleUsers (NOLOCK) ru ON ru.ID = r.ID
LEFT JOIN PersonalRoles (NOLOCK) pr ON pr.ID - ru.UserID
WHERE (ru. IsDeputy = O OR ru.IsDeputy IS NULL)
ORDER BY pr.Name, r.Name;
-- ContextRoles
SELECT cr.ID AS [ID роли],
cr.SqlText AS [Код SQL]
FROM ContextRoles (NOLOCK) cr;
-- Для выявления вхождения идентификаторов ролей в коды контекстных ролей
-- (очень долгая операция, лучше реализовать локально на Python)
--LEFT JOIN Roles (NOLOCK) r ON cr.SqlText LIKE '%'+CONVERT(VARCHAR(50), .ID)+'%'
Загрузка библиотек¶
import pandas as pd
import numpy as np
Загрузка данных¶
# Данные из таблицы KrPermissions, предварительно выгруженные из БД Tessa
KrPermissions = pd.read_csv('files/KrPermissions.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(KrPermissions.info())
KrPermissions.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 187 entries, 0 to 186 Data columns (total 30 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 187 non-null object 1 Название правила доступа 187 non-null object 2 Правило отключено 187 non-null bool 3 Всегда проверять правило 187 non-null bool 4 РПД 187 non-null bool 5 Типы условий 187 non-null bool 6 Создание карточки 187 non-null bool 7 Чтение карточки 187 non-null bool 8 Редактирование карточки 187 non-null bool 9 Удаление карточки 187 non-null bool 10 Добавление файлов 187 non-null bool 11 Редактирование собственных файлов 187 non-null bool 12 Редактирование файлов 187 non-null bool 13 Удаление собственных файлов 187 non-null bool 14 Удаление всех файлов 187 non-null bool 15 Инициация типового процесса отправки задач 187 non-null bool 16 Редактирование маршрута 187 non-null bool 17 Пропуск этапов 187 non-null bool 18 Полный пересчет маршрута 187 non-null bool 19 Ручное редактирование номера 187 non-null bool 20 Создание резолюций 187 non-null bool 21 Подписание файлов 187 non-null bool 22 Создание обсуждений 187 non-null bool 23 Права супермодератора 187 non-null bool 24 Подписка на уведомления 187 non-null bool 25 Создание шаблона и копирование 187 non-null bool 26 Редактирование своих сообщений 187 non-null bool 27 Редактирование всех сообщений 187 non-null bool 28 Чтение обсуждений 187 non-null bool 29 Чтение и отправка сообщений 187 non-null bool dtypes: bool(28), object(2) memory usage: 8.2+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | Всегда проверять правило | РПД | Типы условий | Создание карточки | Чтение карточки | Редактирование карточки | Удаление карточки | … | Создание резолюций | Подписание файлов | Создание обсуждений | Права супермодератора | Подписка на уведомления | Создание шаблона и копирование | Редактирование своих сообщений | Редактирование всех сообщений | Чтение обсуждений | Чтение и отправка сообщений | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 5b5a54df-f4c3-429b-9b90-afcbfc94d904 | Правило 0 | False | True | False | False | True | True | False | False | … | True | False | False | False | False | False | False | False | False | False |
| 1 | 18841597-7fd1-4dd9-a48e-ed7287cb7ca9 | Правило 1 | False | False | False | False | True | True | False | False | … | False | False | False | False | False | False | False | False | False | False |
| 2 | 49097422-ab5d-43db-8d58-1c2fd2e7b951 | Правило 2 | False | False | False | False | True | False | True | False | … | False | False | False | False | False | False | False | False | False | False |
| 3 | f3c8942f-da63-456d-8d4f-c9edd97d9568 | Правило 3 | False | True | False | False | True | True | True | False | … | False | False | False | False | False | False | False | False | False | False |
| 4 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | Правило 4 | False | False | False | False | False | False | True | True | … | True | False | False | False | False | False | False | False | False | False |
5 rows × 30 columns
# Данные из таблицы KrPermissionRoles, предварительно выгруженные из БД Tessa
KrPermissionRoles = pd.read_csv('files/KrPermissionRoles.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(KrPermissionRoles.info())
KrPermissionRoles.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 403 entries, 0 to 402 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 403 non-null object 1 ID роли 403 non-null object 2 Название роли 403 non-null object dtypes: object(3) memory usage: 9.6+ KB None
| ID правила доступа | ID роли | Название роли | |
|---|---|---|---|
| 0 | 20336af0-1547-4441-b701-abb37eb7e80a | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | Беляева В.Д. |
| 1 | 17c8a168-87ff-42ab-a499-a8af288649cf | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | Григорьев Б.Д. |
| 2 | ed9ab1be-8faa-4f18-8fc8-1efc5402342b | e96d002f-ee0f-461a-b831-561ff8b457e3 | Юридический отдел |
| 3 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | Согласующий финансовых документов |
| 4 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | Согласующий финансовых документов |
# Данные из таблицы KrPermissionTypes, предварительно выгруженные из БД Tessa
KrPermissionTypes = pd.read_csv('files/KrPermissionTypes.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(KrPermissionTypes.info())
KrPermissionTypes.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 174 entries, 0 to 173 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 174 non-null object 1 ID типа карточки 135 non-null object 2 Тип карточки 135 non-null object dtypes: object(3) memory usage: 4.2+ KB None
| ID правила доступа | ID типа карточки | Тип карточки | |
|---|---|---|---|
| 0 | de03f571-e211-432c-9c8a-e863d673ebf6 | c86fb70e-7352-480f-a710-e6b75e5cbac2 | Дополнительное соглашение |
| 1 | d94cda5c-6434-4215-8245-a3ed951d652a | 1293034c-e069-482c-a710-8738f6145b72 | Входящий |
| 2 | bf756289-8092-477b-a03c-afb2c49fa6ae | 97ed6f19-5201-441b-acee-8474be8a44db | МЧД |
| 3 | 9fdefb43-5469-4322-8a3d-c9229d89cb72 | c86fb70e-7352-480f-a710-e6b75e5cbac2 | Дополнительное соглашение |
| 4 | efe9a617-b5cc-432f-be74-620c4f57de40 | NaN | NaN |
# Данные из таблицы KrPermissionStates, предварительно выгруженные из БД Tessa
KrPermissionStates = pd.read_csv('files/KrPermissionStates.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(KrPermissionStates.info())
KrPermissionStates.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 178 entries, 0 to 177 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 178 non-null object 1 ID состояния карточки 134 non-null object 2 Состояние карточки 134 non-null object dtypes: object(3) memory usage: 4.3+ KB None
| ID правила доступа | ID состояния карточки | Состояние карточки | |
|---|---|---|---|
| 0 | 5549c392-541d-4667-ac61-91596128d1a6 | 17215e76-92fa-4586-934e-92bc85e7f91b | Проект |
| 1 | 36a36459-e020-4900-80a5-468ebcaf3ca6 | cbae96bd-0d35-4a38-aa01-b6fd2b4b208d | Зарегистрирован |
| 2 | 3d74a414-af74-4d28-a331-2d8ee29312e5 | d3f85efe-2808-416f-93c0-f1589f150e47 | На согласовании |
| 3 | 9ed92537-fb02-4cd5-bf60-bb5ec8b690ce | fdffb12d-be8d-49e2-999e-b5a661dfb955 | На обработке |
| 4 | 14104765-d331-467f-a9ea-639e0f7d49d2 | cbae96bd-0d35-4a38-aa01-b6fd2b4b208d | Зарегистрирован |
# Данные из таблицы KrPermissionExtendedcard, предварительно выгруженные из БД Tessa
KrPermissionCardRules = pd.read_csv('files/KrPermissionExtendedcard.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(KrPermissionCardRules.info())
KrPermissionCardRules.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 5 non-null object 1 РПД. Секция карточки 5 non-null object 2 РПД. Поле карточки 5 non-null object 3 РПД. Разрешение 5 non-null object 4 РПД. Разрешение (рус) 5 non-null object dtypes: object(5) memory usage: 332.0+ bytes None
| ID правила доступа | РПД. Секция карточки | РПД. Поле карточки | РПД. Разрешение | РПД. Разрешение (рус) | |
|---|---|---|---|---|---|
| 0 | 5b5a54df-f4c3-429b-9b90-afcbfc94d904 | Document | DocumentText | Write | Редактирование |
| 1 | 18841597-7fd1-4dd9-a48e-ed7287cb7ca9 | GeneralInformation | CreationDate | DenyWrite | Запрещено редактировать |
| 2 | 49097422-ab5d-43db-8d58-1c2fd2e7b951 | EmployeeCard | Salary | Read | Чтение |
| 3 | f3c8942f-da63-456d-8d4f-c9edd97d9568 | ApprovalStage | Comments | Append | Добавление комментариев |
| 4 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | BasicData | Subject | DenyDelete | Запрещено удалять |
# Данные из таблицы RoleUsers, предварительно выгруженные из БД Tessa
RoleUsers = pd.read_csv('files/RoleUsers.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(RoleUsers.info())
RoleUsers.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 483 entries, 0 to 482 Data columns (total 10 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID пользователя 483 non-null object 1 Имя пользователя 483 non-null object 2 Должность пользователя 483 non-null object 3 Уровень доступа пользователя 472 non-null float64 4 Тип учетной записи пользователя 461 non-null float64 5 Логин пользователя 483 non-null object 6 Блокировка учетной записи пользователя 353 non-null object 7 ID роли 483 non-null object 8 Название роли 483 non-null object 9 Тип роли 483 non-null int64 dtypes: float64(2), int64(1), object(7) memory usage: 37.9+ KB None
| ID пользователя | Имя пользователя | Должность пользователя | Уровень доступа пользователя | Тип учетной записи пользователя | Логин пользователя | Блокировка учетной записи пользователя | ID роли | Название роли | Тип роли | |
|---|---|---|---|---|---|---|---|---|---|---|
| 0 | b554a73d-e711-404c-a92f-6b532d590f73 | Комаров Р.Т. | Начальник отдела | 1.0 | 0.0 | komarovrt | False | 0ebe84b4-137e-4020-b29e-3749d2a6310b | IT-отдел | 2 |
| 1 | 8da6a188-ec22-4d89-832a-ebbfaba2eebf | Ильин О.К. | Начальник отдела | 0.0 | 0.0 | ilinok | NaN | 3a7ba0fd-8929-438a-9b24-26a7bd547ec2 | Отдел продаж | 2 |
| 2 | 628d7ee9-3f74-4d66-bfc6-5ab086c5c903 | Соколов Р.Е. | Начальник отдела | 1.0 | 1.0 | sokolovre | False | daf6589d-885b-49ed-a347-2ea54076ea56 | Отдел кадров | 2 |
| 3 | d12eb580-8dac-4371-bb7d-66261719caef | Комаров И.А. | Старший специалист | 1.0 | 1.0 | komarovia | False | 66d273c8-d957-4bb3-9623-3e790daa54d9 | Отдел продаж | 2 |
| 4 | b42fa3ea-2482-460f-abd2-4a0e3531738c | Смирнова О.Б. | Менеджер проекта | 0.0 | 0.0 | smirnovaob | True | 581bcaa7-d3fe-4483-8cc2-6446e1ea33b4 | Отдел продаж | 2 |
# Данные из таблицы ContextRoles, предварительно выгруженные из БД Tessa
ContextRoles = pd.read_csv('files/ContextRoles.csv').drop('Unnamed: 0', axis=1)#, sep=';', encoding='utf-8-sig')
print(ContextRoles.info())
ContextRoles.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 5 entries, 0 to 4 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 5 non-null object 1 Код SQL 5 non-null object dtypes: object(2) memory usage: 212.0+ bytes None
| ID роли | Код SQL | |
|---|---|---|
| 0 | 3a39dcf7-49d7-4a5c-a765-4aa3c16a081c | \nSELECT u.UserID, u.Name\nFROM Users u\nJOIN … |
| 1 | 48307771-7cf8-43a1-ae95-92fbf4e0d263 | \nSELECT u.UserID, u.Name\nFROM Users u\nJOIN … |
| 2 | 899889c8-9be5-49fc-bde1-9cdf1a65e8eb | \nSELECT u.UserID, u.Name\nFROM Users u\nJOIN … |
| 3 | cc4461f1-02ed-465e-a4c0-ef6b13845bd4 | \nSELECT u.UserID, u.Name\nFROM Users u\nJOIN … |
| 4 | 4a39f1d5-a3ab-4aa4-b748-1fd725321b6d | \nSELECT u.UserID, u.Name\nFROM Users u\nJOIN … |
Предобработка данных¶
Перемещение дополнительной информации из датафреймов с правилами в отдельные датафреймы¶
# Перемещение данных о правилах доступа в отдельный датафрейм
rules_data = KrPermissions[['ID правила доступа', 'Название правила доступа',
'Правило отключено', 'Всегда проверять правило',
'РПД', 'Типы условий']]\
.groupby(['ID правила доступа', 'Название правила доступа',
'Правило отключено', 'Всегда проверять правило',
'РПД', 'Типы условий']).count().reset_index()
KrPermissions = KrPermissions.drop(['Название правила доступа',
'Правило отключено', 'Всегда проверять правило',
'РПД', 'Типы условий'], axis=1)
print(rules_data.info())
rules_data.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 187 entries, 0 to 186 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 187 non-null object 1 Название правила доступа 187 non-null object 2 Правило отключено 187 non-null bool 3 Всегда проверять правило 187 non-null bool 4 РПД 187 non-null bool 5 Типы условий 187 non-null bool dtypes: bool(4), object(2) memory usage: 3.8+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | Всегда проверять правило | РПД | Типы условий | |
|---|---|---|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False | True | True | False |
| 1 | 0359fea5-f9d6-4911-acbe-70f82c858418 | Правило 143 | True | False | False | False |
| 2 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False | False | False | False |
| 3 | 05bd596d-c6ad-474b-80db-fdbecab66f21 | Правило 124 | True | False | False | False |
| 4 | 07cc452b-48c4-4176-b13d-ab576ae7afdc | Правило 67 | False | False | False | False |
# Перемещение названий ролей из правил доступа в отдельный датафрейм
roles_name = KrPermissionRoles[['ID роли', 'Название роли']]\
.groupby(['ID роли', 'Название роли']).count().reset_index()
KrPermissionRoles = KrPermissionRoles.drop(['Название роли'], axis=1)
print(rules_data.info())
rules_data.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 187 entries, 0 to 186 Data columns (total 6 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 187 non-null object 1 Название правила доступа 187 non-null object 2 Правило отключено 187 non-null bool 3 Всегда проверять правило 187 non-null bool 4 РПД 187 non-null bool 5 Типы условий 187 non-null bool dtypes: bool(4), object(2) memory usage: 3.8+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | Всегда проверять правило | РПД | Типы условий | |
|---|---|---|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False | True | True | False |
| 1 | 0359fea5-f9d6-4911-acbe-70f82c858418 | Правило 143 | True | False | False | False |
| 2 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False | False | False | False |
| 3 | 05bd596d-c6ad-474b-80db-fdbecab66f21 | Правило 124 | True | False | False | False |
| 4 | 07cc452b-48c4-4176-b13d-ab576ae7afdc | Правило 67 | False | False | False | False |
Перемещение дополнительной информации из датафреймов с ролями в отдельные датафреймы¶
# Перемещение данных о правилах доступа в отдельный датафрейм
user_data = RoleUsers[['ID пользователя',
'Имя пользователя',
'Логин пользователя',
'Должность пользователя',
'Уровень доступа пользователя',
'Тип учетной записи пользователя',
'Блокировка учетной записи пользователя']]\
.groupby(['ID пользователя',
'Имя пользователя',
'Логин пользователя',
'Должность пользователя',
'Уровень доступа пользователя',
'Тип учетной записи пользователя',
'Блокировка учетной записи пользователя'],
# Не удалять строки с пропусками
dropna=False)\
.count().reset_index()
user_data = user_data[~user_data['ID пользователя'].isnull()]
RoleUsers = RoleUsers.drop(['Имя пользователя',
'Логин пользователя',
'Должность пользователя',
'Уровень доступа пользователя',
'Тип учетной записи пользователя',
'Блокировка учетной записи пользователя'], axis=1)
print(user_data.info())
user_data.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 216 entries, 0 to 215 Data columns (total 7 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID пользователя 216 non-null object 1 Имя пользователя 216 non-null object 2 Логин пользователя 216 non-null object 3 Должность пользователя 216 non-null object 4 Уровень доступа пользователя 211 non-null float64 5 Тип учетной записи пользователя 206 non-null float64 6 Блокировка учетной записи пользователя 159 non-null object dtypes: float64(2), object(5) memory usage: 11.9+ KB None
| ID пользователя | Имя пользователя | Логин пользователя | Должность пользователя | Уровень доступа пользователя | Тип учетной записи пользователя | Блокировка учетной записи пользователя | |
|---|---|---|---|---|---|---|---|
| 0 | 00000000-0000-0000-0000-000000000002 | Бухгалтерские сервисы | accounting_services | Сервис | 0.0 | 2.0 | False |
| 1 | 00000000-0000-0000-0000-000000000003 | ИТ-сервисы | it_services | Сервис | 0.0 | 2.0 | False |
| 2 | 00000000-0000-0000-0000-000000000004 | Сайт компании | company_website | Сервис | 0.0 | 2.0 | False |
| 3 | 00000000-0000-0000-0000-000000000005 | Робот службы безопасности | security_service_robot | Робот | 1.0 | 2.0 | False |
| 4 | 00000000-0000-0000-0000-000000000006 | Робот финансовой службы | financial_service_robot | Робот | 0.0 | 2.0 | False |
# Перемещение данных о правилах доступа в отдельный датафрейм
role_name = RoleUsers[['ID роли', 'Название роли']]\
.groupby(['ID роли', 'Название роли']).count().reset_index()
RoleUsers = RoleUsers.drop(['Название роли'], axis=1)
print(role_name.info())
role_name.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 429 entries, 0 to 428 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 429 non-null object 1 Название роли 429 non-null object dtypes: object(2) memory usage: 6.8+ KB None
| ID роли | Название роли | |
|---|---|---|
| 0 | 00000000-0000-0000-0000-000000000002 | Бухгалтерские сервисы |
| 1 | 00000000-0000-0000-0000-000000000003 | ИТ-сервисы |
| 2 | 00000000-0000-0000-0000-000000000004 | Сайт компании |
| 3 | 00000000-0000-0000-0000-000000000005 | Робот службы безопасности |
| 4 | 00000000-0000-0000-0000-000000000006 | Робот финансовой службы |
# Перемещение данных од известных ролях в отдельный датафрейм
roles = RoleUsers[RoleUsers['ID роли'] != 'Unknown'].drop_duplicates()
print(roles.info())
roles.head(5)
<class 'pandas.core.frame.DataFrame'> Index: 476 entries, 0 to 482 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID пользователя 476 non-null object 1 ID роли 476 non-null object 2 Тип роли 476 non-null int64 dtypes: int64(1), object(2) memory usage: 14.9+ KB None
| ID пользователя | ID роли | Тип роли | |
|---|---|---|---|
| 0 | b554a73d-e711-404c-a92f-6b532d590f73 | 0ebe84b4-137e-4020-b29e-3749d2a6310b | 2 |
| 1 | 8da6a188-ec22-4d89-832a-ebbfaba2eebf | 3a7ba0fd-8929-438a-9b24-26a7bd547ec2 | 2 |
| 2 | 628d7ee9-3f74-4d66-bfc6-5ab086c5c903 | daf6589d-885b-49ed-a347-2ea54076ea56 | 2 |
| 3 | d12eb580-8dac-4371-bb7d-66261719caef | 66d273c8-d957-4bb3-9623-3e790daa54d9 | 2 |
| 4 | b42fa3ea-2482-460f-abd2-4a0e3531738c | 581bcaa7-d3fe-4483-8cc2-6446e1ea33b4 | 2 |
Кластеризация правил и ролей¶
Правила и роли не дающие прав пользователям¶
# Связка полной информации о ролях с идентификаторами правил,
# в которых роли используются
rules_roles = pd.merge(KrPermissionRoles,
roles,
on='ID роли', how='left')
rules_roles = pd.merge(rules_roles,
rules_data[['ID правила доступа', 'Правило отключено']],
on='ID правила доступа', how='left')
print(rules_roles.info())
rules_roles.head(5)
<class 'pandas.core.frame.DataFrame'> RangeIndex: 3655 entries, 0 to 3654 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 3655 non-null object 1 ID роли 3655 non-null object 2 ID пользователя 3655 non-null object 3 Тип роли 3655 non-null int64 4 Правило отключено 3655 non-null bool dtypes: bool(1), int64(1), object(3) memory usage: 117.9+ KB None
| ID правила доступа | ID роли | ID пользователя | Тип роли | Правило отключено | |
|---|---|---|---|---|---|
| 0 | 20336af0-1547-4441-b701-abb37eb7e80a | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | 1 | False |
| 1 | 17c8a168-87ff-42ab-a499-a8af288649cf | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | 1 | False |
| 2 | ed9ab1be-8faa-4f18-8fc8-1efc5402342b | e96d002f-ee0f-461a-b831-561ff8b457e3 | 8d0dc4c3-be5b-4294-82cf-9422c7c00eae | 2 | True |
| 3 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | 776d348c-5e78-45f6-b87d-6f1fbe205bbe | 0 | False |
| 4 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | e932ad1c-5331-4dfd-82b0-b5f45ca45c21 | 0 | False |
# Правила с групповыми ролями, но не контекстными, по которым практически
# не возможно отследить, кому они предоставляют права
rules_not_contextual_roles = rules_roles[rules_roles['Тип роли'] != 4]
print('-'*5, 'Правила без контекстных ролей', '-'*5)
print(rules_roles.info())
rules_roles.head(5)
----- Правила без контекстных ролей ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 3655 entries, 0 to 3654 Data columns (total 5 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 3655 non-null object 1 ID роли 3655 non-null object 2 ID пользователя 3655 non-null object 3 Тип роли 3655 non-null int64 4 Правило отключено 3655 non-null bool dtypes: bool(1), int64(1), object(3) memory usage: 117.9+ KB None
| ID правила доступа | ID роли | ID пользователя | Тип роли | Правило отключено | |
|---|---|---|---|---|---|
| 0 | 20336af0-1547-4441-b701-abb37eb7e80a | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | 1 | False |
| 1 | 17c8a168-87ff-42ab-a499-a8af288649cf | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | 1 | False |
| 2 | ed9ab1be-8faa-4f18-8fc8-1efc5402342b | e96d002f-ee0f-461a-b831-561ff8b457e3 | 8d0dc4c3-be5b-4294-82cf-9422c7c00eae | 2 | True |
| 3 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | 776d348c-5e78-45f6-b87d-6f1fbe205bbe | 0 | False |
| 4 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | e932ad1c-5331-4dfd-82b0-b5f45ca45c21 | 0 | False |
# Предварительный список правил с ролями без пользователей
'''
_rules_without_users = rules_not_contextual_roles[rules_not_contextual_roles['ID пользователя'].isnull()]\
.sort_values(['ID правила доступа', 'ID роли'])\
.drop(['ID пользователя', 'Должность пользователя',
'Уровень доступа пользователя', 'Тип учетной записи пользователя',
'Блокировка учетной записи пользователя'], axis=1).drop_duplicates()
'''
_rules_without_users = rules_not_contextual_roles[rules_not_contextual_roles['ID пользователя'].isnull()]\
.sort_values(['ID правила доступа', 'ID роли'])\
.drop(['ID пользователя'], axis=1).drop_duplicates()
# Правила с ролями без пользователей
rules_without_users = pd.merge(_rules_without_users['ID правила доступа'].drop_duplicates(),
rules_data[['ID правила доступа', 'Название правила доступа', 'Правило отключено']],
on='ID правила доступа', how='inner')
rules_without_users.to_csv('clusters/rules_without_users.csv')
print('-'*5, 'Правила с ролями без пользователей', '-'*5)
print(rules_without_users.info())
rules_without_users.head(5)
----- Правила с ролями без пользователей ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 0 entries Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 0 non-null object 1 Название правила доступа 0 non-null object 2 Правило отключено 0 non-null bool dtypes: bool(1), object(2) memory usage: 132.0+ bytes None
| ID правила доступа | Название правила доступа | Правило отключено |
|---|
# Роли без пользователей в правилах
'''
roles_without_users = pd.merge(_rules_without_users[['ID роли', 'Тип роли']].drop_duplicates(),
rules_data[['ID роли', 'Название роли']],
on='ID роли', how='left')[['ID роли', 'Название роли', 'Тип роли']]
roles_without_users.to_csv('clusters/rules_without_users.csv')
'''
roles_without_users = pd.merge(_rules_without_users[['ID роли', 'Тип роли']].drop_duplicates(),
role_name[['ID роли', 'Название роли']],
on='ID роли', how='left')[['ID роли', 'Название роли', 'Тип роли']]
roles_without_users.to_csv('clusters/rules_without_users.csv')
print('-'*5, 'Роли без пользователей (в правилах)', '-'*5)
print(roles_without_users.info())
roles_without_users.head(5)
----- Роли без пользователей (в правилах) ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 0 entries Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 0 non-null object 1 Название роли 0 non-null object 2 Тип роли 0 non-null int64 dtypes: int64(1), object(2) memory usage: 132.0+ bytes None
| ID роли | Название роли | Тип роли |
|---|
# Предварительный список правил с ролями с пользователями
_rules_with_users = rules_not_contextual_roles[~rules_not_contextual_roles['ID пользователя'].isnull()]\
.sort_values(['ID правила доступа', 'ID роли'])\
.drop(['ID пользователя'], axis=1).drop_duplicates()
# Правила с ролями с пользователями
rules_with_users = pd.merge(_rules_with_users['ID правила доступа'].drop_duplicates(),
rules_data[['ID правила доступа', 'Название правила доступа', 'Правило отключено']],
on='ID правила доступа', how='inner')
rules_with_users.to_csv('clusters/rules_with_users.csv')
print('-'*5, 'Правила с ролями с пользователями', '-'*5)
print(rules_with_users.info())
rules_with_users.head(5)
----- Правила с ролями с пользователями ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 102 entries, 0 to 101 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 102 non-null object 1 Название правила доступа 102 non-null object 2 Правило отключено 102 non-null bool dtypes: bool(1), object(2) memory usage: 1.8+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | |
|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False |
| 1 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False |
| 2 | 09c45d7d-ee39-4e35-b47b-5b40edfa20bf | Правило 184 | False |
| 3 | 131ea06e-e001-4cec-a0f8-b31d29bd57d6 | Правило 20 | False |
| 4 | 13d02e38-aa00-4782-9770-bca53a6838b2 | Правило 22 | False |
# Роли с пользователями в правилах
'''
roles_with_users = pd.merge(_rules_with_users[['ID роли', 'Тип роли']].drop_duplicates(),
rules_data[['ID роли', 'Название роли']],
on='ID роли', how='left')[['ID роли', 'Название роли', 'Тип роли']]
'''
roles_with_users = pd.merge(_rules_with_users[['ID роли', 'Тип роли']].drop_duplicates(),
role_name[['ID роли', 'Название роли']],
on='ID роли', how='left')[['ID роли', 'Название роли', 'Тип роли']]
roles_with_users.to_csv('clusters/roles_with_users.csv')
print('-'*5, 'Роли с пользователями (в правилах)', '-'*5)
print(roles_with_users.info())
roles_with_users.head(5)
----- Роли с пользователями (в правилах) ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 125 entries, 0 to 124 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 125 non-null object 1 Название роли 125 non-null object 2 Тип роли 125 non-null int64 dtypes: int64(1), object(2) memory usage: 3.1+ KB None
| ID роли | Название роли | Тип роли | |
|---|---|---|---|
| 0 | 49d7a40b-b8a2-4e51-ab99-febf59a885b6 | Юридический отдел | 2 |
| 1 | 27a6ba8d-4cc5-464e-a1d9-d30daf643391 | Отдел продаж | 2 |
| 2 | 71a48819-fca5-4d4d-a9b9-0ca13e41b63f | Михайлов Д.Г. | 1 |
| 3 | 8d0dc4c3-be5b-4294-82cf-9422c7c00eae | Титов Д.Д. | 1 |
| 4 | d1c293a6-21aa-4c45-8e77-ceb8f6fc726a | Руководство | 2 |
Правила с заблокированными пользователями¶
# Карточки заблокирванных пользователей
blocked_users = user_data[
(user_data['Логин пользователя'].isna())
| (user_data['Блокировка учетной записи пользователя'] == 1)
& ~(user_data['ID пользователя'] == '11111111-1111-1111-1111-111111111111')
][['ID пользователя', 'Имя пользователя']]
# Карточки не заблокированных пользователей
non_blocked_users = user_data[
~(user_data['Логин пользователя'].isna())
| ~(user_data['Блокировка учетной записи пользователя'] == 1)
][['ID пользователя', 'Имя пользователя']]
print('-'*5, 'Заблокированные пользователи', '-'*5)
print(blocked_users.info())
display(blocked_users.head(5))
print('-'*5, 'Не заблокированные пользователи', '-'*5)
print(non_blocked_users.info())
display(non_blocked_users.head(5))
----- Заблокированные пользователи ----- <class 'pandas.core.frame.DataFrame'> Index: 14 entries, 13 to 196 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID пользователя 14 non-null object 1 Имя пользователя 14 non-null object dtypes: object(2) memory usage: 336.0+ bytes None
| ID пользователя | Имя пользователя | |
|---|---|---|
| 13 | 0b9ec6fd-10d5-4436-8748-3bfe58677e89 | Степанова О.Г. |
| 52 | 3f7cd252-a4db-4774-ad74-6026668d4b07 | Куликова Р.М. |
| 54 | 421d676f-9536-4046-83aa-9b39cf666e30 | Морозов А.А. |
| 55 | 42e0089a-6687-4c36-b291-e50814cd15ed | Смирнова Л.Д. |
| 65 | 4842d040-4327-4245-b837-34561fb30273 | Сорокин М.С. |
----- Не заблокированные пользователи ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 216 entries, 0 to 215 Data columns (total 2 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID пользователя 216 non-null object 1 Имя пользователя 216 non-null object dtypes: object(2) memory usage: 3.5+ KB None
| ID пользователя | Имя пользователя | |
|---|---|---|
| 0 | 00000000-0000-0000-0000-000000000002 | Бухгалтерские сервисы |
| 1 | 00000000-0000-0000-0000-000000000003 | ИТ-сервисы |
| 2 | 00000000-0000-0000-0000-000000000004 | Сайт компании |
| 3 | 00000000-0000-0000-0000-000000000005 | Робот службы безопасности |
| 4 | 00000000-0000-0000-0000-000000000006 | Робот финансовой службы |
# Правила с заблокированными пользователями
_rules_with_blocked_users = rules_not_contextual_roles[
rules_not_contextual_roles['ID пользователя'].isin(blocked_users['ID пользователя'])
]['ID правила доступа'].drop_duplicates()
rules_with_blocked_users = rules_with_users[rules_with_users['ID правила доступа'].isin(_rules_with_blocked_users)].drop_duplicates()
rules_with_blocked_users.to_csv('clusters/rules_with_blocked_users.csv')
# Правила с не заблокированными пользователями
_rules_with_non_blocked_users = rules_not_contextual_roles[
rules_not_contextual_roles['ID пользователя'].isin(non_blocked_users['ID пользователя'])
]['ID правила доступа'].drop_duplicates()
rules_with_non_blocked_users = rules_with_users[rules_with_users['ID правила доступа'].isin(_rules_with_non_blocked_users)].drop_duplicates()
rules_with_non_blocked_users.to_csv('clusters/rules_with_non_blocked_users.csv')
print('-'*5, 'Правила с заблокированными пользователями', '-'*5)
print(rules_with_blocked_users.info())
display(rules_with_blocked_users.head(5))
print()
print('-'*5, 'Правила с не заблокированными пользователями', '-'*5)
print(rules_with_non_blocked_users.info())
display(rules_with_non_blocked_users.head(5))
----- Правила с заблокированными пользователями ----- <class 'pandas.core.frame.DataFrame'> Index: 29 entries, 7 to 99 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 29 non-null object 1 Название правила доступа 29 non-null object 2 Правило отключено 29 non-null bool dtypes: bool(1), object(2) memory usage: 725.0+ bytes None
| ID правила доступа | Название правила доступа | Правило отключено | |
|---|---|---|---|
| 7 | 20336af0-1547-4441-b701-abb37eb7e80a | Правило 26 | False |
| 9 | 2882e956-a847-4425-91eb-2a22860a766e | Правило 86 | False |
| 10 | 2927ff14-1eb4-4c8d-8541-822547b8aa18 | Правило 7 | False |
| 14 | 30b2b26e-1a46-4a60-addb-451eca6ce528 | Правило 6 | True |
| 16 | 35d0ca67-430d-4101-866c-1425472896b1 | Правило 54 | False |
----- Правила с не заблокированными пользователями ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 102 entries, 0 to 101 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 102 non-null object 1 Название правила доступа 102 non-null object 2 Правило отключено 102 non-null bool dtypes: bool(1), object(2) memory usage: 1.8+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | |
|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False |
| 1 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False |
| 2 | 09c45d7d-ee39-4e35-b47b-5b40edfa20bf | Правило 184 | False |
| 3 | 131ea06e-e001-4cec-a0f8-b31d29bd57d6 | Правило 20 | False |
| 4 | 13d02e38-aa00-4782-9770-bca53a6838b2 | Правило 22 | False |
Правила с сотрудниками без групповых ролей¶
# Предварительный список правил с сотрудниками без групповых ролей
_rules_with_users_without_roles = rules_not_contextual_roles[
rules_not_contextual_roles['Тип роли'] == 1 # Тип роли Сотрудник
].sort_values(['ID правила доступа', 'ID роли']).drop(['ID пользователя'], axis=1).drop_duplicates()
# Правила с сотрудниками без групповых ролей
rules_with_users_without_roles = pd.merge(_rules_with_users_without_roles['ID правила доступа'].drop_duplicates(),
rules_data[['ID правила доступа', 'Название правила доступа', 'Правило отключено']],
on='ID правила доступа', how='inner')
rules_with_users_without_roles.to_csv('clusters/rules_with_users_without_roles.csv')
# Пользователи без групповых ролей в правилах
roles_with_users_without_roles = pd.merge(_rules_with_users_without_roles[['ID роли', 'Тип роли']].drop_duplicates(),
roles_name[['ID роли', 'Название роли']],
on='ID роли', how='left')[['ID роли', 'Название роли', 'Тип роли']]
roles_with_users_without_roles.to_csv('clusters/roles_with_users_without_roles.csv')
print('-'*5, 'Правила с сотрудниками без групповых ролей', '-'*5)
print(rules_with_users_without_roles.info())
display(rules_with_users_without_roles.head(5))
print()
print('-'*5, 'Пользователи без групповых ролей в правилах', '-'*5)
print(roles_with_users_without_roles.info())
display(roles_with_users_without_roles.head(5))
----- Правила с сотрудниками без групповых ролей ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 63 entries, 0 to 62 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 63 non-null object 1 Название правила доступа 63 non-null object 2 Правило отключено 63 non-null bool dtypes: bool(1), object(2) memory usage: 1.2+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | |
|---|---|---|---|
| 0 | 09c45d7d-ee39-4e35-b47b-5b40edfa20bf | Правило 184 | False |
| 1 | 131ea06e-e001-4cec-a0f8-b31d29bd57d6 | Правило 20 | False |
| 2 | 13d02e38-aa00-4782-9770-bca53a6838b2 | Правило 22 | False |
| 3 | 17b1b391-9abc-4f8c-9fd3-9e62bee4790d | Правило 103 | False |
| 4 | 17c8a168-87ff-42ab-a499-a8af288649cf | Правило 142 | False |
----- Пользователи без групповых ролей в правилах ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 65 entries, 0 to 64 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 65 non-null object 1 Название роли 65 non-null object 2 Тип роли 65 non-null int64 dtypes: int64(1), object(2) memory usage: 1.7+ KB None
| ID роли | Название роли | Тип роли | |
|---|---|---|---|
| 0 | 71a48819-fca5-4d4d-a9b9-0ca13e41b63f | Михайлов Д.Г. | 1 |
| 1 | 8d0dc4c3-be5b-4294-82cf-9422c7c00eae | Титов Д.Д. | 1 |
| 2 | eb532d6a-5ffa-4d26-83c6-af0912b79e27 | Соловьёва Р.Д. | 1 |
| 3 | f1e9bbca-03a2-4d2e-939f-4573d680d245 | Морозов А.А. | 1 |
| 4 | 57ee420c-1548-42b3-b8b6-f3cbc9b65ce1 | Комарова Т.В. | 1 |
Правила с пользователем System¶
# Предварительный список правил с пользователем System
_rules_with_system = rules_not_contextual_roles[
rules_not_contextual_roles['ID пользователя'] == '11111111-1111-1111-1111-111111111111' # Пользователь System
].sort_values(['ID правила доступа', 'ID роли']).drop(['ID пользователя'], axis=1).drop_duplicates()
# Правила с пользователем System
rules_with_system = pd.merge(_rules_with_system['ID правила доступа'].drop_duplicates(),
rules_data[['ID правила доступа', 'Название правила доступа', 'Правило отключено']],
on='ID правила доступа', how='inner')
rules_with_system.to_csv('clusters/rules_with_system.csv')
# Роли с пользователем System
roles_with_system = pd.merge(_rules_with_system[['ID роли', 'Тип роли']].drop_duplicates(),
roles_name[['ID роли', 'Название роли']],
on='ID роли', how='left')[['ID роли', 'Название роли', 'Тип роли']]
roles_with_system.to_csv('clusters/roles_with_users_without_roles.csv')
print('-'*5, 'Правила с пользователем System', '-'*5)
print(rules_with_system.info())
display(rules_with_system.head(5))
print()
print('-'*5, 'Роли с пользователем System', '-'*5)
print(roles_with_system.info())
display(roles_with_system.head(5))
----- Правила с пользователем System ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 0 entries Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 0 non-null object 1 Название правила доступа 0 non-null object 2 Правило отключено 0 non-null bool dtypes: bool(1), object(2) memory usage: 132.0+ bytes None
| ID правила доступа | Название правила доступа | Правило отключено |
|---|
----- Роли с пользователем System ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 0 entries Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 0 non-null object 1 Название роли 0 non-null object 2 Тип роли 0 non-null int64 dtypes: int64(1), object(2) memory usage: 132.0+ bytes None
| ID роли | Название роли | Тип роли |
|---|
Правила с системными ролями¶
rules_not_contextual_roles
| ID правила доступа | ID роли | ID пользователя | Тип роли | Правило отключено | |
|---|---|---|---|---|---|
| 0 | 20336af0-1547-4441-b701-abb37eb7e80a | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | 80e5677f-e1d6-4ae1-ad2f-3d56ac543394 | 1 | False |
| 1 | 17c8a168-87ff-42ab-a499-a8af288649cf | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | 6de6127b-f01b-4f2e-a9d8-1b8f53092e91 | 1 | False |
| 2 | ed9ab1be-8faa-4f18-8fc8-1efc5402342b | e96d002f-ee0f-461a-b831-561ff8b457e3 | 8d0dc4c3-be5b-4294-82cf-9422c7c00eae | 2 | True |
| 3 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | 776d348c-5e78-45f6-b87d-6f1fbe205bbe | 0 | False |
| 4 | 5286e47f-9078-49a9-b53d-7a832f1d4c36 | fb2f72a0-002b-41f4-b61f-2a9a8660f24b | e932ad1c-5331-4dfd-82b0-b5f45ca45c21 | 0 | False |
| … | … | … | … | … | … |
| 3650 | 35d0ca67-430d-4101-866c-1425472896b1 | 0eda49ad-18db-4d8f-bbfc-5239b3f39252 | 290b018c-cfc2-4bca-aad0-0b117b3a2a19 | 0 | False |
| 3651 | 6e7ba467-4b8f-4628-a007-cfdb2b18c17a | c4ddb00f-7aae-4a49-b468-9af017ed1100 | eaa562e4-bdf3-4355-aa74-54060f2a8ec5 | 2 | False |
| 3652 | 83bd2279-20e7-440a-ab8a-f6b26cede17c | 6f9f1412-d3a6-4be8-8789-5d542b896fa8 | 6f9f1412-d3a6-4be8-8789-5d542b896fa8 | 1 | False |
| 3653 | 56fb5b4b-8bcc-4287-84ac-26af690185c3 | 2bddbdfa-b91b-4ca5-8726-92e6a253f504 | 2bddbdfa-b91b-4ca5-8726-92e6a253f504 | 1 | False |
| 3654 | 862822e0-164e-426e-83fc-07f3af78f110 | 39c44b9b-46bf-4d0a-ba81-6b8084a396ce | 39c44b9b-46bf-4d0a-ba81-6b8084a396ce | 1 | False |
3655 rows × 5 columns
# Предварительный список правил с системными пользователями
'''
_rules_with_systems_roles = rules_not_contextual_roles[rules_not_contextual_roles['ID пользователя'].isin([
#'11111111-1111-1111-1111-111111111111', #'System'
'00000000-0000-0000-0000-000000000002', # 'Бухгалтерские сервисы'
'00000000-0000-0000-0000-000000000003', # 'ИТ-сервисы'
'00000000-0000-0000-0000-000000000004', # 'Сайт компании'
'00000000-0000-0000-0000-000000000005', # 'Робот службы безопасности'
'00000000-0000-0000-0000-000000000006', # 'Робот финансовой службы'
'00000000-0000-0000-0000-000000000007' # 'Юридические сервисы'
])].sort_values([
'ID правила доступа',
'ID роли'
]).drop(['ID пользователя',
'Должность пользователя',
'Уровень доступа пользователя',
'Тип учетной записи пользователя',
'Блокировка учетной записи пользователя'
], axis=1).drop_duplicates()
'''
_rules_with_systems_roles = rules_not_contextual_roles[rules_not_contextual_roles['ID пользователя'].isin([
#'11111111-1111-1111-1111-111111111111', #'System'
'00000000-0000-0000-0000-000000000002', # 'Бухгалтерские сервисы'
'00000000-0000-0000-0000-000000000003', # 'ИТ-сервисы'
'00000000-0000-0000-0000-000000000004', # 'Сайт компании'
'00000000-0000-0000-0000-000000000005', # 'Робот службы безопасности'
'00000000-0000-0000-0000-000000000006', # 'Робот финансовой службы'
'00000000-0000-0000-0000-000000000007' # 'Юридические сервисы'
])].sort_values([
'ID правила доступа',
'ID роли'
]).drop(['ID пользователя'
], axis=1).drop_duplicates()
# Правила с системными пользователями
rules_with_systems_roles = pd.merge(
_rules_with_systems_roles['ID правила доступа'].drop_duplicates(),
rules_data[['ID правила доступа','Название правила доступа','Правило отключено']],
on='ID правила доступа', how='inner')
rules_with_systems_roles.to_csv('clusters/rules_with_system.csv')
# Роли с системными пользователями в правилах
roles_with_systems_roles = pd.merge(
_rules_with_systems_roles[['ID роли','Тип роли']].drop_duplicates(),
role_name[['ID роли','Название роли']],
on='ID роли', how='left'
)[['ID роли','Название роли','Тип роли']]
roles_with_systems_roles.to_csv('clusters/roles_with_system.csv')
print('-'*5, 'Правила с системными пользователями', '-'*5)
print(rules_with_systems_roles.info())
display(rules_with_systems_roles.head(5))
print()
print('-'*5, 'Роли с системными пользователями в правилах','-'*5)
print(roles_with_systems_roles.info())
display(roles_with_systems_roles.head(5))
----- Правила с системными пользователями ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 4 entries, 0 to 3 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 4 non-null object 1 Название правила доступа 4 non-null object 2 Правило отключено 4 non-null bool dtypes: bool(1), object(2) memory usage: 200.0+ bytes None
| ID правила доступа | Название правила доступа | Правило отключено | |
|---|---|---|---|
| 0 | 5f00b5e3-060e-4f76-923b-9c5cee5fb1a2 | Правило 30 | False |
| 1 | 62efd89f-4495-4042-bc08-5ba4fc608d05 | Правило 12 | False |
| 2 | 635e701d-f2bd-4616-8994-db1206c5f882 | Правило 160 | False |
| 3 | b2322015-2883-460c-be26-99803aa581e3 | Правило 53 | False |
----- Роли с системными пользователями в правилах ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 3 entries, 0 to 2 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 3 non-null object 1 Название роли 3 non-null object 2 Тип роли 3 non-null int64 dtypes: int64(1), object(2) memory usage: 204.0+ bytes None
| ID роли | Название роли | Тип роли | |
|---|---|---|---|
| 0 | 00000000-0000-0000-0000-000000000002 | Бухгалтерские сервисы | 1 |
| 1 | 00000000-0000-0000-0000-000000000004 | Сайт компании | 1 |
| 2 | 00000000-0000-0000-0000-000000000005 | Робот службы безопасности | 1 |
Правила с администраторами¶
# Предварительный список правил с администраторами
'''
_rules_with_admins = rules_not_contextual_roles[
(rules_not_contextual_roles['ID пользователя'].isin(['00000000-0000-0000-0000-000000000008'])) # Статическая роль 'Сотрудники с правами Администратора
| (rules_not_contextual_roles['Уровень доступа пользователя']== 1) # Административный уровень доступа
].sort_values(['ID правила доступа','ID роли']).drop([
'ID пользователя', 'Доложность пользователя',
'Уровень доступа пользователя', 'Тип учетной записи пользователя',
'Блокировка учетной записи пользователя'
], axis=1).drop_duplicates
'''
_rules_with_admins = rules_not_contextual_roles[
(rules_not_contextual_roles['ID пользователя'] == '00000000-0000-0000-0000-000000000008') # Статическая роль 'Сотрудники с правами Администратора
| (
rules_not_contextual_roles['ID пользователя'].isin(
user_data[user_data['Уровень доступа пользователя'] == 1]['ID пользователя']
)
) # Административный уровень доступа
].sort_values(['ID правила доступа','ID роли']).drop([
'ID пользователя'], axis=1).drop_duplicates()
# Правила с администраторами
rules_with_admins = pd.merge(_rules_with_admins['ID правила доступа'].drop_duplicates(),
rules_data[['ID правила доступа',
'Название правила доступа',
'Правило отключено']], on='ID правила доступа', how='inner')
rules_with_admins.to_csv('clusters/rules_with_admins.csv')
# Роли с администраторами
roles_with_admins = pd.merge(_rules_with_admins[['ID роли','Тип роли']].drop_duplicates(),
role_name[['ID роли','Название роли']],
on='ID роли', how='left')[['ID роли','Название роли','Тип роли']]
roles_with_admins.to_csv('clusters/roles_with_admins.csv')
print('-'*5, 'Правила с администраторами', '-'*5)
print(rules_with_admins.info())
display(rules_with_admins.head(5))
print()
print('-'*5, 'Роли с администраторами в правилах', '-'*5)
print(roles_with_admins.info())
display(roles_with_admins.head(5))
----- Правила с администраторами ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 69 entries, 0 to 68 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 69 non-null object 1 Название правила доступа 69 non-null object 2 Правило отключено 69 non-null bool dtypes: bool(1), object(2) memory usage: 1.3+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | |
|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False |
| 1 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False |
| 2 | 09c45d7d-ee39-4e35-b47b-5b40edfa20bf | Правило 184 | False |
| 3 | 131ea06e-e001-4cec-a0f8-b31d29bd57d6 | Правило 20 | False |
| 4 | 13d02e38-aa00-4782-9770-bca53a6838b2 | Правило 22 | False |
----- Роли с администраторами в правилах ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 64 entries, 0 to 63 Data columns (total 3 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID роли 64 non-null object 1 Название роли 64 non-null object 2 Тип роли 64 non-null int64 dtypes: int64(1), object(2) memory usage: 1.6+ KB None
| ID роли | Название роли | Тип роли | |
|---|---|---|---|
| 0 | 49d7a40b-b8a2-4e51-ab99-febf59a885b6 | Юридический отдел | 2 |
| 1 | 27a6ba8d-4cc5-464e-a1d9-d30daf643391 | Отдел продаж | 2 |
| 2 | 71a48819-fca5-4d4d-a9b9-0ca13e41b63f | Михайлов Д.Г. | 1 |
| 3 | 8d0dc4c3-be5b-4294-82cf-9422c7c00eae | Титов Д.Д. | 1 |
| 4 | d1c293a6-21aa-4c45-8e77-ceb8f6fc726a | Руководство | 2 |
Объединение данных о результатах анализа правил¶
# Данные о правилах
result_rules = rules_data[['ID правила доступа','Название правила доступа','Правило отключено']].drop_duplicates()
result_rules['РПД'] = np.where(result_rules['ID правила доступа'].isin(rules_data[rules_data['РПД'] == True]['ID правила доступа']), True, False)
result_rules['Типы условий'] = np.where(result_rules['ID правила доступа'].isin(rules_data[rules_data['Типы условий'] == True]['ID правила доступа']), True, False)
# Данные о ролях в правилах
result_rules['Контекстные роли'] = np.where(result_rules['ID правила доступа'].isin(rules_roles[rules_roles['Тип роли'] == 4]['ID правила доступа']), True, False)
result_rules['Роли с пользователями'] = np.where(result_rules['ID правила доступа'].isin(rules_with_users['ID правила доступа']), True, False)
result_rules['Роли без пользователей'] = np.where(result_rules['ID правила доступа'].isin(rules_without_users['ID правила доступа']), True, False)
result_rules['Роли с не заблокированными пользователями'] = np.where(result_rules['ID правила доступа'].isin(rules_with_non_blocked_users['ID правила доступа']), True, False)
result_rules['Роли с заблокированными пользователями'] = np.where(result_rules['ID правила доступа'].isin(rules_with_blocked_users['ID правила доступа']), True, False)
result_rules['Пользователи без групповых ролей'] = np.where(result_rules['ID правила доступа'].isin(rules_with_users_without_roles['ID правила доступа']), True, False)
result_rules['Роли с System'] = np.where(result_rules['ID правила доступа'].isin(rules_with_system['ID правила доступа']), True, False)
result_rules['Роли с системными пользователям'] = np.where(result_rules['ID правила доступа'].isin(rules_with_systems_roles['ID правила доступа']), True, False)
result_rules['Роли с администраторами'] = np.where(result_rules['ID правила доступа'].isin(rules_with_admins['ID правила доступа']), True, False)
# Данные о разрешениях
result_rules['Чтение карточки'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Чтение карточки'] == True]['ID правила доступа']), True, False)
result_rules['Создание карточки'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Создание карточки'] == True]['ID правила доступа']), True, False)
result_rules['Редактирование карточки'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Редактирование карточки'] == True]['ID правила доступа']), True, False)
result_rules['Удаление карточки'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Удаление карточки'] == True]['ID правила доступа']), True, False)
result_rules['Добавление файлов'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Добавление файлов'] == True]['ID правила доступа']), True, False)
result_rules['Редактирование файлов'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Редактирование файлов'] == True]['ID правила доступа']), True, False)
result_rules['Удаление всех файлов'] = np.where(result_rules['ID правила доступа'].isin(KrPermissions[KrPermissions['Удаление всех файлов'] == True]['ID правила доступа']), True, False)
print('-'*5,'Результаты анализа правил','-'*5)
print(result_rules.info())
display(result_rules.head(5))
----- Результаты анализа правил ----- <class 'pandas.core.frame.DataFrame'> RangeIndex: 187 entries, 0 to 186 Data columns (total 21 columns): # Column Non-Null Count Dtype --- ------ -------------- ----- 0 ID правила доступа 187 non-null object 1 Название правила доступа 187 non-null object 2 Правило отключено 187 non-null bool 3 РПД 187 non-null bool 4 Типы условий 187 non-null bool 5 Контекстные роли 187 non-null bool 6 Роли с пользователями 187 non-null bool 7 Роли без пользователей 187 non-null bool 8 Роли с не заблокированными пользователями 187 non-null bool 9 Роли с заблокированными пользователями 187 non-null bool 10 Пользователи без групповых ролей 187 non-null bool 11 Роли с System 187 non-null bool 12 Роли с системными пользователям 187 non-null bool 13 Роли с администраторами 187 non-null bool 14 Чтение карточки 187 non-null bool 15 Создание карточки 187 non-null bool 16 Редактирование карточки 187 non-null bool 17 Удаление карточки 187 non-null bool 18 Добавление файлов 187 non-null bool 19 Редактирование файлов 187 non-null bool 20 Удаление всех файлов 187 non-null bool dtypes: bool(19), object(2) memory usage: 6.5+ KB None
| ID правила доступа | Название правила доступа | Правило отключено | РПД | Типы условий | Контекстные роли | Роли с пользователями | Роли без пользователей | Роли с не заблокированными пользователями | Роли с заблокированными пользователями | … | Роли с System | Роли с системными пользователям | Роли с администраторами | Чтение карточки | Создание карточки | Редактирование карточки | Удаление карточки | Добавление файлов | Редактирование файлов | Удаление всех файлов | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False | True | False | False | True | False | True | False | … | False | False | True | True | True | False | False | True | True | False |
| 1 | 0359fea5-f9d6-4911-acbe-70f82c858418 | Правило 143 | True | False | False | False | False | False | False | False | … | False | False | False | True | False | False | True | False | False | False |
| 2 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False | False | False | False | True | False | True | False | … | False | False | True | True | True | True | True | True | False | False |
| 3 | 05bd596d-c6ad-474b-80db-fdbecab66f21 | Правило 124 | True | False | False | False | False | False | False | False | … | False | False | False | False | True | True | True | True | False | False |
| 4 | 07cc452b-48c4-4176-b13d-ab576ae7afdc | Правило 67 | False | False | False | False | False | False | False | False | … | False | False | False | True | False | True | False | False | False | False |
5 rows × 21 columns
Кластеризация правил¶
# Кластеры правил и рекомендации
result_rules['Кластеры'] = ''
result_rules['Рекомендации'] = ''
# Все роли пустые
mask = ((result_rules['Роли с пользователями'] == False)
& (result_rules['Роли без пользователей'] == True)
| ( (result_rules['Роли с не заблокированными пользователями'] == False)
& (result_rules['Роли с заблокированными пользователями'] == True))
& (result_rules['Кластеры'] == ''))
result_rules.loc[mask, 'Кластеры'] = 'Все роли пустые. '
result_rules.loc[mask, 'Рекомендации'] = 'Удалить правила и роли внутри них. '
# Есть пустые роли
mask = ((result_rules['Роли с пользователями'] == True)
& (result_rules['Роли без пользователей'] == True)
| ( (result_rules['Роли с не заблокированными пользователями'] == True)
& (result_rules['Роли с заблокированными пользователями'] == True)))
result_rules.loc[mask, 'Кластеры'] = 'Пустые роли. '
result_rules.loc[mask, 'Рекомендации'] = 'Проверить правила и роли внутри них. '
# Иднивидуальные роли
mask = (result_rules['Пользователи без групповых ролей'] == True)
result_rules.loc[mask, 'Кластеры'] += 'Индивидуальные роли. '
result_rules.loc[mask, 'Рекомендации'] += 'Использовать групповые роли вместо иднивидуальных'
# Контекстные роли
mask = (result_rules['Контекстные роли'] == True)
result_rules.loc[mask, 'Кластеры'] += 'Контекстные роли. '
result_rules.loc[mask, 'Рекомендации'] += 'Контекстные роли заменить на групповые роли и типы условий. '
# Системные роли
mask = ((result_rules['Роли с системными пользователям'] == True))
result_rules.loc[mask, 'Кластеры'] += 'Системные роли. '
result_rules.loc[mask, 'Рекомендации'] += 'Сверить права системных ролей с их ТЗ. '
# Административные права
mask = ((result_rules['Роли с System'] == True)
| (result_rules['Роли с администраторами'] == True))
result_rules.loc[mask, 'Кластеры'] += 'Административные права. '
result_rules.loc[mask, 'Рекомендации'] += 'Особое внимание на список администраторов. '
# Полные права на модификацию документов
mask = ((result_rules['Редактирование карточки'] == True)
& (result_rules['Удаление карточки'] == True)
& (result_rules['Добавление файлов'] == True)
& (result_rules['Редактирование файлов'] == True)
& (result_rules['Удаление всех файлов'] == True))
result_rules.loc[mask, 'Кластеры'] += 'Полные права на модификацию документов. '
result_rules.loc[mask, 'Рекомендации'] += 'Проверить риск возможности подлога документов. '
# Права на чтение
mask = ((result_rules['Чтение карточки'] == True))
result_rules.loc[mask, 'Кластеры'] += 'Права на чтение. '
result_rules.loc[mask, 'Рекомендации'] += 'Сверить права с бизнес-требованиями на доступ к документам. '
# Права на создание
mask = ((result_rules['Создание карточки'] == True))
result_rules.loc[mask, 'Кластеры'] += 'Права на создание. '
result_rules.loc[mask, 'Рекомендации'] += ''
result_rules.to_csv('clusters/result_rules.csv', sep=';', encoding='utf-8-sig')
result_rules.head()
| ID правила доступа | Название правила доступа | Правило отключено | РПД | Типы условий | Контекстные роли | Роли с пользователями | Роли без пользователей | Роли с не заблокированными пользователями | Роли с заблокированными пользователями | … | Роли с администраторами | Чтение карточки | Создание карточки | Редактирование карточки | Удаление карточки | Добавление файлов | Редактирование файлов | Удаление всех файлов | Кластеры | Рекомендации | |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0 | 0156312e-890f-49e3-8c5d-d8df16376bd4 | Правило 38 | False | True | False | False | True | False | True | False | … | True | True | True | False | False | True | True | False | Административные права. Права на чтение. Права… | Особое внимание на список администраторов. Све… |
| 1 | 0359fea5-f9d6-4911-acbe-70f82c858418 | Правило 143 | True | False | False | False | False | False | False | False | … | False | True | False | False | True | False | False | False | Права на чтение. | Сверить права с бизнес-требованиями на доступ … |
| 2 | 051b8ae8-cefe-4327-9511-777515747775 | Правило 47 | False | False | False | False | True | False | True | False | … | True | True | True | True | True | True | False | False | Административные права. Права на чтение. Права… | Особое внимание на список администраторов. Све… |
| 3 | 05bd596d-c6ad-474b-80db-fdbecab66f21 | Правило 124 | True | False | False | False | False | False | False | False | … | False | False | True | True | True | True | False | False | Права на создание. | |
| 4 | 07cc452b-48c4-4176-b13d-ab576ae7afdc | Правило 67 | False | False | False | False | False | False | False | False | … | False | True | False | True | False | False | False | False | Права на чтение. | Сверить права с бизнес-требованиями на доступ … |
5 rows × 23 columns


