Как в расширении 1С ограничить права на проведение документов, если основные роли нельзя менять?

Программист 1С v8.3 (Управляемые формы) 1C:Бухгалтерия IT и автоматизация бизнеса
← На главную

В практике разработчика 1С часто возникает ситуация, когда необходимо изменить права доступа для определенной группы пользователей в типовой конфигурации. Особенно остро этот вопрос встает, когда конфигурация находится на поддержке и обновляется путем загрузки файла .cf из центрального офиса или от вендора. В этом случае любые изменения в основных ролях будут затерты при очередном обновлении. Казалось бы, логичное решение — создать роль в расширении, но здесь мы сталкиваемся с фундаментальным принципом работы системы прав 1С.

В данной статье мы разберем, почему нельзя просто «запретить» действие новой ролью, и рассмотрим пошаговые алгоритмы решения задачи через механизмы расширений, включая программные проверки и использование подписок на события.

Анализируем проблему: принцип аддитивности прав

Прежде чем переходить к коду, проанализируем, почему стандартное создание роли в расширении не помогает «урезать» права. В платформе «1С:Предприятие 8.3» права пользователя суммируются по принципу логического «ИЛИ». Если пользователю назначено несколько ролей, и хотя бы одна из них разрешает проведение документа РеализацияТоваровУслуг, то никакая другая роль не может это действие запретить.

Следовательно, если в основной конфигурации у пользователя есть роль МенеджерПродаж, которая дает право на проведение, создание в расширении роли без этого права ничего не изменит. Нам необходимо найти способ программного вмешательства, который сработает «поверх» установленных прав. Рассмотрим варианты реализации.

Вариант 1. Создание «маркерной» роли и использование подписки на событие

Этот метод считается наиболее «чистым» и современным для версий платформы 8.3.17 и выше. Суть заключается в том, что мы создаем роль в расширении не для управления правами доступа на уровне метаданных, а как флаг (маркер) для конкретной группы пользователей.

Рассмотрим алгоритм реализации:

  1. Создаем в расширении новую роль, например, ЗапретПроведенияРеализаций. В самой роли не нужно настраивать права на объекты — она будет служить лишь идентификатором.
  2. Добавляем в расширение объект ПодпискаНаСобытие.
  3. В качестве источника для подписки выбираем интересующий нас документ (например, ДокументОбъект.РеализацияТоваровУслуг).
  4. Событие выбираем ПередЗаписью.

Теперь разберем программный код в модуле расширения, который будет обрабатывать это событие. Проанализируем ситуацию: нам нужно запретить только проведение, но оставить возможность записи документа.


Процедура Расш1_ПередЗаписьюДокументаПередЗаписью(Источник, Отказ, РежимЗаписи, РежимПроведения) Экспорт
    
    // Проверяем, что выполняется именно проведение документа
    Если РежимЗаписи = РежимЗаписиДокумента.Проведение Тогда
        
        // Проверяем наличие нашей специальной роли у текущего пользователя
        Если РольДоступна("ЗапретПроведенияРеализаций") Тогда
            
            // Выводим сообщение пользователю и отменяем действие
            Сообщение = Новый СообщениеПользователю;
            Сообщение.Текст = "У вас недостаточно прав для проведения данного документа. Обратитесь к администратору.";
            Сообщение.Сообщить();
            
            Отказ = Истина;
            
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

Важное примечание: Если ваше расширение имеет префикс (например, Расш1_), то при проверке роли методом РольДоступна() необходимо учитывать, как платформа интерпретирует имена ролей из расширений. Обычно используется синтаксис ИмяРасширения_ИмяРоли.

Вариант 2. Перехват метода в модуле объекта (через &Перед или &После)

Если версия вашей платформы ниже 8.3.17, возможность создания подписок на события в расширении может быть ограничена. В этом случае мы воспользуемся механизмом заимствования методов. Рассмотрим, как это сделать без изменения основного кода.

Нам необходимо заимствовать процедуру ОбработкаПроведения или ПередЗаписью непосредственно в модуль объекта документа внутри расширения. Рекомендуется использовать аннотацию &Перед, чтобы логика проверки сработала до начала транзакции проведения.

Посмотрим на пример реализации в модуле объекта расширения:


&Перед("ОбработкаПроведения")
Процедура Расш1_ОбработкаПроведения(Отказ, РежимПроведения)
    
    // Проверяем права программно
    Если РольДоступна("ЗапретПроведенияРеализаций") Тогда
        Отказ = Истина;
        ВызватьИсключение "Операция проведения запрещена для вашего профиля доступа!";
    КонецЕсли;
    
КонецПроцедуры

Почему мы выбираем &Перед? Проанализируем: если мы поставим проверку в &После, основной код проведения уже выполнится, движения будут сформированы, и хотя установка Отказ = Истина все равно отменит транзакцию, это будет менее производительно и может привести к выполнению лишних тяжелых операций на сервере.

Нюансы работы с платформой и версиями

Выясним причину, почему у некоторых разработчиков не получается создать подписку в расширении. Как было отмечено в обсуждении, ключевым фактором является версия платформы:

Использование БСП для управления доступом

Если вы работаете с современной конфигурацией (например, БП 3.0, УТ 11, ERP 2), стоит рассмотреть возможность интеграции вашего решения в общую систему управления доступом Библиотеки Стандартных Подсистем (БСП).

Вместо жесткой проверки РольДоступна(), можно создать свой Вид доступа в расширении и использовать программные интерфейсы БСП для проверки прав. Однако для простой задачи «запретить проведение одной группе» создание подписки в расширении является «золотым стандартом», так как оно полностью изолировано от типового кода.

Рекомендации по внедрению

Проанализируем шаги, которые нужно предпринять для успешного запуска решения:

  1. Тестирование на копии: Всегда проверяйте работу Отказ = Истина. Убедитесь, что при отказе пользователю выдается понятное сообщение, иначе служба поддержки будет завалена вопросами о «непонятном сбое».
  2. Назначение ролей: После создания роли в расширении и подключения расширения к базе, не забудьте зайти в режим «1С:Предприятие» и добавить эту роль в соответствующие Профили групп доступа. Пока роль не назначена пользователю, код запрета срабатывать не будет.
  3. Контроль обновлений: При обновлении основной конфигурации через загрузку .cf ваше расширение останется неизменным. Однако, если в основной конфигурации изменятся параметры заимствованных процедур (например, в ПередЗаписью добавят новый параметр), расширение может перестать применяться. В этом случае достаточно будет обновить сигнатуру метода в расширении.

Таким образом, мы видим, что даже при невозможности изменения состава ролей основной конфигурации, механизм расширений предоставляет гибкие инструменты для тонкой настройки прав доступа через программный слой. Использование роли-маркера в сочетании с подпиской на событие позволяет реализовать сложную логику запретов, не нарушая целостность типового решения.

← На главную