using HyperBooru.ApiModels; using HyperBooru.Services; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace HyperBooru.Controllers; [ApiController] [Authorize] [Route("/api/user")] public class ApiUserController : Controller { private IDbContextFactory dbFactory; public ApiUserController(IDbContextFactory dbFactory) => this.dbFactory = dbFactory; [HttpGet] public async Task GetAllUsersAsync() { using var db = dbFactory.CreateDbContext(); return Ok(await db.Users .Select(u => (ApiModels.User) u) .ToArrayAsync()); } [HttpGet("{userId}")] public async Task GetUserAsync([FromRoute] Guid userId) { using var db = dbFactory.CreateDbContext(); var user = await db.Users .FirstOrDefaultAsync(u => u.Guid == userId); if(user is null) throw new ObjectNotFoundException([ userId ]); return Ok((ApiModels.User) user); } [HttpPost] public async Task CreateUserAsync([FromBody] ApiModels.UserCreateRequest request) { using var db = dbFactory.CreateDbContext(); using var transaction = await db.Database.BeginTransactionAsync(); if(await db.Users.AnyAsync(u => u.Username == request.Username)) throw new ApiModels.ArgumentException("Username already exists"); var user = new User() { Username = request.Username, PasswordHash = UserService.HashPassword(request.Password) }; db.Users.Add(user); await db.SaveChangesAsync(); await transaction.CommitAsync(); return Ok((ApiModels.User) user); } [HttpPatch("{userId}")] public async Task UpdateUserAsync( [FromRoute] Guid userId, [FromBody] ApiModels.UserUpdateRequest request) { using var db = dbFactory.CreateDbContext(); using var transaction = await db.Database.BeginTransactionAsync(); var user = await db.Users.FirstOrDefaultAsync(u => u.Guid == userId); if(user is null) throw new ObjectNotFoundException([ userId ]); if(request.Username is not null) { if(string.IsNullOrWhiteSpace(request.Username)) throw new ApiModels.ArgumentException("Username cannot be empty"); user.Username = request.Username; } if(request.Password is not null) { if(string.IsNullOrWhiteSpace(request.Password)) throw new ApiModels.ArgumentException("Password cannot be empty"); user.PasswordHash = UserService.HashPassword(request.Password); } await db.SaveChangesAsync(); await transaction.CommitAsync(); return Ok((ApiModels.User) user); } [HttpDelete("{userId}")] public async Task DeleteUserAsync([FromRoute] Guid userId) { if(userId == HBContext.AdminUser) throw new ApiModels.ArgumentException("Cannot delete the admin user"); using var db = dbFactory.CreateDbContext(); using var transaction = await db.Database.BeginTransactionAsync(); var user = await db.Users.FirstOrDefaultAsync(u => u.Guid == userId); if(user is null) throw new ObjectNotFoundException([ userId ]); db.Users.Remove(user); await db.SaveChangesAsync(); await transaction.CommitAsync(); return Ok((ApiModels.User) user); } }