@page "/role-grants" @attribute [Microsoft.AspNetCore.Authorization.Authorize(Policy = "FleetAdmin")] @rendermode RenderMode.InteractiveServer @using Microsoft.Extensions.Options @using ZB.MOM.WW.OtOpcUa.Configuration.Entities @using ZB.MOM.WW.OtOpcUa.Configuration.Enums @using ZB.MOM.WW.OtOpcUa.Configuration.Services @using ZB.MOM.WW.OtOpcUa.Security.Ldap @inject IOptionsSnapshot Ldap @inject ILdapGroupRoleMappingService RoleMappings

Role grants

@if (_options is not null) {
LDAP binding
Enabled@(_options.Enabled ? "yes" : "no")
Server@_options.Server:@_options.Port
Transport@_options.Transport
SearchBase@_options.SearchBase
@if (_options.Transport == ZB.MOM.WW.Auth.Abstractions.Ldap.LdapTransport.None && _options.AllowInsecure) {
WarningPlaintext credentials over LDAP — dev mode only
}
}
Group → role (database)
@if (_error is not null) {
@_error
}
@if (_rows.Count == 0) { } else { @foreach (var r in _rows) { } }
LDAP groupRole
No database role grants. Authentication falls back to the appsettings map below.
@r.LdapGroup @r.Role
@if (_options is not null) {
Fallback (appsettings) (@(_options.GroupToRole?.Count ?? 0))
These Authentication:Ldap:GroupToRole entries apply when a group has no database row above.
@if (_options.GroupToRole is null || _options.GroupToRole.Count == 0) {
No appsettings fallback mapping configured.
} else {
@foreach (var kvp in _options.GroupToRole.OrderBy(k => k.Key, StringComparer.OrdinalIgnoreCase)) { }
LDAP groupResolved role
@kvp.Key @kvp.Value
}
} @code { private LdapOptions? _options; private IReadOnlyList _rows = []; private string _newGroup = ""; private AdminRole _newRole = AdminRole.Viewer; private string? _error; private bool _busy; protected override async Task OnInitializedAsync() { _options = Ldap.Value; await ReloadAsync(); } private async Task ReloadAsync() => _rows = (await RoleMappings.ListAllAsync(default)).Where(r => r.IsSystemWide).ToList(); private async Task AddAsync() { _error = null; if (string.IsNullOrWhiteSpace(_newGroup)) { _error = "LDAP group is required."; return; } _busy = true; StateHasChanged(); try { await RoleMappings.CreateAsync(new LdapGroupRoleMapping { LdapGroup = _newGroup.Trim(), Role = _newRole, IsSystemWide = true, ClusterId = null, }, default); _newGroup = ""; _newRole = AdminRole.Viewer; await ReloadAsync(); } catch (Exception ex) { _error = ex.Message; } finally { _busy = false; } } private async Task DeleteAsync(Guid id) { _error = null; _busy = true; StateHasChanged(); try { await RoleMappings.DeleteAsync(id, default); await ReloadAsync(); } catch (Exception ex) { _error = ex.Message; } finally { _busy = false; } } }