mirror of
https://github.com/OPCFoundation/UA-.NETStandard.git
synced 2026-10-18 22:55:08 +08:00
296a904f34
* role management compliant with OPC UA Part 18 Server-side: - New IRoleManager / RoleManager with spec-correct status codes (Bad_AlreadyExists, Bad_NodeIdUnknown, Bad_RequestNotAllowed, Bad_NotFound) for every mutator per Part 18 4.2 / 4.4. - Pre-populate default identities for the three reserved well-known roles per Part 18 4.3 (Anonymous, AuthenticatedUser, TrustedApplication). - Reject mutations on reserved roles with Bad_RequestNotAllowed. - Validate IdentityMappingRuleType per Part 18 4.4.3 (empty criteria for Anonymous/AuthenticatedUser/TrustedApplication; upper-case hex for Thumbprint; Name=Value grammar for X509Subject). - Honour Part 18 4.4.2 default-field-as-wildcard EndpointType comparisons; tighten TrustedApplication/Application rules to require trusted certificate + signed channel. - Introduce CustomConfiguration flag per Part 18 4.4.1. - Add IRoleManager.RoleConfigurationChanged event raised after every successful mutation per Part 18 4.4.1. - Make RoleEntry an immutable snapshot. Address-space binding (typed proxies): - RoleStateBinding switched from stringly-typed OnCallMethod2 plumbing to the source-generated typed proxies (RoleSetState, RoleState, AddRoleMethodState, AddIdentityMethodState, ...). - DiagnosticsNodeManager.AddBehaviourToPredefinedNodeAsync upgrades passive BaseObjectState nodes of RoleSetType / RoleType to the typed RoleSetState / RoleState proxies at predefined-node load time. - New RoleAuthorizationGate.CheckAdmin centralizes SecurityAdmin role plus SignAndEncrypt enforcement per Part 18 4.2 / 4.4 / 5.2. - Bound writable ApplicationsExclude / EndpointsExclude / CustomConfiguration with the same auth gate. - Raise RoleMappingRuleChangedAuditEventType from every successful mutator (Part 18 4.5) via the existing AuditEvents helper. Client library: - New Opc.Ua.Client.Roles.RoleManagementClient + IRoleManagementClient + RoleInfo + SessionRoleExtensions.OpenRoleManagementClient. - Covers list / read / add / remove role, identity, application, endpoint operations plus Set*Exclude via Write Service. Tests: - New RoleManagerTests.cs - 37 NUnit tests for pre-populated roles, reserved-role immutability, spec-correct status codes, criteria validation, ResolveGrantedRoles, exclude semantics, CustomConfiguration, AddRole well-known NodeId reuse, and RoleConfigurationChanged event. Documentation: - Rewrite Docs/RoleBasedUserManagement.md as a Part 18 compliance reference (status-code matrix, client examples, known limitations). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Add Part 18 5 UserManagement implementation Server-side: - New IUserManagement interface (Opc.Ua.Server.UserManagement) modelling Part 18 5.2.1 surface: PasswordLength, PasswordOptions, PasswordRestrictions, SnapshotUsers, AddUser, ModifyUser, RemoveUser, ChangePassword, MustChangePassword, IsUserActive, UserDeactivated event. - Default UserManagement implementation wraps the existing IUserDatabase and stores per-user UserConfigurationMask + description in memory. Validates passwords against PasswordLength + character-class flags from PasswordOptions; honours Part 18 5.2 result codes (Bad_AlreadyExists, Bad_NotFound, Bad_OutOfRange, Bad_NotSupported, Bad_ConfigurationError, Bad_InvalidSelfReference, Bad_IdentityTokenInvalid). - ChangePassword clears the MustChangePassword bit on success. - New UserManagementBinding wires the typed source-generated proxies (UserManagementState, AddUserMethodState, ModifyUserMethodState, RemoveUserMethodState, ChangePasswordMethodState) - typed OnCallAsync delegates everywhere; admin gate via RoleAuthorizationGate.CheckAdmin; ChangePassword gated via RoleAuthorizationGate.CheckSelfUserName; closes active sessions for deactivated users via ISessionManager. - ConfigurationNodeManager.AddBehaviourToPredefinedNodeAsync upgrades the passive UserManagement object to the typed UserManagementState proxy at predefined-node load time; CreateServerConfiguration invokes UserManagementBinding.Bind when an IUserManagement was injected. - IServerInternal gains UserManagement getter + SetUserManagement injector. Tests: - New Tests/Opc.Ua.Server.Tests/UserManagementTests.cs - 18 NUnit tests covering AddUser happy path, duplicate / password-length / config-flag validation, RemoveUser non-existent / self-reference / NoDelete, ModifyUser self-disable / disable-other UserDeactivated event, ChangePassword happy path / same-as-old / wrong-old / MustChangePassword bit clearing / NoChangeByUser rejection, IsUserActive on disabled vs active users. Documentation: - Update Docs/RoleBasedUserManagement.md with a User Management section including the spec result-code matrix, example wiring code, and reduce known limitations - UserManagement is no longer a limitation.
135 lines
5.2 KiB
C#
135 lines
5.2 KiB
C#
/* ========================================================================
|
|
* Copyright (c) 2005-2025 The OPC Foundation, Inc. All rights reserved.
|
|
*
|
|
* OPC Foundation MIT License 1.00
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person
|
|
* obtaining a copy of this software and associated documentation
|
|
* files (the "Software"), to deal in the Software without
|
|
* restriction, including without limitation the rights to use,
|
|
* copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
* copies of the Software, and to permit persons to whom the
|
|
* Software is furnished to do so, subject to the following
|
|
* conditions:
|
|
*
|
|
* The above copyright notice and this permission notice shall be
|
|
* included in all copies or substantial portions of the Software.
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
|
|
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
|
|
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
|
|
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
|
|
* OTHER DEALINGS IN THE SOFTWARE.
|
|
*
|
|
* The complete license agreement can be found here:
|
|
* http://opcfoundation.org/License/MIT/1.00/
|
|
* ======================================================================*/
|
|
|
|
using System.Collections.Generic;
|
|
|
|
namespace Opc.Ua.Server
|
|
{
|
|
/// <summary>
|
|
/// Immutable snapshot of a role's configuration per OPC UA Part 18 §4.4.
|
|
/// </summary>
|
|
/// <remarks>
|
|
/// Returned by <see cref="IRoleManager"/> methods that expose role state to
|
|
/// the address-space binding (<see cref="RoleStateBinding"/>) and to test
|
|
/// code. The lists are caller-owned copies; mutating them does not affect
|
|
/// the manager.
|
|
/// </remarks>
|
|
public sealed class RoleEntry
|
|
{
|
|
internal RoleEntry(
|
|
NodeId roleId,
|
|
string? browseName,
|
|
ushort namespaceIndex,
|
|
bool isReserved,
|
|
bool isWellKnown,
|
|
IReadOnlyList<IdentityMappingRuleType> identities,
|
|
IReadOnlyList<string> applications,
|
|
bool applicationsExclude,
|
|
IReadOnlyList<EndpointType> endpoints,
|
|
bool endpointsExclude,
|
|
bool customConfiguration)
|
|
{
|
|
RoleId = roleId;
|
|
BrowseName = browseName;
|
|
NamespaceIndex = namespaceIndex;
|
|
IsReserved = isReserved;
|
|
IsWellKnown = isWellKnown;
|
|
Identities = identities;
|
|
Applications = applications;
|
|
ApplicationsExclude = applicationsExclude;
|
|
Endpoints = endpoints;
|
|
EndpointsExclude = endpointsExclude;
|
|
CustomConfiguration = customConfiguration;
|
|
}
|
|
|
|
/// <summary>
|
|
/// The role's NodeId (e.g. <c>Opc.Ua.ObjectIds.WellKnownRole_Observer</c>).
|
|
/// </summary>
|
|
public NodeId RoleId { get; }
|
|
|
|
/// <summary>
|
|
/// Browse name of the role; <c>null</c> for unnamed dynamic roles where
|
|
/// the manager only tracks the NodeId.
|
|
/// </summary>
|
|
public string? BrowseName { get; }
|
|
|
|
/// <summary>
|
|
/// Namespace index for the role's NodeId.
|
|
/// </summary>
|
|
public ushort NamespaceIndex { get; }
|
|
|
|
/// <summary>
|
|
/// True if the role is one of the three reserved well-known roles
|
|
/// (<c>Anonymous</c>, <c>AuthenticatedUser</c>, <c>TrustedApplication</c>)
|
|
/// that the spec forbids from being modified or removed (Part 18 §4.3).
|
|
/// </summary>
|
|
public bool IsReserved { get; }
|
|
|
|
/// <summary>
|
|
/// True if the role is one of the nine well-known roles defined in
|
|
/// OPC UA Part 3 §4.9.2 (Anonymous, AuthenticatedUser, TrustedApplication,
|
|
/// Observer, Operator, Engineer, Supervisor, ConfigureAdmin, SecurityAdmin).
|
|
/// </summary>
|
|
public bool IsWellKnown { get; }
|
|
|
|
/// <summary>
|
|
/// Snapshot of identity-mapping rules per Part 18 §4.4.3. Treat as
|
|
/// read-only — modifications are not reflected back into the manager.
|
|
/// </summary>
|
|
public IReadOnlyList<IdentityMappingRuleType> Identities { get; }
|
|
|
|
/// <summary>
|
|
/// Snapshot of ApplicationUris per Part 18 §4.4.1.
|
|
/// </summary>
|
|
public IReadOnlyList<string> Applications { get; }
|
|
|
|
/// <summary>
|
|
/// True if <see cref="Applications"/> is an exclude list.
|
|
/// </summary>
|
|
public bool ApplicationsExclude { get; }
|
|
|
|
/// <summary>
|
|
/// Snapshot of endpoints per Part 18 §4.4.1.
|
|
/// </summary>
|
|
public IReadOnlyList<EndpointType> Endpoints { get; }
|
|
|
|
/// <summary>
|
|
/// True if <see cref="Endpoints"/> is an exclude list.
|
|
/// </summary>
|
|
public bool EndpointsExclude { get; }
|
|
|
|
/// <summary>
|
|
/// True if the role uses vendor-specific configuration (Part 18 §4.4.1).
|
|
/// When <c>true</c>, the role may be granted even when
|
|
/// <see cref="Identities"/> is empty.
|
|
/// </summary>
|
|
public bool CustomConfiguration { get; }
|
|
}
|
|
}
|