185 lines
5.8 KiB
C#
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);
|