using DigitalData.Auth.Claims; using EnvelopeGenerator.API.Controllers.Interfaces; using EnvelopeGenerator.API.Models; using EnvelopeGenerator.Domain.Constants; using Microsoft.AspNetCore.Authentication; using Microsoft.AspNetCore.Authentication.Cookies; using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Options; namespace EnvelopeGenerator.API.Controllers; /// /// Controller verantwortlich für die Benutzer-Authentifizierung, einschließlich Anmelden, Abmelden und Überprüfung des Authentifizierungsstatus. /// [Route("api/[controller]")] [ApiController] public partial class AuthController(IOptions authTokenKeyOptions, IAuthorizationService authService) : ControllerBase, IAuthController { private readonly AuthTokenKeys authTokenKeys = authTokenKeyOptions.Value; /// /// /// public IAuthorizationService AuthService { get; } = authService; /// /// Entfernt das Authentifizierungs-Cookie des Benutzers (AuthCookie) /// /// /// Gibt eine HTTP 200 oder 401. /// /// /// Sample request: /// /// POST /api/auth/logout /// /// /// Erfolgreich gelöscht, wenn der Benutzer ein berechtigtes Cookie hat. /// Wenn es kein zugelassenes Cookie gibt, wird „nicht zugelassen“ zurückgegeben. [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [Authorize(Policy = AuthPolicy.SenderOrReceiver)] [HttpPost("logout")] public async Task Logout() { if (await this.IsUserInPolicyAsync(AuthPolicy.Sender)) Response.Cookies.Delete(authTokenKeys.Cookie); else if (await this.IsUserInPolicyAsync(AuthPolicy.ReceiverOrReceiverTFA)) await HttpContext.SignOutAsync(CookieAuthenticationDefaults.AuthenticationScheme); else return Unauthorized(); return Ok(); } /// /// Prüft, ob der Benutzer ein autorisiertes Token hat. /// /// Wenn ein autorisiertes Token vorhanden ist HTTP 200 asynchron 401 /// /// Sample request: /// /// GET /api/auth /// /// /// Wenn es einen autorisierten Cookie gibt. /// Wenn kein Cookie vorhanden ist oder nicht autorisierte. [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [HttpGet("check")] [Authorize] public IActionResult Check(string? role = null) => role is not null && !User.IsInRole(role) ? Unauthorized() : Ok(); /// /// Checks whether the caller holds a valid per-envelope receiver token for the given envelope key. /// The request must carry a cookie named AuthTokenSignFLOWReceiver.{envelopeKey}. /// /// The unique envelope key extracted from the route. /// Valid per-envelope token found. /// Token is missing, expired or invalid. [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [ProducesResponseType(typeof(void), StatusCodes.Status401Unauthorized)] [Authorize(Policy = AuthPolicy.Receiver)] [HttpGet("check/envelope/{envelopeKey}")] public IActionResult CheckEnvelopeReceiver([FromRoute] string envelopeKey) => Ok(); /// /// Removes the per-envelope receiver cookie for the given envelope key. /// /// The unique envelope key whose cookie should be deleted. /// Cookie successfully deleted. [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [HttpPost("logout/envelope/{envelopeKey}")] public IActionResult LogoutEnvelopeReceiver([FromRoute] string envelopeKey) { var cookieName = CookieNames.GetEnvelopeReceiverCookieName(authTokenKeys.Cookie, envelopeKey); Response.Cookies.Delete(cookieName); return Ok(); } /// /// Removes all per-envelope receiver cookies from the current request. /// /// All envelope receiver cookies successfully deleted. [ProducesResponseType(typeof(void), StatusCodes.Status200OK)] [HttpPost("logout/envelope")] public IActionResult LogoutAllEnvelopeReceivers() { foreach (var cookieName in Request.Cookies.Keys.Where(k => CookieNames.IsEnvelopeReceiverCookie(k, authTokenKeys.Cookie))) Response.Cookies.Delete(cookieName); return Ok(); } }