< Summary

Information
Class: Chronicis.Api.Controllers.ImagesController
Assembly: Chronicis.Api
File(s): /home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/ImagesController.cs
Line coverage
100%
Covered lines: 6
Uncovered lines: 0
Coverable lines: 6
Total lines: 46
Line coverage: 100%
Branch coverage
N/A
Covered branches: 0
Total branches: 0
Branch coverage: N/A
Method coverage

Feature is only available for sponsors

Upgrade to PRO version

Metrics

MethodBranch coverage Crap Score Cyclomatic complexity Line coverage
.ctor(...)100%11100%

File(s)

/home/runner/work/chronicis/chronicis/src/Chronicis.Api/Controllers/ImagesController.cs

#LineLine coverage
 1using Chronicis.Api.Infrastructure;
 2using Chronicis.Api.Models;
 3using Chronicis.Api.Services;
 4using Microsoft.AspNetCore.Authorization;
 5using Microsoft.AspNetCore.Mvc;
 6
 7namespace Chronicis.Api.Controllers;
 8
 9/// <summary>
 10/// Proxy endpoint for serving inline article images.
 11/// Resolves document IDs to fresh SAS download URLs via 302 redirect.
 12/// This avoids storing expiring SAS URLs in article HTML content.
 13/// </summary>
 14[Route("api/images")]
 15public class ImagesController : ControllerBase
 16{
 17    private readonly IImageAccessService _imageAccessService;
 18    private readonly ICurrentUserService _currentUserService;
 19
 120    public ImagesController(
 121        IImageAccessService imageAccessService,
 122        ICurrentUserService currentUserService)
 23    {
 124        _imageAccessService = imageAccessService;
 125        _currentUserService = currentUserService;
 126    }
 27
 28    /// <summary>
 29    /// GET /api/images/{documentId} - Redirect to a fresh SAS download URL for the image.
 30    /// Authenticated users who are members of (or own) the world can access images.
 31    /// </summary>
 32    [HttpGet("{documentId:guid}")]
 33    [Authorize]
 34    public async Task<IActionResult> GetImage(Guid documentId)
 35    {
 36        var user = await _currentUserService.GetRequiredUserAsync();
 37        var result = await _imageAccessService.GetImageDownloadUrlAsync(documentId, user.Id);
 38        return result.Status switch
 39        {
 40            ServiceStatus.NotFound => NotFound(),
 41            ServiceStatus.Forbidden => Forbid(),
 42            ServiceStatus.ValidationError => BadRequest(new { error = result.ErrorMessage }),
 43            _ => Redirect(result.Value!)
 44        };
 45    }
 46}