7.7.3. Администрирование#

7.7.3.1. Описание раздела#

Скрипты и запросы для администрирования прав доступа: диагностика дискретного доступа, проверка привилегий, коррекция параметров правил и удаление некорректных настроек.

7.7.3.2. Скрипты#

7.7.3.2.1. Диагностика параметров правила дискретного доступа#

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

Место применения: Приложение "Администратор" > Настройки > Администрируемые объекты > [Администрируемый объект] > Редактировать > Дискретные ограничения доступа

Внимание

Перед выполнением замените ID правила, роли, параметра и адм.объекта на актуальные значения.

Тип: SQL-запрос

select aror.scode as RuleCode, arord.id as idRuleElement, arorp.sheadline_dz, arorp.jparamvalue from btk_acroleobjrule aror
join btk_acroleobjruledet arord on arord.idacroleobjrule = aror.id
join btk_acroleobjruleparam arorp on arorp.idacroleobjruledet = arord.id
join btk_acobjectrule aor on arord.idacobjrule = aor.id
where aror.id = 30652 -- id правила для конкретной роли
and aror.idacrole = 26754 -- id роли, для которой задан параметр правила
and arorp.id = 35052 -- id позиции правила для конкретной роли
and aor.idacobject = 12046; -- id адм.объекта

7.7.3.2.2. Проверка прав роли на редактирование проводок#

Используется чтобы определить, имеет ли указанная роль право на редактирование (включая удаление) заданных проводок. Выводит список счетов, по которым права отсутствуют. Применяется при расследовании ошибок доступа пользователей.

Место применения: Приложение "Администратор" > Настройки > Администрируемые объекты > [Администрируемый объект] > Редактировать > Дискретные ограничения доступа

Внимание

Перед выполнением замените id проводки (111412) и id пользователя (59052) на актуальные значения.

Тип: SQL-запрос

with acc as (
    select distinct(unnest(array_agg(t.idAccDeb) || array_agg(t.idAccCr))) as idAcc
    from Act_Trans t
    where t.id in (111412)
),
role as ( 
    select ar.idAcc
    ,ar.idAccGroup
    ,ar.gid as gidrole
    from Btk_User u
    join Btk_AcUserGrant ug on ug.idUser = u.id
    join Btk_acProfileGrant pg on pg.idAcProfile = ug.idAcProfile
    join Act_RoleAccRight ar on ar.idAcRole = pg.idAcRole
    where u.id = 59052
    and ar.bDelete = 1
)

select a.sCode as sAccMC
,r.gidrole as gidrole
from (
    select t.idAcc
    from acc t
    except
    select t.idacc
    from (
        select r.idAcc
        from role r
        where r.idAcc in (select t.idAcc from acc t)
        union
        select a.id as idAcc
        from role r
        join Bs_Acc a on a.idAccGroup = r.idAccGroup
        where a.id in (select t.idAcc from acc t)
    ) t
) t
join Bs_Acc a on a.id = t.idAcc
join role r on r.idAcc = a.id
order by a.sCode

7.7.3.2.3. Коррекция параметра правила дискретного доступа#

Используется чтобы удалить некорректное значение из JSON-массива параметра правила дискретного доступа (например, несуществующий ID). Применяется при постобработке после миграции или ошибок настройки.

Место применения: Приложение "Администратор" > Настройки > Администрируемые объекты > [Администрируемый объект] > Редактировать > Дискретные ограничения доступа

Внимание

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

Тип: JEXL-скрипт

var idvAcObject = Btk_AcObjectApi.findByMnemoCode('Pm_AdvRep'); // Адм.объект
var idvAcRole = Btk_AcRoleApi.findByMnemoCode('tstsud8.Documents'); // Роль
var idvAcRoleObjRule = 30652l; // Правило роли
var idvAcRoleObjRuleParam = 35052l; // Параметры позиции правила роли

if (!idvAcObject) {
    dialogs.showMessage("Не найден адм.объект с мнемокодом 'Pm_AdvRep'");
}
if (!idvAcRole) {
    dialogs.showMessage("Не найдена роль с мнемокодом 'tstsud8.Documents'");
}
if (!idvAcRoleObjRule) {
    dialogs.showMessage("Не найдено правило роли с мнемокодом 'Pm_AdvRep34'");
}

var idvParams = sql(`
select
arorp.id as id
from btk_acroleobjrule aror
join btk_acroleobjruledet arord on arord.idacroleobjrule = aror.id
join btk_acobjectrule aor on arord.idacobjrule = aor.id
join btk_acroleobjruleparam arorp on arorp.idacroleobjruledet = arord.id
where
aor.idacobject = `+ idvAcObject +` -- id адм.объекта
and aror.idacrole = `+ idvAcRole +` -- id роли, для которой задан параметр правила
and aror.id = `+ idvAcRoleObjRule +` -- id правила для конкретной роли
and arorp.id = `+ idvAcRoleObjRuleParam +` -- id позиции правила для конкретной роли
;`).asSingle().id;

if(isNotNull(idvParams)) {
  const ropAcRoleObjRuleParam = Btk_AcRoleObjRuleParamApi.load(idvParams);
  var jPropertiesNew = [];
  var jProperties = Btk_AcRoleObjRuleParamApi.parsejParamValue(ropAcRoleObjRuleParam).asJObject();

    var jsonBuilder = "";
    var first = true;
  
    for (element : jProperties) {
      value = element.asLong();
        if (value != 429) {
            if (!first) {
                jsonBuilder = jsonBuilder + ",";
            }
            jsonBuilder = jsonBuilder + value;
            first = false;
        }
    }
    
    var jPropertiesNewString = "[" + jsonBuilder + "]";
    
Btk_AcRoleObjRuleParamApi.setjParamValue(ropAcRoleObjRuleParam, toString(jPropertiesNewString));
}

7.7.3.2.4. Удаление привилегий на уровне административного объекта#

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

Место применения: Приложение "Администратор" > Настройки > Администрируемые объекты > [Администрируемый объект] > Редактировать > Дискретные ограничения доступа

Внимание

В текущем виде содержит незавершённый массив arr = [...] и захардкоженный код объекта 'Act_MainMenuAvi' — перед использованием необходимо завершить логику и указать корректные значения.

Тип: JEXL-скрипт

var arr = [...];

var ia = sql(`
  select opg.id, opg.idacrole  from Btk_AcRoleObjPrivTypeGrant opg
  join Btk_AcObject o on o.id = opg.idacobject
                     where opg.bhasaccess = 1 and o.scode = 'Act_MainMenuAvi'
`).asList();
for(rv:ia) {
if (!arr.contains(rv.idacrole)){
	arr.add(rv.idacrole);
}
                  var rr = Btk_AcRoleApi.load(rv.idacrole);
                  Btk_AcRoleApi.unSync(rr);
                  var rop = Btk_AcRoleObjPrivTypeGrantApi.load(rv.id);
                  Btk_AcRoleObjPrivTypeGrantApi.delete(rop);
}

commit();

Btk_AcRoleGrantRegApi.lazyUpdateAll();
commit();
for(id:arr) {
Btk_UserApi.recalcPrivsMulti(Btk_AcRoleApi.getUsersByRole(id));
}


commit();

7.7.3.2.5. Пример реализации скрипта дискретного доступа#

Используется как шаблон для настройки сложных правил дискретного доступа по нескольким параметрам (бизнес-объект, тип, элементы, признаки). Позволяет протестировать логику фильтрации и отладить условия доступа к записям.

Место применения: Приложение "Администратор" > Настройки > Администрируемые объекты > [Администрируемый объект] > Редактировать > Дискретные ограничения доступа

Тип: JEXL-скрипт

if (parseIdClass(row.gid) != Pm_AdvRepApi.idClass()) {
  return true;
}

// Инициализация переменных с значениями по умолчанию
var idvDoc = row.id;
var ropDoc = null;
var idvBisObj = null;
var idvObjectType = null;
var idvAdvRepItem = [];
var bvExpAlloc = null;
var idvExpAllocBisObj = null;

// Получение значений от проверяемого объекта для проверки на соответствие параметрам
// Загружаем данные только если idvDoc не null
if (idvDoc != null) {
      ropDoc = Pm_AdvRepApi.load(idvDoc);
      // Бизнес единица авансового отчета
      idvBisObj = Pm_AdvRepApi.getAttrValue(ropDoc, 'idBisObj');
      // Тип объекта авансового отчета
      idvObjectType = Pm_AdvRepApi.getAttrValue(ropDoc, 'idObjectType');
      // Элементы позиций авансового отчета
      idvAdvRepItem = sql(`
        select det.idadvrepitem as detitem
        from pm_advrep doc
        left join pm_advrepdet det on det.idadvrep = doc.id
        where doc.id = ${idvDoc}
      ;`).asList();
      // Признак передачи затрат
      bvExpAlloc = sql(`
        select
        coalesce(cast(doc.jobjattrs_dz ->> 'bExpAllocationSng' as int8), 0) as bexpalloc
        from pm_advrep doc
        where doc.id = ${idvDoc}
      ;`).asSingle();
      // Бизнес единица дебитора
      idvExpAllocBisObj = Pm_AdvRepApi.getObjAttrValue(ropDoc, 'idPassExpBisObj');
}

// Параметры дискретного доступа
// Значения параметров для отладки (без получения от системной настройки)
//var params = sql(`
//        select
//         cast(string_to_array(translate(jObj ->> 'idBisObj', '[]', ''), ',') as bigint[]) as idBisObj
//        ,cast(string_to_array(translate(jObj ->> 'idObjectType', '[]', ''), ',') as bigint[]) as idObjectType
//        ,cast(string_to_array(translate(jObj ->> 'idAdvRepItem', '[]', ''), ',') as bigint[]) as idAdvRepItem
//        ,cast(string_to_array(translate(jObj ->> 'idExpAllocBisObj', '[]', ''), ',') as bigint[]) as idExpAllocBisObj
//        from json_object('{"idBisObj", "2", "idObjectType", "24302", "idAdvRepItem", "", "idExpAllocBisObj", "2"}') as jObj
//      ;`).asSingle();
for (p: params) {
  var jObj = toJObject(p);
  // Инициализация переменных для хранения значений параметров дискретного доступа
  var paramBisObj = null;
  var paramObjectType = null;
  var paramAdvRepItem = null;
  var paramExpAllocBisObj = null;
  
  // Значения результата проверки для случая, когда параметр дискретного доступа не задан
  var resBisObj = true;
  var resObjectType = true;
  var resAdvRepItem = false;
  var resExpAlloc = false;
  var resExpAllocBisObj = true;

// Проверки параметров дискретного доступа
// Проверка бизнес единицы
    if ((idvBisObj == null || jObj.contains("idBisObj"))) {
           paramBisObj = jObj.childJArray("idBisObj");
           if (paramBisObj.size() > 0) {
               resBisObj = false;
               var i = 0;
               while (i < paramBisObj.size() && !resBisObj) {
                      var value = paramBisObj.getLong(i);
                      if (value != null) {
                          if (idvBisObj == null || idvBisObj.toString() == value.toString()) {
                          resBisObj = true;
                            }
                          }   
                      i = i + 1;
                      }
            }
         }

// Проверка типа объекта  
    if ((idvObjectType == null || jObj.contains("idObjectType"))) {
           paramObjectType = jObj.childJArray("idObjectType");
           if (paramObjectType.size() > 0) {
               resObjectType = false;
               var i = 0;
               while (i < paramObjectType.size() && !resObjectType) {
                      var value = paramObjectType.getLong(i);
                      if (value != null) {
                          if (idvObjectType == null || idvObjectType.toString() == value.toString()) {
                          resObjectType = true;
                            }
                          }   
                      i = i + 1;
                      }
            }
         }   

// Проверка элемента
    if ((idvAdvRepItem == null || jObj.contains("idAdvRepItem"))) {
           paramAdvRepItem = jObj.childJArray("idAdvRepItem");
           if (paramAdvRepItem.size() > 0) {
              resAdvRepItem = false;
              var i = 0;
              while (i < paramAdvRepItem.size() && !resAdvRepItem) {
                  var value = paramAdvRepItem.getLong(i);
                  if (value != null) {
                    for(r:idvAdvRepItem){
                          if (r.detitem != null and r.detitem.toString() == value.toString()) {
                            resAdvRepItem = true;
                          }
                    }   
                  }
                  i = i + 1;
              }
            }         
    }  

// Проверка признака передачи затрат
    if (bvExpAlloc.bexpalloc != null && bvExpAlloc.bexpalloc != 0) {
        resExpAlloc = true;
     }

// Проверка бизнес единицы дебитора
  if ((idvExpAllocBisObj != null && jObj.contains("idExpAllocBisObj"))) {
           paramExpAllocBisObj = jObj.childJArray("idExpAllocBisObj");
           if (paramExpAllocBisObj.size() > 0) {
               resExpAllocBisObj = false;
               var i = 0;
               while (i < paramExpAllocBisObj.size() && !resExpAllocBisObj) {
                      var value = paramExpAllocBisObj.getLong(i);
                      if (value != null) {
                          if (idvExpAllocBisObj.toString() == value.toString()) {
                             resExpAllocBisObj = true;
                            }
                          }   
                      i = i + 1;
                      }
            }
         }
// Итоговая проверка параметров
// raise('resBisObj: ' + toString(resBisObj) + ' ' + 'resObjectType: ' + toString(resObjectType) + ' ' + 'resAdvRepItem: ' + toString(resAdvRepItem) + ' ' + 'resExpAlloc: ' + toString(resExpAlloc) + ' ' + 'resExpAllocBisObj: ' + toString(resExpAllocBisObj));  
  if (resBisObj == true and resObjectType == true and resAdvRepItem == false) {
    return true;
  }
  else if (resExpAllocBisObj == true and resExpAlloc == true and resObjectType == true and resAdvRepItem == false) {
    return true;
  }
  else {
    return false;
  }
}