forked from xiongyuxing/tiku-backend.net
feat(security): add distributed authorization foundation
This commit is contained in:
75
Tiku.IntegrationTests/SystemScopeAuditTests.cs
Normal file
75
Tiku.IntegrationTests/SystemScopeAuditTests.cs
Normal file
@@ -0,0 +1,75 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Tiku.Application.Security;
|
||||
using Tiku.Domain.Tenancy;
|
||||
using Tiku.Infrastructure.Persistence;
|
||||
|
||||
namespace Tiku.IntegrationTests;
|
||||
|
||||
public sealed class SystemScopeAuditTests
|
||||
{
|
||||
[Fact]
|
||||
public async Task Descriptor_is_required_and_success_is_audited()
|
||||
{
|
||||
await using var factory = new Api.ApiTestFactory();
|
||||
using var outer = factory.CreateSystemScope("Resolve execution scope");
|
||||
var executionScope = outer.ServiceProvider.GetRequiredService<ITenantExecutionScope>();
|
||||
await Assert.ThrowsAsync<ArgumentException>(() => executionScope.ExecuteAsync(
|
||||
new SystemScopeRequest(null, SystemScopeCallerType.Worker, "worker", "", "job-1"),
|
||||
(_, _) => Task.CompletedTask));
|
||||
|
||||
var correlationId = Guid.NewGuid().ToString("N");
|
||||
await executionScope.ExecuteAsync(
|
||||
new SystemScopeRequest(null, SystemScopeCallerType.Worker, "background-worker", "test audit", correlationId),
|
||||
(_, _) => Task.CompletedTask);
|
||||
|
||||
using var verification = factory.CreateSystemScope("Verify execution scope audit");
|
||||
var dbContext = verification.ServiceProvider.GetRequiredService<TikuDbContext>();
|
||||
Assert.Contains(dbContext.AuditLogs, item => item.Action == "system_scope.entered" && item.TargetId == correlationId);
|
||||
Assert.Contains(dbContext.AuditLogs, item => item.Action == "system_scope.completed" && item.TargetId == correlationId);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task Failed_system_scope_rolls_back_business_write_and_persists_failure_audit()
|
||||
{
|
||||
await using var factory = new Api.ApiTestFactory();
|
||||
using var outer = factory.CreateSystemScope("Resolve execution scope");
|
||||
var executionScope = outer.ServiceProvider.GetRequiredService<ITenantExecutionScope>();
|
||||
var correlationId = Guid.NewGuid().ToString("N");
|
||||
var tenantId = Guid.NewGuid();
|
||||
await factory.SeedAsync(new Tenant
|
||||
{
|
||||
Id = tenantId,
|
||||
Slug = tenantId.ToString("N"),
|
||||
Name = "Existing Tenant"
|
||||
});
|
||||
|
||||
await Assert.ThrowsAsync<InvalidOperationException>(() => executionScope.ExecuteAsync(
|
||||
new SystemScopeRequest(
|
||||
tenantId,
|
||||
SystemScopeCallerType.Worker,
|
||||
"background-worker",
|
||||
"verify transactional rollback",
|
||||
correlationId),
|
||||
async (provider, cancellationToken) =>
|
||||
{
|
||||
var dbContext = provider.GetRequiredService<TikuDbContext>();
|
||||
dbContext.TenantBrandings.Add(new TenantBranding
|
||||
{
|
||||
TenantId = tenantId,
|
||||
BrandName = "Must Roll Back"
|
||||
});
|
||||
await dbContext.SaveChangesAsync(cancellationToken);
|
||||
throw new InvalidOperationException("expected failure");
|
||||
}));
|
||||
|
||||
using var verification = factory.CreateSystemScope("Verify failed execution scope audit");
|
||||
var verificationDb = verification.ServiceProvider.GetRequiredService<TikuDbContext>();
|
||||
Assert.DoesNotContain(verificationDb.TenantBrandings, item => item.TenantId == tenantId);
|
||||
Assert.Contains(verificationDb.AuditLogs, item =>
|
||||
item.Action == "system_scope.entered" && item.TargetId == correlationId);
|
||||
Assert.Contains(verificationDb.AuditLogs, item =>
|
||||
item.Action == "system_scope.failed" && item.TargetId == correlationId);
|
||||
Assert.DoesNotContain(verificationDb.AuditLogs, item =>
|
||||
item.Action == "system_scope.completed" && item.TargetId == correlationId);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user