fix(management): elide ExternalSystem AuthConfiguration from responses and audit (arch-review C3)
Claude-Session: https://claude.ai/code/session_01MtdgwpEeCUn6cUA5f1LMPj
This commit is contained in:
@@ -131,4 +131,91 @@ public class SecretProjectionTests : TestKit, IDisposable
|
||||
Arg.Is<object>(o => !ManagementActor.SerializeResult(o).Contains("newpw")),
|
||||
Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
// ========================================================================
|
||||
// Task 8 — ExternalSystem AuthConfiguration elision
|
||||
// ========================================================================
|
||||
|
||||
private IExternalSystemRepository AddExternalSystemRepo(ExternalSystemDefinition def)
|
||||
{
|
||||
var repo = Substitute.For<IExternalSystemRepository>();
|
||||
repo.GetExternalSystemByIdAsync(def.Id, Arg.Any<CancellationToken>()).Returns(def);
|
||||
repo.GetAllExternalSystemsAsync(Arg.Any<CancellationToken>())
|
||||
.Returns(new List<ExternalSystemDefinition> { def });
|
||||
_services.AddScoped(_ => repo);
|
||||
return repo;
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void GetExternalSystem_ResponseOmitsAuthConfiguration()
|
||||
{
|
||||
AddExternalSystemRepo(new ExternalSystemDefinition("es", "https://x", "ApiKey")
|
||||
{
|
||||
Id = 1,
|
||||
AuthConfiguration = """{"apiKey":"es-secret"}""",
|
||||
});
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new GetExternalSystemCommand(1), "Viewer"));
|
||||
|
||||
var resp = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
Assert.DoesNotContain("es-secret", resp.JsonData);
|
||||
Assert.Contains("hasAuthConfiguration", resp.JsonData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void ListExternalSystems_ResponseOmitsAuthConfiguration()
|
||||
{
|
||||
AddExternalSystemRepo(new ExternalSystemDefinition("es", "https://x", "ApiKey")
|
||||
{
|
||||
Id = 1,
|
||||
AuthConfiguration = """{"apiKey":"es-secret"}""",
|
||||
});
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new ListExternalSystemsCommand(), "Viewer"));
|
||||
|
||||
var resp = ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
Assert.DoesNotContain("es-secret", resp.JsonData);
|
||||
Assert.Contains("hasAuthConfiguration", resp.JsonData);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task UpdateExternalSystem_NullAuthConfiguration_PreservesStoredSecret()
|
||||
{
|
||||
var stored = new ExternalSystemDefinition("es", "https://x", "ApiKey")
|
||||
{
|
||||
Id = 1,
|
||||
AuthConfiguration = """{"apiKey":"es-secret"}""",
|
||||
};
|
||||
var repo = AddExternalSystemRepo(stored);
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new UpdateExternalSystemCommand(1, "es", "https://y", "ApiKey", null), "Designer"));
|
||||
ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
await repo.Received(1).UpdateExternalSystemAsync(
|
||||
Arg.Is<ExternalSystemDefinition>(d => d.AuthConfiguration == """{"apiKey":"es-secret"}"""),
|
||||
Arg.Any<CancellationToken>());
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void UpdateExternalSystem_AuditAfterState_OmitsAuthConfiguration()
|
||||
{
|
||||
var stored = new ExternalSystemDefinition("es", "https://x", "ApiKey")
|
||||
{
|
||||
Id = 1,
|
||||
AuthConfiguration = """{"apiKey":"es-secret"}""",
|
||||
};
|
||||
AddExternalSystemRepo(stored);
|
||||
|
||||
var actor = CreateActor();
|
||||
actor.Tell(Envelope(new UpdateExternalSystemCommand(1, "es", "https://y", "ApiKey", """{"apiKey":"newsecret"}"""), "Designer"));
|
||||
ExpectMsg<ManagementSuccess>(TimeSpan.FromSeconds(5));
|
||||
|
||||
_auditService.Received().LogAsync(Arg.Any<string>(), "Update", "ExternalSystem",
|
||||
Arg.Any<string>(), Arg.Any<string>(),
|
||||
Arg.Is<object>(o => !ManagementActor.SerializeResult(o).Contains("newsecret")),
|
||||
Arg.Any<CancellationToken>());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user