Files
QuotifyBE/Controllers/UserContentController.cs
2025-07-24 10:47:20 +02:00

190 lines
5.9 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
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
/// <summary>
/// [AUTHED] Get every image
/// </summary>
/// <remarks>
/// Can (and will) return an empty list if no images are found in DB. <br/>
/// Requires authorization with a JWT, has CORS set.
/// </remarks>
/// <response code="200">Returned on valid request</response>
[HttpGet]
[Authorize]
[EnableCors]
[ProducesResponseType(typeof(List<Image>), 200)]
public async Task<IActionResult> GetImages()
{
// Get all the images
List<Image> images = await _db.Images
.ToListAsync();
// Return to user
return Ok(images);
}
// POST /api/v1/uc/images
/// <summary>
/// [AUTHED] Upload an image and get an its URI
/// </summary>
/// <remarks>
/// Allows authorized users to publish images.
/// A user-reachable path is returned on success.<br/>
/// </remarks>
/// <response code="200">Returned on valid request</response>
/// <response code="400">Returned when file extension is unknown</response>
/// <response code="406">Returned when request does not follow user-provided config</response>
[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<string> allowedExtensions = new List<string>() { ".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/<nazwa pliku>.<rozszerzenie>"
// 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<string> allowedExtensions = new List<string>() { ".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
});
}
}