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