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
{
private readonly AuthTokenKeys authTokenKeys = authTokenKeyOptions.Value;
///
/// Überprüft, ob der Benutzer über die angegebene Berechtigung verfügt.
///
///
///
protected async Task IsUserInPolicyAsync(string policyName)
{
var result = await authService.AuthorizeAsync(User, policyName);
return result.Succeeded;
}
///
/// 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 IsUserInPolicyAsync(AuthPolicy.Sender))
Response.Cookies.Delete(authTokenKeys.Cookie);
else if (await 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();
}