diff options
| author | Jake Mannens <jake@asger.xyz> | 2026-05-08 01:30:38 +1000 |
|---|---|---|
| committer | Jake Mannens <jake@asger.xyz> | 2026-05-08 01:30:38 +1000 |
| commit | a45ad8d3f8da273f80029ba6d34beb7e4ff7d7b5 (patch) | |
| tree | c28beb18ef41b997a234777a134c05c01802d5af | |
| parent | 2b66d00175950d845a794422433d4a350cf87775 (diff) | |
v0.14av0.14a
| -rw-r--r-- | Controllers/ApiMediaController.cs | 2 | ||||
| -rw-r--r-- | Controllers/ApiTagController.cs | 4 | ||||
| -rw-r--r-- | Controllers/ApiUserController.cs | 109 | ||||
| -rw-r--r-- | Controllers/MediaController.cs | 2 | ||||
| -rw-r--r-- | Program.cs | 5 | ||||
| -rw-r--r-- | Server.csproj | 4 | ||||
| -rw-r--r-- | User.cs | 6 |
7 files changed, 128 insertions, 4 deletions
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<HBContext> 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<HBContext> 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<HBContext> dbFactory; + + public ApiUserController(IDbContextFactory<HBContext> dbFactory) => + this.dbFactory = dbFactory; + + [HttpGet] + public async Task<IActionResult> GetAllUsersAsync() { + using var db = dbFactory.CreateDbContext(); + + return Ok(await db.Users + .Select(u => (ApiModels.User) u) + .ToArrayAsync()); + } + + [HttpGet("{userId}")] + public async Task<IActionResult> 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<IActionResult> 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<IActionResult> 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<IActionResult> 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; @@ -14,6 +14,7 @@ public class Program { builder.Services.AddHttpContextAccessor(); builder.Services.AddAuthentication( CookieAuthenticationDefaults.AuthenticationScheme).AddCookie(); + builder.Services.AddAuthorization(); builder.Services.AddControllers().AddJsonOptions(o => { var converter = new JsonStringEnumConverter(); o.JsonSerializerOptions.Converters.Add(converter); @@ -49,12 +50,14 @@ public class Program { using var db = scope.ServiceProvider.GetRequiredService<HBContext>(); db.Database.Migrate(); + app.UseRouting(); app.UseSession(); + app.UseAuthentication(); + app.UseAuthorization(); app.UseHsts(); app.UseHttpsRedirection(); app.UseStaticFiles(); app.UseMiddleware<ExceptionMiddleware>(); - app.UseRouting(); app.MapBlazorHub(); app.MapControllers(); app.MapFallbackToPage("/_Host"); diff --git a/Server.csproj b/Server.csproj index c9afced..14893c7 100644 --- a/Server.csproj +++ b/Server.csproj @@ -6,9 +6,9 @@ <ImplicitUsings>enable</ImplicitUsings> <AssemblyName>HyperBooru</AssemblyName> <RootNamespace>HyperBooru</RootNamespace> - <AssemblyVersion>0.13.0.0</AssemblyVersion> + <AssemblyVersion>0.14.0.0</AssemblyVersion> <FileVersion>$(AssemblyVersion)</FileVersion> - <Version>0.13-alpha</Version> + <Version>0.14-alpha</Version> <UserSecretsId>2907567f-4640-4581-8f4d-0977952d26bd</UserSecretsId> </PropertyGroup> @@ -6,4 +6,10 @@ namespace HyperBooru; public class User : HBObject { public string Username { get; set; } public string PasswordHash { get; set; } + + public static explicit operator ApiModels.User(User user) => + new() { + UserId = user.Guid, + Username = user.Username + }; } |
