ОбработатьНовыйПароль (БСП)

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

Обработать новый пароль. Для формы СменаПароля и перед записью пользователя ИБ.

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

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

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

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

ОбработатьПарольВФорме (БСП)

СоздатьПароль (БСП)

ПодсказкаДляНовогоПароля (БСП)

ОбработатьНовыйДескриптор (БСП)

ОбработатьНовыеДанные (БСП)

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