docs(xmldoc): fill missing XML docs + strip tracking-ID comments across src
v2-ci / build (push) Failing after 41s
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 41s
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>/<returns>/<inheritdoc> where missing and removes project bookkeeping IDs (task/tracking refs) from shipped code comments, so the docs read cleanly and CommentChecker is quiet except for known false positives (PLC/protocol terms, event/IEqualityComparer inheritdoc). Doc/comment-only; no logic changed; solution builds clean.
This commit is contained in:
@@ -33,9 +33,14 @@ public sealed class AutoLoginAuthenticationHandler
|
||||
=> _opts = disableLoginOptions.Value;
|
||||
|
||||
/// <summary>No-op: auto-login writes no cookie, so an explicit sign-in has nothing to persist.</summary>
|
||||
/// <param name="user">The principal that would be signed in.</param>
|
||||
/// <param name="properties">Authentication properties that would be persisted.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public Task SignInAsync(ClaimsPrincipal user, AuthenticationProperties? properties) => Task.CompletedTask;
|
||||
|
||||
/// <summary>No-op: there is no auth cookie to clear; the next request re-authenticates via this handler.</summary>
|
||||
/// <param name="properties">Authentication properties that would be cleared.</param>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public Task SignOutAsync(AuthenticationProperties? properties) => Task.CompletedTask;
|
||||
|
||||
/// <inheritdoc />
|
||||
|
||||
@@ -65,7 +65,8 @@ public sealed class CookieAuthenticationStateProvider : AuthenticationStateProvi
|
||||
}
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <summary>Cancels the background ping loop, awaits its completion, and disposes the cancellation token source.</summary>
|
||||
/// <returns>A task that represents the asynchronous operation.</returns>
|
||||
public async ValueTask DisposeAsync()
|
||||
{
|
||||
_cts.Cancel();
|
||||
|
||||
@@ -132,7 +132,7 @@ public static class AuthEndpoints
|
||||
await http.SignInAsync(CookieAuthenticationDefaults.AuthenticationScheme, principal);
|
||||
|
||||
if (!isForm) return Results.NoContent();
|
||||
// Security-001: validate returnUrl is a relative (local) URL before redirecting.
|
||||
// Validate returnUrl is a relative (local) URL before redirecting.
|
||||
// An attacker can supply an absolute URL (e.g. https://evil.com) via a crafted link;
|
||||
// LoginCard echoes the value verbatim into the hidden form field. Fall back to the
|
||||
// app root rather than following the external URL (open-redirect prevention).
|
||||
|
||||
@@ -135,6 +135,7 @@ public sealed class JwtTokenService
|
||||
/// required pairing whenever a JwtBearer scheme is wired.
|
||||
/// </para>
|
||||
/// </summary>
|
||||
/// <returns>The <see cref="TokenValidationParameters"/> used to validate tokens minted by <see cref="Issue"/>.</returns>
|
||||
public TokenValidationParameters BuildValidationParameters() => new()
|
||||
{
|
||||
ValidateIssuer = true,
|
||||
|
||||
@@ -34,7 +34,7 @@ public sealed class LdapOptions
|
||||
/// Transport security for the LDAP connection — <see cref="LdapTransport.Ldaps"/> (implicit
|
||||
/// TLS), <see cref="LdapTransport.StartTls"/> (upgrade), or <see cref="LdapTransport.None"/>
|
||||
/// (plaintext, dev/test only — requires <see cref="AllowInsecure"/>). Replaces the former
|
||||
/// <c>UseTls</c> bool (Task 1.4): <c>true</c>→<see cref="LdapTransport.Ldaps"/>,
|
||||
/// <c>UseTls</c> bool: <c>true</c>→<see cref="LdapTransport.Ldaps"/>,
|
||||
/// <c>false</c>→<see cref="LdapTransport.None"/>.
|
||||
/// </summary>
|
||||
public LdapTransport Transport { get; set; } = LdapTransport.None;
|
||||
@@ -78,7 +78,7 @@ public sealed class LdapOptions
|
||||
/// <summary>
|
||||
/// Maps LDAP group name → Admin role. Group match is case-insensitive. A user gets every
|
||||
/// role whose source group is in their membership list. Values are the canonical control-plane
|
||||
/// roles (Task 1.7). Example dev mapping:
|
||||
/// roles. Example dev mapping:
|
||||
/// <code>"ReadOnly":"Viewer","ReadWrite":"Designer","AlarmAck":"Administrator"</code>
|
||||
/// </summary>
|
||||
public Dictionary<string, string> GroupToRole { get; set; } = new(StringComparer.OrdinalIgnoreCase);
|
||||
@@ -90,6 +90,7 @@ public sealed class LdapOptions
|
||||
/// handled by the app wrapper around the library service; <see cref="Enabled"/> is carried
|
||||
/// through so the library's own feature gate stays consistent with the app master switch.
|
||||
/// </summary>
|
||||
/// <returns>The projected <see cref="LibLdapOptions"/> for the shared LDAP client library.</returns>
|
||||
public LibLdapOptions ToLibraryOptions() => new()
|
||||
{
|
||||
Enabled = Enabled,
|
||||
|
||||
@@ -20,7 +20,13 @@ public sealed class OtOpcUaGroupRoleMapper(
|
||||
IOptions<LdapOptions> ldapOptions,
|
||||
ILdapGroupRoleMappingService dbMappings) : IGroupRoleMapper<string>
|
||||
{
|
||||
/// <inheritdoc />
|
||||
/// <summary>Maps a user's LDAP group memberships to their OtOpcUa roles.</summary>
|
||||
/// <param name="groups">The LDAP group names the user is a member of.</param>
|
||||
/// <param name="ct">Cancellation token for the DB lookup.</param>
|
||||
/// <returns>
|
||||
/// The merged role mapping — the appsettings <c>GroupToRole</c> baseline unioned with
|
||||
/// any matching system-wide DB grants, with a <c>null</c> <see cref="GroupRoleMapping{TRole}.Scope"/>.
|
||||
/// </returns>
|
||||
public async Task<GroupRoleMapping<string>> MapAsync(IReadOnlyList<string> groups, CancellationToken ct)
|
||||
{
|
||||
ArgumentNullException.ThrowIfNull(groups);
|
||||
|
||||
@@ -29,7 +29,7 @@ namespace ZB.MOM.WW.OtOpcUa.Security.Ldap;
|
||||
/// <remarks>
|
||||
/// Fail-closed: the library never throws, and this wrapper adds no new throwing paths. The
|
||||
/// DevStub result grants the canonical <c>"Administrator"</c> control-plane role (group
|
||||
/// <c>"dev"</c>) so the dev session can navigate the full Admin UI (Task 1.7 renamed the prior
|
||||
/// <c>"dev"</c>) so the dev session can navigate the full Admin UI (renamed from the prior
|
||||
/// <c>"FleetAdmin"</c> to the canonical <c>"Administrator"</c>).
|
||||
/// </remarks>
|
||||
public sealed class OtOpcUaLdapAuthService : ILdapAuthService
|
||||
@@ -80,7 +80,7 @@ public sealed class OtOpcUaLdapAuthService : ILdapAuthService
|
||||
{
|
||||
// Dev bypass: accept any non-empty credentials and grant Administrator WITHOUT a real bind.
|
||||
// Pre-populated Roles are unioned with the mapper output by both consumers, so the grant
|
||||
// survives the move to IGroupRoleMapper. (Task 1.7 canonicalized the role string from the
|
||||
// survives the move to IGroupRoleMapper. (The role string was canonicalized from the
|
||||
// prior "FleetAdmin" to "Administrator".)
|
||||
_logger.LogWarning(
|
||||
"OtOpcUaLdapAuthService: DevStubMode bypass — accepting {User} without a real LDAP bind", username);
|
||||
@@ -90,7 +90,7 @@ public sealed class OtOpcUaLdapAuthService : ILdapAuthService
|
||||
// Fail closed on a plaintext transport unless explicitly opted in. The bespoke service
|
||||
// enforced this at login (not startup), so the host still boots with an insecure-by-default
|
||||
// config and only refuses the bind here — preserved verbatim after the UseTls→Transport
|
||||
// migration (Task 1.4). The shared library's directory client does not re-check this.
|
||||
// migration. The shared library's directory client does not re-check this.
|
||||
if (_options.Transport == LdapTransport.None && !_options.AllowInsecure)
|
||||
return new(false, null, username, [], [],
|
||||
"Insecure LDAP is disabled. Enable a TLS transport or set AllowInsecure for dev/test.");
|
||||
|
||||
@@ -33,6 +33,7 @@ public static class RoleMapper
|
||||
/// </summary>
|
||||
/// <param name="baselineRoles">Roles already resolved from appsettings (or the dev stub).</param>
|
||||
/// <param name="dbRows">LdapGroupRoleMapping rows for the user's groups (from GetByGroupsAsync).</param>
|
||||
/// <returns>The merged, de-duplicated list of roles.</returns>
|
||||
public static IReadOnlyList<string> Merge(
|
||||
IReadOnlyCollection<string> baselineRoles,
|
||||
IReadOnlyCollection<LdapGroupRoleMapping> dbRows)
|
||||
|
||||
@@ -33,6 +33,7 @@ public static class ServiceCollectionExtensions
|
||||
/// </summary>
|
||||
/// <param name="services">The service collection.</param>
|
||||
/// <param name="configuration">The application configuration root.</param>
|
||||
/// <returns>The same service collection, for chaining.</returns>
|
||||
public static IServiceCollection AddOtOpcUaAuth(this IServiceCollection services, IConfiguration configuration)
|
||||
{
|
||||
services.AddOptions<JwtOptions>().Bind(configuration.GetSection(JwtOptions.SectionName));
|
||||
@@ -148,7 +149,7 @@ public static class ServiceCollectionExtensions
|
||||
|
||||
// DriverOperator (policy NAME kept stable): may issue Reconnect/Restart commands against
|
||||
// live driver instances from the Admin UI DriverStatusPanel. The role STRINGS it requires
|
||||
// are the canonical control-plane roles (Task 1.7): Operator (was DriverOperator) and
|
||||
// are the canonical control-plane roles: Operator (was DriverOperator) and
|
||||
// Administrator (was FleetAdmin). Map LDAP group → role via GroupToRole in appsettings
|
||||
// (e.g. "ot-driver-operator": "Operator").
|
||||
o.AddPolicy("DriverOperator", policy =>
|
||||
|
||||
Reference in New Issue
Block a user