При разработке и сопровождении конфигураций на платформе 1С:Предприятие перед разработчиком часто возникает задача ограничить создание новых элементов справочника определенным кругом лиц или при выполнении некоторых условий. На первый взгляд задача кажется тривиальной, но при детальном рассмотрении открывается множество нюансов. Где лучше прописать проверку? Как сделать так, чтобы пользователь не тратил время на заполнение формы, которую он в итоге не сможет записать? Как защитить базу от программного обхода ограничений через внешние обработки?
В этой статье мы подробно разберем все возможные архитектурные подходы на примере Обычных форм, проанализируем их плюсы и минусы, а также выработаем «золотой стандарт» решения этой задачи.
Самый простой и правильный с точки зрения платформы способ — это использование роли. В платформе 1С права на добавление объектов разделены на два уровня. Разберем разницу между ними подробнее:
СоздатьЭлемент() в коде). Попытка записи вызовет ошибку нарушения прав доступа.Однако стандартный ролевой метод имеет существенные ограничения:
Если вам необходима гибкая логика с дополнительными условиями, придется прибегнуть к программному ограничению.
Рассмотрим вариант программного запрета непосредственно в форме нового объекта. Для этого используется событие формы ПередОткрытием. Посмотрим на практический пример реализации такого кода для Обычных форм:
Процедура ПередОткрытием(Отказ, СтандартнаяОбработка)
// Проверяем, является ли объект новым
Если ЭтоНовый() Тогда
ЕстьПраво = абОбщее.ПолучитьПравоРедактированияБонусов();
Если НЕ ЕстьПраво Тогда
Предупреждение("У Вас недостаточно прав для создания новых элементов данного справочника! Обратитесь к администратору.");
СтандартнаяОбработка = Ложь;
Отказ = Истина;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Преимущества этого подхода:
Это самый дружелюбный вариант с точки зрения пользовательского опыта (UX). Мы пресекаем попытку создания элемента «на корню». Пользователь сразу получает предупреждение и форма даже не открывается. Он не тратит свое время на заполнение десятков реквизитов и табличных частей.
Недостатки этого подхода:
Проверка в форме защищает только от интерактивных действий пользователя через стандартный интерфейс. Если пользователь (или программист) запустит внешнюю обработку группового изменения реквизитов, загрузку данных из Excel или обмен данными, то программный код создания объекта легко обойдет эту проверку, так как форма при программной записи вообще не создается и не открывается.
Чтобы сделать ограничение фундаментальным и непреодолимым для внешних обработок, проверку переносят на уровень модуля объекта — в событие ПередЗаписью. Проанализируем этот вариант:
Процедура ПередЗаписью(Отказ)
Если ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если ЭтоНовый() Тогда
Если НЕ абОбщее.ПолучитьПравоРедактированияБонусов() Тогда
ВызватьИсключение "Недостаточно прав для создания нового элемента!";
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Преимущества:
Это максимально надежная защита данных. Ни один программный код (за исключением обменов, если стоит проверка ОбменДанными.Загрузка) не сможет обойти это ограничение.
Недостатки:
С точки зрения удобства пользователя — это худший сценарий. Представьте ситуацию: пользователь открыл форму, ввел 15 реквизитов, заполнил табличную часть, потратил 10 минут времени, нажимает кнопку «ОК» и только в этот момент получает жесткий отказ без возможности сохранить свои труды. Это вызывает колоссальное раздражение у бизнес-пользователей.
Чтобы объединить надежность транзакционной защиты и дружелюбность интерфейса, мы рекомендуем использовать комбинированный подход. Он состоит из трех шагов:
Шаг 1. Контроль на уровне интерфейса (форма объекта). В событии ПередОткрытием формы проверяем права. Если прав нет — не даем пользователю даже открыть форму, выводя понятное предупреждение.
Шаг 2. Контроль на уровне бизнес-логики (Подписка на события). Чтобы сохранить конфигурацию на поддержке и не изменять типовой модуль справочника, мы создаем нетиповую подписку на событие ПередЗаписью для источника СправочникОбъект нужного справочника. В обработчике подписки пишем аналогичную проверку. Это гарантирует безопасность данных от программного изменения.
Шаг 3. Разделение интерактивного и программного создания через дополнительные свойства.
Часто возникает ситуация, когда пользователям вручную создавать элементы нельзя, а регламентным заданиям или обработкам интеграции — можно. Для этого в 1С используется механизм ДополнительныеСвойства. Рассмотрим, как это реализовать.
При программном создании элемента в коде интеграции мы передаем специальный маркер разрешения:
НовыйЭлемент = Справочники.Номенклатура.СоздатьЭлемент();
НовыйЭлемент.Наименование = "Новый товар из интернет-магазина";
// Записываем маркер программного создания
НовыйЭлемент.ДополнительныеСвойства.Вставить("РазрешитьПрограммнуюЗапись", Истина);
НовыйЭлемент.Записать();
А в обработчике подписки на событие ПередЗаписью (в общем модуле) выполняем проверку наличия этого свойства:
Процедура ПередЗаписьюСправочника(Источник, Отказ) Экспорт
Если Источник.ОбменДанными.Загрузка Тогда
Возврат;
КонецЕсли;
Если Источник.ЭтоНовый() Тогда
// Проверяем, пришел ли маркер программной записи
РазрешитьЗапись = Ложь;
Источник.ДополнительныеСвойства.Свойство("РазрешитьПрограммнуюЗапись", РазрешитьЗапись);
Если НЕ РазрешитьЗапись Тогда
// Если маркера нет, значит запись инициирована вручную или сторонней обработкой
Если НЕ абОбщее.ПолучитьПравоРедактированияБонусов() Тогда
Отказ = Истина;
ВызватьИсключение "У Вас нет прав на создание новых элементов этого справочника вручную!";
КонецЕсли;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Таким образом, мы получаем гибкую, отказоустойчивую и дружелюбную к пользователю систему разграничения прав доступа при создании элементов справочников.