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