refactor: rename ScadaLink → ZB.MOM.WW.ScadaBridge (code + projects + namespaces)
Solution + 23 src projects + 26 test projects renamed; folders, csproj, namespaces, and ScadaLinkDbContext/ScadaBridgeDbContext class updated. ActorSystem "scadalink" → "scadabridge", Akka seed-node URLs migrated. SQL roles/logins, LDAP domains, CLI command name, and CLI config dir (~/.scadalink → ~/.scadabridge) also renamed. Build green; 5 Host.Tests fail awaiting SQL login rename in next commit. Pre-existing StaleTagMonitor timing flakes unchanged. Rename script committed at tools/rename-to-scadabridge.sh.
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
using System.Reflection;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace ZB.MOM.WW.ScadaBridge.Host.Tests;
|
||||
|
||||
/// <summary>
|
||||
/// Host-003 regression: secrets must not be committed in plaintext in the
|
||||
/// shipped <c>appsettings.Central.json</c>. Connection-string passwords, the LDAP
|
||||
/// service-account password and the JWT signing key must be supplied via
|
||||
/// environment variables (or another secret store) at deployment time — the
|
||||
/// committed file may only carry non-sensitive structural defaults or
|
||||
/// placeholder values.
|
||||
/// </summary>
|
||||
public class ConfigSecretsTests
|
||||
{
|
||||
private static string FindHostProjectDirectory()
|
||||
{
|
||||
var assemblyDir = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location)!;
|
||||
var dir = new DirectoryInfo(assemblyDir);
|
||||
while (dir != null)
|
||||
{
|
||||
var hostPath = Path.Combine(dir.FullName, "src", "ZB.MOM.WW.ScadaBridge.Host");
|
||||
if (Directory.Exists(hostPath))
|
||||
return hostPath;
|
||||
dir = dir.Parent;
|
||||
}
|
||||
throw new DirectoryNotFoundException("Could not locate src/ZB.MOM.WW.ScadaBridge.Host");
|
||||
}
|
||||
|
||||
private static JsonElement ScadaBridgeSection()
|
||||
{
|
||||
var path = Path.Combine(FindHostProjectDirectory(), "appsettings.Central.json");
|
||||
var json = File.ReadAllText(path);
|
||||
using var doc = JsonDocument.Parse(json);
|
||||
return doc.RootElement.GetProperty("ScadaBridge").Clone();
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CentralConfig_ConnectionStrings_ContainNoPlaintextPassword()
|
||||
{
|
||||
var db = ScadaBridgeSection().GetProperty("Database");
|
||||
foreach (var prop in db.EnumerateObject())
|
||||
{
|
||||
var value = prop.Value.GetString() ?? string.Empty;
|
||||
// A committed connection string must not carry a literal Password= value.
|
||||
// Either the password is delivered via an environment variable or the
|
||||
// whole connection string is. A placeholder reference is acceptable.
|
||||
var idx = value.IndexOf("Password=", StringComparison.OrdinalIgnoreCase);
|
||||
if (idx >= 0)
|
||||
{
|
||||
var after = value[(idx + "Password=".Length)..];
|
||||
var literal = after.Split(';')[0];
|
||||
Assert.True(
|
||||
literal.Length == 0 || literal.Contains('{') || literal.Contains('$'),
|
||||
$"appsettings.Central.json '{prop.Name}' contains a plaintext Password value '{literal}'. " +
|
||||
"Move the secret to an environment variable.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CentralConfig_LdapServiceAccountPassword_IsNotCommitted()
|
||||
{
|
||||
var security = ScadaBridgeSection().GetProperty("Security");
|
||||
if (security.TryGetProperty("LdapServiceAccountPassword", out var pw))
|
||||
{
|
||||
var value = pw.GetString() ?? string.Empty;
|
||||
Assert.True(
|
||||
value.Length == 0 || value.Contains('{') || value.Contains('$'),
|
||||
$"appsettings.Central.json carries a plaintext LdapServiceAccountPassword '{value}'. " +
|
||||
"Move it to an environment variable.");
|
||||
}
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void CentralConfig_JwtSigningKey_IsNotCommitted()
|
||||
{
|
||||
var security = ScadaBridgeSection().GetProperty("Security");
|
||||
if (security.TryGetProperty("JwtSigningKey", out var key))
|
||||
{
|
||||
var value = key.GetString() ?? string.Empty;
|
||||
Assert.True(
|
||||
value.Length == 0 || value.Contains('{') || value.Contains('$'),
|
||||
$"appsettings.Central.json carries a committed JwtSigningKey '{value}'. " +
|
||||
"A committed signing key lets anyone with repo access forge session tokens. " +
|
||||
"Move it to an environment variable.");
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user