Есть роль. Проверяет, что у пользователя есть роль в одном из профилей тех групп доступа, в которых он участвует,
// Проверяет, что у пользователя есть роль в одном из профилей тех групп доступа, в которых он участвует,
// например: роль ПросмотрЖурналаРегистрации, роль ПечатьНепроведенныхДокументов.
//
// Если указан объект (или наборы значений доступа), тогда дополнительно проверяется,
// что группа доступа предоставляет право Чтение указанного объекта (или набор значений доступа разрешен).
//
// Параметры:
// Роль - Строка - имя роли.
//
// СсылкаНаОбъект - Ссылка - на объект, для которого заполняются наборы значений доступа
// для проверки права Чтение.
// - ТаблицаЗначений - таблица произвольных наборов значений доступа с колонками:
// * НомерНабора - Число - номер, группирующий несколько строк в отдельный набор.
// * ВидДоступа - Строка - имя вида доступа, указанного в переопределяемом модуле.
// * ЗначениеДоступа - Ссылка - на тип значения доступа, указанного в переопределяемом модуле.
// Пустую подготовленную таблицу можно получить с помощью функции
// ТаблицаНаборыЗначенийДоступа общего модуля УправлениеДоступом
// (колонки Чтение, Изменение не заполнять).
//
// Пользователь - СправочникСсылка.Пользователи, СправочникСсылка.ВнешниеПользователи, Неопределено - если
// параметр не указан, тогда право проверяется для текущего пользователя.
//
// Возвращаемое значение:
// Булево - если Истина, тогда у пользователя есть роль с учетом ограничений.
//
Функция ЕстьРоль(Знач Роль, Знач СсылкаНаОбъект = Неопределено, Знач Пользователь = Неопределено) Экспорт
Пользователь = ?(ЗначениеЗаполнено(Пользователь), Пользователь, Пользователи.АвторизованныйПользователь());
Если Пользователи.ЭтоПолноправныйПользователь(Пользователь) Тогда
Возврат Истина;
КонецЕсли;
Роль = ОбщегоНазначения.ИдентификаторОбъектаМетаданных("Роль." + Роль);
УстановитьПривилегированныйРежим(Истина);
Если СсылкаНаОбъект = Неопределено ИЛИ НЕ ОграничиватьДоступНаУровнеЗаписей() Тогда
// Проверка, что роль назначается пользователю через группу доступа по профилю.
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("АвторизованныйПользователь", Пользователь);
Запрос.УстановитьПараметр("Роль", Роль);
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА КАК ЗначениеИстина
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ПО (СоставыГруппПользователей.Пользователь = &АвторизованныйПользователь)
| И (СоставыГруппПользователей.ГруппаПользователей = ГруппыДоступаПользователи.Пользователь)
| И (СоставыГруппПользователей.Используется)
| И (НЕ ГруппыДоступаПользователи.Ссылка.ПометкаУдаления)
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиГруппДоступаРоли
| ПО ГруппыДоступаПользователи.Ссылка.Профиль = ПрофилиГруппДоступаРоли.Ссылка
| И (ПрофилиГруппДоступаРоли.Роль = &Роль)
| И (НЕ ПрофилиГруппДоступаРоли.Ссылка.ПометкаУдаления)";
Возврат НЕ Запрос.Выполнить().Пустой();
КонецЕсли;
Если ТипЗнч(СсылкаНаОбъект) = Тип("ТаблицаЗначений") Тогда
НаборыЗначенийДоступа = СсылкаНаОбъект.Скопировать();
Иначе
НаборыЗначенийДоступа = ТаблицаНаборыЗначенийДоступа();
СсылкаНаОбъект.ПолучитьОбъект().ЗаполнитьНаборыЗначенийДоступа(НаборыЗначенийДоступа);
// Выбор только наборов значений доступа, предназначенных для проверки права Чтение.
СтрокиНаборовЧтения = НаборыЗначенийДоступа.НайтиСтроки(Новый Структура("Чтение", Истина));
НомераНаборов = Новый Соответствие;
Для каждого Строка Из СтрокиНаборовЧтения Цикл
НомераНаборов.Вставить(Строка.НомерНабора, Истина);
КонецЦикла;
Индекс = НаборыЗначенийДоступа.Количество()-1;
Пока Индекс > 0 Цикл
Если НомераНаборов[НаборыЗначенийДоступа[Индекс].НомерНабора] = Неопределено Тогда
НаборыЗначенийДоступа.Удалить(Индекс);
КонецЕсли;
Индекс = Индекс - 1;
КонецЦикла;
НаборыЗначенийДоступа.ЗаполнитьЗначения(Ложь, "Чтение, Изменение");
КонецЕсли;
// Уточнение наборов значений доступа.
ИменаВидовДоступа = УправлениеДоступомСлужебныйПовтИсп.СвойстваВидовДоступа().ПоИменам;
Для каждого Строка Из НаборыЗначенийДоступа Цикл
Если Строка.ВидДоступа = "" Тогда
Продолжить;
КонецЕсли;
Если ВРег(Строка.ВидДоступа) = ВРег("ПравоЧтения")
ИЛИ ВРег(Строка.ВидДоступа) = ВРег("ПравоИзменения") Тогда
Если ТипЗнч(Строка.ЗначениеДоступа) <> Тип("СправочникСсылка.ИдентификаторыОбъектовМетаданных") Тогда
Если ОбщегоНазначения.ЭтоСсылка(ТипЗнч(Строка.ЗначениеДоступа)) Тогда
Строка.ЗначениеДоступа = ОбщегоНазначения.ИдентификаторОбъектаМетаданных(ТипЗнч(Строка.ЗначениеДоступа));
Иначе
Строка.ЗначениеДоступа = Неопределено;
КонецЕсли;
КонецЕсли;
Если ВРег(Строка.ВидДоступа) = ВРег("ПравоИзменения") Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка в функции ЕстьРоль модуля УправлениеДоступом.
|В наборе значений доступа указан вид доступа ПравоИзменения
|таблицы с идентификатором ""%1"".
|В ограничении проверки роли (как дополнительного права)
|может быть зависимость только от права Чтения.'"),
Строка.ЗначениеДоступа);
КонецЕсли;
ИначеЕсли ИменаВидовДоступа.Получить(Строка.ВидДоступа) <> Неопределено
ИЛИ Строка.ВидДоступа = "НастройкиПрав" Тогда
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка в функции ЕстьРоль модуля УправлениеДоступом.
|Набор значений доступа содержит известный вид доступа ""%1"",
|который не требуется указывать.
|
|Указывать требуется только специальные виды доступа
|""ПравоЧтения"", ""ПравоИзменения"", если они используются.'"),
Строка.ВидДоступа);
Иначе
ВызватьИсключение СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
НСтр("ru = 'Ошибка в функции ЕстьРоль модуля УправлениеДоступом.
|Набор значений доступа содержит неизвестный вид доступа ""%1"".'"),
Строка.ВидДоступа);
КонецЕсли;
Строка.ВидДоступа = "";
КонецЦикла;
// Добавление служебных полей в набор значений доступа.
УправлениеДоступомСлужебный.ПодготовитьНаборыЗначенийДоступаКЗаписи(Неопределено, НаборыЗначенийДоступа, Истина);
// Проверка, что роль назначается пользователю через группу доступа по профилю с разрешенными наборами значений
// доступа.
Запрос = Новый Запрос;
Запрос.УстановитьПараметр("АвторизованныйПользователь", Пользователь);
Запрос.УстановитьПараметр("Роль", Роль);
Запрос.УстановитьПараметр("НаборыЗначенийДоступа", НаборыЗначенийДоступа);
Запрос.УстановитьПараметр("ТипыВладельцевНастроекПрав", ПараметрыСеанса.ТипыВладельцевНастроекПрав);
Запрос.Текст =
"ВЫБРАТЬ РАЗЛИЧНЫЕ
| НаборыЗначенийДоступа.НомерНабора,
| НаборыЗначенийДоступа.ЗначениеДоступа,
| НаборыЗначенийДоступа.ЗначениеБезГрупп,
| НаборыЗначенийДоступа.СтандартноеЗначение
|ПОМЕСТИТЬ НаборыЗначенийДоступа
|ИЗ
| &НаборыЗначенийДоступа КАК НаборыЗначенийДоступа
|
|ИНДЕКСИРОВАТЬ ПО
| НаборыЗначенийДоступа.НомерНабора,
| НаборыЗначенийДоступа.ЗначениеДоступа
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| ГруппыДоступаПользователи.Ссылка КАК Ссылка
|ПОМЕСТИТЬ ГруппыДоступа
|ИЗ
| Справочник.ГруппыДоступа.Пользователи КАК ГруппыДоступаПользователи
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ПО (СоставыГруппПользователей.Пользователь = &АвторизованныйПользователь)
| И (СоставыГруппПользователей.ГруппаПользователей = ГруппыДоступаПользователи.Пользователь)
| И (СоставыГруппПользователей.Используется)
| И (НЕ ГруппыДоступаПользователи.Ссылка.ПометкаУдаления)
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ Справочник.ПрофилиГруппДоступа.Роли КАК ПрофилиГруппДоступаРоли
| ПО ГруппыДоступаПользователи.Ссылка.Профиль = ПрофилиГруппДоступаРоли.Ссылка
| И (ПрофилиГруппДоступаРоли.Роль = &Роль)
| И (НЕ ПрофилиГруппДоступаРоли.Ссылка.ПометкаУдаления)
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ РАЗЛИЧНЫЕ
| Наборы.НомерНабора
|ПОМЕСТИТЬ НомераНаборов
|ИЗ
| НаборыЗначенийДоступа КАК Наборы
|
|ИНДЕКСИРОВАТЬ ПО
| Наборы.НомерНабора
|;
|
|////////////////////////////////////////////////////////////////////////////////
|ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА КАК ЗначениеИстина
|ИЗ
| ГруппыДоступа КАК ГруппыДоступа
|ГДЕ
| НЕ(ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| НомераНаборов КАК НомераНаборов
| ГДЕ
| ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| НаборыЗначенийДоступа КАК НаборыЗначений
| ГДЕ
| НаборыЗначений.НомерНабора = НомераНаборов.НомерНабора
| И НЕ ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.ЗначенияГруппДоступаПоУмолчанию КАК ЗначенияПоУмолчанию
| ГДЕ
| ЗначенияПоУмолчанию.ГруппаДоступа = ГруппыДоступа.Ссылка
| И ТИПЗНАЧЕНИЯ(ЗначенияПоУмолчанию.ТипЗначенийДоступа) = ТИПЗНАЧЕНИЯ(НаборыЗначений.ЗначениеДоступа)
| И ЗначенияПоУмолчанию.БезНастройки = ИСТИНА)))
| И НЕ ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| НомераНаборов КАК НомераНаборов
| ГДЕ
| ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| НаборыЗначенийДоступа КАК НаборыЗначений
| ГДЕ
| НаборыЗначений.НомерНабора = НомераНаборов.НомерНабора
| И НЕ ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.ЗначенияГруппДоступаПоУмолчанию КАК ЗначенияПоУмолчанию
| ГДЕ
| ЗначенияПоУмолчанию.ГруппаДоступа = ГруппыДоступа.Ссылка
| И ТИПЗНАЧЕНИЯ(ЗначенияПоУмолчанию.ТипЗначенийДоступа) = ТИПЗНАЧЕНИЯ(НаборыЗначений.ЗначениеДоступа)
| И ЗначенияПоУмолчанию.БезНастройки = ИСТИНА))
| И НЕ ЛОЖЬ В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ЛОЖЬ
| ИЗ
| НаборыЗначенийДоступа КАК НаборыЗначений
| ГДЕ
| НаборыЗначений.НомерНабора = НомераНаборов.НомерНабора
| И НЕ ВЫБОР
| КОГДА НаборыЗначений.ЗначениеБезГрупп
| ТОГДА ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.ЗначенияГруппДоступаПоУмолчанию КАК ЗначенияПоУмолчанию
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияГруппДоступа КАК Значения
| ПО
| Значения.ГруппаДоступа = ГруппыДоступа.Ссылка
| И Значения.ЗначениеДоступа = НаборыЗначений.ЗначениеДоступа
| ГДЕ
| ЗначенияПоУмолчанию.ГруппаДоступа = ГруппыДоступа.Ссылка
| И ТИПЗНАЧЕНИЯ(ЗначенияПоУмолчанию.ТипЗначенийДоступа) = ТИПЗНАЧЕНИЯ(НаборыЗначений.ЗначениеДоступа)
| И ЕСТЬNULL(Значения.ЗначениеРазрешено, ЗначенияПоУмолчанию.ВсеРазрешены))
| КОГДА НаборыЗначений.СтандартноеЗначение
| ТОГДА ВЫБОР
| КОГДА ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.ГруппыЗначенийДоступа КАК ГруппыЗначенийДоступа
| ГДЕ
| ГруппыЗначенийДоступа.ЗначениеДоступа = НаборыЗначений.ЗначениеДоступа
| И ГруппыЗначенийДоступа.ГруппаЗначенийДоступа = &АвторизованныйПользователь)
| ТОГДА ИСТИНА
| ИНАЧЕ ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.ЗначенияГруппДоступаПоУмолчанию КАК ЗначенияПоУмолчанию
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.ГруппыЗначенийДоступа КАК ГруппыЗначений
| ПО
| ГруппыЗначений.ЗначениеДоступа = НаборыЗначений.ЗначениеДоступа
| И ЗначенияПоУмолчанию.ГруппаДоступа = ГруппыДоступа.Ссылка
| И ТИПЗНАЧЕНИЯ(ЗначенияПоУмолчанию.ТипЗначенийДоступа) = ТИПЗНАЧЕНИЯ(НаборыЗначений.ЗначениеДоступа)
| ЛЕВОЕ СОЕДИНЕНИЕ РегистрСведений.ЗначенияГруппДоступа КАК Значения
| ПО
| Значения.ГруппаДоступа = ГруппыДоступа.Ссылка
| И Значения.ЗначениеДоступа = ГруппыЗначений.ГруппаЗначенийДоступа
| ГДЕ
| ЕСТЬNULL(Значения.ЗначениеРазрешено, ЗначенияПоУмолчанию.ВсеРазрешены))
| КОНЕЦ
| КОГДА НаборыЗначений.ЗначениеДоступа = ЗНАЧЕНИЕ(Перечисление.ДополнительныеЗначенияДоступа.ДоступРазрешен)
| ТОГДА ИСТИНА
| КОГДА НаборыЗначений.ЗначениеДоступа = ЗНАЧЕНИЕ(Перечисление.ДополнительныеЗначенияДоступа.ДоступЗапрещен)
| ТОГДА ЛОЖЬ
| КОГДА ТИПЗНАЧЕНИЯ(НаборыЗначений.ЗначениеДоступа) = ТИП(Справочник.ИдентификаторыОбъектовМетаданных)
| ТОГДА ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.ТаблицыГруппДоступа КАК ТаблицыГруппДоступаПроверкаПраваНаОбъект
| ГДЕ
| ТаблицыГруппДоступаПроверкаПраваНаОбъект.ГруппаДоступа = ГруппыДоступа.Ссылка
| И ТаблицыГруппДоступаПроверкаПраваНаОбъект.Таблица = НаборыЗначений.ЗначениеДоступа)
| ИНАЧЕ ИСТИНА В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ИСТИНА
| ИЗ
| РегистрСведений.НастройкиПравОбъектов КАК НастройкиПрав
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НаследованиеНастроекПравОбъектов КАК НаследованиеНастроек
| ПО
| НаследованиеНастроек.Объект = НаборыЗначений.ЗначениеДоступа
| И НастройкиПрав.Объект = НаследованиеНастроек.Родитель
| И НаследованиеНастроек.УровеньИспользования < НастройкиПрав.УровеньРазрешенияЧтения
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ПО
| СоставыГруппПользователей.Пользователь = &АвторизованныйПользователь
| И СоставыГруппПользователей.ГруппаПользователей = НастройкиПрав.Пользователь)
| И НЕ ЛОЖЬ В
| (ВЫБРАТЬ ПЕРВЫЕ 1
| ЛОЖЬ
| ИЗ
| РегистрСведений.НастройкиПравОбъектов КАК НастройкиПрав
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.НаследованиеНастроекПравОбъектов КАК НаследованиеНастроек
| ПО
| НаследованиеНастроек.Объект = НаборыЗначений.ЗначениеДоступа
| И НастройкиПрав.Объект = НаследованиеНастроек.Родитель
| И НаследованиеНастроек.УровеньИспользования < НастройкиПрав.УровеньЗапрещенияЧтения
| ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
| ПО
| СоставыГруппПользователей.Пользователь = &АвторизованныйПользователь
| И СоставыГруппПользователей.ГруппаПользователей = НастройкиПрав.Пользователь)
| КОНЕЦ)))";
Возврат НЕ Запрос.Выполнить().Пустой();
КонецФункции
///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////
Канал FastCode 1C в Телеграм! Шаблоны кода, статьи, полезные советы, курсы по 1С (8К участников)