Files
tiku-backend.net/Tiku.Application/Security/AuthorizationCacheModels.cs

88 lines
4.3 KiB
C#

using Tiku.Domain.Identity;
using Tiku.Domain.Tenancy;
using Tiku.Application.Auth;
namespace Tiku.Application.Security;
public enum AuthorizationCacheMode { Disabled, Shadow, Active }
public sealed class AuthorizationCacheOptions
{
public const string SectionName = "Security:AuthorizationCache";
public AuthorizationCacheMode Mode { get; set; } = AuthorizationCacheMode.Disabled;
public int LocalSnapshotSeconds { get; set; } = 60;
public int DistributedStateSeconds { get; set; } = 60;
public int DistributedSnapshotSeconds { get; set; } = 300;
public int JitterPercent { get; set; } = 20;
}
public sealed record CachedSessionSecurityState(
Guid SessionId, Guid UserId, AuthRealm Realm, Guid? TenantId,
string SecurityStamp, DateTimeOffset ExpiresAt, bool Revoked);
public sealed record CachedUserSecurityState(Guid UserId, UserStatus Status, string SecurityStamp);
public sealed record CachedTenantSecurityState(Guid TenantId, TenantStatus Status);
public sealed record CachedMembershipSecurityState(Guid TenantId, Guid UserId, MembershipStatus Status);
public sealed record CachedPlatformAccessState(Guid UserId, long AuthorizationVersion, bool Allowed);
public sealed record CachedAuthorizationVersion(AuthRealm Realm, Guid? TenantId, long Version);
public sealed record AccessSecurityCacheLookup(Guid SessionId, Guid UserId, AuthRealm Realm, Guid? TenantId);
public sealed record AccessSecurityCacheState(
CachedSessionSecurityState? Session,
CachedUserSecurityState? User,
CachedTenantSecurityState? Tenant,
CachedMembershipSecurityState? Membership,
CachedPlatformAccessState? PlatformAccess,
CachedAuthorizationVersion? AuthorizationVersion)
{
public bool Complete => Session is not null && User is not null && AuthorizationVersion is not null &&
(Session.Realm == AuthRealm.Platform && PlatformAccess is not null ||
Session.Realm == AuthRealm.Tenant && Tenant is not null && Membership is not null);
}
public sealed record CachedAuthorizationSnapshot(long Version, CurrentAccessSnapshot Snapshot);
public interface IAccessSecurityCache
{
bool IsConfigured { get; }
Task<AccessSecurityCacheState?> GetAsync(AccessSecurityCacheLookup lookup, CancellationToken cancellationToken = default);
Task SetAsync(AccessSecurityCacheState state, CancellationToken cancellationToken = default);
Task InvalidateSessionAsync(Guid sessionId, CancellationToken cancellationToken = default);
Task InvalidateUserAsync(Guid userId, CancellationToken cancellationToken = default);
Task InvalidateTenantAsync(Guid tenantId, CancellationToken cancellationToken = default);
Task InvalidateMembershipAsync(Guid tenantId, Guid userId, CancellationToken cancellationToken = default);
Task SetAuthorizationVersionAsync(AuthRealm realm, Guid? tenantId, long version, CancellationToken cancellationToken = default);
}
public interface IAuthorizationSnapshotCache
{
Task<CachedAuthorizationSnapshot?> GetAsync(AuthRealm realm, Guid? tenantId, Guid userId, CancellationToken cancellationToken = default);
Task SetAsync(AuthRealm realm, Guid? tenantId, Guid userId, CachedAuthorizationSnapshot snapshot, CancellationToken cancellationToken = default);
}
public interface IAuthorizationStateInvalidator
{
Task InvalidateSessionAsync(Guid sessionId, CancellationToken cancellationToken = default);
Task InvalidateUserAsync(Guid userId, CancellationToken cancellationToken = default);
Task InvalidateTenantAsync(Guid tenantId, CancellationToken cancellationToken = default);
Task InvalidateMembershipAsync(Guid tenantId, Guid userId, CancellationToken cancellationToken = default);
Task<long> BumpScopeAsync(AuthRealm realm, Guid? tenantId, CancellationToken cancellationToken = default);
}
public interface IAuthorizationCacheInvalidationProcessor
{
Task<int> ProcessPendingAsync(int batchSize = 100, CancellationToken cancellationToken = default);
}
public interface IRequestAccessValidator
{
Task<AuthSessionValidationResult?> ValidateAsync(
Guid sessionId,
Guid userId,
AuthRealm realm,
Guid? tenantId,
CancellationToken cancellationToken = default);
}
public sealed class AuthorizationSecurityUnavailableException(Exception innerException)
: Exception("Authentication security dependencies are unavailable.", innerException);