summaryrefslogtreecommitdiff
path: root/Controllers
diff options
context:
space:
mode:
Diffstat (limited to 'Controllers')
-rw-r--r--Controllers/LoginController.cs50
-rw-r--r--Controllers/MediaController.cs113
2 files changed, 163 insertions, 0 deletions
diff --git a/Controllers/LoginController.cs b/Controllers/LoginController.cs
new file mode 100644
index 0000000..b01553c
--- /dev/null
+++ b/Controllers/LoginController.cs
@@ -0,0 +1,50 @@
+using HyperBooru.Services;
+using Microsoft.AspNetCore.Authentication;
+using Microsoft.AspNetCore.Authentication.Cookies;
+using Microsoft.AspNetCore.Cryptography.KeyDerivation;
+using Microsoft.AspNetCore.Mvc;
+using System.Security.Claims;
+
+namespace HyperBooru.Controllers;
+
+[ApiController]
+[Route("/")]
+public class LoginController : Controller {
+ private IHttpContextAccessor httpContextAccessor;
+
+ public LoginController(IHttpContextAccessor httpContextAccessor) =>
+ this.httpContextAccessor = httpContextAccessor;
+
+ [HttpPost("Login")]
+ public async Task<IActionResult> Login(
+ [FromForm] string username,
+ [FromForm] string password,
+ HBContext db) {
+
+ var user = db.Users.FirstOrDefault(u => u.Username == username);
+ if(user is null)
+ return StatusCode(403);
+
+ var hash = UserService.HashPassword(password);
+ if(hash != user.PasswordHash)
+ return StatusCode(403);
+
+ var claims = new Claim[] {
+ new Claim(ClaimTypes.Name, user.Username),
+ new Claim("ObjectId", user.ObjectId.ToString())
+ };
+
+ var claimsIdentity = new ClaimsIdentity(
+ claims,
+ CookieAuthenticationDefaults.AuthenticationScheme);
+
+ var claimsPrincipal = new ClaimsPrincipal(claimsIdentity);
+
+ await httpContextAccessor.HttpContext!.SignInAsync(claimsPrincipal);
+ return Ok();
+ }
+
+ [HttpPost("Logout")]
+ public async Task Logout() =>
+ await httpContextAccessor.HttpContext!.SignOutAsync();
+}
diff --git a/Controllers/MediaController.cs b/Controllers/MediaController.cs
new file mode 100644
index 0000000..3368f45
--- /dev/null
+++ b/Controllers/MediaController.cs
@@ -0,0 +1,113 @@
+using HyperBooru.Services;
+using HyperBooru.Util;
+using Microsoft.AspNetCore.Mvc;
+using Microsoft.EntityFrameworkCore;
+
+namespace HyperBooru.Controllers;
+
+[ApiController]
+[Route("/media")]
+public class MediaController : Controller {
+ private IMediaService mediaService;
+ private IConfigService config;
+ private HBContext db;
+
+ public MediaController(
+ IMediaService mediaService,
+ IConfigService config,
+ HBContext db) {
+
+ this.mediaService = mediaService;
+ this.config = config;
+ this.db = db;
+ }
+
+ [HttpGet("{mediaId}")]
+ public IActionResult Fetch([FromRoute] Guid mediaId) {
+ var media = db.Media
+ .Include(m => m.CurrentUploadedFile)
+ .First(m => m.Guid == mediaId);
+ if(media is null)
+ return NotFound();
+
+ var fs = System.IO.File.OpenRead(mediaService.GetPath(media));
+
+ return new FileStreamResult(fs, media.CurrentUploadedFile.MimeType);
+ }
+
+ [HttpGet("thumb/{mediaId}")]
+ public IActionResult Thumbnail(
+ [FromRoute] Guid mediaId,
+ [FromQuery(Name = "w")] int? width,
+ [FromQuery(Name = "h")] int? height) {
+
+ try {
+ var thumb = mediaService.GetThumbnail(mediaId, width, height);
+ return new FileStreamResult(thumb, "image/jpeg");
+ } catch(ThumbnailException e) {
+ return BadRequest(e.Message);
+ } catch(ObjectNotFoundException e) {
+ return NotFound(e.Message);
+ }
+ }
+
+ [HttpDelete("{mediaId}")]
+ public void Delete([FromRoute] Guid mediaId) {
+ mediaService.Delete(mediaId);
+ }
+
+ [HttpPost]
+ public IActionResult Upload() {
+ if(Request.Form.Files.Count == 0)
+ return BadRequest("No files");
+
+ Media media = new();
+
+ foreach(var formFile in Request.Form.Files) {
+ try {
+ // Parse timestamps from headers
+ DateTime? lastAccessTime =
+ formFile.Headers["X-HyperBooru-LastAccessTime"]
+ .ElementAtOrDefault(0)?
+ .TryParseDateTimeUtc();
+ DateTime? lastWriteTime =
+ formFile.Headers["X-HyperBooru-LastWriteTime"]
+ .ElementAtOrDefault(0)?
+ .TryParseDateTimeUtc();
+ DateTime? createTime =
+ formFile.Headers["X-HyperBooru-CreateTime"]
+ .ElementAtOrDefault(0)?
+ .TryParseDateTimeUtc();
+
+ // Parse original path from headers
+ string? path =
+ formFile.Headers["X-HyperBooru-Path"]
+ .ElementAtOrDefault(0);
+
+ object? pathType = null;
+ string? pathTypeString =
+ formFile.Headers["X-HyperBooru-PathType"]
+ .ElementAtOrDefault(0);
+ Enum.TryParse(typeof(PathType), pathTypeString, true, out pathType);
+
+ media = mediaService.Create(
+ formFile.OpenReadStream(),
+ formFile.FileName,
+ formFile.Headers["X-HyperBooru-Checksum"]
+ .ElementAtOrDefault(0),
+ lastAccessTime,
+ lastWriteTime,
+ createTime,
+ path,
+ (PathType?) pathType);
+ } catch(MediaCreateException e) {
+ return BadRequest(e.Message);
+ }
+ }
+
+ if(Request.Form.Files.Count == 1)
+ return Redirect($"/ViewMedia?m={media.Guid}");
+ else
+ return Redirect($"/Gallery");
+ }
+} \ No newline at end of file