using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using QuotifyBE.Data; using QuotifyBE.Entities; using QuotifyBE.DTOs; using QuotifyBE.Mapping; using Microsoft.AspNetCore.Cors; using Microsoft.EntityFrameworkCore; namespace QuotifyBE.Controllers; [ApiController] [EnableCors] [Route("api/v1/uc")] [Produces("application/json")] public class UserContentController : ControllerBase { private readonly IConfiguration _appsettings; private readonly ApplicationDbContext _db; private readonly GeneralUseHelpers guhf; public UserContentController(IConfiguration appsettings, ApplicationDbContext db, GeneralUseHelpers GUHF) { _appsettings = appsettings; _db = db; guhf = GUHF; } // GET /api/v1/uc/images /// /// [AUTHED] Get every image /// /// /// Can (and will) return an empty list if no images are found in DB.
/// Requires authorization with a JWT, has CORS set. ///
/// Returned on valid request [HttpGet] [Authorize] [EnableCors] [ProducesResponseType(typeof(List), 200)] public async Task GetImages() { // Get all the images List images = await _db.Images .ToListAsync(); // Return to user return Ok(images); } // POST /api/v1/uc/images /// /// [AUTHED] Upload an image and get an its URI /// /// /// Allows authorized users to publish images. /// A user-reachable path is returned on success.
///
/// Returned on valid request /// Returned when file extension is unknown /// Returned when request does not follow user-provided config [HttpPost] [Authorize] [EnableCors] [ProducesResponseType(200)] [ProducesResponseType(typeof(ErrorDTO), 400)] [ProducesResponseType(typeof(ErrorDTO), 406)] /*public IActionResult PostNewImage(IFormFile file) { // Ideally, a hash of the file would be stored somewhere // in the database to have a basic redundancy check, // but this will do for now. ~eee4 // A good idea would be to also check the Content-Type // of submitted files. ~eee4 List allowedExtensions = new List() { ".jpg", ".jpeg", ".jfif", ".png", ".gif", ".avif", ".webp" }; string fileExtension = Path.GetExtension(file.FileName); if (!allowedExtensions.Contains(fileExtension.ToLower())) { return BadRequest(new ErrorDTO { Status = "error", Error_msg = $"Unknown file extension. Please use one of the following: {string.Join(", ", allowedExtensions)}" }); } // TODO: // https://www.youtube.com/watch?v=6-FNejMrVuk // Sprawdź, czy plik spełnia ograniczenia: // 1. Czy rozmiar jest mniejszy od _appsettings["UserContent"]["MaxFileSize"] ? // Jeśli nie, zwróć ErrorDTO ze wiadomością: $"File size exceeds {_appsettings["UserContent"]["MaxFileSize"]}" // Zapisz plik na dysku z pseudolosową nazwą GUID // Wrzucić go do folderu "uploads/images/" // Stwórz URL postaci: "/uploads/images/." // Zwróć powyższy URL return Ok(new { Status = "ok", Filepath = "miejsce na wspomniany URL" }); }*/ //[RequestSizeLimit(10_000_000)] // np. limit 10 MB – możesz zmienić lub pobierać z configu public IActionResult PostNewImage(IFormFile file) { // Obsługa braku pliku if (file == null || file.Length == 0) { return BadRequest(new ErrorDTO { Status = "error", Error_msg = "No file was uploaded." }); } // Dozwolone rozszerzenia List allowedExtensions = new List() { ".jpg", ".jpeg", ".jfif", ".png", ".gif", ".avif", ".webp" }; string fileExtension = Path.GetExtension(file.FileName).ToLower(); if (!allowedExtensions.Contains(fileExtension)) { return BadRequest(new ErrorDTO { Status = "error", Error_msg = $"Unknown file extension. Allowed: {string.Join(", ", allowedExtensions)}" }); } // Sprawdzenie typu MIME (opcjonalnie dokładniejsze) if (!file.ContentType.StartsWith("image/")) { return BadRequest(new ErrorDTO { Status = "error", Error_msg = "Uploaded file is not an image." }); } // Ograniczenie rozmiaru pliku – przykładowo 5 MB const long MaxFileSize = 5 * 1024 * 1024; if (file.Length > MaxFileSize) { return BadRequest(new ErrorDTO { Status = "error", Error_msg = $"File size exceeds {MaxFileSize / 1024 / 1024} MB." }); } // Generowanie unikalnej nazwy string uniqueFileName = $"{Guid.NewGuid()}{fileExtension}"; string relativePath = $"/uploads/images/{uniqueFileName}"; string absolutePath = Path.Combine(Directory.GetCurrentDirectory(), "wwwroot", "uploads", "images", uniqueFileName); // Upewnij się, że katalog istnieje Directory.CreateDirectory(Path.GetDirectoryName(absolutePath)!); // Zapis pliku na dysk using (var stream = new FileStream(absolutePath, FileMode.Create)) { file.CopyTo(stream); } // Zwracany adres URL (np. do użytku w cytacie) return Ok(new { Status = "ok", Filepath = relativePath }); } }