using ZB.MOM.WW.Auth.Abstractions.Ldap; using LibLdapOptions = ZB.MOM.WW.Auth.Abstractions.Ldap.LdapOptions; namespace ZB.MOM.WW.OtOpcUa.Security.Ldap; /// /// LDAP + role-mapping configuration for the Admin UI. Bound from appsettings.json /// Security:Ldap section. Defaults point at the local GLAuth dev instance (see /// C:\publish\glauth\auth.md). /// /// /// Carries both the wire fields the shared ZB.MOM.WW.Auth.Ldap directory client needs /// (///…) AND the app-only concerns /// the shared library has no notion of ( master switch, /// dev bypass, appsettings role baseline). /// The app wrapper (OtOpcUaLdapAuthService) projects this onto the library's /// at construction; see . /// public sealed class LdapOptions { public const string SectionName = "Security:Ldap"; /// Gets or sets a value indicating whether LDAP authentication is enabled. public bool Enabled { get; set; } = true; /// Gets or sets the LDAP server hostname. public string Server { get; set; } = "localhost"; /// Gets or sets the LDAP server port. public int Port { get; set; } = 3893; /// /// Transport security for the LDAP connection — (implicit /// TLS), (upgrade), or /// (plaintext, dev/test only — requires ). Replaces the former /// UseTls bool (Task 1.4): true, /// false. /// public LdapTransport Transport { get; set; } = LdapTransport.None; /// Dev-only escape hatch — must be false in production. Maps to the shared /// library's (renamed from AllowInsecureLdap). public bool AllowInsecure { get; set; } /// /// Dev-only stub: when true, bypasses the real LDAP /// bind and accepts any non-empty username/password, returning a single Administrator role /// so the operator can navigate the full Admin UI. MUST be false in production. /// public bool DevStubMode { get; set; } /// Gets or sets the LDAP search base DN. public string SearchBase { get; set; } = "dc=zb,dc=local"; /// /// Service-account DN used for search-then-bind. When empty, a direct-bind with /// cn={user},{SearchBase} is attempted. /// public string ServiceAccountDn { get; set; } = string.Empty; /// Gets or sets the service account password for LDAP authentication. public string ServiceAccountPassword { get; set; } = string.Empty; /// Gets or sets the LDAP attribute name for user display name. public string DisplayNameAttribute { get; set; } = "cn"; /// Gets or sets the LDAP attribute name for group membership. public string GroupAttribute { get; set; } = "memberOf"; /// /// Attribute the service-account search matches the login name against to resolve the /// user's DN. cn for GLAuth (the dev default); set sAMAccountName for /// Active Directory. /// public string UserNameAttribute { get; set; } = "cn"; /// /// 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: /// "ReadOnly":"Viewer","ReadWrite":"Designer","AlarmAck":"Administrator" /// public Dictionary GroupToRole { get; set; } = new(StringComparer.OrdinalIgnoreCase); /// /// Projects the wire fields onto the shared ZB.MOM.WW.Auth.Ldap /// the directory client consumes. App-only concerns /// (, ) have no library counterpart and are /// handled by the app wrapper around the library service; is carried /// through so the library's own feature gate stays consistent with the app master switch. /// public LibLdapOptions ToLibraryOptions() => new() { Enabled = Enabled, Server = Server, Port = Port, Transport = Transport, AllowInsecure = AllowInsecure, SearchBase = SearchBase, ServiceAccountDn = ServiceAccountDn, ServiceAccountPassword = ServiceAccountPassword, UserNameAttribute = UserNameAttribute, DisplayNameAttribute = DisplayNameAttribute, GroupAttribute = GroupAttribute, }; }