Compare commits
4 Commits
78e87103ef
...
0517a6cfb0
Author | SHA1 | Date | |
---|---|---|---|
0517a6cfb0 | |||
054ed4b461 | |||
4f472bce41 | |||
c902050055 |
@ -1,4 +1,5 @@
|
||||
using Contracts.BindingModels;
|
||||
using BusinessLogic.Tools;
|
||||
using Contracts.BindingModels;
|
||||
using Contracts.BusinessLogicContracts;
|
||||
using Contracts.Converters;
|
||||
using Contracts.Exceptions;
|
||||
@ -28,7 +29,10 @@ namespace BusinessLogic.BusinessLogic
|
||||
public UserViewModel Create(UserBindingModel model)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(model);
|
||||
|
||||
// Проверяем пароль
|
||||
_validatePassword(model.Password);
|
||||
// Хешируем пароль
|
||||
model.PasswordHash = PasswordHasher.Hash(model.Password);
|
||||
var user = _userStorage.Insert(model);
|
||||
if (user is null)
|
||||
{
|
||||
@ -46,7 +50,7 @@ namespace BusinessLogic.BusinessLogic
|
||||
var user = _userStorage.Delete(model);
|
||||
if (user is null)
|
||||
{
|
||||
throw new Exception("Update operation failed.");
|
||||
throw new ElementNotFoundException();
|
||||
}
|
||||
|
||||
return UserConverter.ToView(user);
|
||||
@ -85,6 +89,11 @@ namespace BusinessLogic.BusinessLogic
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(model);
|
||||
|
||||
if (model.Password is not null)
|
||||
{
|
||||
_validatePassword(model.Password);
|
||||
model.PasswordHash = PasswordHasher.Hash(model.Password);
|
||||
}
|
||||
var user = _userStorage.Update(model);
|
||||
if (user is null)
|
||||
{
|
||||
@ -92,5 +101,32 @@ namespace BusinessLogic.BusinessLogic
|
||||
}
|
||||
return UserConverter.ToView(user);
|
||||
}
|
||||
|
||||
public UserViewModel Login(UserBindingModel model)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(model);
|
||||
|
||||
var user = _userStorage.GetElement(new() { Email = model.Email });
|
||||
|
||||
if (user is null)
|
||||
{
|
||||
throw new ElementNotFoundException();
|
||||
}
|
||||
// Проверяем пароль
|
||||
_validatePassword(model.Password);
|
||||
if (PasswordHasher.Verify(model.Password, user.PasswordHash))
|
||||
{
|
||||
throw new AccountException("The passwords don't match.");
|
||||
}
|
||||
return UserConverter.ToView(user);
|
||||
}
|
||||
|
||||
public void _validatePassword(string? password)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(password))
|
||||
{
|
||||
throw new AccountException("The password is null.");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
38
BusinessLogic/Tools/PasswordHasher.cs
Normal file
38
BusinessLogic/Tools/PasswordHasher.cs
Normal file
@ -0,0 +1,38 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace BusinessLogic.Tools
|
||||
{
|
||||
internal class PasswordHasher
|
||||
{
|
||||
/// <summary>
|
||||
/// Хеширует с использование SHA256
|
||||
/// </summary>
|
||||
/// <param name="password">Пароль</param>
|
||||
/// <returns>Хеш пароля</returns>
|
||||
public static string Hash(string password)
|
||||
{
|
||||
using (SHA256 sha256 = SHA256.Create())
|
||||
{
|
||||
byte[] bytes = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
|
||||
return Convert.ToBase64String(bytes);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Проверяет на соответствие пароля и его хеша
|
||||
/// </summary>
|
||||
/// <param name="password">Пароль</param>
|
||||
/// <param name="passHash">Хеш пароля</param>
|
||||
/// <returns></returns>
|
||||
public static bool Verify(string password, string passHash)
|
||||
{
|
||||
var hash = Hash(password);
|
||||
return hash == passHash;
|
||||
}
|
||||
}
|
||||
}
|
@ -13,6 +13,7 @@ namespace Contracts.BindingModels
|
||||
public string SecondName { get; set; } = string.Empty;
|
||||
public string Email { get; set; } = string.Empty;
|
||||
public string PasswordHash { get; set; } = string.Empty;
|
||||
public string? Password { get; set; }
|
||||
public DateTime Birthday { get; set; }
|
||||
public RoleBindingModel Role { get; set; } = null!;
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ namespace Contracts.BusinessLogicContracts
|
||||
{
|
||||
public interface IUserLogic
|
||||
{
|
||||
UserViewModel Login(UserBindingModel model);
|
||||
|
||||
UserViewModel Create(UserBindingModel model);
|
||||
|
||||
UserViewModel Update(UserBindingModel model);
|
||||
|
23
Contracts/Exceptions/AccountException.cs
Normal file
23
Contracts/Exceptions/AccountException.cs
Normal file
@ -0,0 +1,23 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Contracts.Exceptions
|
||||
{
|
||||
public class AccountException : Exception
|
||||
{
|
||||
public AccountException()
|
||||
{
|
||||
}
|
||||
|
||||
public AccountException(string message) : base(message)
|
||||
{
|
||||
}
|
||||
|
||||
public AccountException(string message, Exception inner) : base(message, inner)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
@ -32,7 +32,7 @@ namespace RestAPI.Controllers
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogInformation(ex, "Element not found");
|
||||
_logger.LogInformation(ex, "Role not found");
|
||||
return Results.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
@ -87,7 +87,7 @@ namespace RestAPI.Controllers
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPut]
|
||||
[HttpPatch]
|
||||
public IResult Update([FromBody] RoleBindingModel model)
|
||||
{
|
||||
try
|
||||
|
128
RestAPI/Controllers/UserController.cs
Normal file
128
RestAPI/Controllers/UserController.cs
Normal file
@ -0,0 +1,128 @@
|
||||
using BusinessLogic.BusinessLogic;
|
||||
using Contracts.BindingModels;
|
||||
using Contracts.BusinessLogicContracts;
|
||||
using Contracts.Exceptions;
|
||||
using Contracts.SearchModels;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
|
||||
namespace RestAPI.Controllers
|
||||
{
|
||||
[Route("[controller]/[action]")]
|
||||
[ApiController]
|
||||
public class UserController
|
||||
{
|
||||
private readonly ILogger _logger;
|
||||
private readonly IUserLogic _userLogic;
|
||||
|
||||
public UserController(ILogger<UserController> logger, IUserLogic userLogic)
|
||||
{
|
||||
_userLogic = userLogic;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IResult Login([FromBody] UserBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = _userLogic.Login(model);
|
||||
return Results.Ok(res);
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogInformation(ex, "User not found");
|
||||
return Results.NoContent();
|
||||
}
|
||||
catch (AccountException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Wrong login data");
|
||||
return Results.BadRequest(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error get user");
|
||||
return Results.Problem(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPost]
|
||||
public IResult Registration([FromBody] UserBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = _userLogic.Login(model);
|
||||
return Results.Ok(res);
|
||||
}
|
||||
catch (AccountException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Wrong registration data");
|
||||
return Results.BadRequest(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error create user");
|
||||
return Results.Problem(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpGet]
|
||||
public IResult Get([FromQuery] UserSearchModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = _userLogic.ReadElement(model);
|
||||
return Results.Ok(res);
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogInformation(ex, "User not found");
|
||||
return Results.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error get user");
|
||||
return Results.Problem(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpPatch]
|
||||
public IResult Update([FromBody] UserBindingModel model)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = _userLogic.Update(model);
|
||||
return Results.Ok(res);
|
||||
}
|
||||
catch (AccountException ex)
|
||||
{
|
||||
_logger.LogWarning(ex, "Wrong update data");
|
||||
return Results.BadRequest(ex.Message);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error update user");
|
||||
return Results.Problem(ex.Message);
|
||||
}
|
||||
}
|
||||
|
||||
[HttpDelete]
|
||||
public IResult Delete(Guid id)
|
||||
{
|
||||
try
|
||||
{
|
||||
var res = _userLogic.Delete(new() { Id = id });
|
||||
return Results.Ok(res);
|
||||
}
|
||||
catch (ElementNotFoundException ex)
|
||||
{
|
||||
_logger.LogInformation(ex, "User not found");
|
||||
return Results.NoContent();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
_logger.LogError(ex, "Error delete user");
|
||||
return Results.Problem(ex.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user