Роли пользователя 1С: свойство Роли, РольДоступна и профили групп доступа

· 9 мин

Содержание

Роли пользователя в 1С 8.3 получают через объект ПользовательИнформационнойБазы: у него есть свойство Роли — коллекция объектов метаданных «Роль». Для текущего сеанса достаточно вызвать на сервере ПользователиИнформационнойБазы.ТекущийПользователь().Роли, а чтобы просто проверить одну роль, хватит глобальной функции РольДоступна("ИмяРоли").

Это механизм платформы, он одинаков для любой конфигурации. В типовых решениях на БСП (Бухгалтерия 3.0, ЗУП 3.1, УТ 11) есть второй слой — профили групп доступа. Из них роли и попадают в пользователя, поэтому иногда нужно знать не только «какие роли у него есть», но и «откуда они взялись».

Откуда у пользователя берутся роли

Роль — объект метаданных конфигурации. В ней разработчик отмечает права: чтение, добавление, изменение, проведение и так далее по каждому справочнику, документу, регистру. Плюс ограничения на уровне записей (RLS), если они нужны.

Пользователю информационной базы назначают набор ролей. Итоговые права — это объединение прав всех его ролей. Запретов нет: если хоть одна роль разрешает чтение документа, читать он сможет.

Как назначаются роли, зависит от конфигурации:

  • 🔧 Самописная или небольшая конфигурация без БСП. Роли ставят галочками в Конфигураторе: Администрирование → Пользователи, карточка пользователя, вкладка «Прочие».
  • 🏢 Типовая на БСП. Роли напрямую никто не отмечает. Администратор включает пользователя в группы доступа, у каждой группы есть профиль, а в профиле — список ролей. Программа сама записывает в пользователя ИБ объединение ролей всех его профилей.
  • 🧩 Роли из расширений. Расширение может добавить свои роли. Когда расширение подключено, они видны в Метаданные.Роли и назначаются так же, как роли основной конфигурации.

В типовой конфигурации роль, поставленную вручную в Конфигураторе, программа может снять при следующей записи групп доступа или при обновлении. Меняйте права через профили и группы доступа в пользовательском режиме.

Как получить список ролей пользователя кодом

Работа с пользователями ИБ возможна только на сервере (и в толстом клиенте). Менеджер ПользователиИнформационнойБазы на тонком и веб-клиенте недоступен, поэтому код помещают в серверную процедуру или общий модуль.

Роли текущего пользователя

&НаСервереБезКонтекста
Функция ИменаРолейТекущегоПользователя()

    Результат = Новый Массив;
    ПользовательИБ = ПользователиИнформационнойБазы.ТекущийПользователь();

    Для Каждого Роль Из ПользовательИБ.Роли Цикл
        Результат.Добавить(Роль.Имя);
    КонецЦикла;

    Возврат Результат;

КонецФункции

Каждый элемент коллекции — объект метаданных. У него можно взять:

Свойство / методЧто вернётПример
Роль.Имяимя в конфигурацииПолныеПрава
Роль.Синонимпредставление для людей«Полные права»
Роль.ПолноеИмя()имя с типом объектаРоль.ПолныеПрава

Роли другого пользователя по имени

Для чужого пользователя нужны административные права. Если код вызывает обычный пользователь, включите привилегированный режим на сервере:

Функция РолиПользователя(ИмяПользователя) Экспорт

    УстановитьПривилегированныйРежим(Истина);

    ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоИмени(ИмяПользователя);
    Если ПользовательИБ = Неопределено Тогда
        ВызватьИсключение СтрШаблон("Пользователь ""%1"" не найден", ИмяПользователя);
    КонецЕсли;

    Таблица = Новый ТаблицаЗначений;
    Таблица.Колонки.Добавить("Имя");
    Таблица.Колонки.Добавить("Синоним");

    Для Каждого Роль Из ПользовательИБ.Роли Цикл
        НоваяСтрока = Таблица.Добавить();
        НоваяСтрока.Имя = Роль.Имя;
        НоваяСтрока.Синоним = Роль.Синоним;
    КонецЦикла;

    Таблица.Сортировать("Имя");
    Возврат Таблица;

КонецФункции

НайтиПоИмени ищет по полю «Имя» (логин), а не по полному имени. Если пользователя нет, метод вернёт Неопределено — отсюда проверка.

Роли по элементу справочника «Пользователи»

В конфигурациях на БСП у вас обычно на руках ссылка на элемент справочника Пользователи, а не пользователь ИБ. Связь между ними — реквизит ИдентификаторПользователяИБ:

УстановитьПривилегированныйРежим(Истина);

Идентификатор = ПользовательСсылка.ИдентификаторПользователяИБ;
ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(Идентификатор);

Если ПользовательИБ <> Неопределено Тогда
    Для Каждого Роль Из ПользовательИБ.Роли Цикл
        Сообщить(Роль.Синоним);
    КонецЦикла;
КонецЕсли;

💡 Пустой результат поиска здесь — нормальная ситуация. Элемент справочника может существовать без пользователя ИБ: например, сотрудник заведён, но вход в программу ему не разрешали.

Все пользователи с определённой ролью

Обратная задача — кто в базе имеет роль. Перебираем всех пользователей и проверяем вхождение методом Содержит:

Функция ПользователиСРолью(ИмяРоли) Экспорт

    УстановитьПривилегированныйРежим(Истина);

    РольМД = Метаданные.Роли.Найти(ИмяРоли);
    Если РольМД = Неопределено Тогда
        ВызватьИсключение СтрШаблон("Роль ""%1"" не найдена в конфигурации", ИмяРоли);
    КонецЕсли;

    Результат = Новый Массив;
    Для Каждого ПользовательИБ Из ПользователиИнформационнойБазы.ПолучитьПользователей() Цикл
        Если ПользовательИБ.Роли.Содержит(РольМД) Тогда
            Результат.Добавить(ПользовательИБ.Имя);
        КонецЕсли;
    КонецЦикла;

    Возврат Результат;

КонецФункции

Вызов ПользователиСРолью("ПолныеПрава") вернёт логины всех полноправных пользователей.

Проверка роли: РольДоступна или Роли.Содержит

Когда список не нужен, а нужно только «да/нет», есть два пути.

РольДоступна(Роль) — метод глобального контекста. Проверяет роль текущего пользователя сеанса. Принимает имя строкой или объект метаданных:

Если РольДоступна("ПолныеПрава") Тогда
    Элементы.КомандаПерепровести.Видимость = Истина;
КонецЕсли;

// то же самое, но опечатка в имени роли проявится сразу ошибкой
Если РольДоступна(Метаданные.Роли.ПолныеПрава) Тогда
    // ...
КонецЕсли;

Метод работает и на клиенте, поэтому его удобно использовать в формах без серверного вызова.

ПользовательИБ.Роли.Содержит(РольМД) — проверка любого пользователя, не только текущего. Только сервер.

ЗадачаЧем решатьГде работает
Есть ли роль у текущего пользователяРольДоступнаклиент и сервер
Есть ли роль у другого пользователяРоли.Содержитсервер
Полный список ролейобход ПользовательИБ.Ролисервер
Несколько ролей с учётом привилегированного режима (БСП)Пользователи.РолиДоступнысервер

В БСП функция Пользователи.РолиДоступны принимает имена ролей строкой через запятую и возвращает Истину, только если доступны все перечисленные. Ещё удобный метод — Пользователи.ЭтоПолноправныйПользователь(): он не завязан на конкретное имя роли.

Роли из профилей групп доступа: запрос по данным БСП

Свойство Роли показывает итог. Чтобы понять, через какой профиль пришла роль, нужно смотреть справочники подсистемы «Управление доступом»:

  • ГруппыДоступа — группа, её профиль и табличная часть Пользователи (там могут стоять и пользователи, и группы пользователей);
  • ПрофилиГруппДоступа — профиль и табличная часть Роли, где роль хранится ссылкой на справочник ИдентификаторыОбъектовМетаданных;
  • регистр сведений СоставыГруппПользователей — в какие группы пользователей входит человек.

Запрос, который выводит «профиль → роль» для одного пользователя:

Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
|    ГруппыДоступа.Профиль.Наименование КАК Профиль,
|    РолиПрофиля.Роль.ПолноеИмя КАК Роль
|ИЗ
|    Справочник.ГруппыДоступа.Пользователи КАК Участники
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ГруппыДоступа КАК ГруппыДоступа
|        ПО Участники.Ссылка = ГруппыДоступа.Ссылка
|        ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК РолиПрофиля
|        ПО ГруппыДоступа.Профиль = РолиПрофиля.Ссылка
|ГДЕ
|    НЕ ГруппыДоступа.ПометкаУдаления
|    И НЕ ГруппыДоступа.Профиль.ПометкаУдаления
|    И (Участники.Пользователь = &Пользователь
|        ИЛИ Участники.Пользователь В
|            (ВЫБРАТЬ
|                Составы.ГруппаПользователей
|            ИЗ
|                РегистрСведений.СоставыГруппПользователей КАК Составы
|            ГДЕ
|                Составы.Пользователь = &Пользователь))
|
|УПОРЯДОЧИТЬ ПО
|    Профиль,
|    Роль";
Запрос.УстановитьПараметр("Пользователь", ПользовательСсылка);

Выборка = Запрос.Выполнить().Выбрать();
Пока Выборка.Следующий() Цикл
    Сообщить(СтрШаблон("%1: %2", Выборка.Профиль, Выборка.Роль));
КонецЦикла;

Здесь &Пользователь — ссылка на элемент справочника Пользователи, не пользователь ИБ.

Имена справочников и реквизитов указаны для БСП 3.x. В старых или доработанных конфигурациях они могут отличаться — перед запуском откройте эти объекты в дереве метаданных Конфигуратора и сверьте.

Результат запроса и свойство Роли пользователя ИБ обычно совпадают. Расхождение — повод разобраться: роль могли добавить вручную в Конфигураторе, или права не пересчитались после правки профиля.

Проверка права на действие вместо проверки роли

Часто роль спрашивают ради другого вопроса: «может ли пользователь провести этот документ». Для этого есть ПравоДоступа — он смотрит на сумму прав всех ролей, а не на конкретную роль:

// право текущего пользователя
МожноПроводить = ПравоДоступа("Проведение", Метаданные.Документы.ПоступлениеТоваровУслуг);

// право конкретного пользователя ИБ (только сервер)
МожноЧитать = ПравоДоступа("Чтение", Метаданные.Справочники.Контрагенты, ПользовательИБ);

// что даёт отдельная роль
РольДаётИзменение = ПравоДоступа("Изменение", Метаданные.Справочники.Номенклатура,
    Метаданные.Роли.ПолныеПрава);

Имя права передают строкой: «Чтение», «Добавление», «Изменение», «Удаление», «Проведение», «Просмотр», «Редактирование» и другие — набор зависит от типа объекта. Документ поддерживает «Проведение», справочник — нет.

Почему это надёжнее: имена ролей разработчики меняют, роли дробят и объединяют. Право «Проведение» на документ останется тем же. Код, который проверяет право, переживёт обновление типовой конфигурации, а код, завязанный на имя роли, может сломаться.

💡 ПравоДоступа отвечает про право на объект в целом. Ограничения на уровне записей (RLS) он не учитывает: право на документ есть, но конкретный документ чужой организации пользователь всё равно не прочитает.

Клиент, сервер и привилегированный режим

Где какой метод работает:

  • 🖥️ Тонкий и веб-клиент: доступны РольДоступна и ПравоДоступа без указания пользователя. ПользователиИнформационнойБазы — нет, нужен серверный вызов.
  • ⚙️ Сервер: доступно всё. Для чтения чужих пользователей нужно право «Администрирование» или привилегированный режим.
  • 🔌 Внешнее соединение и фоновые задания: код выполняется на сервере, текущий пользователь — тот, под кем открыто соединение или запущено задание.

Особенности, о которые спотыкаются:

  1. Пустой список пользователей. Пока в базе не создан ни один пользователь, сеанс получает все права. Коллекция Роли текущего пользователя при этом пуста, хотя по факту ограничений нет. Учитывайте это в отладочных базах.
  2. Привилегированный режим. Он отключает проверку прав, но ролей пользователю не добавляет. Код в общем модуле с флагом «Привилегированный» сделает то, на что у пользователя нет прав, а РольДоступна при этом ответит честно — по назначенным ролям.
  3. Роль «Полные права» и «Администратор системы». В типовых конфигурациях это разные роли. Первая даёт доступ ко всем данным, вторая — к администрированию базы (пользователи, обновление, расширения). Проверяйте ту, что нужна под задачу.
  4. Разделённые базы (сервис). В режиме разделения данных права абонента ограничены, и часть административных ролей ему недоступна. Код с проверкой «Администратор системы» там поведёт себя иначе, чем в коробке.
Что вам нужно узнать о ролях?

Где посмотреть роли пользователя без программирования

Не всегда нужен код. Три способа увидеть роли глазами:

  1. Пользовательский режим (БСП). Администрирование → Настройки пользователей и прав → Пользователи, откройте карточку и перейдите к правам доступа. Видны группы доступа, в которые включён человек. Отчёт по правам из карточки покажет итоговые права по объектам.
  2. Конфигуратор. Администрирование → Пользователи, двойной щелчок по пользователю, вкладка «Прочие». Отмеченные галочки — фактические роли пользователя ИБ.
  3. Матрица всех ролей. В дереве метаданных Конфигуратора щёлкните правой кнопкой по ветке «Роли» и выберите «Все роли». Откроется таблица: объекты по строкам, роли по столбцам, права на пересечении. Удобно, когда надо понять, какая роль даёт право на конкретный документ.

Не меняйте роли в Конфигураторе при открытых сеансах пользователей и тем более в типовой конфигурации на БСП: правьте профили групп доступа в пользовательском режиме.

Ошибки при работе с ролями в коде

  • ❌ Сравнение по синониму. Роль.Синоним = "Полные права" сломается в другой локализации или после переименования. Сравнивайте по Имя или объекту метаданных.
  • ❌ Строка с опечаткой в РольДоступна. Строковое имя проверяется только при выполнении, и ошибка всплывёт в той ветке кода, которую редко запускают. Обращение Метаданные.Роли.ИмяРоли проверяет синтаксический контроль модуля — опечатку вы увидите раньше.
  • ❌ Проверка роли там, где нужна проверка права. Код «если роль Бухгалтер — показать кнопку» перестанет работать, когда право на действие выдадут через другой профиль.
  • ❌ Вызов ПользователиИнформационнойБазы из клиентского модуля. Получите ошибку компиляции или выполнения. Выносите в &НаСервере или в серверный общий модуль.
  • ❌ Привилегированный режим «на всякий случай». Включайте его только вокруг чтения пользователей и сразу после — отключайте или держите в отдельной функции. Иначе вся процедура будет игнорировать права.
  • ❌ Перебор ПолучитьПользователей() в цикле по документам. На базе с сотнями пользователей это медленно. Соберите нужные данные один раз в соответствие и используйте его.

Частые вопросы

Почему `РольДоступна` возвращает Ложь, хотя в профиле роль есть?
Скорее всего, права не применились к пользователю ИБ: например, профиль правили, но запись групп доступа не прошла. Откройте и запишите группу доступа заново, затем перезапустите сеанс пользователя — роли читаются при входе.
Нужно ли переподключаться после изменения ролей?
Да. Набор ролей фиксируется при начале сеанса. Пользователь увидит новые права после перезапуска программы.
Можно ли получить роли пользователя через внешнее соединение или COM?
Да, тем же кодом через ПользователиИнформационнойБазы. Учётная запись соединения должна иметь административные права, иначе чужих пользователей она не прочитает.
Как выгрузить роли всех пользователей в таблицу?
Переберите ПользователиИнформационнойБазы.ПолучитьПользователей() и для каждого обойдите свойство Роли, складывая пары «пользователь — роль» в таблицу значений. Её можно вывести в табличный документ или сохранить в файл.
Чем роль отличается от профиля групп доступа?
Роль — объект конфигурации, её меняет только разработчик. Профиль — набор ролей в данных базы, его настраивает администратор в пользовательском режиме без изменения конфигурации.