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

223 lines
5.7 KiB
C#
Raw Normal View History

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
};
}
}
}