mirror of
https://github.com/azaion/admin.git
synced 2026-04-22 21:56:34 +00:00
49de0351c1
fix hardware hash stack in the jwt token claims
108 lines
4.4 KiB
C#
108 lines
4.4 KiB
C#
using Azaion.Common;
|
|
using Azaion.Common.Database;
|
|
using Azaion.Common.Entities;
|
|
using Azaion.Common.Extensions;
|
|
using Azaion.Common.Requests;
|
|
using LinqToDB;
|
|
using Newtonsoft.Json;
|
|
|
|
namespace Azaion.Services;
|
|
|
|
public interface IUserService
|
|
{
|
|
Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default);
|
|
Task<User> ValidateUser(LoginRequest request, CancellationToken cancellationToken = default);
|
|
Task<User?> GetById(Guid? id, CancellationToken cancellationToken = default);
|
|
Task<User?> GetByEmail(string email, CancellationToken cancellationToken = default);
|
|
Task UpdateHardware(string email, HardwareInfo hardwareInfo, CancellationToken cancellationToken = default);
|
|
Task<IEnumerable<User>> GetUsers(string? searchEmail, RoleEnum? searchRole, CancellationToken cancellationToken);
|
|
Task CheckHardware(User user, GetResourceRequest request);
|
|
}
|
|
|
|
public class UserService(IDbFactory dbFactory, ICache cache) : IUserService
|
|
{
|
|
public async Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default)
|
|
{
|
|
await dbFactory.RunAdmin(async db =>
|
|
{
|
|
var existingUser = await db.Users.FirstOrDefaultAsync(u => u.Email == request.Email, token: cancellationToken);
|
|
if (existingUser != null)
|
|
throw new BusinessException(ExceptionEnum.EmailExists);
|
|
|
|
await db.InsertAsync(new User
|
|
{
|
|
Id = Guid.NewGuid(),
|
|
Email = request.Email,
|
|
PasswordHash = request.Password.ToHash(),
|
|
Role = request.Role
|
|
}, token: cancellationToken);
|
|
});
|
|
}
|
|
|
|
public async Task<User?> GetById(Guid? id, CancellationToken cancellationToken = default) =>
|
|
await cache.GetFromCacheAsync($"{nameof(User)}.{id}",
|
|
async () => await dbFactory.Run(async db =>
|
|
await db.Users.FirstOrDefaultAsync(x => x.Id == id, cancellationToken)), TimeSpan.FromHours(2));
|
|
|
|
public async Task<User?> GetByEmail(string email, CancellationToken cancellationToken = default) =>
|
|
await dbFactory.Run(async db =>
|
|
await db.Users.FirstOrDefaultAsync(x => x.Email == email, cancellationToken));
|
|
|
|
public async Task<User> ValidateUser(LoginRequest request, CancellationToken cancellationToken = default) =>
|
|
await dbFactory.Run(async db =>
|
|
{
|
|
var user = await db.Users.FirstOrDefaultAsync(x => x.Email == request.Email, token: cancellationToken);
|
|
if (user == null)
|
|
throw new BusinessException(ExceptionEnum.NoEmailFound);
|
|
|
|
if (request.Password.ToHash() != user.PasswordHash)
|
|
throw new BusinessException(ExceptionEnum.WrongPassword);
|
|
|
|
return user;
|
|
});
|
|
|
|
|
|
public async Task UpdateHardware(string email, HardwareInfo hardware, CancellationToken cancellationToken = default) =>
|
|
await dbFactory.RunAdmin(async db =>
|
|
{
|
|
var hardwareStr = JsonConvert.SerializeObject(hardware);
|
|
|
|
await db.Users.UpdateAsync(x => x.Email == email,
|
|
u => new User
|
|
{
|
|
Hardware = hardwareStr,
|
|
HardwareHash = hardware.Hash
|
|
}, token: cancellationToken);
|
|
});
|
|
|
|
|
|
public async Task<IEnumerable<User>> GetUsers(string? searchEmail, RoleEnum? searchRole, CancellationToken cancellationToken) =>
|
|
await dbFactory.Run(async db =>
|
|
await db.Users
|
|
.WhereIf(!string.IsNullOrEmpty(searchEmail),
|
|
u => u.Email.ToLower().Contains(searchEmail!.ToLower()))
|
|
.WhereIf(searchRole != null,
|
|
u => u.Role == searchRole)
|
|
.ToListAsync(token: cancellationToken));
|
|
|
|
public async Task CheckHardware(User user, GetResourceRequest request)
|
|
{
|
|
if (string.IsNullOrEmpty(user.HardwareHash))
|
|
{
|
|
await UpdateHardware(user.Email, request.Hardware);
|
|
user.HardwareHash = request.Hardware.Hash;
|
|
}
|
|
|
|
var hwHash = await dbFactory.Run(async db =>
|
|
await db.Users
|
|
.Where(x => x.Email == user.Email)
|
|
.Select(x => x.HardwareHash)
|
|
.FirstOrDefaultAsync());
|
|
if (hwHash != user.HardwareHash)
|
|
user.HardwareHash = hwHash;
|
|
|
|
if (user.HardwareHash != request.Hardware.Hash)
|
|
throw new BusinessException(ExceptionEnum.HardwareIdMismatch);
|
|
}
|
|
}
|