using BCrypt.Net; using Biskilog_Accounting.Shared.ClientContractModels; using Biskilog_Accounting.Shared.Enums; using Biskilog_Accounting.Shared.Interfaces; using Microsoft.EntityFrameworkCore; namespace Biskilog_Accounting.Server.Services { public class AuthenticationService : IAuthService { private readonly BiskilogContext m_context; private readonly ITokenService m_tokenService; public AuthenticationService(BiskilogContext a_context, ITokenService a_tokenService) { m_context = a_context; m_tokenService = a_tokenService; } /// /// Returns the status of a user account /// /// AuthEnums public AuthEnums AccountStatus(int? a_id, string? a_username) { if (m_context.Userauths.Any(i => i.UserId == a_id || i.Username == a_username)) { return AuthEnums.Found; } else { return AuthEnums.NotFound; } } /// /// Autenticates a user and returns a tokenized string /// /// /// /// strings public async Task AuthenticateClient(string a_username, string a_password) { var user = await GetUserAsync(a_username, a_password); if (user == null) { return null; } user.LastLogin = DateTime.Now; m_context.Userauths.Update(user); m_context.SaveChanges(); Databasemap databasemap = GetClientDB(user.ClientId); List businessIds = GetSiteaccesspermission(user.ClientId, user.UserId).Select(t => t.BusinessId).ToList(); Contract? contract = GetContract(user.ClientId, businessIds); List businesses = GetClientbusiness(user.ClientId, user.UserId).Select(t => t.BusinessExternalId).ToList(); if (contract == null) return AuthEnums.Invalid.ToString(); return m_tokenService.GenerateToken(user, contract, databasemap, businesses, false); } /// /// Creates a new user account /// /// returns AuthEnums.successful if the account was created successfully public AuthEnums CreateUser(Userauth a_user) { throw new NotImplementedException(); //if (AccountStatus(null, a_user.Username) == AuthEnums.Found) // return AuthEnums.Registered; //a_user.Role = m_context.UserRoles.First(i => i.RoleId== a_user.RoleId); //a_user.Password = BCrypt.Net.BCrypt.HashPassword(a_user.Password); //m_context.Users.Add(a_user); //var result = m_context.SaveChangesAsync(); //result.Wait(); //if(result.Result > 0) //{ // return AuthEnums.Successful; //} //return AuthEnums.Error; } /// /// Deletes a user account /// /// public void DeleteUser(int a_id) { throw new NotImplementedException(); } public List GetClientbusiness(int a_clientId, int userId) { return (from b in m_context.Clientbusinesses join p in m_context.Siteaccesspermissions on new { b.ClientId, b.BusinessId } equals new { p.ClientId, p.BusinessId } where p.UserId == userId && p.ClientId == a_clientId select b).ToList(); } public Databasemap GetClientDB(int a_clientId) { return m_context.Databasemaps.First(t => t.ClientId == a_clientId); } public Contract? GetContract(int a_clientId, List a_businessId) { return m_context.Contracts.FirstOrDefault(c => c.ClientId == a_clientId && a_businessId.Contains(c.BusinessId!.Value) && c.EndDate >= DateTime.Now); } public List GetSiteaccesspermission(int a_clientId, int a_userId) { return m_context.Siteaccesspermissions.Where(t => t.ClientId == a_clientId && t.UserId == a_userId).ToList(); } private async Task GetUserAsync(string username, string password) { //Todo have complete implementation after means of creating user is done try { string? pa = await m_context.Userauths.Where(u => u.Username == username || u.Email == username).Select(u => u.Passsword).FirstOrDefaultAsync(); if (String.IsNullOrEmpty(pa)) { return null; } bool verified = BCrypt.Net.BCrypt.Verify(password, pa); if (verified) { return await m_context.Userauths.FirstAsync(u => u.Username == username || u.Email == username); } else { return null; } } catch (Exception ex) { //possible is user not found return null; } } } }