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