Disable SecurityMaster endpoints (DI implementation pending)
ci / backend (push) Failing after 1s
ci / static (push) Failing after 8s
Build & Test with Secrets / build (push) Failing after 1s
ci / frontend (push) Failing after 22s
Build & Test with Secrets / security-scan (push) Failing after 7s
ci / publish (push) Has been skipped
Build & Test with Secrets / frontend (push) Failing after 1m8s
Build & Test with Secrets / notification (push) Failing after 1s
deploy / deploy (push) Successful in 1m32s
deploy / notify (push) Successful in 1s

SyncSecurityMasterEndpoint and GetSecurityMasterRulesEndpoint disabled
until ISecurityMasterRulesStore and IRemoteSecurityMasterClient are implemented.

DI registrations remain commented in Program.cs.

Co-Authored-By: Claude Haiku 4.5 <noreply@anthropic.com>
This commit is contained in:
2026-08-05 23:56:37 +09:00
parent 3e3678469c
commit 48ae6e9f8d
@@ -30,51 +30,52 @@ public sealed class SyncSecurityMasterResponse
public List<string> Conflicts { get; set; } = new();
}
public sealed class SyncSecurityMasterEndpoint : Endpoint<SyncSecurityMasterRequest, SyncSecurityMasterResponse>
{
private readonly ISecurityMasterSyncHandler _handler;
public SyncSecurityMasterEndpoint(ISecurityMasterSyncHandler handler)
{
_handler = handler;
}
public override void Configure()
{
Post("/api/security/master/sync");
Roles("SecurityAdmin");
AllowAnonymous(); // Override role check if needed for service-to-service
}
public override async Task HandleAsync(SyncSecurityMasterRequest req, CancellationToken ct)
{
var correlationId = HttpContext.TraceIdentifier;
var idempotencyKey = SecurityMasterPolicy.CreateIdempotencyKey(req.FromVersion, correlationId);
var result = await _handler.SyncAsync(
fromVersion: req.FromVersion,
idempotencyKey: idempotencyKey,
correlationId: correlationId,
cancellationToken: ct);
if (!result.IsSuccess)
{
ThrowError($"Version conflict. Local: {req.FromVersion}, Remote: {result.NewVersion}");
}
var response = new SyncSecurityMasterResponse
{
Version = result.NewVersion,
RulesCount = result.AppliedRules.Count,
SyncedAt = DateTime.UtcNow,
Conflicts = result.Conflicts,
};
HttpContext.Response.StatusCode = StatusCodes.Status200OK;
HttpContext.Response.ContentType = "application/json";
await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct);
}
}
// DISABLED: ISecurityMasterRulesStore implementation pending
// public sealed class SyncSecurityMasterEndpoint : Endpoint<SyncSecurityMasterRequest, SyncSecurityMasterResponse>
// {
// private readonly ISecurityMasterSyncHandler _handler;
//
// public SyncSecurityMasterEndpoint(ISecurityMasterSyncHandler handler)
// {
// _handler = handler;
// }
//
// public override void Configure()
// {
// Post("/api/security/master/sync");
// Roles("SecurityAdmin");
// AllowAnonymous(); // Override role check if needed for service-to-service
// }
//
// public override async Task HandleAsync(SyncSecurityMasterRequest req, CancellationToken ct)
// {
// var correlationId = HttpContext.TraceIdentifier;
// var idempotencyKey = SecurityMasterPolicy.CreateIdempotencyKey(req.FromVersion, correlationId);
//
// var result = await _handler.SyncAsync(
// fromVersion: req.FromVersion,
// idempotencyKey: idempotencyKey,
// correlationId: correlationId,
// cancellationToken: ct);
//
// if (!result.IsSuccess)
// {
// ThrowError($"Version conflict. Local: {req.FromVersion}, Remote: {result.NewVersion}");
// }
//
// var response = new SyncSecurityMasterResponse
// {
// Version = result.NewVersion,
// RulesCount = result.AppliedRules.Count,
// SyncedAt = DateTime.UtcNow,
// Conflicts = result.Conflicts,
// };
//
// HttpContext.Response.StatusCode = StatusCodes.Status200OK;
// HttpContext.Response.ContentType = "application/json";
// await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct);
// }
// }
/// <summary>
/// VS-02 BE: Get Security Rules Endpoint
@@ -102,58 +103,59 @@ public sealed class SecurityRuleDto
public DateTime? ExpiresAt { get; set; }
}
public sealed class GetSecurityMasterRulesEndpoint : EndpointWithoutRequest<GetSecurityMasterRulesResponse>
{
private readonly ISecurityMasterRulesStore _store;
private readonly IClock _clock;
public GetSecurityMasterRulesEndpoint(ISecurityMasterRulesStore store, IClock clock)
{
_store = store;
_clock = clock;
}
public override void Configure()
{
Get("/api/security/master/rules");
AllowAnonymous();
}
public override async Task HandleAsync(CancellationToken ct)
{
var state = await _store.GetCurrentStateAsync(ct);
var staleTreshold = _clock.UtcNow.AddMinutes(-5);
if (state.LastSyncAt < staleTreshold)
{
ThrowError("Security rules data is stale");
}
var rules = state.Rules
.Where(r => SecurityMasterPolicy.IsRuleActive(r, _clock.UtcNow.DateTime))
.Select(r => new SecurityRuleDto
{
RuleId = r.RuleId,
ResourceName = r.ResourceName,
Action = r.Action,
Version = r.Version,
EffectiveAt = r.EffectiveAt,
ExpiresAt = r.ExpiresAt,
})
.ToList();
var response = new GetSecurityMasterRulesResponse
{
Rules = rules,
Version = state.Version,
LastSyncAt = state.LastSyncAt,
};
HttpContext.Response.StatusCode = StatusCodes.Status200OK;
HttpContext.Response.ContentType = "application/json";
await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct);
}
}
// DISABLED: ISecurityMasterRulesStore implementation pending
// public sealed class GetSecurityMasterRulesEndpoint : EndpointWithoutRequest<GetSecurityMasterRulesResponse>
// {
// private readonly ISecurityMasterRulesStore _store;
// private readonly IClock _clock;
//
// public GetSecurityMasterRulesEndpoint(ISecurityMasterRulesStore store, IClock clock)
// {
// _store = store;
// _clock = clock;
// }
//
// public override void Configure()
// {
// Get("/api/security/master/rules");
// AllowAnonymous();
// }
//
// public override async Task HandleAsync(CancellationToken ct)
// {
// var state = await _store.GetCurrentStateAsync(ct);
//
// var staleTreshold = _clock.UtcNow.AddMinutes(-5);
// if (state.LastSyncAt < staleTreshold)
// {
// ThrowError("Security rules data is stale");
// }
//
// var rules = state.Rules
// .Where(r => SecurityMasterPolicy.IsRuleActive(r, _clock.UtcNow.DateTime))
// .Select(r => new SecurityRuleDto
// {
// RuleId = r.RuleId,
// ResourceName = r.ResourceName,
// Action = r.Action,
// Version = r.Version,
// EffectiveAt = r.EffectiveAt,
// ExpiresAt = r.ExpiresAt,
// })
// .ToList();
//
// var response = new GetSecurityMasterRulesResponse
// {
// Rules = rules,
// Version = state.Version,
// LastSyncAt = state.LastSyncAt,
// };
//
// HttpContext.Response.StatusCode = StatusCodes.Status200OK;
// HttpContext.Response.ContentType = "application/json";
// await HttpContext.Response.WriteAsync(JsonSerializer.Serialize(response), ct);
// }
// }
/// <summary>
/// VS-02 Application Handler: Orchestrates sync operation