Files
git.stella-ops.org/src/Platform/StellaOps.Platform.WebService/Endpoints/ContextEndpoints.cs
2026-02-20 23:32:20 +02:00

133 lines
4.8 KiB
C#

using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Routing;
using StellaOps.Platform.WebService.Constants;
using StellaOps.Platform.WebService.Contracts;
using StellaOps.Platform.WebService.Services;
using System;
using System.Linq;
namespace StellaOps.Platform.WebService.Endpoints;
public static class ContextEndpoints
{
public static IEndpointRouteBuilder MapContextEndpoints(this IEndpointRouteBuilder app)
{
var context = app.MapGroup("/api/v2/context")
.WithTags("Platform Context");
context.MapGet("/regions", async Task<IResult>(
HttpContext httpContext,
PlatformRequestContextResolver resolver,
PlatformContextService service,
CancellationToken cancellationToken) =>
{
if (!TryResolveContext(httpContext, resolver, out _, out var failure))
{
return failure!;
}
var regions = await service.GetRegionsAsync(cancellationToken).ConfigureAwait(false);
return Results.Ok(regions);
})
.WithName("GetPlatformContextRegions")
.WithSummary("List global regions for context selection")
.RequireAuthorization(PlatformPolicies.ContextRead);
context.MapGet("/environments", async Task<IResult>(
HttpContext httpContext,
PlatformRequestContextResolver resolver,
PlatformContextService service,
[FromQuery(Name = "regions")] string? regions,
CancellationToken cancellationToken) =>
{
if (!TryResolveContext(httpContext, resolver, out _, out var failure))
{
return failure!;
}
var regionFilter = ParseCsv(regions);
var environments = await service.GetEnvironmentsAsync(regionFilter, cancellationToken).ConfigureAwait(false);
return Results.Ok(environments);
})
.WithName("GetPlatformContextEnvironments")
.WithSummary("List global environments with optional region filter")
.RequireAuthorization(PlatformPolicies.ContextRead);
context.MapGet("/preferences", async Task<IResult>(
HttpContext httpContext,
PlatformRequestContextResolver resolver,
PlatformContextService service,
CancellationToken cancellationToken) =>
{
if (!TryResolveContext(httpContext, resolver, out var requestContext, out var failure))
{
return failure!;
}
var preferences = await service.GetPreferencesAsync(requestContext!, cancellationToken).ConfigureAwait(false);
return Results.Ok(preferences);
})
.WithName("GetPlatformContextPreferences")
.WithSummary("Get persisted context preferences for the current user")
.RequireAuthorization(PlatformPolicies.ContextRead);
context.MapPut("/preferences", async Task<IResult>(
HttpContext httpContext,
PlatformRequestContextResolver resolver,
PlatformContextService service,
PlatformContextPreferencesRequest request,
CancellationToken cancellationToken) =>
{
if (!TryResolveContext(httpContext, resolver, out var requestContext, out var failure))
{
return failure!;
}
var preferences = await service.UpsertPreferencesAsync(
requestContext!,
request,
cancellationToken).ConfigureAwait(false);
return Results.Ok(preferences);
})
.WithName("UpdatePlatformContextPreferences")
.WithSummary("Update persisted context preferences for the current user")
.RequireAuthorization(PlatformPolicies.ContextWrite);
return app;
}
private static string[] ParseCsv(string? value)
{
if (string.IsNullOrWhiteSpace(value))
{
return Array.Empty<string>();
}
return value
.Split(',', StringSplitOptions.RemoveEmptyEntries | StringSplitOptions.TrimEntries)
.Where(item => !string.IsNullOrWhiteSpace(item))
.Select(item => item.Trim().ToLowerInvariant())
.Distinct(StringComparer.Ordinal)
.ToArray();
}
private static bool TryResolveContext(
HttpContext context,
PlatformRequestContextResolver resolver,
out PlatformRequestContext? requestContext,
out IResult? failure)
{
if (resolver.TryResolve(context, out requestContext, out var error))
{
failure = null;
return true;
}
failure = Results.BadRequest(new { error = error ?? "tenant_missing" });
return false;
}
}