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