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