search and ai stabilization work, localization stablized.
This commit is contained in:
@@ -3,6 +3,7 @@ using StellaOps.Authority.Persistence.Documents;
|
||||
using StellaOps.Authority.Persistence.Sessions;
|
||||
using System.Collections.Concurrent;
|
||||
using System.Threading;
|
||||
using static StellaOps.Localization.T;
|
||||
|
||||
namespace StellaOps.Authority.Persistence.InMemory.Stores;
|
||||
|
||||
@@ -716,7 +717,7 @@ public sealed class InMemoryRevocationExportStateStore : IAuthorityRevocationExp
|
||||
{
|
||||
if (state.Sequence != expectedSequence)
|
||||
{
|
||||
throw new InvalidOperationException($"Revocation export sequence mismatch. Expected {expectedSequence}, current {state.Sequence}.");
|
||||
throw new InvalidOperationException(_t("auth.persistence.revocation_sequence_mismatch", expectedSequence, state.Sequence));
|
||||
}
|
||||
|
||||
state = new AuthorityRevocationExportStateDocument
|
||||
|
||||
@@ -1,15 +1,15 @@
|
||||
using System;
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using Npgsql;
|
||||
using StellaOps.Authority.Persistence.EfCore.CompiledModels;
|
||||
using StellaOps.Authority.Persistence.EfCore.Context;
|
||||
|
||||
namespace StellaOps.Authority.Persistence.Postgres;
|
||||
|
||||
/// <summary>
|
||||
/// Runtime factory for creating <see cref="AuthorityDbContext"/> instances.
|
||||
/// Uses the static compiled model when schema matches the default; falls back to
|
||||
/// reflection-based model building for non-default schemas (integration tests).
|
||||
/// Always uses reflection-based model building from <see cref="AuthorityDbContext.OnModelCreating"/>.
|
||||
/// When a real compiled model is generated via <c>dotnet ef dbcontext optimize</c>,
|
||||
/// re-enable UseModel() here.
|
||||
/// </summary>
|
||||
internal static class AuthorityDbContextFactory
|
||||
{
|
||||
@@ -22,12 +22,6 @@ internal static class AuthorityDbContextFactory
|
||||
var optionsBuilder = new DbContextOptionsBuilder<AuthorityDbContext>()
|
||||
.UseNpgsql(connection, npgsql => npgsql.CommandTimeout(commandTimeoutSeconds));
|
||||
|
||||
if (string.Equals(normalizedSchema, AuthorityDataSource.DefaultSchemaName, StringComparison.Ordinal))
|
||||
{
|
||||
// Use the static compiled model when schema mapping matches the default model.
|
||||
optionsBuilder.UseModel(AuthorityDbContextModel.Instance);
|
||||
}
|
||||
|
||||
return new AuthorityDbContext(optionsBuilder.Options, normalizedSchema);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ public sealed class ApiKeyRepository : IApiKeyRepository
|
||||
|
||||
await dbContext.Database.ExecuteSqlRawAsync(
|
||||
"UPDATE authority.api_keys SET last_used_at = NOW() WHERE tenant_id = {0} AND id = {1}",
|
||||
tenantId, id,
|
||||
[tenantId, id],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -123,7 +123,7 @@ public sealed class ApiKeyRepository : IApiKeyRepository
|
||||
UPDATE authority.api_keys SET status = 'revoked', revoked_at = NOW(), revoked_by = {0}
|
||||
WHERE tenant_id = {1} AND id = {2} AND status = 'active'
|
||||
""",
|
||||
revokedBy, tenantId, id,
|
||||
[revokedBy, tenantId, id],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -2,6 +2,7 @@ using Microsoft.EntityFrameworkCore;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using StellaOps.Authority.Persistence.EfCore.Models;
|
||||
using StellaOps.Authority.Persistence.Postgres.Models;
|
||||
using static StellaOps.Localization.T;
|
||||
|
||||
namespace StellaOps.Authority.Persistence.Postgres.Repositories;
|
||||
|
||||
@@ -58,7 +59,7 @@ public sealed class RevocationExportStateRepository
|
||||
|
||||
if (affected == 0)
|
||||
{
|
||||
throw new InvalidOperationException($"Revocation export state update rejected. Expected sequence {expectedSequence}.");
|
||||
throw new InvalidOperationException(_t("auth.persistence.revocation_update_rejected", expectedSequence));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -119,7 +119,7 @@ public sealed class SessionRepository : ISessionRepository
|
||||
|
||||
await dbContext.Database.ExecuteSqlRawAsync(
|
||||
"UPDATE authority.sessions SET last_activity_at = NOW() WHERE tenant_id = {0} AND id = {1} AND ended_at IS NULL",
|
||||
tenantId, id,
|
||||
[tenantId, id],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -133,7 +133,7 @@ public sealed class SessionRepository : ISessionRepository
|
||||
UPDATE authority.sessions SET ended_at = NOW(), end_reason = {0}
|
||||
WHERE tenant_id = {1} AND id = {2} AND ended_at IS NULL
|
||||
""",
|
||||
reason, tenantId, id,
|
||||
[reason, tenantId, id],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public sealed class SessionRepository : ISessionRepository
|
||||
UPDATE authority.sessions SET ended_at = NOW(), end_reason = {0}
|
||||
WHERE tenant_id = {1} AND user_id = {2} AND ended_at IS NULL
|
||||
""",
|
||||
reason, tenantId, userId,
|
||||
[reason, tenantId, userId],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -158,6 +158,7 @@ public sealed class SessionRepository : ISessionRepository
|
||||
|
||||
await dbContext.Database.ExecuteSqlRawAsync(
|
||||
"DELETE FROM authority.sessions WHERE expires_at < NOW() - INTERVAL '30 days'",
|
||||
[],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -106,7 +106,7 @@ public sealed class TokenRepository : ITokenRepository
|
||||
UPDATE authority.tokens SET revoked_at = NOW(), revoked_by = {0}
|
||||
WHERE tenant_id = {1} AND id = {2} AND revoked_at IS NULL
|
||||
""",
|
||||
revokedBy, tenantId, id,
|
||||
[revokedBy, tenantId, id],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -120,7 +120,7 @@ public sealed class TokenRepository : ITokenRepository
|
||||
UPDATE authority.tokens SET revoked_at = NOW(), revoked_by = {0}
|
||||
WHERE tenant_id = {1} AND user_id = {2} AND revoked_at IS NULL
|
||||
""",
|
||||
revokedBy, tenantId, userId,
|
||||
[revokedBy, tenantId, userId],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -131,6 +131,7 @@ public sealed class TokenRepository : ITokenRepository
|
||||
|
||||
await dbContext.Database.ExecuteSqlRawAsync(
|
||||
"DELETE FROM authority.tokens WHERE expires_at < NOW() - INTERVAL '7 days'",
|
||||
[],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -251,9 +252,7 @@ public sealed class RefreshTokenRepository : IRefreshTokenRepository
|
||||
UPDATE authority.refresh_tokens SET revoked_at = NOW(), revoked_by = {0}, replaced_by = {1}
|
||||
WHERE tenant_id = {2} AND id = {3} AND revoked_at IS NULL
|
||||
""",
|
||||
revokedBy,
|
||||
(object?)replacedBy ?? DBNull.Value,
|
||||
tenantId, id,
|
||||
[revokedBy, (object?)replacedBy ?? DBNull.Value, tenantId, id],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -267,7 +266,7 @@ public sealed class RefreshTokenRepository : IRefreshTokenRepository
|
||||
UPDATE authority.refresh_tokens SET revoked_at = NOW(), revoked_by = {0}
|
||||
WHERE tenant_id = {1} AND user_id = {2} AND revoked_at IS NULL
|
||||
""",
|
||||
revokedBy, tenantId, userId,
|
||||
[revokedBy, tenantId, userId],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
@@ -278,6 +277,7 @@ public sealed class RefreshTokenRepository : IRefreshTokenRepository
|
||||
|
||||
await dbContext.Database.ExecuteSqlRawAsync(
|
||||
"DELETE FROM authority.refresh_tokens WHERE expires_at < NOW() - INTERVAL '30 days'",
|
||||
[],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ public sealed class UserRepository : IUserRepository
|
||||
SET password_hash = {0}, password_salt = {1}, password_changed_at = NOW()
|
||||
WHERE tenant_id = {2} AND id = {3}
|
||||
""",
|
||||
passwordHash, passwordSalt, tenantId, userId,
|
||||
[passwordHash, passwordSalt, tenantId, userId],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
|
||||
return rows > 0;
|
||||
@@ -238,7 +238,7 @@ public sealed class UserRepository : IUserRepository
|
||||
SET failed_login_attempts = 0, locked_until = NULL, last_login_at = NOW()
|
||||
WHERE tenant_id = {0} AND id = {1}
|
||||
""",
|
||||
tenantId, userId,
|
||||
[tenantId, userId],
|
||||
cancellationToken).ConfigureAwait(false);
|
||||
}
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ using StellaOps.Authority.Persistence.EfCore.Models;
|
||||
using System.Collections.Immutable;
|
||||
using System.Text.Json;
|
||||
using System.Text.Json.Serialization;
|
||||
using static StellaOps.Localization.T;
|
||||
|
||||
namespace StellaOps.Authority.Persistence.Postgres;
|
||||
|
||||
@@ -61,14 +62,17 @@ public sealed class PostgresVerdictManifestStore : IVerdictManifestStore
|
||||
signature_base64 = EXCLUDED.signature_base64,
|
||||
rekor_log_id = EXCLUDED.rekor_log_id
|
||||
""",
|
||||
manifest.ManifestId, manifest.Tenant, manifest.AssetDigest, manifest.VulnerabilityId,
|
||||
JsonSerializer.Serialize(manifest.Inputs, s_jsonOptions),
|
||||
StatusToString(manifest.Result.Status),
|
||||
manifest.Result.Confidence,
|
||||
JsonSerializer.Serialize(manifest.Result, s_jsonOptions),
|
||||
manifest.PolicyHash, manifest.LatticeVersion, manifest.EvaluatedAt, manifest.ManifestDigest,
|
||||
(object?)manifest.SignatureBase64 ?? DBNull.Value,
|
||||
(object?)manifest.RekorLogId ?? DBNull.Value,
|
||||
new object[]
|
||||
{
|
||||
manifest.ManifestId, manifest.Tenant, manifest.AssetDigest, manifest.VulnerabilityId,
|
||||
JsonSerializer.Serialize(manifest.Inputs, s_jsonOptions),
|
||||
StatusToString(manifest.Result.Status),
|
||||
manifest.Result.Confidence,
|
||||
JsonSerializer.Serialize(manifest.Result, s_jsonOptions),
|
||||
manifest.PolicyHash, manifest.LatticeVersion, manifest.EvaluatedAt, manifest.ManifestDigest,
|
||||
(object?)manifest.SignatureBase64 ?? DBNull.Value,
|
||||
(object?)manifest.RekorLogId ?? DBNull.Value,
|
||||
},
|
||||
ct).ConfigureAwait(false);
|
||||
|
||||
return manifest;
|
||||
@@ -226,9 +230,9 @@ public sealed class PostgresVerdictManifestStore : IVerdictManifestStore
|
||||
private static VerdictManifest ToManifest(VerdictManifestEfEntity ef)
|
||||
{
|
||||
var inputs = JsonSerializer.Deserialize<VerdictInputs>(ef.InputsJson, s_jsonOptions)
|
||||
?? throw new InvalidOperationException("Failed to deserialize inputs");
|
||||
?? throw new InvalidOperationException(_t("auth.persistence.deserialize_inputs_failed"));
|
||||
var result = JsonSerializer.Deserialize<VerdictResult>(ef.ResultJson, s_jsonOptions)
|
||||
?? throw new InvalidOperationException("Failed to deserialize result");
|
||||
?? throw new InvalidOperationException(_t("auth.persistence.deserialize_result_failed"));
|
||||
|
||||
return new VerdictManifest
|
||||
{
|
||||
|
||||
@@ -35,6 +35,7 @@
|
||||
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Infrastructure.EfCore\StellaOps.Infrastructure.EfCore.csproj" />
|
||||
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Determinism.Abstractions\StellaOps.Determinism.Abstractions.csproj" />
|
||||
<ProjectReference Include="..\StellaOps.Authority.Core\StellaOps.Authority.Core.csproj" />
|
||||
<ProjectReference Include="..\..\..\__Libraries\StellaOps.Localization\StellaOps.Localization.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
|
||||
Reference in New Issue
Block a user