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