Часто в практике разработки на 1С возникает задача: при проведении определенного документа необходимо программно изменить данные в другом объекте, например, обновить реквизиты в справочнике Номенклатура. Однако у пользователя, который проводит документ, может не быть роли, разрешающей изменение этого справочника. Система закономерно выдает ошибку «Отказ в доступе». Рассмотрим подробнее, как обойти эту ситуацию без прямого расширения пользовательских прав, и проанализируем, почему стандартный метод может не срабатывать.
Первой мыслью разработчика обычно является использование метода УстановитьПривилегированныйРежим(Истина) непосредственно в процедуре ОбработкаПроведения. Но на практике код все равно выпадает с ошибкой прав. Выясним причину такого поведения. На это влияют два ключевых фактора:
УстановитьПривилегированныйРежим работает исключительно в серверном контексте или в файловой базе. Если мы имеем дело с конфигурацией на обычных формах (например, УПП) и работаем в режиме толстого клиента, код обработчика проведения может исполняться на стороне клиента. На клиенте этот метод платформой просто игнорируется, и проверка прав продолжает выполняться.Разберем по шагам наиболее правильный и безопасный метод, соответствующий стандартам разработки 1С. Согласно проверкам автоматических анализаторов кода (например, BSL Language Server или SonarQube), безусловный вызов повышения прав в модуле документа считается уязвимостью. Чтобы сделать все чисто, воспользуемся общими модулями.
Создадим новый Общий модуль, назовем его, например, ОбработкаСправочниковПривилегированный. В свойствах этого модуля (в палитре свойств конфигуратора) обязательно установим флажок Привилегированный. В этом модуле сервер всегда будет работать с полными правами, игнорируя ролевые ограничения.
Перенесем туда логику модификации номенклатуры:
Процедура ОбновитьРеквизитыНоменклатуры(СсылкаНаДокумент) Экспорт
// В этом модуле проверки прав отключены автоматически
// Пишем логику изменения реквизитов справочника Номенклатура
КонецПроцедуры
А в самом модуле документа, в процедуре ОбработкаПроведения, мы просто вызовем нашу функцию:
Процедура ОбработкаПроведения(Отказ, Режим)
// Основная логика проведения (движения по регистрам и т.д.)
// ...
// Вызов привилегированного кода для изменения справочника
ОбработкаСправочниковПривилегированный.ОбновитьРеквизитыНоменклатуры(ЭтотОбъект.Ссылка);
КонецПроцедуры
Посмотрим на альтернативный способ. Платформа 1С позволяет управлять правами при проведении на уровне метаданных. Откроем палитру свойств самого объекта «Документ». Там можно найти флажок Прив. режим при проведении.
При установке этого флага вся процедура проведения автоматически запускается платформой в привилегированном режиме. Дополнительно писать код не нужно. Однако проанализируем ситуацию и возможные риски:
Этот способ можно использовать, но с большой осторожностью, понимая, что безопасность системы снижается.
Если вы все же решаете использовать программное включение, важно понимать, как правильно сбрасывать права. Первое выполнение метода УстановитьПривилегированныйРежим(Истина) на сервере включает нужный режим.
Для его явного выключения необходимо внутри этой же процедуры вызвать метод УстановитьПривилегированныйРежим(Ложь) столько же раз, сколько он был включен. Если вы забудете это сделать, платформа все равно подстрахует: при возврате из процедуры или функции, в которой был включен привилегированный режим, он будет выключен платформой неявно и автоматически.
Стоит отметить, что автоматическое повышение прав через свойства доступно не только для документов. Настроить подобное поведение можно и для других объектов. Например, у Бизнес-процессов есть свойство Привилегированный режим при создании задач, а у функциональных опций — Привилегированный режим при получении. Знание этих свойств поможет более гибко управлять правами в сложных системах.