docs: backfill XML documentation across 756 files
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
v2-ci / build (push) Failing after 1m43s
v2-ci / unit-tests (tests/Core/ZB.MOM.WW.OtOpcUa.Cluster.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.ControlPlane.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Runtime.Tests) (push) Has been skipped
v2-ci / unit-tests (tests/Server/ZB.MOM.WW.OtOpcUa.Security.Tests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.Host.IntegrationTests) (push) Has been skipped
v2-ci / integration (tests/Server/ZB.MOM.WW.OtOpcUa.OpcUaServer.IntegrationTests) (push) Has been skipped
Adds <summary>, <param>, <typeparam>, and <inheritdoc/> tags to public members surfaced by commentchecker — resolves 5,847 of 5,869 issues (99.6%) across three /fixdocs passes.
This commit is contained in:
@@ -22,10 +22,16 @@ public enum OpcUaSecurityProfile
|
||||
Basic256Sha256SignAndEncrypt,
|
||||
}
|
||||
|
||||
/// <summary>Configuration options for OPC UA application hosting.</summary>
|
||||
public sealed class OpcUaApplicationHostOptions
|
||||
{
|
||||
/// <summary>Gets or sets the application name (default "OtOpcUa").</summary>
|
||||
public string ApplicationName { get; set; } = "OtOpcUa";
|
||||
|
||||
/// <summary>Gets or sets the application URI (default "urn:OtOpcUa").</summary>
|
||||
public string ApplicationUri { get; set; } = "urn:OtOpcUa";
|
||||
|
||||
/// <summary>Gets or sets the product URI (default "https://zb.com/otopcua").</summary>
|
||||
public string ProductUri { get; set; } = "https://zb.com/otopcua";
|
||||
|
||||
/// <summary>Listening port for the binary endpoint (default 4840).</summary>
|
||||
@@ -93,6 +99,10 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
|
||||
private StandardServer? _server;
|
||||
private ImpersonateEventHandler? _impersonateHandler;
|
||||
|
||||
/// <summary>Initializes a new instance of the OPC UA application host.</summary>
|
||||
/// <param name="options">The host configuration options.</param>
|
||||
/// <param name="logger">The logger for diagnostic output.</param>
|
||||
/// <param name="userAuthenticator">An optional user authenticator for UserName tokens; uses null implementation if not provided.</param>
|
||||
public OpcUaApplicationHost(
|
||||
OpcUaApplicationHostOptions options,
|
||||
ILogger<OpcUaApplicationHost> logger,
|
||||
@@ -103,9 +113,15 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
|
||||
_userAuthenticator = userAuthenticator ?? NullOpcUaUserAuthenticator.Instance;
|
||||
}
|
||||
|
||||
/// <summary>Gets the OPC Foundation application instance, or null if not yet started.</summary>
|
||||
public ApplicationInstance? ApplicationInstance => _application;
|
||||
|
||||
/// <summary>Gets the OPC UA server instance, or null if not yet started.</summary>
|
||||
public StandardServer? Server => _server;
|
||||
|
||||
/// <summary>Starts the OPC UA application and server.</summary>
|
||||
/// <param name="server">The standard server instance to start.</param>
|
||||
/// <param name="cancellationToken">A cancellation token for the operation.</param>
|
||||
public async Task StartAsync(StandardServer server, CancellationToken cancellationToken)
|
||||
{
|
||||
_server = server;
|
||||
@@ -215,6 +231,9 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
|
||||
/// the full SDK. Side-effects are confined to mutating <see cref="ImpersonateEventArgs"/>
|
||||
/// and logging.
|
||||
/// </summary>
|
||||
/// <param name="authenticator">The user authenticator to validate credentials.</param>
|
||||
/// <param name="args">The impersonation event arguments to process.</param>
|
||||
/// <param name="logger">The logger for diagnostic output.</param>
|
||||
internal static void HandleImpersonation(
|
||||
IOpcUaUserAuthenticator authenticator,
|
||||
ImpersonateEventArgs args,
|
||||
@@ -351,6 +370,7 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
|
||||
/// falls back to a single None entry so the server doesn't refuse to start with no
|
||||
/// listening endpoints — the misconfiguration is logged and very visible.
|
||||
/// </summary>
|
||||
/// <param name="profiles">The security profiles to build policies for.</param>
|
||||
internal static IEnumerable<ServerSecurityPolicy> BuildSecurityPolicies(IEnumerable<OpcUaSecurityProfile> profiles)
|
||||
{
|
||||
var seen = new HashSet<OpcUaSecurityProfile>();
|
||||
@@ -409,6 +429,7 @@ public sealed class OpcUaApplicationHost : IAsyncDisposable
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>Disposes the application host and cleans up resources.</summary>
|
||||
public ValueTask DisposeAsync()
|
||||
{
|
||||
if (_impersonateHandler is not null && _server?.CurrentInstance?.SessionManager is { } sessionManager)
|
||||
|
||||
@@ -30,13 +30,18 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
||||
private readonly ConcurrentDictionary<string, FolderState> _folders = new(StringComparer.Ordinal);
|
||||
private FolderState? _root;
|
||||
|
||||
/// <summary>Initializes a new instance of the <see cref="OtOpcUaNodeManager"/> class with the OPC UA server and configuration.</summary>
|
||||
/// <param name="server">The OPC UA server instance.</param>
|
||||
/// <param name="configuration">The application configuration.</param>
|
||||
public OtOpcUaNodeManager(IServerInternal server, ApplicationConfiguration configuration)
|
||||
: base(server, configuration, DefaultNamespaceUri)
|
||||
{
|
||||
// SystemContext is initialised by the base ctor.
|
||||
}
|
||||
|
||||
/// <summary>Gets the count of variable nodes currently managed.</summary>
|
||||
public int VariableCount => _variables.Count;
|
||||
/// <summary>Gets the count of folder nodes currently managed.</summary>
|
||||
public int FolderCount => _folders.Count;
|
||||
|
||||
/// <summary>
|
||||
@@ -44,6 +49,10 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
||||
/// variable node on first call; subsequent calls update Value + StatusCode +
|
||||
/// SourceTimestamp and call <c>ClearChangeMasks</c> so subscribed clients see the change.
|
||||
/// </summary>
|
||||
/// <param name="nodeId">The node identifier of the variable.</param>
|
||||
/// <param name="value">The new value to write.</param>
|
||||
/// <param name="quality">The OPC UA quality status code.</param>
|
||||
/// <param name="sourceTimestampUtc">The timestamp of the value in UTC.</param>
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(nodeId);
|
||||
@@ -61,6 +70,10 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
||||
/// <summary>Apply an alarm-state write. Surfaced as a two-element Variable carrying
|
||||
/// <c>[active, acknowledged]</c> — proper <c>AlarmConditionState</c> + event firing
|
||||
/// comes when the F14b walker integration lands and registers real condition nodes.</summary>
|
||||
/// <param name="alarmNodeId">The node identifier of the alarm variable.</param>
|
||||
/// <param name="active">Whether the alarm is currently active.</param>
|
||||
/// <param name="acknowledged">Whether the alarm has been acknowledged.</param>
|
||||
/// <param name="sourceTimestampUtc">The timestamp of the alarm state change in UTC.</param>
|
||||
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(alarmNodeId);
|
||||
@@ -82,6 +95,9 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
||||
/// folder hierarchy. Idempotent: the second call with the same id returns the cached
|
||||
/// folder so adding child variables under it still works.
|
||||
/// </summary>
|
||||
/// <param name="folderNodeId">The node identifier of the folder.</param>
|
||||
/// <param name="parentNodeId">The node identifier of the parent folder; null to use the namespace root.</param>
|
||||
/// <param name="displayName">The display name of the folder.</param>
|
||||
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(folderNodeId);
|
||||
@@ -116,6 +132,10 @@ public sealed class OtOpcUaNodeManager : CustomNodeManager2
|
||||
/// Idempotent. Materialises Galaxy / SystemPlatform tags so they're browseable before the
|
||||
/// Galaxy driver issues SubscribeBulk.
|
||||
/// </summary>
|
||||
/// <param name="variableNodeId">The node identifier of the variable.</param>
|
||||
/// <param name="parentFolderNodeId">The node identifier of the parent folder; null to use the namespace root.</param>
|
||||
/// <param name="displayName">The display name of the variable.</param>
|
||||
/// <param name="dataType">The OPC UA data type name (e.g., "Boolean", "Int32", "String").</param>
|
||||
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType)
|
||||
{
|
||||
ArgumentException.ThrowIfNullOrEmpty(variableNodeId);
|
||||
|
||||
@@ -28,6 +28,9 @@ public sealed class Phase7Applier
|
||||
private readonly IOpcUaAddressSpaceSink _sink;
|
||||
private readonly ILogger<Phase7Applier> _logger;
|
||||
|
||||
/// <summary>Initializes a new instance of the Phase7Applier class.</summary>
|
||||
/// <param name="sink">The OPC UA address space sink to apply changes to.</param>
|
||||
/// <param name="logger">The logger instance.</param>
|
||||
public Phase7Applier(IOpcUaAddressSpaceSink sink, ILogger<Phase7Applier> logger)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(sink);
|
||||
@@ -40,6 +43,8 @@ public sealed class Phase7Applier
|
||||
/// Apply <paramref name="plan"/> to the sink. Returns a summary of what was applied so
|
||||
/// callers (OpcUaPublishActor) can correlate the work back to the originating deployment.
|
||||
/// </summary>
|
||||
/// <param name="plan">The plan to apply.</param>
|
||||
/// <returns>A Phase7ApplyOutcome summarizing the applied changes.</returns>
|
||||
public Phase7ApplyOutcome Apply(Phase7Plan plan)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(plan);
|
||||
@@ -104,6 +109,7 @@ public sealed class Phase7Applier
|
||||
/// Idempotent: each <c>EnsureFolder</c> call returns the existing folder if already
|
||||
/// present, so re-applies are cheap.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition result containing the hierarchy to materialise.</param>
|
||||
public void MaterialiseHierarchy(Phase7CompositionResult composition)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(composition);
|
||||
@@ -136,6 +142,7 @@ public sealed class Phase7Applier
|
||||
/// the Galaxy driver's <c>OnDataChange</c> path fills the value in once SubscribeBulk lands.
|
||||
/// Idempotent.
|
||||
/// </summary>
|
||||
/// <param name="composition">The composition result containing the Galaxy tags to materialise.</param>
|
||||
public void MaterialiseGalaxyTags(Phase7CompositionResult composition)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(composition);
|
||||
|
||||
@@ -18,6 +18,9 @@ public sealed record Phase7CompositionResult(
|
||||
IReadOnlyList<GalaxyTagPlan> GalaxyTags)
|
||||
{
|
||||
/// <summary>Convenience constructor for tests + earlier callers that don't carry UNS or Galaxy data.</summary>
|
||||
/// <param name="equipmentNodes">The equipment nodes.</param>
|
||||
/// <param name="driverInstancePlans">The driver instance plans.</param>
|
||||
/// <param name="scriptedAlarmPlans">The scripted alarm plans.</param>
|
||||
public Phase7CompositionResult(
|
||||
IReadOnlyList<EquipmentNode> equipmentNodes,
|
||||
IReadOnlyList<DriverInstancePlan> driverInstancePlans,
|
||||
@@ -28,6 +31,11 @@ public sealed record Phase7CompositionResult(
|
||||
}
|
||||
|
||||
/// <summary>Convenience constructor for callers carrying UNS but not Galaxy data.</summary>
|
||||
/// <param name="unsAreas">The UNS areas.</param>
|
||||
/// <param name="unsLines">The UNS lines.</param>
|
||||
/// <param name="equipmentNodes">The equipment nodes.</param>
|
||||
/// <param name="driverInstancePlans">The driver instance plans.</param>
|
||||
/// <param name="scriptedAlarmPlans">The scripted alarm plans.</param>
|
||||
public Phase7CompositionResult(
|
||||
IReadOnlyList<UnsAreaProjection> unsAreas,
|
||||
IReadOnlyList<UnsLineProjection> unsLines,
|
||||
@@ -74,6 +82,10 @@ public sealed record GalaxyTagPlan(
|
||||
public static class Phase7Composer
|
||||
{
|
||||
/// <summary>Convenience overload for legacy callers + tests that don't yet supply UNS / Galaxy data.</summary>
|
||||
/// <param name="equipment">The equipment.</param>
|
||||
/// <param name="driverInstances">The driver instances.</param>
|
||||
/// <param name="scriptedAlarms">The scripted alarms.</param>
|
||||
/// <returns>The composition result.</returns>
|
||||
public static Phase7CompositionResult Compose(
|
||||
IReadOnlyList<Equipment> equipment,
|
||||
IReadOnlyList<DriverInstance> driverInstances,
|
||||
@@ -82,6 +94,12 @@ public static class Phase7Composer
|
||||
Array.Empty<Tag>(), Array.Empty<Namespace>());
|
||||
|
||||
/// <summary>UNS-aware overload that doesn't yet supply Galaxy tags.</summary>
|
||||
/// <param name="unsAreas">The UNS areas.</param>
|
||||
/// <param name="unsLines">The UNS lines.</param>
|
||||
/// <param name="equipment">The equipment.</param>
|
||||
/// <param name="driverInstances">The driver instances.</param>
|
||||
/// <param name="scriptedAlarms">The scripted alarms.</param>
|
||||
/// <returns>The composition result.</returns>
|
||||
public static Phase7CompositionResult Compose(
|
||||
IReadOnlyList<UnsArea> unsAreas,
|
||||
IReadOnlyList<UnsLine> unsLines,
|
||||
@@ -91,6 +109,17 @@ public static class Phase7Composer
|
||||
Compose(unsAreas, unsLines, equipment, driverInstances, scriptedAlarms,
|
||||
Array.Empty<Tag>(), Array.Empty<Namespace>());
|
||||
|
||||
/// <summary>
|
||||
/// Composes the address space build plan from the configuration entities.
|
||||
/// </summary>
|
||||
/// <param name="unsAreas">The UNS areas.</param>
|
||||
/// <param name="unsLines">The UNS lines.</param>
|
||||
/// <param name="equipment">The equipment.</param>
|
||||
/// <param name="driverInstances">The driver instances.</param>
|
||||
/// <param name="scriptedAlarms">The scripted alarms.</param>
|
||||
/// <param name="tags">The tags.</param>
|
||||
/// <param name="namespaces">The namespaces.</param>
|
||||
/// <returns>The composition result.</returns>
|
||||
public static Phase7CompositionResult Compose(
|
||||
IReadOnlyList<UnsArea> unsAreas,
|
||||
IReadOnlyList<UnsLine> unsLines,
|
||||
|
||||
@@ -26,6 +26,7 @@ public sealed record Phase7Plan(
|
||||
IReadOnlyList<GalaxyTagPlan> RemovedGalaxyTags,
|
||||
IReadOnlyList<Phase7Plan.GalaxyTagDelta> ChangedGalaxyTags)
|
||||
{
|
||||
/// <summary>Gets a value indicating whether the composition plan contains no changes.</summary>
|
||||
public bool IsEmpty =>
|
||||
AddedEquipment.Count == 0 && RemovedEquipment.Count == 0 && ChangedEquipment.Count == 0 &&
|
||||
AddedDrivers.Count == 0 && RemovedDrivers.Count == 0 && ChangedDrivers.Count == 0 &&
|
||||
@@ -46,6 +47,8 @@ public static class Phase7Planner
|
||||
/// Element equality on the projection records doubles as the "did this change" check,
|
||||
/// so any field difference moves an item from "stable" to ChangedX.
|
||||
/// </summary>
|
||||
/// <param name="previous">The previous composition result.</param>
|
||||
/// <param name="next">The new composition result.</param>
|
||||
public static Phase7Plan Compute(Phase7CompositionResult previous, Phase7CompositionResult next)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(previous);
|
||||
|
||||
@@ -12,23 +12,45 @@ public sealed class SdkAddressSpaceSink : IOpcUaAddressSpaceSink
|
||||
{
|
||||
private readonly OtOpcUaNodeManager _nodeManager;
|
||||
|
||||
/// <summary>Initializes a new instance of the SdkAddressSpaceSink class.</summary>
|
||||
/// <param name="nodeManager">The OPC UA node manager.</param>
|
||||
public SdkAddressSpaceSink(OtOpcUaNodeManager nodeManager)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(nodeManager);
|
||||
_nodeManager = nodeManager;
|
||||
}
|
||||
|
||||
/// <summary>Writes a value to the OPC UA address space.</summary>
|
||||
/// <param name="nodeId">The OPC UA node identifier.</param>
|
||||
/// <param name="value">The value being written.</param>
|
||||
/// <param name="quality">The OPC UA quality status.</param>
|
||||
/// <param name="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
public void WriteValue(string nodeId, object? value, OpcUaQuality quality, DateTime sourceTimestampUtc)
|
||||
=> _nodeManager.WriteValue(nodeId, value, quality, sourceTimestampUtc);
|
||||
|
||||
/// <summary>Writes alarm state to the OPC UA address space.</summary>
|
||||
/// <param name="alarmNodeId">The alarm node identifier.</param>
|
||||
/// <param name="active">Whether the alarm is active.</param>
|
||||
/// <param name="acknowledged">Whether the alarm is acknowledged.</param>
|
||||
/// <param name="sourceTimestampUtc">The source timestamp in UTC.</param>
|
||||
public void WriteAlarmState(string alarmNodeId, bool active, bool acknowledged, DateTime sourceTimestampUtc)
|
||||
=> _nodeManager.WriteAlarmState(alarmNodeId, active, acknowledged, sourceTimestampUtc);
|
||||
|
||||
/// <summary>Ensures a folder node exists in the address space.</summary>
|
||||
/// <param name="folderNodeId">The folder node identifier.</param>
|
||||
/// <param name="parentNodeId">The parent folder node identifier.</param>
|
||||
/// <param name="displayName">The display name for the folder.</param>
|
||||
public void EnsureFolder(string folderNodeId, string? parentNodeId, string displayName)
|
||||
=> _nodeManager.EnsureFolder(folderNodeId, parentNodeId, displayName);
|
||||
|
||||
/// <summary>Ensures a variable node exists in the address space.</summary>
|
||||
/// <param name="variableNodeId">The variable node identifier.</param>
|
||||
/// <param name="parentFolderNodeId">The parent folder node identifier.</param>
|
||||
/// <param name="displayName">The display name for the variable.</param>
|
||||
/// <param name="dataType">The OPC UA data type.</param>
|
||||
public void EnsureVariable(string variableNodeId, string? parentFolderNodeId, string displayName, string dataType)
|
||||
=> _nodeManager.EnsureVariable(variableNodeId, parentFolderNodeId, displayName, dataType);
|
||||
|
||||
/// <summary>Rebuilds the entire OPC UA address space.</summary>
|
||||
public void RebuildAddressSpace() => _nodeManager.RebuildAddressSpace();
|
||||
}
|
||||
|
||||
@@ -23,12 +23,17 @@ public sealed class SdkServiceLevelPublisher : IServiceLevelPublisher
|
||||
private readonly IServerInternal _serverInternal;
|
||||
private readonly ILogger<SdkServiceLevelPublisher> _logger;
|
||||
|
||||
/// <summary>Initializes a new instance of the SdkServiceLevelPublisher class.</summary>
|
||||
/// <param name="serverInternal">The OPC UA server internal interface.</param>
|
||||
/// <param name="logger">The logger instance.</param>
|
||||
public SdkServiceLevelPublisher(IServerInternal serverInternal, ILogger<SdkServiceLevelPublisher> logger)
|
||||
{
|
||||
_serverInternal = serverInternal;
|
||||
_logger = logger;
|
||||
}
|
||||
|
||||
/// <summary>Publishes the service level to the OPC UA Server object.</summary>
|
||||
/// <param name="serviceLevel">The service level value to publish.</param>
|
||||
public void Publish(byte serviceLevel)
|
||||
{
|
||||
var node = _serverInternal.ServerObject?.ServiceLevel;
|
||||
|
||||
@@ -17,6 +17,10 @@ public interface IOpcUaUserAuthenticator
|
||||
/// reject codes, and a thrown exception escapes into the OPC UA SDK's session-activation
|
||||
/// path where it surfaces as a generic <c>BadInternalError</c>.
|
||||
/// </summary>
|
||||
/// <param name="username">The username to authenticate.</param>
|
||||
/// <param name="password">The cleartext password to authenticate.</param>
|
||||
/// <param name="ct">The cancellation token.</param>
|
||||
/// <returns>An OpcUaUserAuthResult indicating success or failure.</returns>
|
||||
Task<OpcUaUserAuthResult> AuthenticateUserNameAsync(string username, string password, CancellationToken ct);
|
||||
}
|
||||
|
||||
@@ -27,9 +31,16 @@ public sealed record OpcUaUserAuthResult(
|
||||
IReadOnlyList<string> Roles,
|
||||
string? Error)
|
||||
{
|
||||
/// <summary>Creates a successful authentication result with the specified display name and roles.</summary>
|
||||
/// <param name="displayName">The display name for the authenticated user.</param>
|
||||
/// <param name="roles">The roles to assign to the authenticated user.</param>
|
||||
/// <returns>A successful OpcUaUserAuthResult.</returns>
|
||||
public static OpcUaUserAuthResult Allow(string displayName, IReadOnlyList<string> roles) =>
|
||||
new(true, displayName, roles, null);
|
||||
|
||||
/// <summary>Creates a failed authentication result with the specified error message.</summary>
|
||||
/// <param name="error">The error message describing why authentication failed.</param>
|
||||
/// <returns>A failed OpcUaUserAuthResult.</returns>
|
||||
public static OpcUaUserAuthResult Deny(string error) =>
|
||||
new(false, null, Array.Empty<string>(), error);
|
||||
}
|
||||
@@ -44,6 +55,11 @@ public sealed class NullOpcUaUserAuthenticator : IOpcUaUserAuthenticator
|
||||
public static readonly NullOpcUaUserAuthenticator Instance = new();
|
||||
private NullOpcUaUserAuthenticator() { }
|
||||
|
||||
/// <summary>Authenticates a username (always denies in this null implementation).</summary>
|
||||
/// <param name="username">The username to authenticate.</param>
|
||||
/// <param name="password">The cleartext password to authenticate.</param>
|
||||
/// <param name="ct">The cancellation token.</param>
|
||||
/// <returns>A task that returns a denial result indicating no authenticator is configured.</returns>
|
||||
public Task<OpcUaUserAuthResult> AuthenticateUserNameAsync(string username, string password, CancellationToken ct) =>
|
||||
Task.FromResult(OpcUaUserAuthResult.Deny("No UserName authenticator is configured on this server."));
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user