fix(security): additive permitted-sites filter on secured-write query/count (plan R2-07 T5)
This commit is contained in:
+66
@@ -164,6 +164,72 @@ public class SecuredWriteRepositoryTests : IClassFixture<MsSqlMigrationFixture>
|
||||
Assert.Equal(0, await repo.CountAsync(status: "Executed", siteId: siteId));
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task QueryAsync_PermittedSiteIds_ReturnsOnlyPermittedRows()
|
||||
{
|
||||
Skip.IfNot(_fixture.Available, _fixture.SkipReason);
|
||||
|
||||
// Distinct per-run site identifiers stand in for "SITE1"/"SITE2"/"SITE3" so the
|
||||
// permitted-set filter is asserted deterministically against a shared MSSQL.
|
||||
var site1 = NewSiteId();
|
||||
var site2 = NewSiteId();
|
||||
var site3 = NewSiteId();
|
||||
await using var context = CreateContext();
|
||||
var repo = new SecuredWriteRepository(context);
|
||||
|
||||
await repo.AddAsync(NewRow(site1, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(site1, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(site2, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(site3, status: "Pending"));
|
||||
|
||||
var rows = await repo.QueryAsync(status: null, siteId: null, skip: 0, take: 100,
|
||||
permittedSiteIds: new[] { site1, site3 });
|
||||
Assert.Equal(3, rows.Count);
|
||||
Assert.DoesNotContain(rows, r => r.SiteId == site2);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task CountAsync_PermittedSiteIds_CountsOnlyPermittedRows()
|
||||
{
|
||||
Skip.IfNot(_fixture.Available, _fixture.SkipReason);
|
||||
|
||||
var site1 = NewSiteId();
|
||||
var site2 = NewSiteId();
|
||||
var site3 = NewSiteId();
|
||||
await using var context = CreateContext();
|
||||
var repo = new SecuredWriteRepository(context);
|
||||
|
||||
await repo.AddAsync(NewRow(site1, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(site1, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(site2, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(site3, status: "Pending"));
|
||||
|
||||
var count = await repo.CountAsync(status: null, siteId: null,
|
||||
permittedSiteIds: new[] { site1, site3 });
|
||||
Assert.Equal(3, count);
|
||||
}
|
||||
|
||||
[SkippableFact]
|
||||
public async Task QueryAsync_NullPermittedSiteIds_IsUnfiltered_BackCompat()
|
||||
{
|
||||
Skip.IfNot(_fixture.Available, _fixture.SkipReason);
|
||||
|
||||
// 4 rows on a single unique site; null permittedSiteIds must not filter them
|
||||
// out — exactly today's behavior.
|
||||
var siteId = NewSiteId();
|
||||
await using var context = CreateContext();
|
||||
var repo = new SecuredWriteRepository(context);
|
||||
|
||||
await repo.AddAsync(NewRow(siteId, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(siteId, status: "Pending"));
|
||||
await repo.AddAsync(NewRow(siteId, status: "Executed"));
|
||||
await repo.AddAsync(NewRow(siteId, status: "Rejected"));
|
||||
|
||||
var rows = await repo.QueryAsync(status: null, siteId: siteId, skip: 0, take: 100,
|
||||
permittedSiteIds: null);
|
||||
Assert.Equal(4, rows.Count);
|
||||
}
|
||||
|
||||
// --- helpers ------------------------------------------------------------
|
||||
|
||||
private ScadaBridgeDbContext CreateContext()
|
||||
|
||||
Reference in New Issue
Block a user