Remove dead dialect methods; unblock explicit-creds tag-metadata path
Two cleanups from the post-EnsureTagAsync punch list — both isolated, no protocol discovery required. #89 dead code in Historian2020ProtocolDialect: - BrowseTagNamesAsync and GetTagMetadataAsync on the dialect both threw ProtocolEvidenceMissingException, but HistorianClient routes those calls directly to HistorianWcfTagClient — the dialect overrides were never reached. Removed both methods. ReadBlocksAsync stays (it's a deliberate guardrailed entry on the public surface). #90 explicit-creds tag-metadata path: - HistorianWcfTagClient.WcfRetrievalSession.ValidateSupportedAuth threw ProtocolEvidenceMissingException whenever IntegratedSecurity=false AND UserName/Password were supplied. But the surrounding code already wires those creds through ApplyWindowsCredential -> factory.Credentials.Windows.ClientCredential — the validator was just being conservative about an untested combination. - Inverted the check: now only rejects the no-auth-at-all combination (IntegratedSecurity=false + no UserName + no Password). The other three valid auth shapes pass through to WCF. Tests: 161 -> 163 (+2). New unit test verifies the no-auth case still throws; new gated live integration test GetTagMetadataAsync_ExplicitCredentials_AgainstLocalHistorian exercises the explicit-creds path when HISTORIAN_USER+HISTORIAN_PASSWORD are set, skips cleanly otherwise. CLAUDE.md updated: removed the two now-resolved entries from "Remaining gaps"; explicit-creds line refined to note the live-verification env-var requirement. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -87,17 +87,6 @@ internal sealed class Historian2020ProtocolDialect
|
||||
#pragma warning restore CA1416
|
||||
}
|
||||
|
||||
public IAsyncEnumerable<string> BrowseTagNamesAsync(string filter, CancellationToken cancellationToken)
|
||||
{
|
||||
return Missing<string>("StartLikeTagNameSearch/GetLikeTagnames", cancellationToken);
|
||||
}
|
||||
|
||||
public Task<HistorianTagMetadata?> GetTagMetadataAsync(string tag, CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
throw new ProtocolEvidenceMissingException("GetTagInfoByName/GetTagInfos");
|
||||
}
|
||||
|
||||
public Task<HistorianConnectionStatus> GetConnectionStatusAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
cancellationToken.ThrowIfCancellationRequested();
|
||||
|
||||
@@ -351,10 +351,18 @@ internal static class HistorianWcfTagClient
|
||||
|
||||
private static void ValidateSupportedAuth(HistorianClientOptions options)
|
||||
{
|
||||
// Three valid auth shapes:
|
||||
// 1. IntegratedSecurity=true (current Windows identity, no UserName/Password)
|
||||
// 2. IntegratedSecurity=false + UserName + Password (NTLM/Kerberos with explicit creds)
|
||||
// 3. IntegratedSecurity=true + UserName + Password (impersonation/explicit override)
|
||||
// The fourth combination — IntegratedSecurity=false with no UserName/Password — has
|
||||
// no way to authenticate against the /Hist-Integrated endpoint and is rejected.
|
||||
if (!options.IntegratedSecurity
|
||||
&& (!string.IsNullOrEmpty(options.UserName) || !string.IsNullOrEmpty(options.Password)))
|
||||
&& string.IsNullOrEmpty(options.UserName)
|
||||
&& string.IsNullOrEmpty(options.Password))
|
||||
{
|
||||
throw new ProtocolEvidenceMissingException("Open2 explicit username/password tag browse");
|
||||
throw new ProtocolEvidenceMissingException(
|
||||
"Tag browse / metadata requires either IntegratedSecurity=true OR an explicit UserName + Password.");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user