В процессе сопровождения сложных систем на платформе 1С, таких как Управление производственным предприятием (УПП) 1.3, часто возникает задача тонкой настройки прав доступа. Рассмотрим типичную ситуацию: необходимо запретить конкретному пользователю или группе пользователей проводить документ Корректировка качества товаров, если в его табличной части установлено определенное значение в колонке Новое качество. Мы разберем два основных способа реализации этой задачи: через механизм RLS (Record Level Security) и через Подписку на событие.
Механизм RLS позволяет накладывать ограничения непосредственно на уровне запросов к базе данных. Проанализируем, как это работает технически. Ограничение RLS задается в свойствах роли на конкретное право (например, Чтение или Изменение). Однако здесь есть несколько критических нюансов, которые мы должны учитывать.
Во-первых, права в системе 1С работают по принципу аддитивности. Это означает, что если пользователю назначено несколько ролей, и хотя бы в одной из них даны полные права на объект без RLS, то любые ограничения в других ролях будут проигнорированы. Чтобы ограничение сработало, оно должно быть прописано во всех ролях, доступных пользователю, имеющих право на изменение данного документа.
Во-вторых, RLS накладывается на весь объект целиком. Чтобы проверить условие по строкам табличной части, нам придется использовать вложенный запрос. Рассмотрим пример логики текста ограничения:
ГДЕ НЕ (&ОпределенныйПользователь = &ТекущийПользователь
ИЛИ СУЩЕСТВУЕТ (
ВЫБРАТЬ 1
ИЗ Документ.КорректировкаКачестваТоваров.Товары КАК ТЧ
ГДЕ ТЧ.Ссылка = Ссылка
И ТЧ.КачествоНовое = &НужноеЗначение
))
Важно понимать, что использование СУЩЕСТВУЕТ в RLS по табличным частям может существенно снизить производительность системы, так как при каждом обращении к списку документов или попытке записи платформа будет выполнять дополнительные соединения таблиц на уровне СУБД. Кроме того, при нарушении прав через RLS пользователь получит невнятное системное сообщение: "У вас недостаточно прав доступа", что затрудняет понимание причины ошибки.
Для конфигураций, находящихся на поддержке (как УПП 1.3), наиболее грамотным решением является использование Подписки на событие. Этот метод позволяет внедрить проверку, не изменяя типовой модуль объекта, что значительно упрощает процесс будущих обновлений. Выясним, как реализовать это пошагово.
Шаг 1. Создание роли. Сначала мы создадим новую роль (например, КонтрольКачестваДокументов), которую назначим тем пользователям, для которых нужно ввести ограничение. Или, наоборот, назначим роль тем, кому разрешено проводить любые документы, и будем проверять отсутствие этой роли.
Шаг 2. Создание общего модуля. Создадим новый нетиповой общий модуль (например, РаботаСПравамиПользователейПереопределяемый). Установим у него свойства Сервер и Внешнее соединение.
Шаг 3. Создание подписки на событие. В дереве метаданных найдем ветку Общие -> Подписки на события и добавим новую подписку:
ДокументОбъект.КорректировкаКачестваТоваровПередЗаписьюПроанализируем пример программного кода, который мы напишем в обработчике:
Процедура ПередЗаписьюДокументаКонтрольКачества(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
// Нас интересует только момент проведения или записи проведенного документа
Если НЕ (РежимЗаписи = РежимЗаписиДокумента.Проведение ИЛИ Источник.Проведен) Тогда
Возврат;
КонецЕсли;
// Проверяем наличие роли у текущего пользователя
Если РольДоступна("ОпределеннаяРольБезОграничений") Тогда
Возврат; // Пользователю можно всё
КонецЕсли;
// Обходим табличную часть и ищем запрещенное значение
Для Каждого СтрокаТЧ Из Источник.Товары Цикл
Если СтрокаТЧ.КачествоНовое = Справочники.Качество.НайтиПоНаименованию("Брак") Тогда
Отказ = Истина;
Сообщение = Новый СообщениеПользователю;
Сообщение.Текст = "У вас недостаточно прав для установки качества 'Брак' в документе!";
Сообщение.Сообщить();
Прервать;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Разберем, почему опытные разработчики в 90% случаев выбирают именно подписку на событие для решения подобных бизнес-задач:
Важный момент: если вы решите использовать метод с функцией РольДоступна(), помните, что она проверяет наличие роли у текущего пользователя в текущем сеансе. Это надежный способ разграничения логики действий внутри кода.
Мы рассмотрели два подхода к ограничению доступа. Несмотря на то, что RLS является мощным встроенным инструментом платформы для ограничения видимости данных, для задач контроля бизнес-логики (таких как проверка заполнения табличной части при проведении) оптимальным выбором будет использование Подписки на событие. Это обеспечит стабильность системы, высокую скорость работы и удобство сопровождения конфигурации 1С:УПП 1.3.