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