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