Разработка типов прав доступа в Directum RX

30 5

Предыстория

Во времена десктоп клиента типы прав доступа можно было создавать через Администрирование.

Как было: Открываете модуль Администрирование, на обложке в блоке Права доступа нажимаете «Типы прав доступа», появится окно со списком объектов и типами прав. Находите в списке нужный объект и в табличке типов прав щелкаете правой кнопкой мыши в меню выбираете Создать тип прав. Вводите в появившейся карточке Имя, Описание, Область применения и в списке Операции ставите нужные галочки для разрешения и запрещения операций. Сохраняете. Теперь тип прав доступен для выбора в доступе к объекту.

Пример карточки для типа прав, тут можете посмотреть список операций:

Задача

Теперь когда десктоп сменился вебом, а дополнительные типы прав вдруг потребуются, можно написать свой тип прав в инициализации. Для кастомного типа прав можно выбрать любой набор разрешающих и запрещающих операций.

Пример разработки типа прав

Давайте рассмотрим, как написать свой тип прав. Для примера возьмем кейс, в котором заказчику требовалось, чтобы некоторые пользователи видели только карточку документа, но не могли просматривать тело документа.

Напишем функцию инициализации, которой при вызове будем передавать Guid типа документа, для которого предназначен данный тип прав. 

//Пример функции инициализации для создания типа прав
public static void CreateAccessRightTypeForDoc(Guid entityTypeGuid)
{
      // Создать тип прав "Только просмотр карточки".
      var maskAll = Sungero.Docflow.OfficialDocumentOperations.Read ^ Sungero.Docflow.OfficialDocumentOperations.Approve ^ Sungero.Docflow.OfficialDocumentOperations.Create
        ^ Sungero.Docflow.OfficialDocumentOperations.ReadBody ^ Sungero.Docflow.OfficialDocumentOperations.CreateVersion ^ Sungero.Docflow.OfficialDocumentOperations.DelegateAccess
        ^ Sungero.Docflow.OfficialDocumentOperations.Delete ^ Sungero.Docflow.OfficialDocumentOperations.DeleteVersion ^ Sungero.Docflow.OfficialDocumentOperations.ManageRelations
        ^ Sungero.Docflow.OfficialDocumentOperations.Register  ^ Sungero.Docflow.OfficialDocumentOperations.Manage  ^ Sungero.Docflow.OfficialDocumentOperations.SendByExchange
        ^ Sungero.Docflow.OfficialDocumentOperations.Update  ^ Sungero.Docflow.OfficialDocumentOperations.UpdateBody;
      var mask = Sungero.Docflow.OfficialDocumentOperations.Read;
      Sungero.Docflow.PublicInitializationFunctions.Module.CreateAccessRightsType(entityTypeGuid.ToString), Resources.ReadCardOnlyAccessRightType, maskAll, mask, Sungero.CoreEntities.AccessRightsType.AccessRightsTypeArea.Instance, Constants.Module.DefaultAccessRightsTypeSid.ReadCardOnly, false, string.Empty);
} 
    

В переменной maskAll перечисляем все типы операций, в переменной mask – разрешенные. В результате будет создан тип прав, в котором запрещены все операции кроме Просмотра карточки.

Если требуется создать тип прав без запрещений, то в maskAll укажите только разрешенные операции, либо в вызове функции передавайте mask вместо maskAll. Запрещающие операции по приоритету выше, чем разрешающие. Например, если у какого-то пользователя есть коробочные права типа Изменение и ваш кастомный тип прав с запретом на Изменение карточки, то менять карточку пользователь не сможет.

Sungero.CoreEntities.AccessRightsType.AccessRightsTypeArea – область применения (для типа, экземпляра сущности или обоих вариантов)
Constants.Module.DefaultAccessRightsTypeSid.ReadCardOnly – константа с GUID’ом типа прав.

Если будете обращаться к ней из других модулей, при создании константы укажите атрибут Public.

public static class DefaultAccessRightsTypeSid
{
  /// <summary>
  /// GUID типа прав Только просмотр карточки.
  /// </summary>
  [Public]
  public static readonly Guid ReadCardOnly = Guid.Parse("7065196C-2423-4ADF-8AD5-D3D998F77BCE");
}

Для того чтобы выдать права нашего кастомного типа в коде обращаемся к ним через константу:

_obj.AccessRights.Grant(<реципиент>, centrvd.<Модуль>.PublicConstants.Module.DefaultAccessRightsTypeSid.ReadCardOnly);

После публикации и инициализации для документа, Guid которого мы указывали при вызове функции CreateAccessRightTypeForDoc в инициализации, у нас будет доступен для выбора тип прав "Только просмотр карточки".

30
Авторизуйтесь, чтобы оценить материал.
3
Александр Волошин

Добрый день. Спасибо за статью.

Уточните, пожалуйста, в строке

Sungero.Docflow.PublicInitializationFunctions.Module.CreateAccessRightsType(entityTypeGuid.ToString), Resources.ReadCardOnlyAccessRightType, mask, mask, Sungero.CoreEntities.AccessRightsType.AccessRightsTypeArea.Instance, Constants.Module.DefaultAccessRightsTypeSid.ReadCardOnly, false, string.Empty);

переменная mask встречается 2 раза. Так задумано или опечатка?

Алена Перейма

Александр, давайте первой укажу maskAll для ясности. Если оба раза использовать mask мы получим тип прав в котором будет только разрешение на просмотр карточки без запрещения остальных операций. Если первой будет maskAll, а второй просто mask мы получим тип прав в котором разрешен просмотр карточки, а все остальные операции запрещены. В нашем кейсе нужен был тип прав без запрещений на остальные, чтобы в случае выдачи дополнительных прав (например при отправке на согласование по регламенту) пользователь тело документа все же увидел.

Подскажите пожалуйста, как выдать права на удаление отдельного конкретного объекта (объект документ)?

Guid entityTypeGuid - это GUID типа сущности, насколько понимаю. Как его получить, если знаешь класс названия сущности? 

например у меня кастомный тип документов, наследник InternalDocumentBase, как мне узнать его entityTypeGuid?

maskAll - все запрещаемые операции, а mask - все разрещаемые, т.е. если мне нужно просто добавить возможность удаления объекта, я в первую маску ставлю 0, а во вторую Sungero.Docflow.OfficialDocumentOperations.Delete, правильно?

 

Алена Перейма

Татьяна, чтобы выдать права на удаление одного конкретного документа, вам нужен тип прав в котором разрешено удаление. Если вы переопределите какой-то тип прав, то все кто обладают этими правами смогут удалять.

Есть роль, сотрудники входящие в которую имеют права на удаление. Может временно включить сотрудника в роль для вас будет удобнее разработки.

Guid entityTypeGuid можно получить в студии если по сущности щелкнуть правой кнопкой мыши и выбрать в меню Скопировать идентификатор, если хотите получать в коде - var docGuid = document.GetEntityMetadata().GetOriginal().NameGuid; (пример из серверной функции модуля Docflow)

Если запрещать ничего в правах не собираетесь, а только разрешить, вам достаточно будет одну маску с набором операций (или только операцией удаления) и использовать ее дважды в функции.

Татьяна Щербакова

Добрый день еще раз!

1) Есть какой-то способ динамически выдавать права (например из действия в экземпляре), чтобы при этом не считалось, что это текущий пользователь выдает права? 

Бывает, нужно ситуационно выдать дополнительные права на экземпляр текущему пользователю или после его действия выдать права кому-то другому, но у самого этого пользователя прав на выдачу прав нет

2) Есть какой-то хороший способ выдать права "всем кроме"? Например у меня есть кастомные запрещающие права на изменение тела документа, мне надо выдать эти запрещающие права всем пользователям, кроме роли Администраторы, это должно делаться при инициализации один раз и далее работать без каких-либо редактирований со стороны админов. Как такое лучше делать? Выдать права всем, а потом забрать у админов не сработало

Авторизуйтесь, чтобы написать комментарий