ОбновитьРолиВнешнихПользователей (БСП)

Автор: 1С
ОбщийМодуль.ПользователиСлужебный
1С БСП

Обновить роли внешних пользователей. Обновляет список ролей пользователей информационной базы, которые соответствуют

// Обновляет список ролей пользователей информационной базы, которые соответствуют
// внешним пользователям. Состав ролей вычисляется исходя из вхождения внешних
// пользователей в группы внешних пользователей, кроме тех внешних пользователей,
// для которых роли установлены непосредственно.
//  Требуется только при разрешении редактирования ролей, например, если
// встроена подсистема Управление доступом, то эта процедура не требуется.
// 
// Параметры:
//  МассивВнешнихПользователей - Неопределено - все внешние пользователи.
//                               СправочникСсылка.ГруппаВнешнихПользователей,
//                               Массив элементов СправочникСсылка.ВнешниеПользователи.
//
Процедура ОбновитьРолиВнешнихПользователей(Знач МассивВнешнихПользователей = Неопределено) Экспорт
	
	Если ЗапретРедактированияРолей() Тогда
		// Роли устанавливаются другим механизмом, например, механизмом подсистемы УправлениеДоступом.
		Возврат;
	КонецЕсли;
	
	Если ТипЗнч(МассивВнешнихПользователей) = Тип("Массив")
	   И МассивВнешнихПользователей.Количество() = 0 Тогда
		
		Возврат;
	КонецЕсли;
	
	УстановитьПривилегированныйРежим(Истина);
	
	НачатьТранзакцию();
	Попытка
		Если ТипЗнч(МассивВнешнихПользователей) <> Тип("Массив") Тогда
			
			Если МассивВнешнихПользователей = Неопределено Тогда
				ГруппаВнешнихПользователей = Справочники.ГруппыВнешнихПользователей.ВсеВнешниеПользователи;
			Иначе
				ГруппаВнешнихПользователей = МассивВнешнихПользователей;
			КонецЕсли;
			
			Запрос = Новый Запрос;
			Запрос.УстановитьПараметр("ГруппаВнешнихПользователей", ГруппаВнешнихПользователей);
			Запрос.Текст =
			"ВЫБРАТЬ
			|	СоставыГруппПользователей.Пользователь
			|ИЗ
			|	РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
			|ГДЕ
			|	СоставыГруппПользователей.ГруппаПользователей = &ГруппаВнешнихПользователей";
			
			МассивВнешнихПользователей = Запрос.Выполнить().Выгрузить().ВыгрузитьКолонку("Пользователь");
		КонецЕсли;
		
		Пользователи.НайтиНеоднозначныхПользователейИБ(Неопределено);
		
		ИдентификаторыПользователейИБ = Новый Соответствие;
		
		Запрос = Новый Запрос;
		Запрос.УстановитьПараметр("ВнешниеПользователи", МассивВнешнихПользователей);
		Запрос.Текст =
		"ВЫБРАТЬ
		|	ВнешниеПользователи.Ссылка КАК ВнешнийПользователь,
		|	ВнешниеПользователи.ИдентификаторПользователяИБ
		|ИЗ
		|	Справочник.ВнешниеПользователи КАК ВнешниеПользователи
		|ГДЕ
		|	ВнешниеПользователи.Ссылка В(&ВнешниеПользователи)
		|	И (НЕ ВнешниеПользователи.УстановитьРолиНепосредственно)";
		
		Выборка = Запрос.Выполнить().Выбрать();
		Пока Выборка.Следующий() Цикл
			ИдентификаторыПользователейИБ.Вставить(
				Выборка.ВнешнийПользователь, Выборка.ИдентификаторПользователяИБ);
		КонецЦикла;
		
		// Подготовка таблицы старых ролей внешних пользователей.
		СтарыеРолиВнешнихПользователей = Новый ТаблицаЗначений;
		
		СтарыеРолиВнешнихПользователей.Колонки.Добавить(
			"ВнешнийПользователь", Новый ОписаниеТипов("СправочникСсылка.ВнешниеПользователи"));
		
		СтарыеРолиВнешнихПользователей.Колонки.Добавить(
			"Роль", Новый ОписаниеТипов("Строка", , Новый КвалификаторыСтроки(200)));
		
		ТекущийНомер = МассивВнешнихПользователей.Количество() - 1;
		Пока ТекущийНомер >= 0 Цикл
			
			// Проверка необходимости обработки пользователя.
			ПользовательИБ = Неопределено;
			ИдентификаторПользователяИБ = ИдентификаторыПользователейИБ[МассивВнешнихПользователей[ТекущийНомер]];
			Если ИдентификаторПользователяИБ <> Неопределено Тогда
				
				ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
					ИдентификаторПользователяИБ);
			КонецЕсли;
			
			Если ПользовательИБ = Неопределено
			 ИЛИ ПустаяСтрока(ПользовательИБ.Имя) Тогда
				
				МассивВнешнихПользователей.Удалить(ТекущийНомер);
			Иначе
				Для каждого Роль Из ПользовательИБ.Роли Цикл
					СтараяРольВнешнегоПользователя = СтарыеРолиВнешнихПользователей.Добавить();
					СтараяРольВнешнегоПользователя.ВнешнийПользователь = МассивВнешнихПользователей[ТекущийНомер];
					СтараяРольВнешнегоПользователя.Роль = Роль.Имя;
				КонецЦикла;
			КонецЕсли;
			ТекущийНомер = ТекущийНомер - 1;
		КонецЦикла;
		
		// Подготовка списка ролей отсутствующих в метаданных и которые нужно переустановить.
		Запрос = Новый Запрос;
		Запрос.МенеджерВременныхТаблиц = Новый МенеджерВременныхТаблиц;
		Запрос.УстановитьПараметр("ВнешниеПользователи", МассивВнешнихПользователей);
		Запрос.УстановитьПараметр("ВсеРоли", ВсеРоли().Таблица.Получить());
		Запрос.УстановитьПараметр("СтарыеРолиВнешнихПользователей", СтарыеРолиВнешнихПользователей);
		Запрос.УстановитьПараметр("ИспользоватьВнешнихПользователей",
			ПолучитьФункциональнуюОпцию("ИспользоватьВнешнихПользователей"));
		// АПК:96-выкл: допустимо, так как строки не должны повторятся и объем данных небольшой (от единиц до тысяч).
		Запрос.Текст =
		"ВЫБРАТЬ
		|	СтарыеРолиВнешнихПользователей.ВнешнийПользователь,
		|	СтарыеРолиВнешнихПользователей.Роль
		|ПОМЕСТИТЬ СтарыеРолиВнешнихПользователей
		|ИЗ
		|	&СтарыеРолиВнешнихПользователей КАК СтарыеРолиВнешнихПользователей
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВсеРоли.Имя
		|ПОМЕСТИТЬ ВсеРоли
		|ИЗ
		|	&ВсеРоли КАК ВсеРоли
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	СоставыГруппПользователей.ГруппаПользователей КАК ГруппаВнешнихПользователей,
		|	СоставыГруппПользователей.Пользователь КАК ВнешнийПользователь,
		|	Роли.Роль.Имя КАК Роль
		|ПОМЕСТИТЬ ВсеНовыеРолиВнешнихПользователей
		|ИЗ
		|	Справочник.ГруппыВнешнихПользователей.Роли КАК Роли
		|		ВНУТРЕННЕЕ СОЕДИНЕНИЕ РегистрСведений.СоставыГруппПользователей КАК СоставыГруппПользователей
		|		ПО (СоставыГруппПользователей.Пользователь В (&ВнешниеПользователи))
		|			И (СоставыГруппПользователей.ГруппаПользователей = Роли.Ссылка)
		|			И (&ИспользоватьВнешнихПользователей = ИСТИНА)
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ РАЗЛИЧНЫЕ
		|	ВсеНовыеРолиВнешнихПользователей.ВнешнийПользователь,
		|	ВсеНовыеРолиВнешнихПользователей.Роль
		|ПОМЕСТИТЬ НовыеРолиВнешнихПользователей
		|ИЗ
		|	ВсеНовыеРолиВнешнихПользователей КАК ВсеНовыеРолиВнешнихПользователей
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	СтарыеРолиВнешнихПользователей.ВнешнийПользователь
		|ПОМЕСТИТЬ ИзмененныеВнешниеПользователи
		|ИЗ
		|	СтарыеРолиВнешнихПользователей КАК СтарыеРолиВнешнихПользователей
		|		ЛЕВОЕ СОЕДИНЕНИЕ НовыеРолиВнешнихПользователей КАК НовыеРолиВнешнихПользователей
		|		ПО (НовыеРолиВнешнихПользователей.ВнешнийПользователь = СтарыеРолиВнешнихПользователей.ВнешнийПользователь)
		|			И (НовыеРолиВнешнихПользователей.Роль = СтарыеРолиВнешнихПользователей.Роль)
		|ГДЕ
		|	НовыеРолиВнешнихПользователей.Роль ЕСТЬ NULL 
		|
		|ОБЪЕДИНИТЬ
		|
		|ВЫБРАТЬ
		|	НовыеРолиВнешнихПользователей.ВнешнийПользователь
		|ИЗ
		|	НовыеРолиВнешнихПользователей КАК НовыеРолиВнешнихПользователей
		|		ЛЕВОЕ СОЕДИНЕНИЕ СтарыеРолиВнешнихПользователей КАК СтарыеРолиВнешнихПользователей
		|		ПО НовыеРолиВнешнихПользователей.ВнешнийПользователь = СтарыеРолиВнешнихПользователей.ВнешнийПользователь
		|			И НовыеРолиВнешнихПользователей.Роль = СтарыеРолиВнешнихПользователей.Роль
		|ГДЕ
		|	СтарыеРолиВнешнихПользователей.Роль ЕСТЬ NULL 
		|;
		|
		|////////////////////////////////////////////////////////////////////////////////
		|ВЫБРАТЬ
		|	ВсеНовыеРолиВнешнихПользователей.ГруппаВнешнихПользователей,
		|	ВсеНовыеРолиВнешнихПользователей.ВнешнийПользователь,
		|	ВсеНовыеРолиВнешнихПользователей.Роль
		|ИЗ
		|	ВсеНовыеРолиВнешнихПользователей КАК ВсеНовыеРолиВнешнихПользователей
		|ГДЕ
		|	НЕ ИСТИНА В
		|				(ВЫБРАТЬ ПЕРВЫЕ 1
		|					ИСТИНА КАК ЗначениеИстина
		|				ИЗ
		|					ВсеРоли КАК ВсеРоли
		|				ГДЕ
		|					ВсеРоли.Имя = ВсеНовыеРолиВнешнихПользователей.Роль)";
		// АПК:96-вкл: допустимо, так как строки не должны повторятся и объем данных небольшой (от единиц до тысяч).
		
		// Регистрация ошибок имен ролей в профилях групп доступа.
		Выборка = Запрос.Выполнить().Выбрать();
		Пока Выборка.Следующий() Цикл
			
			ТекстСообщения = СтроковыеФункцииКлиентСервер.ПодставитьПараметрыВСтроку(
				НСтр("ru= 'При обновлении ролей внешнего пользователя
				          |""%1""
				          |роль ""%2""
				          |группы внешних пользователей ""%3""
				          |не найдена в метаданных.'"),
				СокрЛП(Выборка.ВнешнийПользователь.Наименование),
				Выборка.Роль,
				Строка(Выборка.ГруппаВнешнихПользователей));
			
			ЗаписьЖурналаРегистрации(
				НСтр("ru = 'Пользователи.Роль не найдена в метаданных'",
				     ОбщегоНазначения.КодОсновногоЯзыка()),
				УровеньЖурналаРегистрации.Ошибка,
				,
				,
				ТекстСообщения,
				РежимТранзакцииЗаписиЖурналаРегистрации.Транзакционная);
		КонецЦикла;
		
		// Обновление ролей пользователей ИБ.
		Запрос.Текст =
		"ВЫБРАТЬ
		|	ИзмененныеВнешниеПользователиИРоли.ВнешнийПользователь,
		|	ИзмененныеВнешниеПользователиИРоли.Роль
		|ИЗ
		|	(ВЫБРАТЬ
		|		НовыеРолиВнешнихПользователей.ВнешнийПользователь КАК ВнешнийПользователь,
		|		НовыеРолиВнешнихПользователей.Роль КАК Роль
		|	ИЗ
		|		НовыеРолиВнешнихПользователей КАК НовыеРолиВнешнихПользователей
		|	ГДЕ
		|		НовыеРолиВнешнихПользователей.ВнешнийПользователь В
		|				(ВЫБРАТЬ
		|					ИзмененныеВнешниеПользователи.ВнешнийПользователь
		|				ИЗ
		|					ИзмененныеВнешниеПользователи КАК ИзмененныеВнешниеПользователи)
		|	
		|	ОБЪЕДИНИТЬ ВСЕ
		|	
		|	ВЫБРАТЬ
		|		ВнешниеПользователи.Ссылка,
		|		""""
		|	ИЗ
		|		Справочник.ВнешниеПользователи КАК ВнешниеПользователи
		|	ГДЕ
		|		ВнешниеПользователи.Ссылка В
		|				(ВЫБРАТЬ
		|					ИзмененныеВнешниеПользователи.ВнешнийПользователь
		|				ИЗ
		|					ИзмененныеВнешниеПользователи КАК ИзмененныеВнешниеПользователи)) КАК ИзмененныеВнешниеПользователиИРоли
		|
		|УПОРЯДОЧИТЬ ПО
		|	ИзмененныеВнешниеПользователиИРоли.ВнешнийПользователь,
		|	ИзмененныеВнешниеПользователиИРоли.Роль";
		Выборка = Запрос.Выполнить().Выбрать();
		
		ПользовательИБ = Неопределено;
		Пока Выборка.Следующий() Цикл
			Если ЗначениеЗаполнено(Выборка.Роль) Тогда
				ПользовательИБ.Роли.Добавить(Метаданные.Роли[Выборка.Роль]);
				Продолжить;
			КонецЕсли;
			Если ПользовательИБ <> Неопределено Тогда
				ПользовательИБ.Записать();
			КонецЕсли;
			
			ПользовательИБ = ПользователиИнформационнойБазы.НайтиПоУникальномуИдентификатору(
				ИдентификаторыПользователейИБ[Выборка.ВнешнийПользователь]);
			
			ПользовательИБ.Роли.Очистить();
		КонецЦикла;
		Если ПользовательИБ <> Неопределено Тогда
			ПользовательИБ.Записать();
		КонецЕсли;
		
		ЗафиксироватьТранзакцию();
	Исключение
		ОтменитьТранзакцию();
		ВызватьИсключение;
	КонецПопытки;
	
КонецПроцедуры

///////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2019, ООО 1С-Софт
// Все права защищены. Эта программа и сопроводительные материалы предоставляются 
// в соответствии с условиями лицензии Attribution 4.0 International (CC BY 4.0)
// Текст лицензии доступен по ссылке:
// https://creativecommons.org/licenses/by/4.0/legalcode
///////////////////////////////////////////////////////////////////////////////////////////////////////

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

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

ОбновитьРолиПользователей (БСП)

НедоступныеРолиПоТипуПользователя (БСП)

ОбновитьПредставлениеВнешнегоПользователяПриЗаписи (БСП)

ОбновитьСоставыГруппВнешнихПользователей (БСП)

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

ПриОбновленииРолейПользователяИБ (БСП)

ЗапретРедактированияРолей (БСП)

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