При настройке разграничения прав доступа на уровне записей (RLS) в типовых конфигурациях поколения 1С:УПП 1.3 и 1С:Комплексная автоматизация 1.1 администраторы и разработчики часто сталкиваются с типовой проблемой. Пользователю корректно ограничивают видимость контрагентов (например, менеджер должен видеть только своих партнеров), однако при попытке ввести документ на основании другого (к примеру, создать документ «Заявка на доставку» на основании «Перемещения товаров») система блокирует действие. В окне появляется сообщение: «У пользователя недостаточно прав на выполнение операции над базой данных», а в журнале регистрации фиксируется событие Доступ. Отказ в доступе - чтение.
Выясним причину такого поведения платформы 1С и разберем по шагам, как исправить эту ошибку как штатными средствами предприятия, так и корректировкой шаблона ограничений в конфигураторе.
Проанализируем ситуацию: почему платформа требует право на чтение при создании нового документа, когда у пользователя уже есть право на добавление?
В платформе 1С:Предприятие при открытии формы нового объекта и инициализации его данных система выполняет считывание начального состояния реквизитов. Если для таблицы документа настроен RLS на чтение, накладываемый запрос выполняется еще до записи объекта. В момент создания «Заявки на доставку» из документа «Перемещение товаров» реквизит Контрагент в новом объекте остается незаполненным, то есть содержит значение ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка) либо NULL.
Посмотрим на типовой подзапрос RLS, применяемый в конфигурациях на обычных формах:
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
ПО Контрагенты.Ссылка = ТекущаяТаблица.#Параметр(1)
ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.НастройкиПравДоступаПользователей КАК НастройкиПравДоступаПользователей
ПО НастройкиПравДоступаПользователей.ОбъектДоступа = ВЫБОР
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Контрагенты)
ТОГДА ЕСТЬNULL(Контрагенты.ГруппаДоступаКонтрагента, ЗНАЧЕНИЕ(Справочник.ГруппыДоступаКонтрагентов.ПустаяСсылка))
...
Обратим внимание на конструкцию ЕСТЬNULL(Контрагенты.ГруппаДоступаКонтрагента, ЗНАЧЕНИЕ(Справочник.ГруппыДоступаКонтрагентов.ПустаяСсылка)). Если контрагент в шапке документа пустой, левое соединение со справочником не находит строку. В результате поле группы доступа контрагента оказывается NULL, а функция ЕСТЬNULL заменяет его на пустую ссылку справочника ГруппыДоступаКонтрагентов.
Если для группы пользователей, к которой принадлежит текущий сотрудник, в регистре прав явно не задано разрешение на чтение пустой группы доступа, предикат RLS возвращает ложь. Платформа расценивает это как отсутствие доступа к документу и блокирует открытие формы с отказом в чтении.
Кроме того, при вводе на основании часто срабатывает каскадная проверка прав. В процедуре ОбработкаЗаполнения или при интерактивном формировании формы считываются реквизиты документа-основания («Перемещение товаров»). Если в перемещении задействован склад или организация, на чтение которых у менеджера нет прав по соответствующим видам RLS, платформа также выдает отказ в доступе.
Рассмотрим наиболее правильный способ устранения ошибки без изменения конфигурации базы данных. Нам необходимо разрешить пользователю видеть объекты с пустым значением группы доступа контрагентов.
Разберем по шагам порядок настройки через пользовательский интерфейс:
ГруппыПользователей или напрямую регистр сведений НастройкиПравДоступаПользователей).Объект доступа выберем тип данных Группы доступа контрагентов, но само значение оставим пустым (не выбирая конкретный элемент). В результате в поле запишется пустая ссылка.Вид наследования прав доступа установим значение Только для текущего права.Важный нюанс: при разрешении пустой группы доступа пользователи получат возможность видеть и редактировать все документы и контрагентов, у которых группа доступа не заполнена. Поэтому проконтролируйте, чтобы у всех реальных партнеров в базе реквизит ГруппаДоступаКонтрагента был обязательно заполнен.
Если специфика учета не позволяет открывать доступ к пустой группе через пользовательские настройки, скорректируем текст запроса RLS непосредственно в роли конфигурации. Наша задача — явно исключить из ограничения проверку тех документов, где контрагент не указан.
Рассмотрим вариант доработки в блоке проверки контрагента. В условии соединения или в секции ГДЕ исключим пустую ссылку справочника контрагентов:
#Если &ИспользоватьОграничениеПоКонтрагенты #Тогда
ЛЕВОЕ СОЕДИНЕНИЕ Справочник.Контрагенты КАК Контрагенты
ПО Контрагенты.Ссылка = ТекущаяТаблица.#Параметр(1)
И Контрагенты.Ссылка <> ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка)
#КонецЕсли
Либо добавим проверку в условие отбора подзапроса RLS, чтобы для пустых значений контрагента проверка на наличие вхождения в регистр прав не производилась вовсе:
#Если &ИспользоватьОграничениеПоКонтрагенты #Тогда
КОГДА НазначениеВидовОбъектовДоступа.ВидОбъектаДоступа = ЗНАЧЕНИЕ(Перечисление.ВидыОбъектовДоступа.Контрагенты)
И (ТекущаяТаблица.#Параметр(1) ЕСТЬ NULL
ИЛИ ТекущаяТаблица.#Параметр(1) = ЗНАЧЕНИЕ(Справочник.Контрагенты.ПустаяСсылка))
ТОГДА ИСТИНА
#КонецЕсли
Такой подход гарантирует, что пока документ находится в стадии создания и контрагент в нем еще не выбран, ограничение RLS пропускает строку, не вызывая аварийного завершения транзакции платформы.
Если отказ на чтение возникает из-за обращения к реквизитам документа-основания (например, когда пользователь имеет право создавать заявку на доставку, но не имеет доступа к просмотру некоторых реквизитов исходного перемещения), стандартным решением является вызов алгоритма заполнения в привилегированном режиме.
Посмотрим на пример оборачивания кода в процедуре ОбработкаЗаполнения модуля объекта документа:
УстановитьПривилегированныйРежим(Истина);
Попытка
// Считывание данных документа-основания
ЗаполнитьПоДокументуОснованию(ДанныеЗаполнения);
Исключение
УстановитьПривилегированныйРежим(Ложь);
ВызватьИсключение;
КонецПопытки;
УстановитьПривилегированныйРежим(Ложь);
Также можно вынести логику выборки реквизитов документа-основания в общий серверный модуль с установленным признаком Привилегированный. Это исключит влияние RLS на считывание служебных данных при автоматическом заполнении реквизитов.