Userinfo: Access Control
IMPORTANT
Перед прочитанням технічної доки ДУЖЕ наполегливо рекомендую ознайомитись з загальними доками по Правах доступу у категорії Knowledge Base.
Модуль відповідає за зберігання та розрахунок прав доступу до дій / сторінок / обʼєктів.
Ініціалізація
Усереднена ініціалізація в апплікейшені виглядає десь так:
main.ts
// main.ts
import { createUserAccessControl } from './app/composables/useUserAccessControl';
import { useUserinfoStore } from './modules/userinfo/store/userinfoStore';
const initApp = async () => {
const app = createApp(App)
// ..
/* Перед ініціалізацією userinfoStore маємо спершу зареєструвати pinia */
.use(pinia);
const { initialize, routeAccessGuard } = useUserinfoStore();
try {
/*
Ініціалізуємо userinfoStore, який під капотом ініціалізує
і accessStore
Саме на цьому етапі робиться запит на Права, і їх
трансформація для доступу в геттерах
*/
await initialize();
/*
Компоузабл створюємо після ініціалізації стора,
бо нам треба прокинути цей стор, щоб ініціалізувати компоузабл
(компоузабл напряму залежить від стора,
тому що бігає в стор перевіряти права)
*/
createUserAccessControl(useUserinfoStore);
/*
Ініціалізуємо роутер після того, ініціалізували userinfoStore
і routeAccessGuard вже знає, куди (не)можна пускати користувача.
*/
await initRouter({
beforeEach: [
routeAccessGuard,
],
});
} catch (err) {
console.error('Error initializing app', err);
}
/*
Отут дуже важливо!
Ми реєструємо роутер ПІСЛЯ того,
як ініціалізуємо userinfo i Access Control,
тому що вже на старті роутера нам необхідно
запустити guard
*/
app.use(router);
app.use(WebitelUi, {
...WebitelUiOptions,
router,
}); // setup webitel ui after router init
return app;
};І допоміжні copy-paste файли useUserAccessControl і userinfoStore:
useUserAccessControl code
// crm/../useUserAccessControl.ts
import { createUserAccessControlComposable } from '@webitel/ui-sdk/modules/Userinfo';
export let useUserAccessControl: ReturnType<
typeof createUserAccessControlComposable
>;
export const createUserAccessControl = (useUserinfoStore) => {
useUserAccessControl = createUserAccessControlComposable(useUserinfoStore);
return useUserAccessControl;
};userinfoStore code
// crm/../userinfoStore.ts
import { createUserinfoStore } from '@webitel/ui-sdk/modules/Userinfo';
export const useUserinfoStore = createUserinfoStore();В яких місцях відбувається перевірка Прав
На фронтенді є 3 таких основних місця:
- Перевірка на етапі роутингу: глобальний router guard, який реєструється при ініціалізації
userinfoStore.
В основному, виконує функцію "пустити" / "не пустити" до певної сторінки.
Перевірка на CRUD в середині компонентів:
useUserAccessControlcomposable, який використовується в компонентах для перевірки CRUD (!) прав до конкретного обʼєкта.Специфічні перевірки на глобальні права або ліцензії:
userinfoStoreзі своїми геттерами для таких кейсів.
Перевірка на етапі роутингу
В кожному апплікейшені глобально реєструється (один, конкретний) beforeEnter route guard, Який перевіряє роути згідно їхніх meta філдів.
В роутах апплікейшена (там де права мають перевірятись) має бути вказана meta, по якій перевірятиметься. Мета складається з 2х полів:
WtObject– Обʼєкт, який варто перевірити при вході на певний роутUiSection– Секція, видимість до якої треба перевірити при вході на певний роут
WARNING
Якщо цих метаданих у роута немає, то він НЕ перевіряється.
IMPORTANT
Зверніть увагу!
Пошук цих метаданих відбувається по дереву роутингу знизу вверх. Тобто, братиметься найперший перент, який має ці метадані.
Перевірка на CRUD в середині компонентів
Опрацьовується через useUserAccessControl composable (який до речі теж сетапиться в кожному апплікейшені окремо на рівні його ініціалізації).
useUserAccessControl виконує 2 функції, залежно від параметра:
(За замовчуванням) перевіряє CRUD права згідно метаданих в роуті.
Може приймати на вхід параметрами
WtObject, або інші параметри для роботи з Виключеннями. Тоді рахує те саме, але вже до переданого параметра.
Специфічні перевірки на глобальні права або ліцензії
Коли нам не підходить все що вище, і треба перевірити щось специфічне. Наприклад, наявність ліцензії CallCenter для роботи у Workspace, або право (Global Role Permissions) на прослуховування записів розмов.
Тоді ми userinfoStore тягнемо спеціальні геттери, в які передаємо відповідні параметри (як правило, це values з enum'ів), і отримуємо true / false
Повʼязані enum'и
WtObject– обʼєкт / сутність системи, до якої можна перевіряти права.SpecialGlobalAction– специфічна глобальна дія, до якої можна перевіряти права (наприклад, на записи розмов).WebitelLicense– ліцензія.WtApplication.UiSection:AdminSections,AuditorSections,SupervisorSections,CrmSections.