ПостоянныеВидыОграниченийПравОбъектовМетаданных (БСП)

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

Постоянные виды ограничений прав объектов метаданных. Возвращает таблицу значений, содержащую вид ограничений доступа по каждому праву

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

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

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

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

ПриЗаполненииВидовОграниченийПравОбъектовМетаданных (БСП)

ВидыОграниченийПравОбъектовМетаданных (БСП)

TurboConf ИР адаптер 2.47