142 lines
4.9 KiB
C#
142 lines
4.9 KiB
C#
using back.DataModels;
|
|
using back.persistance.blob;
|
|
using back.persistance.data.repositories.Abstracts;
|
|
using back.services.engine.Crypto;
|
|
using back.services.engine.mailing;
|
|
using System.Text;
|
|
using System.Text.Json;
|
|
|
|
namespace back.services.bussines.UserService;
|
|
|
|
public class UserService(
|
|
IUserRepository userRepository, ICryptoService cryptoService,
|
|
IEmailService emailService,
|
|
IBlobStorageService blobStorageService,
|
|
JsonSerializerOptions jsonSerializerOptions
|
|
) : IUserService
|
|
{
|
|
private readonly IUserRepository _repository = userRepository ?? throw new ArgumentNullException(nameof(userRepository));
|
|
private readonly ICryptoService _cryptoService = cryptoService;
|
|
private readonly IEmailService _emailService = emailService;
|
|
private readonly IBlobStorageService _blobStorageService = blobStorageService;
|
|
|
|
public async Task<User?> Create(string clientId, User user)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(user);
|
|
|
|
if (user.Id != null && await _repository.Exists(user.Id))
|
|
{
|
|
return await _repository.GetById(user.Id);
|
|
}
|
|
if (string.IsNullOrEmpty(user.Email) || string.IsNullOrEmpty(user.Password))
|
|
{
|
|
return null;
|
|
}
|
|
if (await _repository.Exists(user.Email))
|
|
{
|
|
return await _repository.GetByEmail(user.Email);
|
|
}
|
|
|
|
if (string.IsNullOrEmpty(user.Salt))
|
|
{
|
|
user.Salt = _cryptoService.Salt();
|
|
}
|
|
user.Password = _cryptoService.Decrypt(clientId, user.Password) ?? string.Empty;
|
|
user.Password = _cryptoService.HashPassword(user.Password, user.Salt) ?? string.Empty;
|
|
|
|
user.CreatedAt = DateTimeOffset.UtcNow.ToString("dd-MM-yyyy HH:mm:ss zz");
|
|
|
|
//user.Roles.Add(Role.UserRole);
|
|
|
|
await _repository.Insert(user);
|
|
await _repository.SaveChanges();
|
|
return user;
|
|
}
|
|
|
|
public async Task<User?> Update(User user)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(user);
|
|
if (user.Id == null || !await _repository.Exists(user.Id))
|
|
{
|
|
return null;
|
|
}
|
|
var existingUser = await _repository.GetById(user.Id);
|
|
if (existingUser == null) return null;
|
|
existingUser.Email = user.Email;
|
|
await _repository.Update(existingUser);
|
|
await _repository.SaveChanges();
|
|
return existingUser;
|
|
}
|
|
|
|
public async Task<User?> Login(string email, string decryptedPass)
|
|
{
|
|
var salt = await _repository.GetUserSaltByEmail(email);
|
|
var hashedPassword = _cryptoService.HashPassword(decryptedPass, salt);
|
|
var user = await _repository.Login(email, hashedPassword ?? string.Empty);
|
|
return user;
|
|
}
|
|
|
|
public async Task<User?> Login(string email, string password, string clientId)
|
|
{
|
|
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(password)) return null;
|
|
|
|
try
|
|
{
|
|
var decryptedPass = _cryptoService.Decrypt(clientId, password);
|
|
var user = await Login(email, decryptedPass ?? string.Empty);
|
|
return user;
|
|
}
|
|
catch
|
|
{
|
|
return null;
|
|
}
|
|
}
|
|
|
|
public async Task SendResetPassword(string email)
|
|
{
|
|
var exists = await _repository.ExistsByEmail(email);
|
|
if (!exists)
|
|
{
|
|
return;
|
|
}
|
|
await _emailService.SendEmailAsync(
|
|
tos: email,
|
|
from: "admin@mmorales.photo",
|
|
subject: "Reset Password",
|
|
body: "If you received this email, it means that you have requested a password reset. Please follow the instructions in the email to reset your password."
|
|
);
|
|
}
|
|
|
|
public async Task<User?> ValidateSystemUser(string email, string password, string systemKey, string clientId)
|
|
{
|
|
var decryptedPassword = _cryptoService.Decrypt(clientId, password) ?? string.Empty;
|
|
var decryptedsystemKey = _cryptoService.Decrypt(clientId, systemKey) ?? string.Empty;
|
|
if (string.IsNullOrEmpty(email) || string.IsNullOrEmpty(decryptedPassword) || string.IsNullOrEmpty(decryptedsystemKey))
|
|
{
|
|
return null;
|
|
}
|
|
if (!email.Equals(User.SystemUser.Email, StringComparison.InvariantCultureIgnoreCase))
|
|
{
|
|
return null;
|
|
}
|
|
|
|
var systemKeyBytes = await _blobStorageService.GetBytes("systemkey.lock");
|
|
var systemKeyString = Encoding.UTF8.GetString(systemKeyBytes ?? []);
|
|
var systemKeyObject = JsonSerializer.Deserialize<SystemKey>(systemKeyString, jsonSerializerOptions);
|
|
if (systemKeyObject == null || !systemKeyObject.IsValid(email, decryptedPassword, decryptedsystemKey))
|
|
{
|
|
return null;
|
|
}
|
|
if (!await _repository.ExistsByEmail(email))
|
|
{
|
|
return null;
|
|
}
|
|
var user = await _repository.GetByEmail(email);
|
|
if (user == null)
|
|
{
|
|
return null;
|
|
}
|
|
return await Login(user.Email!, decryptedPassword);
|
|
}
|
|
}
|