Как ограничить доступ к контрагентам по папкам в 1С:Бухгалтерия 3.0 с помощью расширения

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

В процессе разработки часто возникает задача ограничить видимость данных для конкретного пользователя. В конфигурации 1С:Бухгалтерия предприятия 3.0 (БП 3.0) штатные механизмы групп доступа для справочника Контрагенты отсутствуют, в отличие от Управление торговлей 11. Рассмотрим подробно, как реализовать ограничение доступа по папкам (иерархии) через механизм расширений, проанализируем типичные ошибки и выберем оптимальный метод реализации.

Причина №1: Почему «снятие галочек» в роли не работает

Разберем типичную ситуацию: разработчик заимствует роль в расширение, снимает в ней права на чтение справочника и назначает эту роль пользователю. Однако пользователь все равно видит все записи. Выясним причину этого поведения. В платформе 1С реализован принцип аддитивности (суммирования) прав. Если у пользователя назначено несколько ролей, и хотя бы одна из них (например, типовая роль ЧтениеКонтрагентов или Бухгалтер) разрешает доступ к объекту, то никакие другие «ограничивающие» роли в расширении этот доступ не закроют.

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

  1. Необходимо создать в основной конфигурации или расширении новый Профиль групп доступа.
  2. В этом профиле нужно исключить все стандартные роли, которые дают право доступа к справочнику Контрагенты.
  3. Добавить в профиль свою роль из расширения, в которой и будет прописана логика ограничения. Для контроля итоговых прав удобно использовать отчеты по пользователям, ролям и профилям доступа.

Вариант 1: Программная установка фильтра в динамическом списке

Это наиболее простой способ, который часто выбирают для быстрой реализации. Суть заключается в том, чтобы при открытии формы списка справочника принудительно устанавливать отбор по родителю. Рассмотрим, как это сделать в расширении формы списка.

Добавим в расширение форму списка справочника Контрагенты и перехватим событие ПриСозданииНаСервере. Пропишем следующий код:


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

КонецПроцедуры

Важный нюанс: Этот метод защищает только «от честных людей». Если пользователь воспользуется консолью запросов или универсальным отчетом, он увидит все данные.

Вариант 2: Использование RLS (Record Level Security) в расширении

Механизм RLS позволяет ограничить доступ на уровне самой платформы, независимо от того, через какую форму или отчет пользователь запрашивает данные. С версии платформы 8.3.10 расширения поддерживают создание ролей с шаблонами ограничений.

Разберем алгоритм настройки RLS для ограничения по иерархии:

  1. Заимствуем справочник Контрагенты в расширение.
  2. Создаем в расширении новую роль, например, Расш1_ЧтениеКонтрагентовСГруппировкой.
  3. Для объекта Справочник.Контрагенты в поле «Чтение» прописываем условие ГДЕ.

Пример текста ограничения (RLS):


ГДЕ (ЭтоГруппа = ИСТИНА) 
ИЛИ (Родитель В ИЕРАРХИИ (&ПараметрСеанса_РазрешеннаяГруппаКонтрагентов))

Проанализируем это условие: Первая часть (ЭтоГруппа = ИСТИНА) необходима для того, чтобы пользователь видел дерево папок. Если закрыть доступ ко всем папкам, кроме целевой, пользователь может не увидеть иерархию вообще. Вторая часть ограничивает доступ непосредственно к элементам и вложенным папкам выбранной группы.

Особенности использования параметров в RLS

Использование фиксированных GUID или наименований прямо в тексте RLS считается плохой практикой. Правильнее использовать Параметры сеанса. Вы можете создать свой параметр сеанса в расширении и инициализировать его при старте системы (в модуле сеанса расширения), указав там ссылку на разрешенную папку.

Рассмотрим пример инициализации параметра сеанса в расширении:


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

Интеграция с БСП (Библиотека стандартных подсистем)

Поскольку Бухгалтерия предприятия 3.0 базируется на БСП, рекомендуется использовать стандартные шаблоны доступа. Даже если в типовой конфигурации БП нет вида доступа «Группы доступа контрагентов», механизм управления доступом можно расширить.

Посмотрим на преимущества использования шаблона #ПоЗначениям:

Риски и производительность при использовании RLS

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

Справочник Контрагенты используется практически во всех первичных документах (Платежные поручения, Реализации, Поступления). Когда пользователь с RLS открывает журнал документов, система вынуждена для каждой строки проверять, имеет ли пользователь право видеть контрагента, указанного в этом документе. Это приводит к значительному усложнению SQL-запросов и может вызвать замедление работы интерфейса («фризы») при больших объемах данных.

Совет: Если стоит задача только скрыть «чужих» клиентов в списке, но при этом пользователь должен видеть документы по ним (или работать в общих журналах), лучше использовать программные фильтры в формах (Вариант 1) в сочетании с запретом на использование внешних обработок.

Контроль записи новых элементов

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

Чтобы этого избежать, добавим проверку в расширение модуля объекта справочника:


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

Подводя итог, отметим: для жесткого и безопасного разделения данных в БП 3.0 следует использовать RLS в расширении с опорой на параметры сеанса. Для легкого косметического разделения достаточно фиксированных отборов в динамических списках форм.

← На главную