using Asp.Versioning; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using TarninaHub.Application.Abstractions; using TarninaHub.Application.Dtos; using TarninaHub.Application.Security; namespace TarninaHub.Controllers; [ApiController] [ApiVersion("1.0")] [Route("api/consents")] [Authorize] public class ConsentsController : ControllerBase { private readonly IConsentService _consentService; private readonly IAuditLogService _auditLogService; public ConsentsController(IConsentService consentService, IAuditLogService auditLogService) { _consentService = consentService; _auditLogService = auditLogService; } [HttpPost] public async Task> Grant( GrantConsentRequest request, CancellationToken cancellationToken) { var userId = User.GetUserId(); if (string.IsNullOrWhiteSpace(userId)) { return Unauthorized(); } if (!ConsentScopes.All.Contains(request.Scope)) { ModelState.AddModelError(nameof(request.Scope), $"Scope must be one of: {string.Join(", ", ConsentScopes.All)}."); return ValidationProblem(ModelState); } var consent = await _consentService.GrantAsync(userId, request, cancellationToken); await _auditLogService.RecordAsync( userId, "consent.grant", consent.Id, new Dictionary { ["scope"] = request.Scope }, cancellationToken); return StatusCode(StatusCodes.Status201Created, consent); } [HttpGet("mine")] public async Task>> GetMine(CancellationToken cancellationToken) { var userId = User.GetUserId(); if (string.IsNullOrWhiteSpace(userId)) { return Unauthorized(); } var consents = await _consentService.ListForUserAsync(userId, cancellationToken); return Ok(consents); } [HttpPost("{consentId}/revoke")] public async Task Revoke(string consentId, CancellationToken cancellationToken) { var userId = User.GetUserId(); if (string.IsNullOrWhiteSpace(userId)) { return Unauthorized(); } var revoked = await _consentService.RevokeAsync(consentId, userId, cancellationToken); if (!revoked) { return NotFound(); } await _auditLogService.RecordAsync( userId, "consent.revoke", consentId, new Dictionary(), cancellationToken); return NoContent(); } }