using FluentResults; using IdentityShroud.Api.Validation; using IdentityShroud.Core.Messages; using IdentityShroud.Core.Messages.Realm; using IdentityShroud.Core.Services; using Microsoft.AspNetCore.Http.HttpResults; using Microsoft.AspNetCore.Mvc; namespace IdentityShroud.Api; public static class RealmApi { public static void MapRealmEndpoints(this IEndpointRouteBuilder app) { var realmsGroup = app.MapGroup("/realms"); realmsGroup.MapPost("", RealmCreate) .Validate() .WithName("Create Realm") .Produces(StatusCodes.Status201Created); var realmSlugGroup = realmsGroup.MapGroup("{slug}"); realmSlugGroup.MapGet("", GetRealmInfo); realmSlugGroup.MapGet(".well-known/openid-configuration", GetOpenIdConfiguration); var openidConnect = realmSlugGroup.MapGroup("openid-connect"); openidConnect.MapPost("auth", OpenIdConnectAuth); openidConnect.MapPost("token", OpenIdConnectToken); openidConnect.MapGet("jwks", OpenIdConnectJwks); } private static async Task, InternalServerError>> RealmCreate(RealmCreateRequest request, [FromServices] IRealmService service) { var response = await service.Create(request); if (response.IsSuccess) return TypedResults.Created($"/realms/{response.Value.Slug}", response.Value); // TODO make helper to convert failure response to a proper HTTP result. return TypedResults.InternalServerError(); } private static Task OpenIdConnectJwks(HttpContext context) { throw new NotImplementedException(); } private static Task OpenIdConnectToken(HttpContext context) { throw new NotImplementedException(); } private static Task OpenIdConnectAuth(HttpContext context) { throw new NotImplementedException(); } private static async Task, BadRequest, NotFound>> GetOpenIdConfiguration( [FromServices]IRealmService realmService, HttpContext context, string slug) { if (string.IsNullOrEmpty(slug)) return TypedResults.BadRequest(); var realm = await realmService.FindBySlug(slug); if (realm is null) return TypedResults.NotFound(); var s = $"{context.Request.Scheme}://{context.Request.Host}{context.Request.Path}"; var searchString = $"realms/{slug}"; int index = s.IndexOf(searchString, StringComparison.OrdinalIgnoreCase); string baseUri = s.Substring(0, index + searchString.Length); return TypedResults.Json(new OpenIdConfiguration() { AuthorizationEndpoint = baseUri + "/openid-connect/auth", TokenEndpoint = baseUri + "/openid-connect/token", Issuer = baseUri, JwksUri = baseUri + "/openid-connect/jwks", }, AppJsonSerializerContext.Default.OpenIdConfiguration); } private static string GetRealmInfo() { return "Hello World!"; /* keycloak returns this { "realm": "mpluskassa", "public_key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEApYbLAeOLDEwzL4tEwuE2LfisOBXoQqWA9RdP3ph6muwF1ErfhiBSIB2JETKf7F1OsiF1/qnuh4uDfn0TO8bK3lSfHTlIHWShwaJ/UegS9ylobfIYXJsz0xmJK5ToFaSYa72D/Dyln7ROxudu8+zc70sz7bUKQ0/ktWRsiu76vY6Kr9+18PgaooPmb2QP8lS8IZEv+gW5SLqoMc1DfD8lsih1sdnQ8W65cBsNnenkWc97AF9cMR6rdD2tZfLAxEHKYaohAL9EsQsLic3P2f2UaqRTAOvgqyYE5hyJROt7Pyeyi8YSy7zXD12h2mc0mrSoA+u7s/GrOLcLoLLgEnRRVwIDAQAB", "token-service": "https://iam.kassacloud.nl/auth/realms/mpluskassa/protocol/openid-connect", "account-service": "https://iam.kassacloud.nl/auth/realms/mpluskassa/account", "tokens-not-before": 0 } */ } // [HttpGet("")] // public ActionResult Index() // { // return new JsonResult("Hello world!"); // } // [HttpGet("{slug}/.well-known/openid-configuration")] // public ActionResult GetOpenIdConfiguration( // string slug, // [FromServices]LinkGenerator linkGenerator) // { // var s = $"{HttpContext.Request.Scheme}://{HttpContext.Request.Host}{HttpContext.Request.Path}"; // var searchString = $"realms/{slug}"; // int index = s.IndexOf(searchString, StringComparison.OrdinalIgnoreCase); // string baseUri = s.Substring(0, index + searchString.Length); // // return new JsonResult(baseUri); // } // [HttpPost("{slug}/protocol/openid-connect/token")] // public ActionResult GetOpenIdConnectToken(string slug) // // { // return new JsonResult("Hello world!"); // } }