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 and image id is returned on success.
///
/// Returned on valid request /// Returned when request does not contain a file or the file is blank /// Returned when image size is too large /// Returned when file extension/mimetype is unknown [HttpPost] [Authorize] [EnableCors] [ProducesResponseType(200)] [ProducesResponseType(typeof(ErrorDTO), 400)] [ProducesResponseType(typeof(ErrorDTO), 413)] [ProducesResponseType(typeof(ErrorDTO), 415)] 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 StatusCode(415, 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 StatusCode(415, new ErrorDTO { Status = "error", Error_msg = "Uploaded file is not an image." }); } // Ograniczenie rozmiaru pliku do tego, ustawionego przez użytkownika int MaxFileSize = int.TryParse(_appsettings.GetSection("UserContent")["MaxFileSize"], out int r) ? r : 5 * 1024 * 1024; if (file.Length > MaxFileSize) { return StatusCode(413, 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); } // Dodaj do bazy Image image = new Image { Url = relativePath }; _db.Images.Add(image); _db.SaveChanges(); // Zwracany adres URL (np. do użytku w cytacie) return Ok(new { Status = "ok", Filepath = relativePath, ImageId = image.Id }); } }