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