В процессе разработки в среде 1С:Предприятие 8.3 часто возникает задача разграничения видимости документов. Типичный сценарий: рядовые сотрудники не должны видеть документы с определенным видом операции (например, «Выплата зарплаты»), в то время как руководители должны иметь полный доступ ко всем данным. В этой статье мы подробно разберем, как реализовать такое ограничение несколькими способами: от быстрого программного фильтра до настройки прав на уровне записей (RLS).
Проанализируем самый распространенный метод — установку отбора в процедуре ПриСозданииНаСервере. Важно понимать разницу между обычным отбором и ФиксированнымиНастройками. Фиксированные настройки не видны пользователю в меню «Настроить список», и он не сможет их отключить самостоятельно.
Рассмотрим пример кода, который проверяет наличие роли и устанавливает запрет на отображение определенных операций:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Проверяем, есть ли у пользователя роль "Руководитель"
Если Не РольДоступна("Руководитель") Тогда
// Находим элемент отбора в фиксированных настройках динамического списка
НовыйОтбор = Список.КомпоновщикНастроек.ФиксированныеНастройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
НовыйОтбор.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("ВидОперации");
НовыйОтбор.ВидСравнения = ВидСравненияКомпоновкиДанных.НеРавно;
НовыйОтбор.ПравоеЗначение = Перечисления.ВидыОперацийДДС.ВыплатаСотрудникам;
НовыйОтбор.Использование = Истина;
КонецЕсли;
КонецПроцедуры
В этом примере мы используем вид сравнения НеРавно. Это позволяет скрыть только конкретные «секретные» документы, оставляя все остальные видимыми. Если же нам нужно разрешить только определенные виды операций, мы заменим НеРавно на ВТексте или Равно.
Выясним, как поступить, если условие фильтрации слишком сложное для простого отбора. В таких случаях мы можем программно модифицировать текст запроса динамического списка. Это дает нам полный контроль над логикой выборки данных.
Рассмотрим, как можно «склеить» запрос в зависимости от прав доступа:
&НаСервере
Процедура НастроитьТекстЗапросаСписка()
ТекстЗапроса =
"ВЫБРАТЬ
| ДокументДДС.Ссылка КАК Ссылка,
| ДокументДДС.Дата КАК Дата,
| ДокументДДС.Номер КАК Номер,
| ДокументДДС.ВидОперации КАК ВидОперации
|ИЗ
| Документ.УП_ДокументДДС КАК ДокументДДС";
Если Не РольДоступна("Руководитель") Тогда
// Добавляем жесткое ограничение в секцию ГДЕ
ТекстЗапроса = ТекстЗапроса + "
|ГДЕ
| ДокументДДС.ВидОперации <> ЗНАЧЕНИЕ(Перечисление.ВидыОперацийДДС.ВыплатаСотрудникам)";
КонецЕсли;
Список.ТекстЗапроса = ТекстЗапроса;
КонецПроцедуры
Важный нюанс: при динамическом изменении текста запроса платформа переинициализирует список. Если у пользователя были установлены свои пользовательские отборы, они могут сброситься, если структура полей изменится. Поэтому старайтесь менять только секцию ГДЕ.
Посмотрим на более профессиональный и безопасный подход. Программные фильтры в форме списка — это лишь визуальное скрытие. Если пользователь получит прямую ссылку на документ или сформирует отчет, он увидит данные. Чтобы закрыть доступ на уровне ядра платформы, используется RLS.
Разберем по шагам, как настроить RLS для нашей задачи:
Документ.УП_ДокументДДС.
ГДЕ ВидОперации <> ЗНАЧЕНИЕ(Перечисление.ВидыОперацийДДС.ВыплатаСотрудникам)
Теперь, даже если программист забудет поставить фильтр в форме, платформа сама отсечет запрещенные записи. У руководителя же будет отдельная роль (например, «Руководитель»), где ограничение RLS не прописано, что даст ему право видеть всё. Помните, что использование РАЗРЕШЕННЫЕ в запросах отчетов теперь станет обязательным, иначе пользователи без прав руководителя будут получать ошибку доступа.
Если ваша конфигурация построена на базе БСП (Библиотеки стандартных подсистем), правильнее будет проверять не конкретную роль, а вхождение пользователя в профиль или группу доступа. Это позволяет администратору менять права в режиме «Предприятие» без изменения конфигурации.
Проанализируем пример функции, которая проверяет принадлежность к профилю:
// В общем модуле
Функция ПользовательИмеетПрофиль(НаименованиеПрофиля) Экспорт
УстановитьПривилегированныйРежим(Истина);
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ГруппыДоступа.Ссылка
|ИЗ
| Справочник.ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| ГруппыДоступа.Профиль.Наименование = &Наименование
| И ГруппыДоступа.Пользователи.Пользователь = &ТекущийПользователь";
Запрос.УстановитьПараметр("Наименование", НаименованиеПрофиля);
Запрос.УстановитьПараметр("ТекущийПользователь", Пользователи.ТекущийПользователь());
Возврат Не Запрос.Выполнить().Пустой();
КонецФункции
Рассмотрим критическую ошибку новичков: ограничение установлено только в списке. Пользователь может открыть документ по ссылке из истории или через поиск. Чтобы этого избежать, обязательно добавим проверку в самой форме документа.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Если это новый документ, проверка может не требоваться,
// но для существующего - обязательно
Если Объект.ВидОперации = Перечисления.ВидыОперацийДДС.ВыплатаСотрудникам
И Не РольДоступна("Руководитель") Тогда
ТекстСообщения = "У вас недостаточно прав для просмотра документов выплаты зарплаты.";
ОбщегоНазначенияКлиентСервер.СообщитьПользователю(ТекстСообщения);
Отказ = Истина;
КонецЕсли;
КонецПроцедуры
Мы проанализировали различные методы ограничения доступа к данным динамического списка. Подведем итоги: