Скрывать плитку в зависимости от того, входит ли пользователь в статическую роль
Скрывать плитку в зависимости от того, входит ли пользователь в статическую роль¶
Если требуется скрыть плитку в зависимости от каких-то полей карточки и вхождения пользователя в статическую роль, то лучше всего при загрузке карточки на сервере в расширении CardGetExtension.AfterRequest проверить статическую роль (можно через RoleRepository), необходимые параметры (поля) карточки и установить в карточке флажок в Card.Info.
// при регистрации расширения его нужно будет фильтровать по типу карточки
// .WhenCardTypes(...), чтобы оно выполнялось только для нужных карточек
public override void AfterRequest(ICardStoreExtensionContext context)
{
if (!context.IsSuccessful)
{ return; }
// вызываем некоторый метод для проверки
if (CheckUserInRole(context.Session.User.ID))
{
context.Response.Card.Info["ShowSomeTile"] = true;
}
}
Далее на клиенте в плитке необходимо написать Evaluating-обработчик, который смотрит на card.Info.TryGet<bool>(“ShowSomeTile”) и если возвращает true, то отображает плитку. Также действие, которое предполагается выполнить по плитке, должно предусматривать ещё одну проверку на сервере. Например, плитка сохраняет карточку с запуском некоторого бизнес-процесса, тогда в расширении на запуск процесса на сервере надо проверить роль ещё раз.
Несколько полезных советов:
-
Если проверка прав очень длительная, то в системе есть возможность при загрузке рассчитать некоторые права, поместить их в структуре данных UserID + CardId + объект с правами, а затем подписать эту структуру ЭП (сериализовав ее в массив байт предварительно). Далее подписанную структуру помещают в секцию Info карточки вместе с подписью. При сохранении или инициации какого-то процесса на сервере - с клиента передается подписанная структура. А на сервере при запуске процесса просто проверить подпись, не выполняя дополнительных проверок (ключ для подписи известен только серверу, и корректная подпись гарантирует, что проверка была выполнена на серверной стороне при загрузке карточки). Пример подписи массива data.
using Tessa.Platform; using Tessa.Platform.Runtime;
byte[] data = ... ; byte[] signingKey = RuntimeHelper.GenerateSignature(); ISignatureProvider signatureProvider = this.signatureProviderFactory.CreateProvider(signingKey); byte[] signature = signatureProvider.Sign(data);
-
Лучше всего для реализации функционала “Пользователь входит в роль и имеет права” определять не одну статическую роль, а несколько любых ролей. Для настроек проекта создать карточку с настройками (флаг “Единственный экземпляр”). В неё добавить список ролей через контрол “Список” (указать представление DurableRoles, чтобы не выводить контекстные роли). А для определения прав проверить, есть ли пользователь в составе этих ролей (прямой select с джоином на RoleUsers). Это позволит настраивать произвольный список сотрудников вперемешку с подразделениями, статическими ролями и пр., а затем очень быстро проверять вхождение в одну из ролей по списку (необходимые индексы в системе уже есть).
Если видимость плитки не зависит от карточки, а зависит только от пользователя (например, это видимость для плитки создания карточки на правой панели, или это видимость плитки “Регистрации” для всех карточек), то роль можно расчитывать следующими способами:
- При инициализации приложения.
Есть расширение, в котором на сервере можно рассчитать права при старте приложения, а потом на клиенте получить этот флаг и записать либо в статическую переменную (не очень правильный подход, но простой), либо в ContainerControlled-зависимость в Unity (правильный подход: регистрируем класс SomeSettings со свойствами SomeTileIsVisible: bool, устанавливаем свойства в расширении, и читаем его в Evaluating плитки).
- При первом обращении.
Актуально, когда плитка отображается очень редко, зависит от карточки или представления, и права нет смысла рассчитывать при старте приложения. Например, плитка регистрации определённых видов карточек в определённых состояниях. Это делается таким же ContainerControlled-классом, в котором метод GetSomeSetting() при первом обращении выполняет кастомный CardRequest на сервер, который на сервере считает права для текущей карточки. Затем на клиенте значение сохраняется и при последующих обращениях возвращается сразу же. Делать каждый раз запрос к серверу в Evaluating нельзя, т.к. событие очень часто вызывается.
- При открытии вкладки.
Это расширения TileExtension.InitializingLocal. Например, во вкладке есть карточка, для которой может понадобиться расчитать права. Тогда обращаемся к серверу в момент открытия вкладки и запоминаем настройку, чтобы не было задержки при открытии боковой панели (т.к. Evaluating выполняется именно при открытии панели).