Перейти к основному содержанию
`Ctrl`+`K`

# Безопасность и системное управление

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

## Логические выражения доступности операций и атрибутов

Для настройки редакируемости атрибутов и доступности операций используется сервис jexl-выражений доступности. Настройка выполняется в интерфейсе:
`Сущности > Обозреватель проекта > {ВыборкаAvi} > Редактор атрибутов/операций > {Атрибут/Операция}`.

Результат выполнения выражения определяет состояние:

- Доступно — если скрипт вернул `true` или `null`.

- Недоступно — если скрипт вернул `false`.

### Структура закладки

Закладка «Выражения доступности (после/до CWA)» разделена на две части:

После checkWorkability | До checkWorkability
--- | ---
Выражение имеет приоритет над прикладной логикой | Прикладная логика имеет приоритет над выражением
Результат прикладной логики может быть перезаписан | Результат выражения может быть перезаписан прикладным кодом
Состояние недоступно в прикладной логике | Состояние может использоваться в прикладной логике

Примечание

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

### Выбор типа выражения доступности

- Используйте левую форму (после CWA), если необходимо переопределить прикладную логику. Результат выражения установит статус «только для чтения» независимо от кода.

- Используйте правую форму (до CWA), если результат выражения должен быть доступен для использования в прикладной логике.

## Аудит

Аудит фиксирует события в системе: вставка, изменение, удаление, выполнение операций и др. Данные хранятся в схеме `Aud` в таблицах формата `<ИмяКлассаШапкиБО>_dzAud`, создаваемых в табличном пространстве, указанном в настройке модуля `btk` — «Табличное пространство аудита» (по умолчанию `pg_default`).

Внимание

Если аудит включён для класса, но не включён или не синхронизирован для класса-шапки БО (определяется по полю `gidRoot_dz`), данные аудита сохраняться не будут.

### Настройка аудита

1. Откройте приложение «Настройка системы».

2. Перейдите в раздел «Сущности > Классы».

3. Выберите нужный класс.

4. На закладке «Характеристики» установите флаг «Вести аудит».

5. Если класс не является шапкой БО, включите аудит для шапки.

6. Для класса-шапки выполните операцию «Создать оболочку аудита» — будет создана таблица в схеме `Aud`.

7. Очистите кэш:
   `Сервис > Управление решением > Очистить кэш ORM (shared кэш)`.

Внимание

Для активации аудита пользователь должен переоткрыть форму.

### Просмотр данных аудита

- В карточке объекта: `Информация > Аудит объекта`.

- В списке объектов: контекстное меню → `Информация > Аудит`.

- Общий журнал: `Настройка системы > Аудит > Аудит`.

### API аудита

- `Btk_AuditPkg().isEnabledAudit` — проверка, ведётся ли аудит.

- `Btk_AuditPkg().setEnabledAudit(Boolean)` — включение/отключение аудита в сессии.

- `Btk_AuditPkg().insertRow(...)` — ручное добавление записи в аудит.

### Перенос таблиц аудита в другое табличное пространство

1. Откройте «Настройка системы».

2. Перейдите в «Настройки и сервисы > Настройки модулей системы > Общие настройки модулей».

3. Выберите модуль `btk`.

4. В поле «Табличное пространство аудита» укажите новое значение.

5. Нажмите операцию «Скачать файл со скриптом переноса таблиц аудита», выполните SQL-скрипт.

## Пообъектный доступ

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

Права реализуются через группу доступа (`Btk_RlsAccessGroup`). На один объект может быть назначена только одна группа доступа для пользователя или роли.

### Управление правами

Используется библиотека `Btk_RlsLib`:

- `manageAccess` — настройка прав для выбранных строк в стандартной выборке (через `gid` или `id`/`idClass`).

- `manageAccessByGid` — настройка прав для одного объекта.

- `manageAccessByGidList` — настройка прав для списка объектов.

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

### Работа с правами в бизнес-логике

Методы пакета `Btk_RlsPkg`:

- `grantToUsers` — выдача прав пользователям.

- `revokeFromUsers` — отзыв прав у пользователей.

- `grantToRoles` — выдача прав ролям.

- `revokeFromRoles` — отзыв прав у ролей.

### Удаление объектов с пообъектным доступом

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

- `clearByObject` — очистка прав для одного объекта.

- `clearByObjectList` — очистка прав для списка объектов.

### Проверка прав

- В запросах: используйте таблицу `Btk_RlsUserRightsFlat`, условие через `EXISTS` по `gidObj` и `idUser`.

- В бизнес-логике: методы `getAccessByObject`, `getAccessByObjectList`.

## Сервис универсальных коллекций

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

При удалении записей вызывается:

    Btk_UniversalTabPkg().deleteManualCollections(rop.gid)

### Варианты поведения при удалении

- Каскадное удаление — удаляются все записи коллекций, ссылающиеся на удаляемый объект.

- Генерация ошибки — если есть связанные записи, операция прерывается с ошибкой.

### Подключение из приложения

1. Откройте «Настройка системы».

2. Перейдите в «Сущности > Классы».

3. Откройте карточку класса.

4. Перейдите на закладку «Коллекции» — здесь отображаются все коллекции и доступно добавление универсальной.

5. При необходимости добавьте универсальную коллекцию:

   - Укажите класс и атрибут ссылочности.

   - Поддерживаются типы:

     - `Long` + `RefObject` с указанием класса.

     - `Varchar` + `RefAnyObject`.

   - Допускается использование проектных атрибутов и характеристик в `jObjAttrs_dz`.

   Внимание

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

6. Настройте «Действие при удалении».

7. При необходимости удалите коллекцию — доступно только для вручную добавленных.

8. Сбросьте объектный кэш — класс `Btk_ClassCollection` кэшируется.

Внимание

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

### Подключение из кода

Для программного подключения используйте метод:

    Btk_ClassCollectionApi().register(
      idpBtkClass: NLong,
      idpRefClass: NLong,
      idpRefAttr: NLong,
      spDelAction: NString
    ): ApiRop

Доступные действия определены в объекте `Btk_ClassCollectionApi`.

## Справочник параметров

Для реализации локальных коллекций с техническими параметрами используются:

- Трейт `Prm_ParamCalcApi` (`ru.bitec.app.prm.techparam.Prm_ParamCalcApi`).

- Абстрактное отображение `Prm_CalcTechOpParamAbsAvi` (`ru.bitec.app.prm.techparam.Prm_CalcTechOpParamAbsAvi`).

### Prm_ParamCalcApi

Трейт обеспечивает функциональность заполнения и расчёта параметров.

Типичные атрибуты коллекции:

- `idTechParameter` — ссылка на параметр `Prm_TechParameter`.

- `idRefTable` — ссылка на таблицу значений `Prm_RefTable`.

- `nValue`, `sValue`, `dValue` — числовое, строковое, датовое значения.

- `bManualInput` — признак ручного ввода.

#### Пример реализации

    class Mnf_MCOperParamApi extends Mnf_MCOperParamDpi[Mnf_MCOperParamAro, Mnf_MCOperParamApi, Mnf_MCOperParamAta]
      with Prm_ParamCalcApi[EntityAbst, java.lang.Long, Mnf_MCOperParamAro] {

      override protected def entityAta: Mnf_MCOperParamAta = Mnf_MCOperParamAta

      override lazy val apiParent = Mnf_MCOperApi().asInstanceOf[SApi[AnyRef, Aro[_ <: AnyRef]]]

      override def getsValue(rop: ApiRop): NString = rop.get(_.sValue)
      override def getnValue(rop: ApiRop): NNumber = rop.get(_.nValue)
      override def getdValue(rop: ApiRop): NDate = rop.get(_.dValue)
      override def getidValue(rop: ApiRop): NLong = rop.get(_.idValue)

      override def setidTechParam(rop: ApiRop, value: NLong): Unit = setidTechParameter(rop, value)
      override def getidTechParam(rop: ApiRop): NLong = rop.get(_.idTechParameter)

      override def getidRefTable(rop: ApiRop): NLong = rop.get(_.idRefTable)

      override def getidCalcFormulaByParent(ropParent: AnyRop): NLong =
        ropParent.asInstanceOf[Mnf_MCOperApi#ApiRop].get(_.idCalcFormula)

      override def isManualInput(rop: ApiRop): Boolean = rop.get(_.bManualInput).toBoolean
    }

Если какие-либо атрибуты не используются, их геттеры можно вернуть как `null`, сеттеры — как `Unit()`.

#### Дополнительные методы

- `setParamValueRichAnyRef` — установка значения типа `RichAnyRef`.

- `getParamValue` — получение значения параметра.

- `clearAllValues` — очистка всех значений.

- `fillByParent` — заполнение по формуле от родителя.

- `getsParamsCodeAndValueByParent` — строка вида `(код: значение)`.

### Prm_CalcTechOpParamAbsAvi

Абстрактное отображение содержит два функциональных трейта:

#### Default_Calc

Используется для расчёта параметров по формуле без сохранения значений.

Примечание

Пример: `Mct_TechOpParamAvi.List_idOperCardOperationForCalculate`.
Интерфейс: Управление данными об изделии (Судостроение) → Технология → Справочник операционных карт → Закладка Операции → Проверка формул по параметрам.

Для использования:

- Унаследуйтесь от `Prm_CalcTechOpParamAbsAvi`.

- Переопределите `getFormula` и `getParams`.

#### SavedParamsCalc

Используется для коллекций с сохраняемыми значениями. Может работать вместе с `Prm_ParamCalcApi`.

Переопределяются:

- Сеттеры значений.

- `onRefresh`, `onRefreshItem`, `getAdditionalInfo`.

Необязательный метод `refreshValues` (по умолчанию `active = false`) — для вызова `refreshParamValByParent` и дополнительной логики.

Примечание

Примеры использования:

- `ru.bitec.app.mnf.manufCard.Mnf_MCOperTestParamAvi.List_idMcOper`

- `ru.bitec.app.mct.techproc.Mct_TechProcNormGroupParamAvi.List_idTechProcNorm`