DepartmentProject/DepartmentPortal/Security/SecurityBusinessLogic/BusinessLogics/UserManager.cs

223 lines
5.7 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using ModelTools.BusinessLogics;
using SecurityBusinessLogic.BindingModels;
using SecurityBusinessLogic.ViewModels;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;
namespace SecurityBusinessLogic.BusinessLogics
{
/// <summary>
/// Менеджер по работе с пользователем системы
/// </summary>
public class UserManager
{
private readonly int _countDayToBanned = 3;
private readonly int _countMaxAttempt = 3;
private readonly RoleBusinessLogic _roleBusinessLogic;
private readonly UserBusinessLogic _userBusinessLogic;
private static UserManager _userManager;
private static readonly object _lockObject = new();
private UserManager()
{
_roleBusinessLogic = UnityContainerConfigurator.Resolve<RoleBusinessLogic>();
_userBusinessLogic = UnityContainerConfigurator.Resolve<UserBusinessLogic>();
}
public static UserManager GetInstance
{
get
{
if (_userManager == null)
{
lock (_lockObject)
{
_userManager = new UserManager();
}
}
return _userManager;
}
}
/// <summary>
/// Аутентифицированный пользователь
/// </summary>
public UserViewModel User { get; private set; }
/// <summary>
/// Список ролей аутентифицированного пользователь
/// </summary>
public List<Guid> Roles { get; private set; }
/// <summary>
/// Сообщение об ошибке
/// </summary>
public string ErrorMessage { get; private set; }
/// <summary>
/// Идентификатор аутентифицированного пользователь
/// </summary>
public Guid? UserId => User?.Id;
/// <summary>
/// Выполнена ли аутентификация
/// </summary>
public bool IsAuth => User != null;
/// <summary>
/// Аутентификация пользователя
/// </summary>
/// <param name="login"></param>
/// <param name="password"></param>
/// <returns></returns>
public async Task LoginAsync(string login, string password)
{
await Task.Run(() =>
{
UserSetBindingModel model;
var passwordHash = GetPasswordHash(password);
var user = _userBusinessLogic.GetElement(new UserGetBindingModel
{
Login = login,
Password = passwordHash,
SkipCheck = true
});
if (user == null)
{
if(_userBusinessLogic.Errors.Count > 0)
{
throw new Exception(_userBusinessLogic.Errors[0].Message);
}
user = _userBusinessLogic.GetElement(new UserGetBindingModel
{
Login = login,
IsBanned = true,
SkipCheck = true
});
if (user != null)
{
user.CountAttempt++;
if (user.CountAttempt > _countMaxAttempt)
{
user.IsBanned = true;
user.DateBanned = DateTime.Now;
}
model = GetSetBindingModel(user);
model.Password = passwordHash;
_userBusinessLogic.Update(model);
}
if (_userBusinessLogic.Errors.Count > 0)
{
throw new Exception(_userBusinessLogic.Errors[0].Message);
}
throw new Exception("Введен неверный логин/пароль");
}
if (user.IsBanned)
{
if (user.DateBanned.Value.AddDays(_countDayToBanned) > DateTime.Now)
{
user.IsBanned = false;
}
else
{
throw new Exception("Пользователь заблокирован");
}
}
user.DateLastVisit = DateTime.Now;
user.CountAttempt = 0;
model = GetSetBindingModel(user);
model.Password = passwordHash;
_userBusinessLogic.Update(model);
User = user;
Roles = _roleBusinessLogic.GetList(new RoleGetBindingModel { UserId = User.Id }).List.Select(x => x.Id).ToList();
});
}
/// <summary>
/// Выход из системы
/// </summary>
/// <returns></returns>
public async Task LogoutAsync()
{
await Task.Run(() =>
{
User = null;
Roles = null;
});
}
/// <summary>
/// Смена пароля
/// </summary>
/// <param name="login"></param>
/// <param name="oldPassword"></param>
/// <param name="newPassword"></param>
public void ChangePassword(string login, string oldPassword, string newPassword)
{
var user = _userBusinessLogic.GetElement(new UserGetBindingModel
{
Login = login,
Password = GetPasswordHash(oldPassword),
SkipCheck = true
});
if (user == null)
{
throw new Exception("Введен неверный логин/пароль");
}
if (user.IsBanned)
{
throw new Exception("Пользователь забаннен");
}
var model = GetSetBindingModel(user);
model.Password = GetPasswordHash(newPassword);
_userBusinessLogic.Update(model);
}
/// <summary>
/// Получение хеша пароля
/// </summary>
/// <param name="password"></param>
/// <returns></returns>
public static string GetPasswordHash(string password) => Encoding.ASCII.GetString((new MD5CryptoServiceProvider()).ComputeHash(Encoding.ASCII.GetBytes(password)));
/// <summary>
/// Получение модели для сохранения из представления
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
private static UserSetBindingModel GetSetBindingModel(UserViewModel model)
{
return new UserSetBindingModel
{
Id = model.Id,
Login = model.Login,
LecturerId = model.LecturerId,
StudentId = model.StudentId,
EmployeeId = model.EmployeeId,
Avatar = model.Avatar,
IsBanned = model.IsBanned,
DateBanned = model.DateBanned,
CountAttempt = model.CountAttempt,
DateLastVisit = model.DateLastVisit
};
}
}
}