feat(auth): add Redis authorization caching

This commit is contained in:
2026-08-01 12:20:31 +08:00
parent 84c2b0b21d
commit 46abf4d62f
36 changed files with 21757 additions and 35 deletions

View File

@@ -176,6 +176,11 @@ internal sealed class PlatformAdminService(
Metadata = JsonObjectOrDefault(command.Metadata)
};
dbContext.Tenants.Add(tenant);
dbContext.AuthorizationScopeVersions.Add(new AuthorizationScopeVersion
{
Realm = AuthRealm.Tenant,
TenantId = tenant.Id
});
var owner = new User
{
Email = ownerEmail,
@@ -250,6 +255,8 @@ internal sealed class PlatformAdminService(
await dbContext.SaveChangesAsync(cancellationToken);
await provider.GetRequiredService<ITenantFeatureCacheInvalidator>()
.InvalidateAsync(tenant.Id, cancellationToken);
await provider.GetRequiredService<IAuthorizationStateInvalidator>()
.InvalidateTenantAsync(tenant.Id, cancellationToken);
var domainCount = await dbContext.TenantDomains.CountAsync(domain => domain.TenantId == tenant.Id, cancellationToken);
var expiresAt = await dbContext.TenantSaasSubscriptions
.Where(subscription => subscription.TenantId == tenant.Id)
@@ -379,7 +386,7 @@ internal sealed class PlatformAdminService(
CancellationToken cancellationToken = default)
{
await AssertPlatformPermissionAsync(actor, BackendPermissions.PlatformStaffManage, cancellationToken);
return await ExecuteSystemAsync("platform staff upsert", async dbContext =>
return await ExecuteSystemAsync("platform staff upsert", async (provider, dbContext) =>
{
var user = command.UserId.HasValue
? await dbContext.Users.SingleOrDefaultAsync(item => item.Id == command.UserId.Value, cancellationToken)
@@ -431,6 +438,9 @@ internal sealed class PlatformAdminService(
}));
AddAudit(dbContext, actor, "platform.staff.upserted", user.Id, new { user.Email, Phone = MaskPhone(user.Phone), user.Status, RoleIds = roleIds });
await dbContext.SaveChangesAsync(cancellationToken);
var invalidator = provider.GetRequiredService<IAuthorizationStateInvalidator>();
await invalidator.InvalidateUserAsync(user.Id, cancellationToken);
await invalidator.BumpScopeAsync(AuthRealm.Platform, null, cancellationToken);
var roleCodes = await dbContext.PlatformBackendRoles.AsNoTracking()
.Where(role => roleIds.Contains(role.Id))
.Select(role => role.Code)
@@ -445,7 +455,7 @@ internal sealed class PlatformAdminService(
CancellationToken cancellationToken = default)
{
await AssertPlatformPermissionAsync(actor, BackendPermissions.PlatformStaffManage, cancellationToken);
return await ExecuteSystemAsync("platform staff status update", async dbContext =>
return await ExecuteSystemAsync("platform staff status update", async (provider, dbContext) =>
{
var user = await dbContext.Users.SingleOrDefaultAsync(item => item.Id == command.UserId, cancellationToken)
?? throw new PlatformAdminException("Platform staff user was not found.", "staff_not_found");
@@ -453,6 +463,8 @@ internal sealed class PlatformAdminService(
user.Status = command.Status;
AddAudit(dbContext, actor, "platform.staff.status_changed", user.Id, new { From = from, To = command.Status, command.Reason });
await dbContext.SaveChangesAsync(cancellationToken);
await provider.GetRequiredService<IAuthorizationStateInvalidator>()
.InvalidateUserAsync(user.Id, cancellationToken);
var roleCodes = await (
from binding in dbContext.PlatformBackendUserRoles.AsNoTracking()
join role in dbContext.PlatformBackendRoles.AsNoTracking() on binding.RoleId equals role.Id