using System; using System.Linq; using System.Threading.Tasks; using Microsoft.EntityFrameworkCore; using Microsoft.Extensions.Configuration; using SharpRSS.API.Contracts.DTO; using SharpRSS.API.Contracts.Models; using SharpRSS.API.Contracts.Payloads; using SharpRSS.API.Models; using ToolQit; using ToolQit.Extensions; using ToolQit.Logging; namespace SharpRSS.API.Data { public class AuthService { public AuthService(IConfiguration configuration) { _configuration = configuration; _log = LogManager.CreateLogger(typeof(AuthService)); _log.Information("Setting up service..."); } private readonly IConfiguration _configuration; private readonly ILog _log; public async Task> CreateUser(ModifyUser user) { if (user.UserName.IsNullEmptyWhiteSpace() || user.Password.IsNullEmptyWhiteSpace()) return ResultOr.Failed("Username or password cannot be empty!"); DbUser newUser; try { DbAccess access = new DbAccess(_configuration); bool userExists = access.Users.Any(u => u.Uid == user.UserName); if (userExists) return ResultOr.Failed("Username already exists!"); newUser = new DbUser(user); access.Users.Add(newUser); bool saved = await access.SaveChangesAsync() > 0; if (!saved) { _log.Warning("Failed to save user: {UserName} to database", user.UserName); return ResultOr.Failed("Could not save user to database!"); } } catch (Exception e) { _log.Error(e, "Failed to create user: {UserName}", user.UserName); return ResultOr.Failed($"Failed to create user: {user.UserName}", ResultStatus.InternalFail); } return ResultOr.Ok(newUser.ToDto()); } public async Task> UpdateUser(ModifyUser user) { if (user.UserName.IsNullEmptyWhiteSpace()) return ResultOr.Failed("Username cannot be empty!"); try { DbAccess access = new DbAccess(_configuration); DbUser? dbUser = await access.Users.Where(u => u.Uid == user.UserName).FirstOrDefaultAsync(); if (dbUser == null) return ResultOr.Failed($"User{user.UserName} does not exists, first create an user then modify!"); dbUser.Update(user); access.Update(dbUser); bool saved = await access.SaveChangesAsync() > 0; if (!saved) { _log.Warning("Failed to save user: '{UserName}'", dbUser.Uid); return ResultOr.Failed($"Could not save user: '{dbUser.Uid}'"); } return ResultOr.Ok(dbUser.ToDto()); } catch (Exception e) { _log.Error(e, e.Message); return ResultOr.Failed(e.Message, ResultStatus.InternalFail); } } public async Task RemoveUserAsync(string userId) { if (userId.IsNullEmptyWhiteSpace()) return new Result("User id is empty!", ResultStatus.Failed); try { DbAccess access = new DbAccess(_configuration); DbUser? dbUser = await access.Users.Where(u => u.Uid == userId).FirstOrDefaultAsync(); if (dbUser == null) return new Result($"Could not find user: '{userId}'", ResultStatus.Failed); access.Users.Remove(dbUser); bool removed = await access.SaveChangesAsync() > 0; return new Result(removed ? "" : $"Failed to remove user: '{dbUser.Uid}'!", removed ? ResultStatus.Ok : ResultStatus.Failed); } catch (Exception e) { _log.Error(e, e.Message); return new Result(e.Message, ResultStatus.InternalFail); } } public async Task> GetUsersAsync(int results = 20, int skip = 0, string searchQuery = "") { if (results is 0 or > 20) results = 20; try { DbAccess access = new DbAccess(_configuration); if (!searchQuery.IsNullEmptyWhiteSpace()) { IQueryable queryResult = access.Users.Where(u => EF.Functions.Like(u.Uid, $"%{searchQuery}%") || EF.Functions.Like(u.Email, $"%{searchQuery}%") || EF.Functions.Like(u.DisplayName, $"%{searchQuery}%")); var searchResults = await queryResult.Skip(skip).Take(results).ToListAsync(); return new ListResult(searchResults, queryResult.Count()); } var users = await access.Users.Skip(skip).Take(results).ToListAsync(); return new ListResult(users, access.Users.Count()); } catch (Exception e) { _log.Error(e, "Error while loading users from database!"); return new ListResult(null, 0, "Error while loading users from database!", ResultStatus.Failed); } } public async Task> GetUserAsync(string userId) { if (userId.IsNullEmptyWhiteSpace()) return new ResultOr(null, "User ID is empty!", ResultStatus.Failed); try { DbAccess access = new DbAccess(_configuration); User? user = await access.Users.Where(u => u.Uid == userId).FirstOrDefaultAsync(); return new ResultOr(user, user == null ? $"Could not find user with id: {userId}!" : "", user == null ? ResultStatus.Failed : ResultStatus.Ok); } catch (Exception e) { _log.Error(e, e.Message); return new ResultOr(null, e.Message, ResultStatus.Failed); } } } }