@page "/clusters/{ClusterId}/acls" @attribute [Authorize(Policy = AdminUiPolicies.AuthenticatedRead)] @rendermode RenderMode.InteractiveServer @using Microsoft.EntityFrameworkCore @using ZB.MOM.WW.OtOpcUa.Configuration @using ZB.MOM.WW.OtOpcUa.Configuration.Entities @inject IDbContextFactory DbFactory

ACLs · @ClusterId

New ACL grant
@if (_rows is null) {

Loading…

} else {
ACL rows grant principals specific NodePermissions on a scope (the cluster, a namespace, an area, an equipment, a raw device, a tag). A principal is an API key's principal, or the reserved anonymous principal that an anonymous session authenticates as.
@_rows.Count ACL row@(_rows.Count == 1 ? "" : "s")
@if (_rows.Count == 0) {
No ACL rows for this cluster — no principal holds WriteOperate or AlarmAck here, so writes and alarm acknowledges are refused. Reads, browses, subscriptions and history reads are unaffected.
} else {
@foreach (var a in _rows) { }
NodeAclId Principal Scope Scope target Permissions Notes
@a.NodeAclId @a.Principal @a.ScopeKind @(a.ScopeId ?? "—") @foreach (var perm in PermissionChips(a.PermissionFlags)) { @perm } @(a.Notes ?? "") Edit
}
} @code { [Parameter] public string ClusterId { get; set; } = ""; private List? _rows; protected override async Task OnInitializedAsync() { await using var db = await DbFactory.CreateDbContextAsync(); _rows = await db.NodeAcls.AsNoTracking() .Where(a => a.ClusterId == ClusterId) .OrderBy(a => a.NodeAclId) .ToListAsync(); } private static IEnumerable PermissionChips(ZB.MOM.WW.OtOpcUa.Configuration.Enums.NodePermissions flags) { foreach (var v in Enum.GetValues()) { // Skip None (zero) and composite values that aren't single bits. var n = (int)v; if (n == 0) continue; if ((n & (n - 1)) != 0) continue; if (flags.HasFlag(v)) yield return v.ToString(); } } }