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