Still working on getting client credential flow complete, most of the request works but still working on generating the JWT.

This commit is contained in:
eelke 2026-03-16 19:15:04 +01:00
parent 1a8c63808a
commit 8782ef39c6
80 changed files with 1331 additions and 414 deletions

View file

@ -5,11 +5,7 @@ using IdentityShroud.Core.Model;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
namespace IdentityShroud.Api;
public record ClientCreateReponse(int Id, string ClientId);
namespace IdentityShroud.Api.Apis;
/// <summary>
/// The part of the api below realms/{slug}/clients
@ -20,12 +16,12 @@ public static class ClientApi
public static void MapEndpoints(this IEndpointRouteBuilder erp)
{
RouteGroupBuilder clientsGroup = erp.MapGroup("clients");
RouteGroupBuilder clientsGroup = erp.MapGroup("clients");
clientsGroup.MapPost("", ClientCreate)
.Validate<ClientCreateRequest>()
.WithName("ClientCreate")
.Produces(StatusCodes.Status201Created);
.Produces(StatusCodes.Status201Created)
.Validate<ClientCreateRequest>()
.WithName("ClientCreate");
var clientIdGroup = clientsGroup.MapGroup("{clientId}")
.AddEndpointFilter<ClientIdValidationFilter>();
@ -43,11 +39,12 @@ public static class ClientApi
return TypedResults.Ok(new ClientMapper().ToDto(client));
}
private static async Task<Results<CreatedAtRoute<ClientCreateReponse>, InternalServerError>>
private static async Task<Results<CreatedAtRoute<ClientRepresentation>, InternalServerError>>
ClientCreate(
Guid realmId,
ClientCreateRequest request,
[FromServices] IClientService service,
[FromServices] IDataEncryptionService cryptor,
HttpContext context,
CancellationToken cancellationToken)
{
@ -60,9 +57,12 @@ public static class ClientApi
}
Client client = result.Value;
ClientRepresentation clientRepresentation = new ClientMapper().ToDto(client);
var secret = SelectBestSecret(client.Secrets);
if (secret is {} s)
clientRepresentation.Secret = cryptor.DecryptUtf8ToString(realm.DataEncryptionKeys, s.Secret);
return TypedResults.CreatedAtRoute(
new ClientCreateReponse(client.Id, client.ClientId),
clientRepresentation,
ClientGetRouteName,
new RouteValueDictionary()
{
@ -70,4 +70,28 @@ public static class ClientApi
["clientId"] = client.Id,
});
}
private static ClientSecret? SelectBestSecret(List<ClientSecret> clientSecrets)
{
ClientSecret? result = null;
foreach (var cs in clientSecrets)
{
if (cs.RevokedAt is null && (!cs.Expires.HasValue || cs.Expires.Value > DateTime.UtcNow))
{
if (result is null)
{
result = cs;
}
else
{
int d = (cs.Expires ?? DateTime.MaxValue).CompareTo(result.Expires ?? DateTime.MaxValue);
if (d > 0 || (d == 0 && cs.CreatedAt > result.CreatedAt))
result = cs;
}
}
}
return result;
}
}