ЕстьРоль (БСП)

Автор: 1С
ОбщийМодуль.УправлениеДоступом
1С БСП

Есть роль. Проверяет, что у пользователя есть роль в одном из профилей тех групп доступа, в которых он участвует,

// Проверяет, что у пользователя есть роль в одном из профилей тех групп доступа, в которых он участвует,
// например: роль ПросмотрЖурналаРегистрации, роль ПечатьНепроведенныхДокументов.
//
// Если указан объект (или наборы значений доступа), тогда дополнительно проверяется,
// что группа доступа предоставляет право Чтение указанного объекта (или набор значений доступа разрешен).
//
// Параметры:
//  Роль           - Строка - имя роли.
//
//  СсылкаНаОбъект - Ссылка - на объект, для которого заполняются наборы значений доступа
//                   для проверки права Чтение.
//                 - ТаблицаЗначений - таблица произвольных наборов значений доступа с колонками:
//                     * НомерНабора     - Число  - номер, группирующий несколько строк в отдельный набор.
//                     * ВидДоступа      - Строка - имя вида доступа, указанного в переопределяемом модуле.
//                     * ЗначениеДоступа - Ссылка - на тип значения доступа, указанного в переопределяемом модуле.
//                       Пустую подготовленную таблицу можно получить с помощью функции
//                       ТаблицаНаборыЗначенийДоступа общего модуля УправлениеДоступом
//                       (колонки Чтение, Изменение не заполнять).
//
//  Пользователь   - СправочникСсылка.Пользователи, СправочникСсылка.ВнешниеПользователи, Неопределено - если
//                   параметр не указан, тогда право проверяется для текущего пользователя.
//
// Возвращаемое значение:
//  Булево - если Истина, тогда у пользователя есть роль с учетом ограничений.
//
Функция ЕстьРоль(Знач Роль, Знач СсылкаНаОбъект = Неопределено, Знач Пользователь = Неопределено) Экспорт
	
	Пользователь = ?(ЗначениеЗаполнено(Пользователь), Пользователь, Пользователи.АвторизованныйПользователь());
	Если Пользователи.ЭтоПолноправныйПользователь(Пользователь) Тогда
		Возврат Истина;
	КонецЕсли;
	Роль = ОбщегоНазначения.ИдентификаторОбъектаМетаданных("Роль." + Роль);
	
	УстановитьПривилегированныйРежим(Истина);
	
	Если СсылкаНаОбъект = Неопределено ИЛИ НЕ ОграничиватьДоступНаУровнеЗаписей() Тогда
		// Проверка, что роль назначается пользователю через группу доступа по профилю.
		Запрос = Новый Запрос;
		Запрос.УстановитьПараметр("АвторизованныйПользователь", Пользователь);
		Запрос.УстановитьПараметр("Роль", Роль);
		Запрос.Текст =
		"ВЫБРАТЬ ПЕРВЫЕ 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
///////////////////////////////////////////////////////////////////////////////////////////////////////

Рекомендации

Похожие публикации

ВсеРоли (БСП)

РольВладелец (БСП)

РольАдминистратор (БСП)

РольПользователь (БСП)

РольОператор (БСП)

ПредставлениеРоли (БСП)

ИдентификаторAPIРоли (БСП)

ПроверитьНазначениеРолей (БСП)

ЕстьИсполнителиРоли (БСП)

РолиДоступны (БСП)

Синтакс-помощник БСП с нейросетевым ассистентом