Reworked code around signing keys have key details much more isolated from the other parts of the program.

This commit is contained in:
eelke 2026-02-21 20:15:46 +01:00
parent eb872a4f44
commit 0c6f227049
40 changed files with 474 additions and 281 deletions

View file

@ -0,0 +1,19 @@
using FluentValidation;
using IdentityShroud.Core.Messages.Realm;
namespace IdentityShroud.Api;
public class RealmCreateRequestValidator : AbstractValidator<RealmCreateRequest>
{
private const string SlugPattern = @"^(?=.{1,40}$)[a-z0-9]+(?:-[a-z0-9]+)*$";
public RealmCreateRequestValidator()
{
RuleFor(x => x.Id)
.NotEqual(Guid.Empty).When(x => x.Id.HasValue);
RuleFor(x => x.Slug)
.Matches(SlugPattern).Unless(x => x.Slug is null);
RuleFor(x => x.Name)
.NotNull().Length(1, 255);
}
}

View file

@ -0,0 +1,33 @@
using FluentValidation;
namespace IdentityShroud.Api;
public class ValidateFilter<T> : IEndpointFilter where T : class
{
public async ValueTask<object?> InvokeAsync(
EndpointFilterInvocationContext context,
EndpointFilterDelegate next)
{
// Grab the deserialized argument (the DTO) from the context.
// The order of arguments matches the order of parameters in the endpoint delegate.
var dto = context.Arguments
.FirstOrDefault(arg => arg is T) as T;
if (dto == null)
return Results.BadRequest("Unable to read request body.");
// Resolve the matching validator from DI.
var validator = context.HttpContext.RequestServices
.GetService<IValidator<T>>();
if (validator != null)
{
var validationResult = await validator.ValidateAsync(dto);
if (!validationResult.IsValid)
return Results.ValidationProblem(validationResult.ToDictionary());
}
// Validation passed continue to the actual handler.
return await next(context);
}
}