using Azaion.Common; using Azaion.Common.Database; using Azaion.Common.Entities; using Azaion.Common.Requests; using LinqToDB; namespace Azaion.Services; public interface IUserService { Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default); Task ValidateUser(GetResourceRequest request, CancellationToken cancellationToken = default); } public class UserService(IDbFactory dbFactory) : IUserService { public async Task RegisterUser(RegisterUserRequest request, CancellationToken cancellationToken = default) { await dbFactory.Run(async db => { var existingUser = await db.Users.FirstOrDefaultAsync(u => u.Username == request.Email, token: cancellationToken); if (existingUser != null) throw new BusinessException(ExceptionEnum.UserExists, "User already exists"); await db.InsertAsync(new User { Username = request.Email, PasswordHash = request.Password.ToHash(), Role = request.Role }, token: cancellationToken); }); } public async Task ValidateUser(GetResourceRequest request, CancellationToken cancellationToken = default) => await dbFactory.Run(async db => { var user = await db.Users.FirstOrDefaultAsync(x => x.Username == request.Username, token: cancellationToken); if (user == null) throw new BusinessException(ExceptionEnum.NoUserFound, "No user found"); if (request.Password.ToHash() != user.PasswordHash) throw new BusinessException(ExceptionEnum.PasswordIncorrect, "Passwords do not match"); //If user's hardware Id is empty (usually on the first time login), then write down user if (string.IsNullOrEmpty(user.HardwareId)) await db.Users.UpdateAsync(x => x.Username == request.Username, u => new User{HardwareId = request.HardwareId}, token: cancellationToken); else { //But if hardware Id exists, it should match with request if (user.HardwareId != request.HardwareId) throw new BusinessException(ExceptionEnum.HardwareIdMismatch, "Hardware id mismatch"); } return user; }); }