@@ -197,12 +197,44 @@ public sealed record FocasFixedTreeOptions
|
||||
/// <paramref name="OverrideParameters"/> declares the four MTB-specific override
|
||||
/// <c>cnc_rdparam</c> numbers surfaced under <c>Override/</c>; pass <c>null</c> to
|
||||
/// suppress the entire <c>Override/</c> subfolder for that device (issue #259).
|
||||
/// <paramref name="Password"/> (issue #271, plan PR F4-d) is the CNC connection-level
|
||||
/// password emitted via <c>cnc_wrunlockparam</c> on connect when the controller
|
||||
/// gates parameter writes / certain reads behind a password switch (16i + some
|
||||
/// 30i firmwares with parameter-protect on).
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para><b>No-log invariant:</b> <see cref="Password"/> is a secret. The driver MUST NOT
|
||||
/// log it. <c>FocasDeviceOptions.ToString()</c> would include the field by default
|
||||
/// because it's a positional record member, so the record's auto-generated
|
||||
/// <c>ToString</c> is overridden via <see cref="PrintMembers"/> below to redact
|
||||
/// the password. Any new logging surface that touches <see cref="FocasDeviceOptions"/>
|
||||
/// must continue to redact. See <c>docs/v2/focas-deployment.md</c> § "FOCAS password
|
||||
/// handling" for the no-log invariant and rotation runbook.</para>
|
||||
/// </remarks>
|
||||
public sealed record FocasDeviceOptions(
|
||||
string HostAddress,
|
||||
string? DeviceName = null,
|
||||
FocasCncSeries Series = FocasCncSeries.Unknown,
|
||||
FocasOverrideParameters? OverrideParameters = null);
|
||||
FocasOverrideParameters? OverrideParameters = null,
|
||||
string? Password = null)
|
||||
{
|
||||
/// <summary>
|
||||
/// Issue #271 (plan PR F4-d) — record auto-generated <c>ToString</c> would print
|
||||
/// <see cref="Password"/> verbatim. Override the printer so the secret is replaced
|
||||
/// with <c>"***"</c> when the field is non-null. The no-log invariant relies on
|
||||
/// this — every Serilog destructure that flows a <see cref="FocasDeviceOptions"/>
|
||||
/// value through <c>{Device}</c> gets redaction for free.
|
||||
/// </summary>
|
||||
private bool PrintMembers(System.Text.StringBuilder builder)
|
||||
{
|
||||
builder.Append("HostAddress = ").Append(HostAddress);
|
||||
builder.Append(", DeviceName = ").Append(DeviceName);
|
||||
builder.Append(", Series = ").Append(Series);
|
||||
builder.Append(", OverrideParameters = ").Append(OverrideParameters);
|
||||
builder.Append(", Password = ").Append(Password is null ? "<null>" : "***");
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// One FOCAS-backed OPC UA variable. <paramref name="Address"/> is the canonical FOCAS
|
||||
|
||||
Reference in New Issue
Block a user