Files
Rafał Tyński fa1199539b feat(backend): add communication, tester, admin and middleman modules
Implement step 17 modules: threads/messages, notifications with automation (submission.created, idea.created, grant_call.opened), innovation test feedback, admin panel (submissions, verify, metrics, grant call status), Middleman adaptation and partnerships. Split multi-type files into one type per file and replace object-valued dictionaries with string-valued maps in data contracts (migrations 0006/0007).
2026-10-04 03:49:45 +02:00

99 lines
2.7 KiB
C#

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<ActionResult<ConsentResponse>> 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<string, string?> { ["scope"] = request.Scope },
cancellationToken);
return StatusCode(StatusCodes.Status201Created, consent);
}
[HttpGet("mine")]
public async Task<ActionResult<IReadOnlyList<ConsentResponse>>> 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<IActionResult> 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<string, string?>(),
cancellationToken);
return NoContent();
}
}