826312befe
Clears CommentChecker findings in src/ (3,280 -> 209, the remainder being false positives like PLC-5/IEEE-754/M0.0) by adding missing summaries/params/returns, normalising inheritdoc usage, and removing Gitea/review tracking IDs while keeping the rationale they annotated. Comment-only: comment-stripped sources are identical to the parent commit.
72 lines
3.7 KiB
C#
72 lines
3.7 KiB
C#
using Opc.Ua;
|
|
|
|
namespace ZB.MOM.WW.OtOpcUa.OpcUaServer.Security;
|
|
|
|
/// <summary>
|
|
/// A <see cref="UserIdentity"/> that additionally carries the LDAP-resolved roles
|
|
/// (<see cref="OpcUaUserAuthResult.Roles"/>) for the authenticated session. The SDK stores the
|
|
/// instance we assign to <c>ImpersonateEventArgs.Identity</c> by reference onto
|
|
/// <c>Session.Identity</c>/<c>Session.EffectiveIdentity</c> (no wrapping or copying), so a method
|
|
/// handler can later recover the roles via
|
|
/// <c>(context as ISessionOperationContext)?.UserIdentity as RoleCarryingUserIdentity</c> — the
|
|
/// seam the inbound alarm ack/shelve <c>AlarmAck</c> gate (T18) reads. This type only carries the
|
|
/// roles; it makes no auth decision.
|
|
/// </summary>
|
|
public sealed class RoleCarryingUserIdentity : UserIdentity
|
|
{
|
|
/// <summary>
|
|
/// Initializes a new instance, building the base identity from the same UserName token the
|
|
/// SDK decrypted and attaching the authenticator's resolved roles.
|
|
/// </summary>
|
|
/// <param name="token">The user identity token the SDK handed to the impersonation handler.</param>
|
|
/// <param name="roles">The roles resolved by the authenticator (e.g. <c>ReadOnly</c>, <c>AlarmAck</c>).</param>
|
|
public RoleCarryingUserIdentity(UserIdentityToken token, IReadOnlyList<string> roles)
|
|
: this(token, roles, principal: string.Empty, apiKeyId: null)
|
|
{
|
|
}
|
|
|
|
/// <summary>
|
|
/// Initializes a new instance carrying the ACL principal and the authenticating key id alongside
|
|
/// the roles.
|
|
/// </summary>
|
|
/// <param name="token">The user identity token the SDK handed to the impersonation handler.</param>
|
|
/// <param name="roles">The roles resolved by the authenticator.</param>
|
|
/// <param name="principal">The ACL principal this session authenticates as.</param>
|
|
/// <param name="apiKeyId">The public id of the key that authenticated, or null for anonymous.</param>
|
|
public RoleCarryingUserIdentity(
|
|
UserIdentityToken token, IReadOnlyList<string> roles, string principal, string? apiKeyId)
|
|
: base(token)
|
|
{
|
|
ArgumentNullException.ThrowIfNull(roles);
|
|
// Freeze to a defensive copy so a caller mutating the source list can never retroactively
|
|
// alter this session's granted roles, and so the gate's per-ack `.Contains(...)` runs over a
|
|
// known-small frozen array.
|
|
Roles = [.. roles];
|
|
Principal = principal ?? string.Empty;
|
|
ApiKeyId = apiKeyId;
|
|
}
|
|
|
|
/// <summary>The roles the authenticator granted this session, used by downstream permission gates.</summary>
|
|
public IReadOnlyList<string> Roles { get; }
|
|
|
|
/// <summary>
|
|
/// The ACL principal this session authenticates as — the name <c>NodeAcl</c> rows key on, and what
|
|
/// the permission trie matches. Empty when the authenticator predates the principal model, which
|
|
/// the ACL gate treats as unauthorized.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// ⚠️ <b>This is NOT <see cref="UserIdentity.DisplayName"/>.</b> The base class derives that from
|
|
/// the presented token, so for a key-bearing client it is the static username <c>apikey</c> —
|
|
/// identical for every key in the fleet and useless as an identity. See
|
|
/// <see cref="OpcUaUserAuthResult.Principal"/>.
|
|
/// </remarks>
|
|
public string Principal { get; }
|
|
|
|
/// <summary>
|
|
/// Public id of the API key that authenticated this session, or null for anonymous. Lets an open
|
|
/// session be re-checked against a later deployment that revoked the key, instead of the key
|
|
/// remaining usable until the client happens to disconnect.
|
|
/// </summary>
|
|
public string? ApiKeyId { get; }
|
|
}
|