Refactored GetCulture to return null if cookie is missing or invalid, and added GetCultureOrDefault for fallback. Updated TestLocalizerController and CultureMiddleware to use new methods for more accurate culture detection. Localizer now returns only the localized string value.
155 lines
5.9 KiB
C#
155 lines
5.9 KiB
C#
using EnvelopeGenerator.Application.Common.Dto.EnvelopeReceiver;
|
|
using EnvelopeGenerator.Application.Common.Dto.Receiver;
|
|
using EnvelopeGenerator.Web.Models;
|
|
using Microsoft.AspNetCore.Authentication;
|
|
using Microsoft.AspNetCore.Authentication.Cookies;
|
|
using Microsoft.AspNetCore.Http.HttpResults;
|
|
using Microsoft.AspNetCore.Localization;
|
|
using Microsoft.AspNetCore.Mvc;
|
|
using System.Globalization;
|
|
using System.Security.Claims;
|
|
|
|
namespace EnvelopeGenerator.Web.Extensions;
|
|
|
|
public static class WebExtensions
|
|
{
|
|
#region Auth
|
|
public static string? GetClaimValue(this ClaimsPrincipal user, string claimType) => user.FindFirstValue(claimType);
|
|
|
|
public static string? GetAuthEnvelopeUuid(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.NameIdentifier);
|
|
|
|
public static string? GetAuthReceiverSignature(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Hash);
|
|
|
|
public static string? GetAuthReceiverName(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Name);
|
|
|
|
public static string? GetAuthReceiverMail(this ClaimsPrincipal user) => user.FindFirstValue(ClaimTypes.Email);
|
|
|
|
public static string? GetAuthEnvelopeTitle(this ClaimsPrincipal user) => user.FindFirstValue(EnvelopeClaimTypes.Title);
|
|
|
|
public static int? GetAuthEnvelopeId(this ClaimsPrincipal user)
|
|
{
|
|
var env_id_str = user.FindFirstValue(EnvelopeClaimTypes.Id);
|
|
return int.TryParse(env_id_str, out int env_id) ? env_id : null;
|
|
}
|
|
|
|
public static async Task SignInEnvelopeAsync(this HttpContext context, EnvelopeReceiverDto er, string receiverRole)
|
|
{
|
|
var claims = new List<Claim> {
|
|
new(ClaimTypes.NameIdentifier, er.Envelope!.Uuid),
|
|
new(ClaimTypes.Hash, er.Receiver!.Signature),
|
|
new(ClaimTypes.Name, er.Name ?? string.Empty),
|
|
new(ClaimTypes.Email, er.Receiver.EmailAddress),
|
|
new(EnvelopeClaimTypes.Title, er.Envelope.Title),
|
|
new(EnvelopeClaimTypes.Id, er.Envelope.Id.ToString()),
|
|
new(ClaimTypes.Role, receiverRole)
|
|
};
|
|
|
|
var claimsIdentity = new ClaimsIdentity(claims, CookieAuthenticationDefaults.AuthenticationScheme);
|
|
|
|
var authProperties = new AuthenticationProperties
|
|
{
|
|
AllowRefresh = false,
|
|
IsPersistent = false
|
|
};
|
|
|
|
await context.SignInAsync(
|
|
CookieAuthenticationDefaults.AuthenticationScheme,
|
|
new ClaimsPrincipal(claimsIdentity),
|
|
authProperties);
|
|
}
|
|
#endregion
|
|
|
|
#region Cookie
|
|
public static string? GetCulture(this IRequestCookieCollection cookies)
|
|
{
|
|
if (cookies[CookieRequestCultureProvider.DefaultCookieName] is string cookieValue)
|
|
return CookieRequestCultureProvider.ParseCookieValue(cookieValue)?.Cultures.FirstOrDefault().Value;
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public static string GetCultureOrDefault(this IRequestCookieCollection cookies) => GetCulture(cookies) ?? CultureInfo.CurrentCulture.Name;
|
|
|
|
public static void SetCulture(this IResponseCookies cookies, string culture)
|
|
{
|
|
var cookieOptions = new CookieOptions
|
|
{
|
|
Secure = false,
|
|
SameSite = SameSiteMode.Strict,
|
|
HttpOnly = true
|
|
};
|
|
cookies.Append(
|
|
CookieRequestCultureProvider.DefaultCookieName,
|
|
CookieRequestCultureProvider.MakeCookieValue(new RequestCulture(culture)),
|
|
cookieOptions);
|
|
}
|
|
#endregion
|
|
|
|
#region View error
|
|
//TODO: integrate localizer for ready-to-use views
|
|
//TODO: integrate to global exception handler middleware
|
|
public static ViewResult ViewError(this Controller controller, ErrorViewModel errorViewModel) => controller.View("_Error", errorViewModel);
|
|
|
|
public static ViewResult ViewError404(this Controller controller) => controller.ViewError(new()
|
|
{
|
|
Title = "404",
|
|
Subtitle = "Die von Ihnen gesuchte Seite ist nicht verfügbar",
|
|
Body = "Sie können derzeit nur an Sie gerichtete Briefe einsehen und unterschreiben.",
|
|
});
|
|
|
|
public static ViewResult ViewEnvelopeNotFound(this Controller controller) => controller.ViewError(new()
|
|
{
|
|
Title = "404",
|
|
Subtitle = "Document not found",
|
|
Body = "Wenn Sie diese URL in Ihrer E-Mail erhalten haben, wenden Sie sich bitte an das IT-Team."
|
|
});
|
|
|
|
public static ViewResult ViewDocumentNotFound(this Controller controller) => controller.ViewError(new()
|
|
{
|
|
Title = "404",
|
|
Subtitle = "Umschlag nicht gefunden",
|
|
Body = "Wenn Sie diese URL in Ihrer E-Mail erhalten haben, wenden Sie sich bitte an das IT-Team."
|
|
});
|
|
|
|
public static ViewResult ViewAccessCodeNotSent(this Controller controller) => controller.ViewError(new()
|
|
{
|
|
Title = "500",
|
|
Subtitle = "Der Zugangscode konnte nicht gesendet werden",
|
|
Body = "Bitte kontaktieren Sie das IT-Team."
|
|
});
|
|
|
|
public static ViewResult ViewInnerServiceError(this Controller controller) => controller.ViewError(new()
|
|
{
|
|
Title = "500",
|
|
Subtitle = "Ein unerwarteter Fehler ist aufgetreten",
|
|
Body = "Bitte kontaktieren Sie das IT-Team."
|
|
});
|
|
#endregion
|
|
|
|
#region HttpContext
|
|
public static CultureInfo? GetCultureByAcceptLanguage(this HttpContext context)
|
|
{
|
|
var acceptLanguage = context.Request.Headers.AcceptLanguage.ToString();
|
|
if (string.IsNullOrWhiteSpace(acceptLanguage))
|
|
return null;
|
|
|
|
foreach (var value in acceptLanguage.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries))
|
|
{
|
|
var cultureName = value.Split(';', 2)[0];
|
|
if (string.IsNullOrWhiteSpace(cultureName))
|
|
continue;
|
|
|
|
try
|
|
{
|
|
return new CultureInfo(cultureName);
|
|
}
|
|
catch (CultureNotFoundException)
|
|
{
|
|
// ignore invalid cultures and continue
|
|
}
|
|
}
|
|
|
|
return null;
|
|
}
|
|
#endregion
|
|
} |