Files
Media.JoshHeaps.Net/Media.JoshHeaps.Net/Api/MediaApi.cs
T
2026-01-02 17:13:39 -07:00

185 lines
5.8 KiB
C#

using Media.JoshHeaps.Net.Services;
using Microsoft.AspNetCore.Mvc;
using System.Security.Claims;
namespace Media.JoshHeaps.Net.Api;
[ApiController]
[Route("api/media")]
public class MediaApi(MediaService mediaService, FolderService folderService) : ControllerBase
{
[HttpGet("load")]
public async Task<IActionResult> LoadMedia([FromQuery] int offset = 0, [FromQuery] int limit = 20, [FromQuery] long? folderId = null)
{
// Get user ID from JWT claims or session
var userId = GetUserIdFromAuth();
if (userId == null)
{
return Unauthorized();
}
var media = await mediaService.GetUserMediaAsync(userId.Value, offset, limit, folderId, userId.Value);
return Ok(media);
}
[HttpGet("image/{mediaId}")]
public async Task<IActionResult> GetImage(long mediaId)
{
// Get user ID from JWT claims or session
var userId = GetUserIdFromAuth();
if (userId == null)
{
return Unauthorized(new { error = "Not authenticated" });
}
// Get media metadata (includes ownership check)
var media = await mediaService.GetMediaByIdAsync(mediaId, userId.Value);
if (media == null)
{
return NotFound(new { error = "Image not found or access denied" });
}
// Get decrypted image data
var imageData = await mediaService.GetDecryptedMediaDataAsync(mediaId, userId.Value);
if (imageData == null)
{
return NotFound(new { error = "Image file not found" });
}
// Return image with proper content type
return File(imageData, media.MimeType);
}
[HttpPost("upload")]
public async Task<IActionResult> UploadImage([FromForm] IFormFile file, [FromForm] string? description, [FromForm] long? folderId)
{
// Get user ID from JWT claims or session
var userId = GetUserIdFromAuth();
if (userId == null)
{
return Unauthorized(new { error = "Not authenticated" });
}
// Check folder ownership if uploading to a folder (can't upload to shared folders)
if (folderId.HasValue)
{
var ownerId = await folderService.GetFolderOwnerIdAsync(folderId.Value);
if (ownerId != userId.Value)
{
return Forbid("Cannot upload to shared folders");
}
}
if (file == null || file.Length == 0)
{
return BadRequest(new { error = "No file provided" });
}
// Validate file type
var allowedTypes = new[] { "image/jpeg", "image/png", "image/gif", "image/webp" };
if (!allowedTypes.Contains(file.ContentType.ToLower()))
{
return BadRequest(new { error = "Invalid file type. Only images (JPG, PNG, GIF, WEBP) are allowed" });
}
// Validate file size (10MB limit)
if (file.Length > 10 * 1024 * 1024)
{
return BadRequest(new { error = "File size exceeds 10MB limit" });
}
// Save media using existing service
var media = await mediaService.SaveMediaAsync(userId.Value, file, description, folderId);
if (media == null)
{
return StatusCode(500, new { error = "Failed to upload image" });
}
return Ok(media);
}
[HttpPut("move")]
public async Task<IActionResult> MoveMedia([FromBody] MoveMediaRequest request)
{
// Get user ID from JWT claims or session
var userId = GetUserIdFromAuth();
if (userId == null)
{
return Unauthorized(new { error = "Not authenticated" });
}
var success = await mediaService.MoveMediaToFolderAsync(request.MediaId, userId.Value, request.FolderId);
if (!success)
{
return BadRequest(new { error = "Failed to move media" });
}
return Ok(new { success = true });
}
[HttpPut("move-bulk")]
public async Task<IActionResult> MoveBulkMedia([FromBody] MoveBulkMediaRequest request)
{
// Get user ID from JWT claims or session
var userId = GetUserIdFromAuth();
if (userId == null)
{
return Unauthorized(new { error = "Not authenticated" });
}
if (request.MediaIds == null || !request.MediaIds.Any())
{
return BadRequest(new { error = "No media IDs provided" });
}
var successCount = 0;
var failedIds = new List<long>();
foreach (var mediaId in request.MediaIds)
{
var success = await mediaService.MoveMediaToFolderAsync(mediaId, userId.Value, request.FolderId);
if (success)
{
successCount++;
}
else
{
failedIds.Add(mediaId);
}
}
return Ok(new {
success = failedIds.Count == 0,
movedCount = successCount,
failedCount = failedIds.Count,
failedIds = failedIds
});
}
/// <summary>
/// Gets user ID from either JWT claims (for API) or session (for web)
/// </summary>
private long? GetUserIdFromAuth()
{
// First try JWT claims (for mobile/API authentication)
var userIdClaim = User.FindFirst(ClaimTypes.NameIdentifier)?.Value;
if (!string.IsNullOrEmpty(userIdClaim) && long.TryParse(userIdClaim, out var jwtUserId))
{
return jwtUserId;
}
// Fall back to session (for web authentication)
var userIdString = HttpContext.Session.GetString("UserId");
if (!string.IsNullOrEmpty(userIdString) && long.TryParse(userIdString, out var sessionUserId))
{
return sessionUserId;
}
return null;
}
}
public record MoveMediaRequest(long MediaId, long? FolderId);
public record MoveBulkMediaRequest(List<long> MediaIds, long? FolderId);