Добрый день, коллеги.
БП 3.0.63.15, платформа 8.3.10.2667.
Создано расширение конфигурации, в котором добавлена роль "РЗО_НаКонтроле". По сути, это ограничивающая роль. При ее наличии, перехваченные функции запрещают пользователю ряд действий, если исполняются определенные условия. По плану, запрещают даже если у пользователя полные права.
Требуется в определенном месте кода проверить заданность у пользователя этой роли, независимо от наличия полных прав.
Собственно, появились вопросы.
1. Не совсем понятно, как эта роль задается пользователю вообще. Через "Конфигуратор - Администрирование - Пользователи" это сделать нельзя - роли просто нет в списке с флажками. Так задумано разработчиком технологии?
(Я через конфигуратор с тестовыми целями задавал, не желая при отладке влезать в профили групп доступа. Разумеется, затем добавил роль в профиль групп доступа, и назначил пользователю).
2. Теперь непонятно, как программно определить, есть эта роль, или нет.
Функция РольДоступна("РЗО_НаКонтроле") всегда возвращает Ложь. Подозреваю, что на уровне системы эта роль не задалась, потому что №1.
Функция УправлениеДоступом.ЕстьРоль вроде бы должна проверять не только задание ролей на уровне системы, но и на уровне профилей групп.
Однако для пользователя с полными правами она всегда возвращает Истина, потому что в ней есть код:
Если Пользователи.ЭтоПолноправныйПользователь(Пользователь) Тогда
Возврат Истина;
КонецЕсли;
Примерно тоже самое делает Пользователи.РольДоступна, даже несмотря на заявленную возможность игнорировать полные права (если задать аргумент УчитыватьПривилегированныйРежим).
Колдовать свою функцию с запросом к профилям групп тоже не хочется.
Мне нужно просто иметь возможность задать пользователю роль из расширения и программно проверить ее установленность, независимо от наличия у пользователя полных прав / прав администрирования.
Как выкрутиться?
(6)
Разобрался.
Наличие у пользователя встроенного профиля Администратор препятствует добавлению каких-либо иных ролей, кроме ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок, независимо от присвоенных профилей.
Указанное поведение явным образом захардкодили в УправлениеДоступомСлужебный.ОбновитьРолиПользователей.
Я такой подставы не ожидал :-)
Если не присваивать пользователю профиль Администратора, то добавленные в расширении роли (помещенные в какой-либо профиль) прекрасно добавляются, и проверяются даже простым вызовом РольДоступна(...).
Спасибо всем, кто ответил. За ключевые моменты, которые дали мне отправную точку в разборках, распределил sm.
(1)
Пример добавления собственных ролей пользователям через расширение 1С: ссылка.
Роли, созданные в расширениях, вы можете добавить пользователю только программно. Например, таким образом.
Правильнее проверять не через строку РольДоступна( "РЗО_НаКонтроле"),
а через метаданные РольДоступна(Метаданные.Роли.РЗО_НаКонтроле).
(1)
Сначала выполняешь следующее:
1) Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(); так создастся эл. справочника ИдентификаторыОбъектовРасширений. После чего его можно будет выбирать в профили доступа.
2) Создаешь профиль и группу доступа в режиме предприятия
3) В коде пишешь
РольДоступна("РЗО_НаКонтроле")
(1)
Сначала выполняешь следующее:
1) Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника(); так создастся эл. справочника ИдентификаторыОбъектовРасширений. После чего его можно будет выбирать в профили доступа.
2) Создаешь профиль и группу доступа в режиме предприятия
3) В коде пишешь
РольДоступна("РЗО_НаКонтроле")
(3)
Хм, забавно. ИдентификаторыОбъектовРасширений созданы как нужно (т.е. есть элемент справочника на мою добавленную роль). Справочники.ИдентификаторыОбъектовМетаданных.ОбновитьДанныеСправочника() - я запустил уже после, оно ничего не поменяло.
В профиль полномочий роль добавлена.
Пользователю профиль назначен.
В конфигураторе не видно добавленных ролей (как это указано на картинке во вложении).
Профиль удален, передобавлен заново с перезаписью пользователя. Добавлен другому (не текущему) пользователю (вдруг это влияет).
В конфигураторе ролей все еще не видно.
(6)
Разобрался.
Наличие у пользователя встроенного профиля Администратор препятствует добавлению каких-либо иных ролей, кроме ПолныеПрава, АдминистраторСистемы и ИнтерактивноеОткрытиеВнешнихОтчетовИОбработок, независимо от присвоенных профилей.
Указанное поведение явным образом захардкодили в УправлениеДоступомСлужебный.ОбновитьРолиПользователей.
Я такой подставы не ожидал :-)
Если не присваивать пользователю профиль Администратора, то добавленные в расширении роли (помещенные в какой-либо профиль) прекрасно добавляются, и проверяются даже простым вызовом РольДоступна(...).
Спасибо всем, кто ответил. За ключевые моменты, которые дали мне отправную точку в разборках, распределил sm.
Кстати, вполне логичное поведение с точки зрения оптимизации. Большое количество лишних ролей с RLS замедлит доступ к данным. А полные права по идее должны перекрывать все необходимые доступы.
(3) пункт 1 делается сам сейчас.
Пункт 2 сделали ручками, роли очистились. Платформа 8.3.18, режим совместимости 8.3.12.
Пункт 3 возвращает ложь, нам нужно сопоставить профиль пользователя с ролями в конфигураторе.
(1)
Пример добавления собственных ролей пользователям через расширение 1С: ссылка.
Роли, созданные в расширениях, вы можете добавить пользователю только программно. Например, таким образом.
Правильнее проверять не через строку РольДоступна( "РЗО_НаКонтроле"),
а через метаданные РольДоступна(Метаданные.Роли.РЗО_НаКонтроле).
(4) Спасибо за ссылки, стало значительно понятнее в общей логике. Программно роль добавляется. С меня точно апельсин, как доразберусь с тем, что роль не добавляется на уровне управления пользователями в БП (см. (6))
Содержит (Contains)
Синтаксис:
Содержит(<Роль>)
Параметры:
<Роль> (обязательный)
Тип: ОбъектМетаданных. Искомая роль.
Возвращаемое значение:
Тип: Булево. Истина - роль содержится в коллекции; Ложь - в противном случае.
Описание:
Определяет, содержит ли коллекция используемых ролей пользователя указанную роль.
Отсюда строка Если НЕ ПользовательИБ.Роли.Содержит(РЗО_НаКонтроле) Тогда...
Я бы решил задачу таким образом: взял за основу функцию УправлениеДоступом.ЕстьРоль()
- скопировал её в расширение, переименовал, и закомментировал злосчастные строки
// Если Пользователи.ЭтоПолноправныйПользователь(Пользователь) Тогда
// Возврат Истина;
// КонецЕсли;
А после в зависимости от целей и возможностей:
- либо оставил как независимую функцию с другим наименованием,
- либо дописал перед ней "&Вместо("ЕстьРоль")", предварительно добавив в расширение модуль УправлениеДоступом, и использовал стандартный вызов по типовому имени.
Сейчас проверил у себя в базе последний вариант - всё отработало на Ура!
(9) Этот вариант я рассматривал как последнее средство.
Колдовать свою функцию с запросом к профилям групп тоже не хочется
Зачем-то ведь сделали именно так, намеренно введя в код такие хаки. Боялся что-либо поломать на уровне типового поведения (если делать перехват), и не люблю дублировать код (если делать свою копию).
Лично я вышел из положения, вставив свою функцию проверки доступности роли:
Функция РольРасширенияДоступна(ИмяРоли) Экспорт
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| ПрофилиГруппДоступаРоли.Роль КАК Роль
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиГруппДоступаРоли
| ПО ГруппыДоступаПользователи.Ссылка.Профиль = ПрофилиГруппДоступаРоли.Ссылка
|ГДЕ
| ГруппыДоступаПользователи.Пользователь = &Пользователь
| И ПрофилиГруппДоступаРоли.Роль ССЫЛКА Справочник.ИдентификаторыОбъектовРасширений
| И ВЫРАЗИТЬ(ПрофилиГруппДоступаРоли.Роль КАК Справочник.ИдентификаторыОбъектовРасширений).Имя = &ИмяРоли";
Запрос.УстановитьПараметр("ИмяРоли", ИмяРоли);
Запрос.УстановитьПараметр("Пользователь", Пользователи.ТекущийПользователь());
УстановитьПривилегированныйРежим(Истина);
РольНайдена = Не Запрос.Выполнить().Пустой();
УстановитьПривилегированныйРежим(Ложь);
Возврат РольНайдена;
КонецФункции