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