Как подключить регистр накопления к производительному RLS в БСП 3 и избежать сброса прав при обновлении?

Программист 1С v8.3 (Управляемые формы) 1С:Комплексная автоматизация IT и автоматизация бизнеса
← На главную

При внедрении производительного (универсального) механизма ограничения прав доступа на уровне записей (RLS) в конфигурациях на базе Библиотеки стандартных подсистем (БСП 3, например, в «1С:Комплексная автоматизация 2» или «1С:ERP») разработчики часто сталкиваются с неочевидным поведением системы для добавленных регистров накопления. В отличие от документов и справочников, шаблоны ограничений для регистров требуют обязательного наличия предопределенного элемента в служебном справочнике ИдентификаторыОбъектовМетаданных. Попытка вынести этот предопределенный элемент в расширение конфигурации приводит к тому, что при первом же обновлении конфигурации или регламентном обновлении служебных данных привязка слетает, создаются пустые дубли и доступ блокируется.

Разберем подробно механизм возникновения этой ошибки и рассмотрим надежные варианты ее устранения.

Почему возникает конфликт при использовании расширения конфигурации

Проанализируем архитектуру работы механизма RLS в БСП для регистров. В типовом шаблоне ограничения прав #ДляРегистра(...) текст формируемого запроса обращается к метаданным через платформенную конструкцию ЗНАЧЕНИЕ(...), например:

ЗНАЧЕНИЕ(Справочник.ИдентификаторыОбъектовМетаданных.РегистрНакопленияМойРегистр)

Конструкция ЗНАЧЕНИЕ требует строгого указания предопределенного элемента метаданных конфигурации. Когда мы заимствуем справочник ИдентификаторыОбъектовМетаданных в расширение и создаем там предопределенный элемент, поведение платформы и процедур БСП входит в противоречие:

  1. Платформа 1С инициализирует предопределенный элемент из расширения, однако значения его реквизитов (таких как ПолноеИмя, Имя, Синоним) остаются незаполненными в информационной базе.
  2. Процедура обновления служебных данных БСП (Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника()) обходит метаданные основной конфигурации и ищет элемент справочника по реквизиту ПолноеИмя = "РегистрНакопления.МойРегистр".
  3. Поскольку у предопределенного элемента из расширения эти поля не инициализированы типовым кодом, процедура БСП считает объект отсутствующим и создает новый обычный (непредопределенный) элемент справочника.
  4. В результате шаблон RLS по-прежнему ссылается на предопределенный элемент с пустыми данными, а реальные ключи доступа привязываются к обычному элементу. Это ломает всю логику фильтрации данных.
  5. Если вручную связать созданный элемент через реквизит ИмяПредопределенныхДанных, система временно начинает работать, но любая процедура обновления вспомогательных данных БСП снова сбрасывает эту привязку.

Способ 1. Добавление предопределенного элемента в основную конфигурацию (штатный метод)

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

Разберем по шагам, как выполнить настройку:

  1. В дереве метаданных основной конфигурации откроем свойства справочника ИдентификаторыОбъектовМетаданных и включим возможность изменения с сохранением поддержки.
  2. В ветке предопределенных элементов справочника добавим новый элемент с именем вида РегистрНакопленияИмяВашегоРегистра (например, РегистрНакопленияаа_МойРегистр).
  3. Обновим конфигурацию базы данных.
  4. Запустим сеанс в режиме «1С:Предприятие» и выполним обработку обновления служебных данных БСП (обработка ОбновлениеВспомогательныхДанных или запуск с параметром ЗапуститьОбновлениеИнформационнойБазы). Обработчик БСП обнаружит предопределенный элемент в основной конфигурации, корректно заполнит все его реквизиты и свяжет с метаданными.

Важно: При последующих типовых обновлениях конфигурации («Сравнить и объединить с файлом обновления») добавленные разработчиком предопределенные элементы в справочнике ИдентификаторыОбъектовМетаданных не удаляются и не затираются, если не снимать с них галочки объединения.

Способ 2. Программная корректировка идентификатора через модуль расширения

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

Для этого перехватим процедуру обновления идентификаторов в модуле менеджера справочника ИдентификаторыОбъектовМетаданных через расширение с директивой &После:


&После("ОбновитьДанныеСправочника")
Процедура Расш1_ОбновитьДанныеСправочника(ПараметрыОбновления = Неопределено)
    ЭлементСсылка = Справочники.ИдентификаторыОбъектовМетаданных.НайтиПоРеквизиту("ПолноеИмя", "РегистрНакопления.аа_МойРегистр");
    Если ЗначениеЗаполнено(ЭлементСсылка) И НЕ ЭлементСсылка.Предопределенный Тогда
        ОбъектИдентификатор = ЭлементСсылка.ПолучитьОбъект();
        ОбъектИдентификатор.ИмяПредопределенныхДанных = "РегистрНакопленияаа_МойРегистр";
        Попытка
            ОбъектИдентификатор.Записать();
        Исключение
            ЗаписьЖурналаРегистрации("RLS.ОбновлениеИдентификаторов", УровеньЖурналаРегистрации.Ошибка,,, ОписаниеОшибки());
        КонецПопытки;
    КонецЕсли;
КонецПроцедуры

В таком варианте после каждого выполнения обновления вспомогательных данных БСП система самостоятельно пропишет имя предопределенного элемента в реквизит ИмяПредопределенныхДанных, предотвратив сбой расчета прав доступа.

Способ 3. Перенос регистра в расширение с использованием справочника идентификаторов расширений

Если ставится цель полностью изолировать доработку от основной конфигурации, перенесем сам регистр накопления в расширение. В архитектуре БСП для объектов, созданных в расширениях, предусмотрен отдельный механизм:

  1. Создадим регистр накопления непосредственно в расширении.
  2. Предопределенный элемент добавим в специальный справочник ИдентификаторыОбъектовРасширений внутри расширения.
  3. В тексте ограничения доступа роли изменим имя источника метаданных в параметрах шаблона:

#ДляРегистра("ИдентификаторыОбъектовРасширений.РегистрНакопленияаа_МойРегистр", "Партнер", ...)

В этом сценарии механизмы синхронизации БСП обрабатывают объекты расширений по отдельному регламенту и не конфликтуют со справочником основной конфигурации.

Контрольный чек-лист для проверки RLS регистра накопления

Чтобы универсальное ограничение доступа гарантированно заработало без ошибок, убедимся в выполнении следующих настроек:

  1. Определяемые типы: Проверим, что тип РегистрНакопленияНаборЗаписей.аа_МойРегистр включен в определяемый тип ВладелецЗначенийКлючейДоступа (или ВладелецЗначенийКлючейДоступаРегистр / ВладелецЗначенийКлючейДоступаНаборЗаписей в зависимости от релиза БСП).
  2. Регистрация метаданных: В общем модуле УправлениеДоступомПереопределяемый в процедуре ПриЗаполненииСписковСОграничениемДоступа зарегистрируем регистр: Списки.Вставить(Метаданные.РегистрыНакопления.аа_МойРегистр.ПолноеИмя());
  3. Модуль менеджера регистра: В модуле менеджера созданного регистра определим экспортную процедуру описания логики RLS:
    
    Процедура ПриЗаполненииОграниченияДоступа(Ограничение) Экспорт
        Ограничение.Текст =
            "РазрешитьЧтениеИзменение
            |ГДЕ
            |    ЗначениеРазрешено(Партнер)";
    КонецПроцедуры
    
  4. Индексация измерений: Убедимся, что для измерения Партнер включено свойство Индексировать или Индексировать с дополнительным упорядочиванием, так как поля, по которым строятся ключи доступа, требуют обязательной индексации для исключения деградации производительности СУБД.
  5. Валидация: Воспользуемся встроенной в БСП внешней обработкой ПроверкаВнедренияБСП.erf. Отчет по подсистеме «Управление доступом» покажет любые несоответствия в типах, шаблонах или идентификаторах метаданных.
← На главную