Дискретный доступ
Contents
Дискретный доступ#
Дискретный доступ позволяет выдавать привилегии в рамках объектов классов или записей в администрируемой выборке.
Настройка привилегии#
Административный объект#
Открыть карточку
Адм. объекта
Установить признак
Дискретный доступ
Перейти на закладку
Дискретные ограничения доступа
Создать
Дискретное ограничение
.
Дискретное ограничение доступа#
Создать новую запись или встать на запись для редактирования
Указать уникальное в рамка адм. объекта имя и наименование
Настроить тип правила
Настроить параметры правила.
На закладке
Скрипт для фильтрации объектных привилегий
написать sql-запрос, который будет фильтровать списки объектовНа закладке
Скрипт проверки строк по объектному кешу
написать jexl-скрипт, который будет по rop-у объекта или строке выборки возвращать признак, что условие выполнилось для этого объекта.
Тип правила#
Доступны 3 варианта типа правила:
Примитивное
Составное
Без параметров
Примитивное правило#
Состоит из одного параметра.
При анализе прав пользователя со всех его ролей будут собраны значения параметров и собраны в один массив примитивных значений.
Например для числового правила будет собран массив вида: [10, 20, 30]
Составное правило#
Состоит из нескольких параметров.
При анализе прав пользователя используется следующий алгоритм:
Для каждого набора значений, указанных на роли, формируется json-объект вида:
{ <ИД параметра 1>: [<Массив указанных значений>], <ИД параметра 2>: [<Массив указанных значений>], ... <ИД параметра n>: [<Массив указанных значений>] }
Каждая роль может обладать несколькими наборами значений на одно правило. По этому результатом агрегации настроенных значений на роли будет массив, содержащий объекты, указанные в п.1:
[ {json-объект для набора 1}, {json-объект для набора 2}, ... {json-объект для набора n}, ]
При агрегации прав пользователя:
со всех ролей анализируются массивы, описанные в п.2
в json-е заменяются ИД параметров на их имена
каждый элемент массива приводится к строке
собирается результирующий массив, содержащий уникальные строки.
Таким образом исключаются дублирующие настройки на ролях.
Пример агрегации прав пользователя:
[
{
"paramName1": ["a", "b", "c"],
"paramName2": [1, 2, 3]
},
{
"paramName1": ["c", "d", "e"],
"paramName2": [3, 4, 5]
}
]
Правило без параметров#
Не содержит параметров.
При анализе прав пользователя, если хотя на одной роли будет правило без параметров, оно будет проверяться.
Параметры правила#
Позволяют настроить тип данных и ссылочность для значений, которые будут указаны на ролях.
Если правило примитивное, то у него доступен для настройки только один параметр, для составного правила доступны несколько параметров.
Скрипт для фильтрации объектных привилегий#
Используется для фильтрации списков объектов, через наложение макроса универсального фильтра &DefUniFltMacros
.
Доступные макросы внутри текста скрипта:
(&<Имя атрибута>)
Будет заменено на указанное имя атрибута. Например,t.id
Для фильтрации доступны все атрибуты дата-сета выборки шапки БО.(¶ms)
Массив строк, в котором будут параметры, собранные со всех ролей пользователя.(&CurrentUserID)
Будет заменено на ИД текущего пользователя.(&CurrentUserName)
Будет заменено на имя текущего пользователя.
Запрос чаще всего представляет из себя exist
, в котором джойнится таблица класса, и через массив значений накладываются условия фильтрации.
Скрипт проверки строк по объектному кешу#
Используется для проверки ограничения по объектам, используя объектный кеш.
Представляет из себя jexl-скрипт
, который возвращает true
, если объект проходит условие, и false
- если не проходит.
Доступные переменные:
row
\Если адм. объект создан по классу, то в этой переменной будет
rop
проверяемого объекта. Это не исходныйrop
, а его оберткаJexlRop
, которая позволяет обращаться к полям объекта.Совет
Для получения исходного
rop
воспользуйтесь следующим примером://в переменной jexlRop находится объект класса JexlRop var rop = jexlRop.data()
Если адм. объект создан не по классу, то здесь будет json-представление строки дата-сета выборки.
params
массив значений параметров, собранных со всех ролей пользователя.если правило примитивное - то будет содержать примитивы (строка или число)
если правило составное - то будет содержать строки, каждая из которых - json
Роль#
Открыть карточку роли или выбрать ее в списке;
перейти на закладку
Дискретный доступ
;создать новую запись, выбрав адм. объект;
указать значение параметров для ограничений;
сопоставить объектные и элементарные привилегии с нужным значением параметров ограничений, заполнив поле
Ограничение дискретного доступа
Ограничение доступа к объектам класса.#
Выдается через объектные привилегии с системными именами edit#
и view#
Совет
Если таких привилегий нет у адм. объекта, то выполните его синхронизацию.
Дискретные ограничения применяются только, если:
это главная выборка адм. объекта (шапка БО);
это не супер-пользователь;
к адм. объекту приминаются настройки администрирования;
адм. объект имеет признак
Дискретный доступ
.
Определение объектов для проверки дискретных прав#
При проверке дискретных привилегий строки, в контексте которых требуется проверить наличие прав, определяются методом acRows
Алгоритм работы метода:
Если выборка принадлежит классу (
thisApi() != null
), то для всех выделенных записей через поле первичного ключа загружаютсяпровайдеры строк
, из них через полеgidRoot_dz
определяются шапки БОЕсли выборка не принадлежит классу (
thisApi() == null
), то по всем выделенным строкам собирается json-массив, содержащий на каждую строку json-объект, в котором ключ - имя атрибута, значение - значение атрибута.
Ограничение списков#
Используя значения параметров всех ролей и настроенные «Скрипты для фильтрации объектных привилегий» формируется условие ограничения и накладывается фильтрация через макрос &DefUniFltMacros
.
Ограничение открытия карточек#
На открытие карточки используя значения параметров всех ролей выполняется jexl-скрипт
, настроенный в Скрипт проверки строк по объектному кешу
. Если у пользователя нет прав на объект, то будет выдана ошибка.
Ограничение на редактирование объектов#
На beforeEdit
или delete
проверяется наличие привилегии edit#
(выполняется jexl-скрипт
, настроенный в Скрипт проверки строк по объектному кешу
). Если у пользователя нет прав на объект, то будет выдана ошибка.
Ограничение на объектные привилегии#
Если для объектной привилегии указано Ограничение дискретного доступа
, то такая привилегия может быть проверена только в контексте какого-либо объекта.
Для проверки объектных привилегий используется метод Btk_AdminPkg().hasObjPriv
.
Пример:
if (Btk_AdminPkg().hasObjPriv("SomeObjectName", "SomePrivName", Seq(rop))) {
//код, выполняемый при наличии привилегии
}
Если для привилегии, имеющей ограничение, выполнить проверку без передачи объектов, то будет выдана ошибка.
Ограничение на элементарные привилегии#
Для элементарной привилегии может быть указано ограничение дискретного доступа. Если ограничение указано, то при выполнении операции будут проверены права в контексте записей в выборке.
На загрузку выборки или перезагрузку ClassLoader
-а происходит подписка на событие выполнения операции.
При выполнении операции проверяются дискретные права на эту элементарную привилегию:
Получение
acRows
Для полученных строк выполняется
jexl-скрипт
, настроенный вСкрипт проверки строк по объектному кешу
Если прав нет, то выдается ошибка.
Примеры скриптов#
Примитивное правило по атрибуту класса#
Правило значимое, тип данных строка. Фильтрация по like атрибута sCode
Скрипт для фильтрации объектных привилегий:
select 1
from RplTst_ClassTree tt
join (
select cast(json_array_elements_text(cast((¶ms) as json)) as varchar) as sCode
) as codes
on tt.sCode like codes.sCode
where tt.id = (&id)
Скрипт проверки строк по объектному кешу:
for (p: params) {
if (row.sCode != null && p != null) {
if (like(row.sCode, p)) {
return true;
}
}
}
Примитивное правило по атрибуту коллекции#
Правило ссылочное на Btk_Group
. Фильтрация по прямому вхождению объекта в группу (фильтрация коллекции Btk_ObjectGroup
).
Скрипт для фильтрации объектных привилегий:
select 1
from Rpltst_TestGroup tt
join Btk_ObjectGroup og
on tt.gid = og.gidSrcObject
join (
select cast(json_array_elements_text(cast((¶ms) as json)) as int8) as id
) as params
on og.idGroup = params.id
where tt.id = (&id)
Скрипт проверки строк по объектному кешу:
for (p: params) {
var rops = toJRops(Btk_ObjectGroupApi.byParent(row.data())).asList();
if (p != null) {
for (r: rops) {
if (r.idGroup == p) {
return true;
}
}
}
}
Примитивное правило по адм. объекту, созданному не по классу (произвольная выборка)#
Правило значимое, тип данных строка. Фильтрация регистронезависимая по like поля sClass
Скрипт для фильтрации объектных привилегий:
select 1
from json_array_elements_text(cast((¶ms) as json)) as p
where upper((&sClass)) like upper(p)
Скрипт проверки строк по объектному кешу:
for (p: params) {
if (row.sClass != null && p != null) {
if (like(row.sClass.toUpperCase(), p.toUpperCase())) {
return true;
}
}
}
Составное правило по 3 атрибутам класса#
Параметры правила:
dDate
- Значимый, тип данных дата.nNumber
- Значимый, тип данных числоsCaption
- Значимый, тип данных строка
Фильтрация отбирает записи у которых дата меньше указанной, число равно указанному, и Наименование по like регистронезависимо совпадает с указанной
Скрипт для фильтрации объектных привилегий:
select 1
from RplTst_AllDbTypes tt
where tt.id = (&id)
and exists (
select 1
from (
select v -> 'dDate' as dDate
,v -> 'nNumber' as nNumber
,v -> 'sCaption' as sCaption
from json_array_elements(cast((¶ms) as json)
) as v
) p
where exists (
select 1
from json_array_elements_text(p.dDate) pp
where tt.dDate <= to_timestamp(pp, 'DD.MM.YYYY HH24:MI:SS')
)
and exists (
select 1
from json_array_elements_text(p.nNumber) pp
where tt.nNumber = cast(pp as numeric)
)
and exists (
select 1
from json_array_elements_text(p.sCaption) pp
where upper(tt.sCaption) like upper(pp)
)
)
Скрипт проверки строк по объектному кешу:
for (p: params) {
var jObj = toJObject(p);
var res = true
//проверка даты
if (res) {
res = false
var aValues = jObj.childJArray("dDate");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getDate(i);
if (row.dDate <= value) {
res = true;
}
i = i + 1;
}
}
//проверка числа
if (res) {
res = false
var aValues = jObj.childJArray("nNumber");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getNumber(i);
if (row.nNumber == value) {
res = true;
}
i = i + 1;
}
}
//проверка наименования
if (res) {
res = false
var aValues = jObj.childJArray("sCaption");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getString(i);
if (row.sCaption != null && value != null) {
if (like(row.sCaption.toUpperCase(), value.toUpperCase())) {
res = true;
}
}
i = i + 1;
}
}
if (res) {
return true;
}
}
Составное правило по атрибуту класса и коллекции#
Параметры правила:
sCaption
- Значимый, тип данных строкаidGroup
- ссылочный наBtk_Group
Фильтрация отбирает записи, у которых Наименование по like регистронезависимо совпадает с указанным, и есть прямое вхождение в группу (фильтрация коллекции Btk_ObjectGroup
).
Скрипт для фильтрации объектных привилегий:
select 1
from RplTst_TestGroup tt
where tt.id = (&id)
and exists (
select 1
from (
select v -> 'sCaption' as sCaption
,v -> 'idGroup' as idGroup
from json_array_elements(cast((¶ms) as json)) as v
) p
where exists (
select 1
from json_array_elements_text(p.sCaption) pp
where upper(tt.sCaption) like upper(pp)
)
and exists (
select 1
from Btk_ObjectGroup og
join json_array_elements_text(p.idGroup) pp
on og.idGroup = cast(pp as int8)
where og.gidSrcObject = tt.gid
)
)
Скрипт проверки строк по объектному кешу:
for (p: params) {
var jObj = toJObject(p);
var res = true
//проверка наименования
if (res) {
res = false
var aValues = jObj.childJArray("sCaption");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getString(i);
if (row.sCaption != null && value != null) {
if (like(row.sCaption.toUpperCase(), value.toUpperCase())) {
res = true;
}
}
i = i + 1;
}
}
//проверка группы
if (res) {
res = false
var rops = toJRops(Btk_ObjectGroupApi.byParent(row.data())).asList();
var aValues = jObj.childJArray("idGroup");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getLong(i);
for (r: rops) {
if (r.idGroup == value) {
res = true;
}
}
i = i + 1;
}
}
if (res) {
return true;
}
}
Составное правило по 2 атрибутам адм. объекта, созданного не по классу (произвольная выборка)#
Параметры правила:
sClass
- Значимый, тип данных строкаidRefClass
- ссылочный наBtk_Class
Фильтрация отбирает записи, у которых поле sClass
по like регистронезависимо совпадает с указанным, и поле idRefClass
совпадает с указанным
Скрипт для фильтрации объектных привилегий:
select 1
from (
select v -> 'sClass' as sClass
,v -> 'idRefClass' as idRefClass
from json_array_elements(cast((¶ms) as json)) as v
) p
where exists (
select 1
from json_array_elements_text(p.sClass) pp
where upper((&sClass)) like upper(pp)
)
and exists (
select 1
from json_array_elements_text(p.idRefClass) pp
where (&idRefClass) = cast(pp as int8)
)
Скрипт проверки строк по объектному кешу:
for (p: params) {
var jObj = toJObject(p);
var res = true
//проверка sClass
if (res) {
res = false
var aValues = jObj.childJArray("sClass");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getString(i);
if (row.sClass != null && value != null) {
if (like(row.sClass.toUpperCase(), value.toUpperCase())) {
res = true;
}
}
i = i + 1;
}
}
//проверка idRefClass
if (res) {
res = false
var aValues = jObj.childJArray("idRefClass");
var i = 0
while(i < aValues.size() && !res) {
var value = aValues.getLong(i);
if (row.idRefClass == value) {
res = true;
}
i = i + 1;
}
}
if (res) {
return true;
}
}