From a45ad8d3f8da273f80029ba6d34beb7e4ff7d7b5 Mon Sep 17 00:00:00 2001 From: Jake Mannens Date: Fri, 8 May 2026 01:30:38 +1000 Subject: v0.14a --- Controllers/ApiMediaController.cs | 2 + Controllers/ApiTagController.cs | 4 +- Controllers/ApiUserController.cs | 109 ++++++++++++++++++++++++++++++++++++++ Controllers/MediaController.cs | 2 + 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 Controllers/ApiUserController.cs (limited to 'Controllers') diff --git a/Controllers/ApiMediaController.cs b/Controllers/ApiMediaController.cs index 0539b77..a324f35 100644 --- a/Controllers/ApiMediaController.cs +++ b/Controllers/ApiMediaController.cs @@ -1,5 +1,6 @@ using HyperBooru.ApiModels; using HyperBooru.Services; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; using System.Text.Json; @@ -7,6 +8,7 @@ using System.Text.Json; namespace HyperBooru.Controllers; [ApiController] +[Authorize] [Route("/api/media")] public class ApiMediaController : Controller { private IDbContextFactory dbFactory; diff --git a/Controllers/ApiTagController.cs b/Controllers/ApiTagController.cs index afd5b05..26e3dc4 100644 --- a/Controllers/ApiTagController.cs +++ b/Controllers/ApiTagController.cs @@ -1,9 +1,11 @@ -using Microsoft.AspNetCore.Mvc; +using Microsoft.AspNetCore.Authorization; +using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace HyperBooru.Controllers; [ApiController] +[Authorize] [Route("/api/tag")] public class ApiTagController : Controller { private IDbContextFactory dbFactory; diff --git a/Controllers/ApiUserController.cs b/Controllers/ApiUserController.cs new file mode 100644 index 0000000..d678287 --- /dev/null +++ b/Controllers/ApiUserController.cs @@ -0,0 +1,109 @@ +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); + + return user is null ? NotFound() : 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)) + return BadRequest("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) + return NotFound(); + + if(request.Username is not null) { + if(string.IsNullOrWhiteSpace(request.Username)) + return BadRequest("Username cannot be empty"); + user.Username = request.Username; + } + + if(request.Password is not null) { + if(string.IsNullOrWhiteSpace(request.Password)) + return BadRequest("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) + return BadRequest("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) + return NotFound(); + + db.Users.Remove(user); + + await db.SaveChangesAsync(); + await transaction.CommitAsync(); + + return Ok((ApiModels.User) user); + } +} diff --git a/Controllers/MediaController.cs b/Controllers/MediaController.cs index 96ecb44..6a9e1fc 100644 --- a/Controllers/MediaController.cs +++ b/Controllers/MediaController.cs @@ -1,12 +1,14 @@ using HyperBooru.ApiModels; using HyperBooru.Services; using HyperBooru.Util; +using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.EntityFrameworkCore; namespace HyperBooru.Controllers; [ApiController] +[Authorize] [Route("/media")] public class MediaController : Controller { private IHttpContextAccessor httpContextAccessor; -- cgit v1.3