223 lines
5.7 KiB
C#
223 lines
5.7 KiB
C#
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
|
||
};
|
||
}
|
||
}
|
||
} |