Добрый день, коллеги.
БП 3.0.63.15, платформа 8.3.10.2667.

Создано расширение конфигурации, в котором добавлена роль "РЗО_НаКонтроле". По сути, это ограничивающая роль. При ее наличии, перехваченные функции запрещают пользователю ряд действий, если исполняются определенные условия. По плану, запрещают даже если у пользователя полные права.
Требуется в определенном месте кода проверить заданность у пользователя этой роли, независимо от наличия полных прав.

Собственно, появились вопросы.

1. Не совсем понятно, как эта роль задается пользователю вообще. Через "Конфигуратор - Администрирование - Пользователи" это сделать нельзя - роли просто нет в списке с флажками. Так задумано разработчиком технологии?

(Я через конфигуратор с тестовыми целями задавал, не желая при отладке влезать в профили групп доступа. Разумеется, затем добавил роль в профиль групп доступа, и назначил пользователю).

2. Теперь непонятно, как программно определить, есть эта роль, или нет.
Функция РольДоступна("РЗО_НаКонтроле") всегда возвращает Ложь. Подозреваю, что на уровне системы эта роль не задалась, потому что №1.
Функция УправлениеДоступом.ЕстьРоль вроде бы должна проверять не только задание ролей на уровне системы, но и на уровне профилей групп.
Однако для пользователя с полными правами она всегда возвращает Истина, потому что в ней есть код:

```1c
    Если Пользователи.ЭтоПолноправныйПользователь(Пользователь) Тогда
    Возврат Истина;
    КонецЕсли;
```

Примерно тоже самое делает Пользователи.РольДоступна, даже несмотря на заявленную возможность игнорировать полные права (если задать аргумент УчитыватьПривилегированныйРежим).
Колдовать свою функцию с запросом к профилям групп тоже не хочется.

Мне нужно просто иметь возможность задать пользователю роль из расширения и программно проверить ее установленность, независимо от наличия у пользователя полных прав / прав администрирования.
Как выкрутиться?
---
Разобрался.
Наличие у пользователя встроенного профиля Администратор препятствует добавлению каких-либо иных ролей, кроме ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок, независимо от присвоенных профилей.
Указанное поведение явным образом захардкодили в УправлениеДоступомСлужебный.ОбновитьРолиПользователей.
Я такой подставы не ожидал :-)

Если не присваивать пользователю профиль Администратора, то добавленные в расширении роли (помещенные в какой-либо профиль) прекрасно добавляются, и проверяются даже простым вызовом РольДоступна(...).

Спасибо всем, кто ответил. За ключевые моменты, которые дали мне отправную точку в разборках, распределил sm.
---
Пример добавления собственных ролей пользователям через расширение 1С: ссылка.
Роли, созданные в расширениях, вы можете добавить пользователю только программно. Например, таким образом.

Правильнее проверять не через строку РольДоступна( "РЗО_НаКонтроле"),
а через метаданные РольДоступна(Метаданные.Роли.РЗО_НаКонтроле).
---
Сначала выполняешь следующее:
1) Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(); так создастся эл. справочника ИдентификаторыОбъектовРасширений. После чего его можно будет выбирать в профили доступа.
2) Создаешь профиль и группу доступа в режиме предприятия
3) В коде пишешь
РольДоступна("РЗО_НаКонтроле")
---
Сначала выполняешь следующее:
1) Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(); так создастся эл. справочника ИдентификаторыОбъектовРасширений. После чего его можно будет выбирать в профили доступа.
2) Создаешь профиль и группу доступа в режиме предприятия
3) В коде пишешь
РольДоступна("РЗО_НаКонтроле")
---
Хм, забавно. ИдентификаторыОбъектовРасширений созданы как нужно (т.е. есть элемент справочника на мою добавленную роль). Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника() - я запустил уже после, оно ничего не поменяло.
В профиль полномочий роль добавлена.
Пользователю профиль назначен.
В конфигураторе не видно добавленных ролей (как это указано на картинке во вложении).
Профиль удален, передобавлен заново с перезаписью пользователя. Добавлен другому (не текущему) пользователю (вдруг это влияет).
В конфигураторе ролей все еще не видно.

Что я делаю не так?
---
Разобрался.
Наличие у пользователя встроенного профиля Администратор препятствует добавлению каких-либо иных ролей, кроме ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок, независимо от присвоенных профилей.
Указанное поведение явным образом захардкодили в УправлениеДоступомСлужебный.ОбновитьРолиПользователей.
Я такой подставы не ожидал :-)

Если не присваивать пользователю профиль Администратора, то добавленные в расширении роли (помещенные в какой-либо профиль) прекрасно добавляются, и проверяются даже простым вызовом РольДоступна(...).

Спасибо всем, кто ответил. За ключевые моменты, которые дали мне отправную точку в разборках, распределил sm.
---
Я такой подставы не ожидал :-)
Кстати, вполне логичное поведение с точки зрения оптимизации. Большое количество лишних ролей с RLS замедлит доступ к данным. А полные права по идее должны перекрывать все необходимые доступы.
---
пункт 1 делается сам сейчас.
Пункт 2 сделали ручками, роли очистились. Платформа 8.3.18, режим совместимости 8.3.12.
Пункт 3 возвращает ложь, нам нужно сопоставить профиль пользователя с ролями в конфигураторе.
---
нашел решение вопроса Проверка наличия роли у пользователя.
---
Пример добавления собственных ролей пользователям через расширение 1С: ссылка.
Роли, созданные в расширениях, вы можете добавить пользователю только программно. Например, таким образом.

Правильнее проверять не через строку РольДоступна( "РЗО_НаКонтроле"),
а через метаданные РольДоступна(Метаданные.Роли.РЗО_НаКонтроле).
---
Спасибо за ссылки, стало значительно понятнее в общей логике. Программно роль добавляется. С меня точно апельсин, как доразберусь с тем, что роль не добавляется на уровне управления пользователями в БП (см. (6))
---
Вот пример - тут это есть (установка роли из расширения и её проверка) https://infostart.ru/public/861358/
---
по пункту 2.
Синтаксис-помощник

РолиПользователя (UserRoles)

Содержит (Contains)
Синтаксис:
Содержит(<Роль>)
Параметры:
<Роль> (обязательный)
Тип: ОбъектМетаданных. Искомая роль.
Возвращаемое значение:
Тип: Булево. Истина - роль содержится в коллекции; Ложь - в противном случае.
Описание:
Определяет, содержит ли коллекция используемых ролей пользователя указанную роль.
 Отсюда строка Если НЕ ПользовательИБ.Роли.Содержит(РЗО_НаКонтроле) Тогда...
---
Этот вариант я тоже пробовал. Так же отрабатывает, как и РольДоступна. То есть, никак.

Проблема сейчас похоже в том, что мне не удается назначить роль штатными средствами БП.
---
Я бы решил задачу таким образом: взял за основу функцию УправлениеДоступом.ЕстьРоль()
- скопировал её в расширение, переименовал, и закомментировал злосчастные строки
// Если Пользователи.ЭтоПолноправныйПользователь(Пользователь) Тогда
// Возврат Истина;
// КонецЕсли;
А после в зависимости от целей и возможностей:
- либо оставил как независимую функцию с другим наименованием,
- либо дописал перед ней "&Вместо("ЕстьРоль")", предварительно добавив в расширение модуль УправлениеДоступом, и использовал стандартный вызов по типовому имени.

Сейчас проверил у себя в базе последний вариант - всё отработало на Ура!
---
Этот вариант я рассматривал как последнее средство.

Колдовать свою функцию с запросом к профилям групп тоже не хочется

Зачем-то ведь сделали именно так, намеренно введя в код такие хаки. Боялся что-либо поломать на уровне типового поведения (если делать перехват), и не люблю дублировать код (если делать свою копию).
---
Лично я вышел из положения, вставив свою функцию проверки доступности роли:

```1c
    Функция РольРасширенияДоступна(ИмяРоли) Экспорт

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

    Запрос.УстановитьПараметр("ИмяРоли", ИмяРоли);
    Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь());

    УстановитьПривилегированныйРежим(Истина);
    РольНайдена = Не Запрос.Выполнить().Пустой();
    УстановитьПривилегированныйРежим(Ложь);

    Возврат РольНайдена;

    КонецФункции
```
---
Если добавить роль из расширения пользователю с полными правами в режиме конфигуратора, то функция РольДоступна(...) вполне срабатывает.