# Администрируемые объекты и привилегии

## Общее описание

`Администрируемый объект` — логически связанный набор привилегий для массовой раздачи прав.

Администрируемый объект генерируется при установке или обновлении системы для следующих сущностей:
- произвольная выборка;
- класс:
  - справочник;
  - настройка;
  - журнал;
  - документ;
- пакеты;
- приложения.

Список администрируемых объектов доступен по пути:
- `Администратор > Настройки > Администрируемые объекты`.

## Интерфейс администрируемых объектов

При открытии раздела `Администрируемые объекты` отображается общий список всех администрируемых объектов системы.

В списке по каждому объекту отображаются его основные сведения и служебные признаки:
- код;
- наименование;
- описание;
- группа;
- модуль;
- признаки и параметры состояния объекта;
- дата окончания.

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

## Карточка администрируемого объекта

Карточка администрируемого объекта открывается при переходе к выбранному объекту и используется для просмотра и изменения его параметров.

В карточке задаются основные сведения об объекте:
- `Код` — уникальный идентификатор администрируемого объекта;
- `Наименование` — отображаемое название объекта в интерфейсе;
- `Модуль` — модуль системы, к которому относится объект;
- `Группа` — группа, в составе которой отображается объект;
- `Описание` — текстовое описание назначения объекта.

Также в карточке настраиваются признаки администрируемого объекта:
- `Не распространяются настройки администрирования` — если флаг установлен, отключается обработка всех настроек администрирования для данного объекта и входящих в него нижестоящих объектов. Этот признак является характеристикой самого администрируемого объекта, а не роли;
- `Не требуется настройка прав доступа по состояниям` — если флаг установлен, отключается контроль переходов между состояниями для документов данного объекта. Этот признак также является характеристикой самого администрируемого объекта, а не роли;
- `Дискретный доступ` — если флаг установлен, включается механизм дискретного доступа: права выдаются не на весь объект, а в разрезе конкретных записей или объектов классов;
- `Проверять изменение прав объектов на коммите` — если флаг установлен, при сохранении объекта проверяется, не стал ли он недоступен для пользователя после редактирования. При нарушении прав изменения откатываются с ошибкой. Проверка работает только при включённом флаге `Дискретный доступ`;
- `Не используется` — признак, что объект не используется в текущей настройке прав;
- `Устарел` — признак, что объект относится к устаревшим.

Для отключения администрирования или изменения его режима используются следующие поля карточки:
- `Не распространяются настройки администрирования`;
- `Не требуется настройка прав доступа по состояниям`;
- `Дискретный доступ`;
- `Проверять изменение прав объектов на коммите`.

### Узлы администрирования

Во вкладке `Узлы администрирования` отображаются узлы администрирования, входящие в состав выбранного администрируемого объекта.

Узел администрирования группирует элементы администрируемого объекта для массовой раздачи прав. По умолчанию для каждого администрируемого объекта создаётся одна основная группа.

Узел администрирования зарезервирован на случай, если в системе потребуется настраивать права в зависимости от `типа объекта` или `состояния`.

Для выбранного узла отображаются связанные с ним элементы администрируемого объекта.

**Элементы администрируемого объекта**

Элемент администрируемого объекта (`acObjectItem`) создаётся для объектов, по которым требуется раздавать права на элементарные привилегии. Через такие элементы в роли настраиваются права на атрибуты, операции, отображения и другие составные части администрируемого объекта.

По умолчанию выборка со всеми отображениями регистрируется как один элемент администрируемого объекта с именем `{SelName}#Default`. Для каждой операции и каждого атрибута выборки в разрезе системного имени создаётся элементарная привилегия.

Для отображения можно сформировать отдельный элемент администрируемого объекта. Такой элемент используется при настройке прав в роли и позволяет выдавать права на отображение независимо от стандартного элемента `{SelName}#Default`.

Для переноса отображения в отдельный элемент администрируемого объекта используется аннотация:

```scala
@AcItemRep(name = "{Name}")
```

Элемент администрируемого объекта получит имя:

```text
{SelName}#{Name}
```

Элемент администрируемого объекта можно задать в AVM-разметке через атрибут `acItemRep` в теге `<representation>`.

Пример:

```xml
<representation name="Tree_ResourceFiltered"
                editMode="notEdit"
                caption="Ресурсы"
                acItemRep="Tree_ResourceFiltered">
    <!-- разметка дерева -->
</representation>
```

После обновления административного объекта в системе появится отдельный элемент администрируемого объекта. Для него можно отдельно настраивать права в роли: чтение, редактирование, интерактивные права и другие элементарные привилегии, если они применимы к данному отображению.

Значение `acItemRep` должно быть уникальным в пределах одного администрируемого объекта. Если `acItemRep` не указан, отображение остаётся в составе стандартного элемента `{SelName}#Default`.

```{note}
Изменения вступят в силу после обновления административного объекта.

Для создания элементов администрируемого объекта по выборкам, не имеющим класса, в AVM-разметке обязательно должен быть тег <acObject/>. Для таких выборок формируется администрируемый объект и элемент администрируемого объекта с суффиксом Avi в имени.
```

### Объектные привилегии

Во вкладке `Объектные привилегии` отображаются объектные привилегии, созданные для выбранного администрируемого объекта.

Во вкладке можно добавлять объектные привилегии для данного объекта.

Объектные привилегии предоставляют базовый доступ к объектам администрируемого объекта. Без них пользователь не сможет работать с объектом, даже если ему выданы элементарные привилегии.

Объектные привилегии являются специальными системными привилегиями для конкретного объекта и используются для настройки особых действий и режимов доступа.

Например, если включён дискретный доступ, но у пользователя нет права `view#`, он не увидит объекты ни в выборке, ни в карточке.

**Автогенерируемые объектные привилегии**

Автоматически создаются следующие объектные привилегии:
- `edit#` — право на редактирование объектов; создаются дискретные привилегии для контроля доступа к операциям изменения;
- `view#` — право на просмотр объектов; создаются дискретные привилегии для контроля доступа к чтению и отображению;
- `viewReport#` — доступ на чтение из печатных форм; создаются дискретные привилегии для контроля данных в отчётах.

Если администрируемый объект создан на основе класса с поддержкой групп, дополнительно генерируются:
- `group.edit#` — право на редактирование групп объектов;
- `group.view#` — право на просмотр групп объектов.

**Привилегии на переход состояний**

Привилегии на переход состояний ограничивают доступные переходы между состояниями.

Ограничения реализованы в стандартном выпадающем списке для состояний `ru.bitec.app.btk.Btk_ClassStateAvi.Lookup_Class`.

Если для объекта включён признак `Не требуется настройка прав доступа на состояния`, пользователю доступны любые переходы состояний. Для настройки доступа по отдельным переходам сначала необходимо определить возможные переходы для типа объекта, а затем выдать права на них.

Имя привилегии формируется по правилу:
```scala
s"StateChange_OT:${idObjectType}_SS:${idStartState}_FS:$idFinishState"
```

Функция проверки возможности перехода:
`ru.bitec.app.btk.Btk_AdminPkg#hasStateChangePriv`.

**Ручное создание объектных привилегий**

Для ручного создания привилегий на классе (`odm.xml`) или пакете (`pkg.xml`) используйте XML-разметку.

Пример:
```xml
<admin>
    <privileges>
        <privilege name="SbtManage" caption="Управление решением"/>
    </privileges>
</admin>
```

```{note}
Изменения вступят в силу после обновления административного объекта.
```

### Дискретные ограничения доступа

Во вкладке `Дискретные ограничения доступа` создаются и настраиваются правила дискретного доступа для выбранного администрируемого объекта.

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

Дискретные ограничения позволяют задавать выражения для правил выдачи дискретных привилегий на конкретной роли.

**Принцип настройки:**
1. Администратор определяет дискретные ограничения на администрируемом объекте.
2. Администратор определяет дискретные правила в роли: каждое правило содержит ограничение и набор параметров.
3. Администратор выдаёт грант на дискретную привилегию роли. При синхронизации пользователей выполняется расчёт привилегий по алгоритму объединения грантов.

При проверке привилегии в бизнес-логике в функцию передаётся перечень строк, для которых выполняется проверка.

При ограничении запроса по дискретной привилегии каждое ограничение добавляется в условие `WHERE`.

**Алгоритм объединения грантов:**
1. Пусть `g1` и `g2` — гранты пользователю на объектную привилегию `p`.
2. Если `g1` или `g2` имеют тип `полный доступ`, вернуть грант на `p` с полным доступом.
3. Иначе вернуть грант на `p`, объединив ограничения.

**Алгоритм объединения ограничений:**
1. Пусть `A` — массив ограничений для грантов `g1` и `g2`.
2. Пусть `S` — пустое множество ограничений. Параметры не входят в ключ множества.
3. Для каждого `g` из `A`:
   1. Если `g` уже существует в `S`, добавить новые параметры к ограничению в `S`.
   2. Иначе добавить `g` в `S`.
4. Вернуть `S`.

**Скрипт фильтрации** используется в универсальной фильтрации для ограничения видимости по объектам.

**Скрипт проверки объектного кэша** используется в автономной бизнес-логике для проверки возможности действия со строкой.

## Привилегии администрируемого объекта

### Элементарные привилегии

Элементарные привилегии разграничивают действия пользователя и создаются по выборке на:
- операции;
- атрибуты;
- сеттеры атрибута.

Для операций и сеттеров атрибута создаются дискретные привилегии.

### Типы элементарных привилегий

Система поддерживает следующие типы элементарных привилегий:
- **Чтение** — настройки видимости атрибутов;
- **Редактирование** — сеттеры атрибутов;
- **Добавление** — операции вставки и копирования;
- **Удаление** — операция удаления;
- **Интерактивные права** — остальные операции.

Для изменения типа привилегии, соответствующей операции выборки, используйте аннотацию `@AcPrivilegeType`.

Пример:
```scala
@AcPrivilegeType(value = PrivilegeTypes.Read)
def myOperation(): Unit = {}
```

```{note}
Изменения вступят в силу после обновления административного объекта.
```

### Дискретные привилегии

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

В интерфейсе настройки ролей такие привилегии выдаются с ограничением по дискретному правилу.

## Администрирование приложений

Для администрирования приложений создаётся администрируемый объект `Приложения` (`Btk_ApplicationsListPkg`).

Объектные привилегии импортируются в него из XML-файлов `META-INF/applications.xml` всех подключённых модулей.

Если разработчик добавляет новый административный объект, новый атрибут или новую привилегию, они не появляются автоматически в интерфейсах настройки прав. Чтобы изменения стали доступны для настройки, необходимо выполнить обновление административных объектов.

Выданные права на такую привилегию обеспечивают отображение приложения в меню выбора приложений.