using System; using Shouldly; using Xunit; using ZB.MOM.WW.OtOpcUa.Host.Configuration; using ZB.MOM.WW.OtOpcUa.Host.Domain; namespace ZB.MOM.WW.OtOpcUa.Tests.Authentication { public class UserAuthenticationTests { [Fact] public void AuthenticationConfiguration_Defaults() { var config = new AuthenticationConfiguration(); config.AllowAnonymous.ShouldBeTrue(); config.AnonymousCanWrite.ShouldBeTrue(); } [Fact] public void AuthenticationConfiguration_LdapDefaults() { var config = new AuthenticationConfiguration(); config.Ldap.ShouldNotBeNull(); config.Ldap.Enabled.ShouldBeFalse(); config.Ldap.Host.ShouldBe("localhost"); config.Ldap.Port.ShouldBe(3893); config.Ldap.BaseDN.ShouldBe("dc=lmxopcua,dc=local"); config.Ldap.ReadOnlyGroup.ShouldBe("ReadOnly"); config.Ldap.WriteOperateGroup.ShouldBe("WriteOperate"); config.Ldap.WriteTuneGroup.ShouldBe("WriteTune"); config.Ldap.WriteConfigureGroup.ShouldBe("WriteConfigure"); config.Ldap.AlarmAckGroup.ShouldBe("AlarmAck"); config.Ldap.TimeoutSeconds.ShouldBe(5); } [Fact] public void LdapConfiguration_BindDnTemplate_Default() { var config = new LdapConfiguration(); config.BindDnTemplate.ShouldBe("cn={username},dc=lmxopcua,dc=local"); } [Fact] public void LdapAuthenticationProvider_ValidBind_ReturnsTrue() { // This test requires GLAuth running on localhost:3893 // Skip if not available var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("readonly", "readonly123").ShouldBeTrue(); } catch (Exception) { // GLAuth not running - skip gracefully } } [Fact] public void LdapAuthenticationProvider_InvalidPassword_ReturnsFalse() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("readonly", "wrongpassword").ShouldBeFalse(); } catch (Exception) { } } [Fact] public void LdapAuthenticationProvider_UnknownUser_ReturnsFalse() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("nonexistent", "anything").ShouldBeFalse(); } catch (Exception) { } } [Fact] public void LdapAuthenticationProvider_ReadOnlyUser_HasReadOnlyRole() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("readonly", "readonly123").ShouldBeTrue(); var roles = provider.GetUserRoles("readonly"); roles.ShouldContain("ReadOnly"); roles.ShouldNotContain("WriteOperate"); roles.ShouldNotContain("AlarmAck"); } catch (Exception) { } } [Fact] public void LdapAuthenticationProvider_WriteOperateUser_HasWriteOperateRole() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("writeop", "writeop123").ShouldBeTrue(); var roles = provider.GetUserRoles("writeop"); roles.ShouldContain("WriteOperate"); roles.ShouldNotContain("AlarmAck"); } catch (Exception) { } } [Fact] public void LdapAuthenticationProvider_AlarmAckUser_HasAlarmAckRole() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("alarmack", "alarmack123").ShouldBeTrue(); var roles = provider.GetUserRoles("alarmack"); roles.ShouldContain("AlarmAck"); roles.ShouldNotContain("WriteOperate"); } catch (Exception) { } } [Fact] public void LdapAuthenticationProvider_AdminUser_HasAllRoles() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); try { provider.ValidateCredentials("admin", "admin123").ShouldBeTrue(); var roles = provider.GetUserRoles("admin"); roles.ShouldContain("ReadOnly"); roles.ShouldContain("WriteOperate"); roles.ShouldContain("WriteTune"); roles.ShouldContain("WriteConfigure"); roles.ShouldContain("AlarmAck"); } catch (Exception) { } } [Fact] public void LdapAuthenticationProvider_ImplementsIRoleProvider() { var ldapConfig = CreateGlAuthConfig(); var provider = new LdapAuthenticationProvider(ldapConfig); (provider is IRoleProvider).ShouldBeTrue(); } [Fact] public void LdapAuthenticationProvider_ConnectionFailure_ReturnsFalse() { var ldapConfig = new LdapConfiguration { Enabled = true, Host = "localhost", Port = 19999, // no server here TimeoutSeconds = 1 }; var provider = new LdapAuthenticationProvider(ldapConfig); provider.ValidateCredentials("anyone", "anything").ShouldBeFalse(); } [Fact] public void LdapAuthenticationProvider_ConnectionFailure_GetUserRoles_FallsBackToReadOnly() { var ldapConfig = new LdapConfiguration { Enabled = true, Host = "localhost", Port = 19999, // no server here TimeoutSeconds = 1, ServiceAccountDn = "cn=svc,dc=test", ServiceAccountPassword = "test" }; var provider = new LdapAuthenticationProvider(ldapConfig); var roles = provider.GetUserRoles("anyone"); roles.ShouldContain("ReadOnly"); } private static LdapConfiguration CreateGlAuthConfig() { return new LdapConfiguration { Enabled = true, Host = "localhost", Port = 3893, BaseDN = "dc=lmxopcua,dc=local", BindDnTemplate = "cn={username},dc=lmxopcua,dc=local", ServiceAccountDn = "cn=serviceaccount,dc=lmxopcua,dc=local", ServiceAccountPassword = "serviceaccount123", TimeoutSeconds = 5, ReadOnlyGroup = "ReadOnly", WriteOperateGroup = "WriteOperate", WriteTuneGroup = "WriteTune", WriteConfigureGroup = "WriteConfigure", AlarmAckGroup = "AlarmAck" }; } } }