using FastBlog.Core.Models; using FastBlog.Core.Models.Files; using FastBlog.Core.Services; using FastBlog.Web.Middlewares; using Microsoft.AspNetCore.Mvc; namespace FastBlog.Web.Controllers; [SimpleAuth] [Route("files")] public class FilesController(FileService fileService) : Controller { private const long MaxFileSize = 8L * 1024L * 1024L * 1024L; [HttpGet] public async Task Index() { var files = await fileService.GetFiles(new PagedRequest(25, 0)); return View("Index", files); } [HttpGet("{offset:int}")] public async Task Page(int offset) { var files = await fileService.GetFiles(new PagedRequest(25, offset)); return View("Index", files); } [HttpDelete("{metaId:int}")] public async Task Delete(int metaId) { var result = await fileService.DeleteFile(metaId); return result ? await Index() : NotFound(); } [HttpPost] public async Task Upload([FromForm(Name = "sourcePath")] string? sourcePath) { // TODO: Validate path to prevent directory traversal // rn I am the only user so I dont care if (HttpContext.Request.Form.Files.Count < 1) return BadRequest("File is required."); var file = HttpContext.Request.Form.Files[0]; if (file.Length > MaxFileSize) return BadRequest("File is too large."); var meta = new FileMeta { SourceLocation = Path.Combine(sourcePath ?? "", file.FileName), CreatedAt = DateTime.UtcNow, MimeType = file.ContentType }; var result = await fileService.AddFile(meta, file.OpenReadStream); if (result.IsError) { return result.AsError.ShortCode switch { "already_exists" => Conflict(), _ => throw result.AsError }; } return await Index(); } }