Политика безопасности
Политика безопасности определяет, к каким элементам системы — формам в навигаторе, свойствам форм и т.д. — имеет доступ каждый пользователь. Доступ задаётся не отдельному пользователю, а ролям. Пользователю назначаются главная роль и, при необходимости, дополнительные роли. Итоговое право доступа складывается по всем ролям пользователя: оно есть, если хотя бы одна роль явно разрешает (Разрешить); иначе — если ни одна явно не запрещает (Запретить); в остальных случаях (роли указывают По умолчанию) — доступ есть. Для каждой роли отдельно настраиваются доступ к формам в навигаторе (Разрешить / Запретить / По умолчанию) и доступ к свойствам форм (Просмотр / Изменение / Переход / Групповая корректировка).
Настройка ролей пользователя
В системе используется понятие Пользователь. Пользователь - это объект, который содержит информацию об одном человеке, работающим в системе.
Функциональные возможности Пользователя определяются его Ролью или списком Ролей. Роль устанавливает какие формы, поля и кнопки будут доступны.
В карточке Пользователя (Администрирование > Доступ > Пользователи) указывается Главная роль, при необходимости назначаются Дополнительные роли (рис. 1.).

Рис. 1. Назначение сотруднику ролей
Настройка доступа к элементам системы
Настройка политики безопасности для каждой Роли осуществляется в меню Администрирование > Доступ > Политика безопасности. На данной форме определяется состав Ролей – кнопки Добавить, Удалить, Копировать. При копировании Роли, копируются и все права.

Рис. 2. Настройка политики безопасности по ролям
Для каждой Роли нужно указать наименование (Имя) и код (Код), а также можно задать следующие параметры:
Показывать расширенное описание свойств во всплывающих подсказках– при наведении на на свойство, кнопку, поле и т.д. во всплывающем окне будет отображаться описание.

Рис. 3. Расширенное описание сво-ва
Открывать форму один раз– при выборе в навигаторе уже открытой на рабочем столе формы пользователь перейдет на нее, дополнительное окно открыто не будет. Если есть потребность открыть несколько окон с данной формой,необходимо удерживать клавишуCtrlпри вызове формы . Данное ограничение можно установить и для конкретного пользователя на вкладкеПользователи.Автоматически переподключаться при потере соединения– при разрыве соединения с сервером приложений клиент будет повторно подключаться к нему автоматически, без подтверждения пользователя.Формы при открытии клиента– для роли можно определить формы, которые будут открыты сразу после входа пользователя в программу. Для этого на вкладкеНавигатор, в полеПорядокпри открытии клиента для нужных форм указывается номер по порядку (см. рис. 2).Развернуть на весь экран при открытии клиента– при входе в систему у пользователя будет отображено только рабочее окно на весь экран без меню навигации.Отключить роль– доступы, настроенные для роли не будут применяться.
Вкладка Навигатор
На вкладке Навигатор отображаются все существующие в системе Формы. Они отображаются либо в виде дерева, либо в виде таблицы. В древовидном представлении список форм отражает структуру имеющихся модулей и наиболее удобен для управления доступом к ним.
Для каждой формы в колонке Доступ можно установить один из трех статусов:
Разрешить - форма будет доступна пользователю
Запретить - форма будет недоступна пользователю
По умолчанию - форма по умолчанию будет доступна пользователю с данной ролью. Если у пользователя несколько ролей, форма будет доступна если среди этих ролей есть Разрешить или нет Запретить.

Рис. 4. Пример настройки доступа к формам
Статус, установленный для ветви дерева, автоматически действует на дочерние ветви. При необходимости, дочерней ветви можно установить другой статус доступа, в таком случае статус родительского элемента будет подсвечен серым фоном, чтобы пользователь мог визуально определить, что в структуре данной ветви есть элементы с отличным статусом допуска. В соответствии с настройками, приведенными на рис. 4 пользователь в модуле Розничная торговля не будет видеть и не сможет работать с блоком форм CRM.
Рис. 5. Результат настройки доступа к формам
Вкладка Свойства
На вкладке Свойства отображены все существующие в системе свойства всех форм - это поля, кнопки, чекбоксы и т.д. Они также как и формы имеют иерархическое (Дерево) и табличное (Таблица) представление.
Для роли может быть установлен один из трех статусов доступа на действия в отношении свойств:
Просмотр - для пользователя свойство отображается или нет;
Изменение - пользователь может или нет изменить значение свойства;
Редактирование объекта - может ли пользователь вызвать событие редактирования объекта этого свойства. При запрете пункт Перейти по ссылке скрыт из контекстного меню свойства, и событие вызвать нельзя.
Устанавливается статус доступа к свойствам аналогично доступу к формам. Однако, учитывая большое количество разнообразных свойств в приложении, на вкладке Свойства удобно определить уровень доступа к группе свойств, соответствующей верхним ветвям дерева, либо просмотреть статус допусков роли в разрезе свойств.

Рис. 6. Управление правами доступа к свойствам
Чтобы определить уровень доступа к конкретному свойству на форме удобно воспользоваться контекстным меню. Для этого необходимо нажать правой клавишей мыши на кнопку или поле, доступ к которому нужно настроить и в контекстном меню выбрать Настройка политики свойства. Откроется окно Политики безопасности, в котором можно установить уровень доступа к свойству для каждой роли или для нескольких, затем нажать ОК. Все изменения, внесенные и сохраненные через контекстное меню, также отображаются на вкладке Свойства формы Политика безопасности.

Рис. 7. Вариант настройки доступа к отдельному свойству
Статусы Просмотр и Изменение связаны между собой, и связь настраивается двумя рабочими параметрами. Действие, изменение которого роли явно запрещено, по умолчанию ей и не показывается. disableActionForbidViewOnForbidChange (по умолчанию false) эту связь снимает, и запрещённое к выполнению действие остаётся видимым. Второй параметр, disableDefaultChangeOnReadOnlyChange (по умолчанию false), касается обработчиков изменения, которые на самом деле ничего не меняют, например выбора значения: по умолчанию такой обработчик считается не изменением, а навигацией, и статус Изменение к нему не применяется, а значение true заставляет проверять его наравне с обычными изменениями. На встроенную роль Только чтение оба параметра не влияют — для неё и связь статусов, и пропуск проверки действуют всегда.
Кроме уровней доступа, в блоке Параметры окна Политика безопасности задаются настройки самого свойства, общие для всех ролей. Отметка Не может быть null добавляет для свойства ограничение определенности: если все параметры свойства принадлежат своим классам, его значение не должно быть NULL. Ограничение создается при запуске сервера приложений, поэтому отметка начинает действовать только после его перезапуска. Для свойства, чей stats[Property] не меньше порога maxStatsProperty[], например для остатка на дату и время, ограничение не создается, а в лог start выводится предупреждение.
Вкладка Пользователи
На этой вкладке отображены все пользователи системы, которым назначена выделенная роль в качестве главной либо дополнительной.

Рис. 8. Вкладка "Пользователи"
Все изменения сделанные на форме Политика безопасности активизируются после очередного входа пользователя в систему.
По умолчанию в платформе предустановлены 4 роли:
- Администратор (admin)
- Только чтение (readonly)
- По умолчанию (default)
- Самостоятельная регистрация (selfRegister)
Следует помнить, что при установке для формы или свойства доступа По умолчанию применяется разрешение или запрет, в зависимости от установленных дополнительных ролей. Установленный доступ По умолчанию не применяет значение, указанное в настройках роли По умолчанию. Чтобы для пользователя действовали доступы, настроенные в роли По умолчанию, ему необходимо назначить эту роль.
Создание пользователей и ролей из кода
Пользователи, роли и назначения ролей — обычные объекты и свойства системных модулей Authentication и Security, поэтому всё, что настраивается на описанных выше формах, можно задать и в коде приложения — например, при заполнении начальных или демонстрационных данных. Такую инициализацию обычно подключают к обработчику события запуска, например onStarted[]:
IF NOT userRoleSID('manager') THEN
NEW r = UserRole {
name(r) <- 'Manager';
sid(r) <- 'manager';
}
IF NOT customUserLogin('jsmith') THEN
NEW u = CustomUser {
login(u) <- 'jsmith';
firstName(u) <- 'John';
lastName(u) <- 'Smith';
email(u) <- 'jsmith@company.com';
setSHA256Password(u, 'secret');
mainRole(u) <- userRoleSID('manager');
in(u, userRoleSID('readonly')) <- TRUE;
}
- Имя пользователя
name[Contact]вычисляется какfirstName[Contact]иlastName[Contact], соединённые пробелом, поэтому записываются именно эти два свойства, а не само имя. - Пароль хранится в виде хеша в
sha256Password[CustomUser]. ДействиеsetSHA256Password[CustomUser, STRING]хеширует переданный пароль и записывает хеш туда. - Главная роль записывается в
mainRole[User], а дополнительная роль назначается записьюTRUEвin[CustomUser, UserRole].userRoleSID[STRING]находит роль по коду, аcustomUserLogin[ISTRING]— пользователя по логину. При сохранении изменений созданному пользователю автоматически назначается также дополнительная рольdefault(а при логинеadmin— ещё и рольadmin). - Объект приложения (например, сотрудник) связывается со своим пользователем обычным первичным свойством, объявляемым в приложении:
user = DATA CustomUser (Employee);.
Права записываются так же — в хранимые свойства прав модуля Security: dataPermission[UserRole, NavigatorElement] для элемента навигатора, dataPermissionView[UserRole, ActionOrProperty] и остальные типы прав для свойства или действия, — с ключами-объектами модуля Reflection, которые navigatorElementCanonicalName[STRING], propertyCanonicalName[STRING] и actionCanonicalName[STRING] находят по каноническому имени. Эти объекты появляются только после синхронизации метаданных при запуске, которая выполняется после onStarted[] (события запуска), поэтому права заполняют в onFinallyStarted[]: раньше поиск элемента, добавленного после предыдущего запуска, возвращает NULL, а запись по ключу NULL ничего не меняет.
onFinallyStarted() + {
dataPermission(userRoleSID('manager'), navigatorElementCanonicalName('HR.salaries')) <- Permission.forbid;
dataPermissionView(userRoleSID('manager'), propertyCanonicalName('HR.salary[HR.Employee]')) <- Permission.forbid;
}