search and ai stabilization work, localization stablized.

This commit is contained in:
master
2026-02-24 23:29:36 +02:00
parent 4f947a8b61
commit b07d27772e
766 changed files with 55299 additions and 3221 deletions

View File

@@ -12,7 +12,9 @@ using StellaOps.Cryptography.Plugin.SmSoft;
using System.Linq;
using System.Text.Json.Serialization;
using StellaOps.Localization;
using StellaOps.Router.AspNet;
using static StellaOps.Localization.T;
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddLogging();
@@ -44,6 +46,9 @@ builder.Services.AddAuthorization(options =>
builder.Services.AddStellaOpsTenantServices();
builder.Services.AddStellaOpsCors(builder.Environment, builder.Configuration);
builder.Services.AddStellaOpsLocalization(builder.Configuration);
builder.Services.AddTranslationBundle(System.Reflection.Assembly.GetExecutingAssembly());
// Stella Router integration
var routerEnabled = builder.Services.AddRouterMicroservice(
builder.Configuration,
@@ -62,14 +67,17 @@ if (app.Environment.IsDevelopment())
}
app.UseStellaOpsCors();
app.UseStellaOpsLocalization();
app.UseAuthentication();
app.UseAuthorization();
app.UseStellaOpsTenantMiddleware();
app.TryUseStellaRouter(routerEnabled);
await app.LoadTranslationsAsync();
app.MapGet("/health", () => Results.Ok(new SmHealthResponse("ok")))
.WithName("SmRemoteHealth")
.WithDescription("Returns the liveness status of the SM Remote crypto service. Always returns 200 OK with status 'ok' when the service is running. Used by infrastructure health probes.")
.WithDescription(_t("smremote.health.description"))
.AllowAnonymous();
app.MapGet("/status", (ICryptoProviderRegistry registry) =>
@@ -78,7 +86,7 @@ app.MapGet("/status", (ICryptoProviderRegistry registry) =>
return Results.Ok(new SmStatusResponse(true, "cn.sm.soft", algorithms));
})
.WithName("SmRemoteStatus")
.WithDescription("Returns the availability status and supported algorithms of the SM Remote crypto provider. Reports the active provider name (cn.sm.soft or cn.sm.remote.http) and the list of supported signature algorithms.")
.WithDescription(_t("smremote.status.description"))
.AllowAnonymous();
app.MapPost("/hash", (HashRequest req) =>
@@ -87,7 +95,7 @@ app.MapPost("/hash", (HashRequest req) =>
!TryGetSupportedHashAlgorithm(req.AlgorithmId, out var algorithmId) ||
!TryDecodeBase64(req.PayloadBase64, out var payload))
{
return Results.BadRequest("missing or invalid fields");
return Results.BadRequest(_t("smremote.error.missing_or_invalid_fields"));
}
var digest = new Org.BouncyCastle.Crypto.Digests.SM3Digest();
@@ -101,7 +109,7 @@ app.MapPost("/hash", (HashRequest req) =>
Convert.ToHexString(hash).ToLowerInvariant()));
})
.WithName("SmRemoteHash")
.WithDescription("Computes an SM3 hash of the provided base64-encoded payload. Returns the hash as both base64 and lowercase hex. Defaults to SM3 if algorithmId is omitted. Returns 400 if the payload is missing, invalid base64, or an unsupported algorithm is requested.")
.WithDescription(_t("smremote.hash.description"))
.RequireAuthorization(SmRemotePolicies.Sign)
.RequireTenant();
@@ -112,12 +120,12 @@ app.MapPost("/encrypt", (EncryptRequest req) =>
!TryDecodeBase64(req.KeyBase64, out var keyBytes) ||
!TryDecodeBase64(req.PayloadBase64, out var payload))
{
return Results.BadRequest("missing or invalid fields");
return Results.BadRequest(_t("smremote.error.missing_or_invalid_fields"));
}
if (keyBytes.Length != 16)
{
return Results.BadRequest("invalid sm4 key length");
return Results.BadRequest(_t("smremote.error.invalid_sm4_key_length"));
}
var cipher = new Org.BouncyCastle.Crypto.Paddings.PaddedBufferedBlockCipher(
@@ -129,7 +137,7 @@ app.MapPost("/encrypt", (EncryptRequest req) =>
return Results.Ok(new EncryptResponse(algorithmId, Convert.ToBase64String(ciphertext)));
})
.WithName("SmRemoteEncrypt")
.WithDescription("Encrypts the provided base64-encoded payload using SM4-ECB with PKCS7 padding and the supplied 128-bit (16-byte) base64-encoded key. Returns the ciphertext as base64. Returns 400 if the key, payload, or algorithm is missing, invalid, or the key length is not 16 bytes.")
.WithDescription(_t("smremote.encrypt.description"))
.RequireTenant();
app.MapPost("/decrypt", (DecryptRequest req) =>
@@ -139,12 +147,12 @@ app.MapPost("/decrypt", (DecryptRequest req) =>
!TryDecodeBase64(req.KeyBase64, out var keyBytes) ||
!TryDecodeBase64(req.CiphertextBase64, out var ciphertext))
{
return Results.BadRequest("missing or invalid fields");
return Results.BadRequest(_t("smremote.error.missing_or_invalid_fields"));
}
if (keyBytes.Length != 16)
{
return Results.BadRequest("invalid sm4 key length");
return Results.BadRequest(_t("smremote.error.invalid_sm4_key_length"));
}
try
@@ -158,11 +166,11 @@ app.MapPost("/decrypt", (DecryptRequest req) =>
}
catch (Org.BouncyCastle.Crypto.InvalidCipherTextException)
{
return Results.BadRequest("invalid ciphertext");
return Results.BadRequest(_t("smremote.error.invalid_ciphertext"));
}
})
.WithName("SmRemoteDecrypt")
.WithDescription("Decrypts the provided base64-encoded SM4-ECB ciphertext using the supplied 128-bit (16-byte) base64-encoded key with PKCS7 unpadding. Returns the plaintext payload as base64. Returns 400 if the key, ciphertext, or algorithm is invalid, or if the ciphertext padding is corrupt.")
.WithDescription(_t("smremote.decrypt.description"))
.RequireTenant();
app.MapPost("/sign", async (SignRequest req, ICryptoProviderRegistry registry, TimeProvider timeProvider, CancellationToken ct) =>
@@ -172,7 +180,7 @@ app.MapPost("/sign", async (SignRequest req, ICryptoProviderRegistry registry, T
string.IsNullOrWhiteSpace(req.AlgorithmId) ||
!TryDecodeBase64(req.PayloadBase64, out var payload))
{
return Results.BadRequest("missing or invalid fields");
return Results.BadRequest(_t("smremote.error.missing_or_invalid_fields"));
}
var provider = ResolveProvider(registry);
@@ -184,7 +192,7 @@ app.MapPost("/sign", async (SignRequest req, ICryptoProviderRegistry registry, T
return Results.Ok(new SignResponse(Convert.ToBase64String(signature)));
})
.WithName("SmRemoteSign")
.WithDescription("Signs the provided base64-encoded payload using the SM2 algorithm and the specified key ID. Seeds the key from an ephemeral EC key pair if not already present. Returns the base64-encoded SM2 signature. Returns 400 if the key ID, algorithm, or payload is missing or invalid.")
.WithDescription(_t("smremote.sign.description"))
.RequireTenant();
app.MapPost("/verify", async (VerifyRequest req, ICryptoProviderRegistry registry, TimeProvider timeProvider, CancellationToken ct) =>
@@ -193,7 +201,7 @@ app.MapPost("/verify", async (VerifyRequest req, ICryptoProviderRegistry registr
!TryDecodeBase64(req.PayloadBase64, out var payload) ||
!TryDecodeBase64(req.Signature, out var signature))
{
return Results.BadRequest("missing or invalid fields");
return Results.BadRequest(_t("smremote.error.missing_or_invalid_fields"));
}
var provider = ResolveProvider(registry);
@@ -205,11 +213,11 @@ app.MapPost("/verify", async (VerifyRequest req, ICryptoProviderRegistry registr
return Results.Ok(new VerifyResponse(ok));
})
.WithName("SmRemoteVerify")
.WithDescription("Verifies an SM2 signature against the provided base64-encoded payload using the specified key ID. Returns a boolean valid field indicating whether the signature matches. Returns 400 if the key ID, algorithm, payload, or signature is missing or invalid base64.")
.WithDescription(_t("smremote.verify.description"))
.RequireTenant();
app.TryRefreshStellaRouterEndpoints(routerEnabled);
app.Run();
await app.RunAsync().ConfigureAwait(false);
static ICryptoProvider ResolveProvider(ICryptoProviderRegistry registry)
{

View File

@@ -11,6 +11,10 @@
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Cryptography.Plugin.SmSoft\\StellaOps.Cryptography.Plugin.SmSoft.csproj" />
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Cryptography.DependencyInjection\\StellaOps.Cryptography.DependencyInjection.csproj" />
<ProjectReference Include="..\\..\\Authority\\StellaOps.Authority\\StellaOps.Auth.ServerIntegration\\StellaOps.Auth.ServerIntegration.csproj" />
<ProjectReference Include="..\\..\\__Libraries\\StellaOps.Localization\\StellaOps.Localization.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Translations\*.json" />
</ItemGroup>
<PropertyGroup Label="StellaOpsReleaseVersion">
<Version>1.0.0-alpha1</Version>

View File

@@ -0,0 +1,15 @@
{
"_meta": { "locale": "en-US", "namespace": "smremote", "version": "1.0" },
"smremote.health.description": "Returns the liveness status of the SM Remote crypto service. Always returns 200 OK with status 'ok' when the service is running. Used by infrastructure health probes.",
"smremote.status.description": "Returns the availability status and supported algorithms of the SM Remote crypto provider. Reports the active provider name (cn.sm.soft or cn.sm.remote.http) and the list of supported signature algorithms.",
"smremote.hash.description": "Computes an SM3 hash of the provided base64-encoded payload. Returns the hash as both base64 and lowercase hex. Defaults to SM3 if algorithmId is omitted. Returns 400 if the payload is missing, invalid base64, or an unsupported algorithm is requested.",
"smremote.encrypt.description": "Encrypts the provided base64-encoded payload using SM4-ECB with PKCS7 padding and the supplied 128-bit (16-byte) base64-encoded key. Returns the ciphertext as base64. Returns 400 if the key, payload, or algorithm is missing, invalid, or the key length is not 16 bytes.",
"smremote.decrypt.description": "Decrypts the provided base64-encoded SM4-ECB ciphertext using the supplied 128-bit (16-byte) base64-encoded key with PKCS7 unpadding. Returns the plaintext payload as base64. Returns 400 if the key, ciphertext, or algorithm is invalid, or if the ciphertext padding is corrupt.",
"smremote.sign.description": "Signs the provided base64-encoded payload using the SM2 algorithm and the specified key ID. Seeds the key from an ephemeral EC key pair if not already present. Returns the base64-encoded SM2 signature. Returns 400 if the key ID, algorithm, or payload is missing or invalid.",
"smremote.verify.description": "Verifies an SM2 signature against the provided base64-encoded payload using the specified key ID. Returns a boolean valid field indicating whether the signature matches. Returns 400 if the key ID, algorithm, payload, or signature is missing or invalid base64.",
"smremote.error.missing_or_invalid_fields": "missing or invalid fields",
"smremote.error.invalid_sm4_key_length": "invalid sm4 key length",
"smremote.error.invalid_ciphertext": "invalid ciphertext"
}