summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Controllers/ApiMediaController.cs2
-rw-r--r--Controllers/ApiTagController.cs4
-rw-r--r--Controllers/ApiUserController.cs109
-rw-r--r--Controllers/MediaController.cs2
-rw-r--r--Program.cs5
-rw-r--r--Server.csproj4
-rw-r--r--User.cs6
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;
diff --git a/Program.cs b/Program.cs
index 34db56f..5863368 100644
--- a/Program.cs
+++ b/Program.cs
@@ -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>
diff --git a/User.cs b/User.cs
index 61ef03f..87384d2 100644
--- a/User.cs
+++ b/User.cs
@@ -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
+ };
}