feat(security): add distributed authorization foundation

This commit is contained in:
2026-07-29 10:40:10 +08:00
parent c7f9a4e3c9
commit df88fa19cb
76 changed files with 22020 additions and 88 deletions

View File

@@ -20,5 +20,8 @@ public sealed class SmsRateLimitedException()
public sealed class AuthProviderNotConfiguredException(string provider)
: AuthException("auth_provider_not_configured", $"The {provider} auth provider is not configured.");
public sealed class AuthSecurityUnavailableException()
: AuthException("auth_security_unavailable", "Authentication security services are unavailable.");
public sealed class InvalidAuthChallengeException(string code = "invalid_auth_challenge")
: AuthException(code, "The authentication challenge is invalid, consumed, or expired.");

View File

@@ -0,0 +1,21 @@
namespace Tiku.Application.Security;
public enum CapabilityOperation
{
Read,
Write
}
public interface ICapabilityAccessEvaluator
{
Task<bool> IsAllowedAsync(
Guid tenantId,
string moduleCode,
CapabilityOperation operation,
CancellationToken cancellationToken = default);
Task<IReadOnlySet<string>> GetEnabledModulesAsync(
Guid tenantId,
CapabilityOperation operation = CapabilityOperation.Read,
CancellationToken cancellationToken = default);
}

View File

@@ -0,0 +1,23 @@
namespace Tiku.Application.Security;
public sealed record DistributedRateLimitBucket(string Key, int PermitLimit, TimeSpan Window);
public sealed record DistributedRateLimitResult(bool Allowed, TimeSpan? RetryAfter = null);
public interface IRedisSecurityStore
{
bool IsConfigured { get; }
Task<DistributedRateLimitResult> ConsumeAsync(
IReadOnlyCollection<DistributedRateLimitBucket> buckets,
CancellationToken cancellationToken = default);
Task<bool> PingAsync(CancellationToken cancellationToken = default);
Task SetInvalidationVersionAsync(
string realm,
Guid? tenantId,
Guid? userId,
long version,
CancellationToken cancellationToken = default);
}

View File

@@ -1,16 +1,31 @@
namespace Tiku.Application.Security;
public enum SystemScopeCallerType
{
Platform,
Worker,
Migrator,
PublicQuestionBank,
Test
}
public sealed record SystemScopeRequest(
Guid? TargetTenantId,
SystemScopeCallerType CallerType,
string Caller,
string Reason,
string CorrelationId);
public interface ITenantExecutionScope
{
Task ExecuteAsync(
Guid? targetTenantId,
string reason,
SystemScopeRequest request,
Func<IServiceProvider, CancellationToken, Task> operation,
CancellationToken cancellationToken = default);
Task<TResult> ExecuteAsync<TResult>(
Guid? targetTenantId,
string reason,
SystemScopeRequest request,
Func<IServiceProvider, CancellationToken, Task<TResult>> operation,
CancellationToken cancellationToken = default);
}