Initial commit: scadaproj umbrella — sister-project index, auth component normalization (design + GAPS), and the built ZB.MOM.WW.Auth shared library (0.1.0, flattened in).
This commit is contained in:
@@ -0,0 +1,102 @@
|
||||
// GLAuth integration test — opt-in only.
|
||||
//
|
||||
// Prerequisites
|
||||
// -------------
|
||||
// 1. A running GLAuth instance (plaintext LDAP, no TLS).
|
||||
// A ready-made Docker Compose stack lives in the sibling repo:
|
||||
// ~/Desktop/ScadaBridge/infra/glauth
|
||||
// Start it with: docker compose up -d
|
||||
// Default listen address: localhost:3893
|
||||
//
|
||||
// 2. Set the following environment variables before running:
|
||||
// ZB_LDAP_IT=1 (required — gates the test)
|
||||
// ZB_LDAP_SERVER=localhost (optional, default localhost)
|
||||
// ZB_LDAP_PORT=3893 (optional, default 3893)
|
||||
// ZB_LDAP_BASE=dc=lmxopcua,dc=local (optional)
|
||||
// ZB_LDAP_SVC_DN=cn=svc,dc=lmxopcua,dc=local (service-account DN)
|
||||
// ZB_LDAP_SVC_PW=svcpass (service-account password)
|
||||
// ZB_LDAP_USER=alice (test user login)
|
||||
// ZB_LDAP_PW=alicepass (test user password)
|
||||
// ZB_LDAP_USERATTR=cn (optional, default cn)
|
||||
//
|
||||
// Run command:
|
||||
// ZB_LDAP_IT=1 ZB_LDAP_SVC_DN=... ZB_LDAP_SVC_PW=... \
|
||||
// ZB_LDAP_USER=... ZB_LDAP_PW=... \
|
||||
// dotnet test tests/ZB.MOM.WW.Auth.Ldap.Tests \
|
||||
// --filter "FullyQualifiedName~GLAuthIntegrationTests"
|
||||
//
|
||||
// Without ZB_LDAP_IT=1 the test is SKIPPED — it does not affect the normal CI run.
|
||||
|
||||
using System.Net.Sockets;
|
||||
using ZB.MOM.WW.Auth.Abstractions.Ldap;
|
||||
using ZB.MOM.WW.Auth.Ldap;
|
||||
|
||||
namespace ZB.MOM.WW.Auth.Ldap.Tests.Integration;
|
||||
|
||||
public sealed class GLAuthIntegrationTests
|
||||
{
|
||||
/// <summary>
|
||||
/// Performs a real bind-then-search-then-bind against a live GLAuth instance.
|
||||
/// Verifies that authentication succeeds and that at least one LDAP group is returned.
|
||||
/// Skipped unless <c>ZB_LDAP_IT=1</c> is set; skipped again if the server is unreachable.
|
||||
/// </summary>
|
||||
[SkippableFact]
|
||||
public async Task Authenticate_AgainstRealGLAuth_Succeeds()
|
||||
{
|
||||
// ------------------------------------------------------------------ opt-in gate
|
||||
Skip.IfNot(
|
||||
Environment.GetEnvironmentVariable("ZB_LDAP_IT") == "1",
|
||||
"Set ZB_LDAP_IT=1 and a reachable GLAuth to run.");
|
||||
|
||||
// ------------------------------------------------------------------ read config
|
||||
var server = Environment.GetEnvironmentVariable("ZB_LDAP_SERVER") ?? "localhost";
|
||||
var port = int.TryParse(Environment.GetEnvironmentVariable("ZB_LDAP_PORT"), out var p) ? p : 3893;
|
||||
var baseDn = Environment.GetEnvironmentVariable("ZB_LDAP_BASE") ?? "dc=lmxopcua,dc=local";
|
||||
var svcDn = Environment.GetEnvironmentVariable("ZB_LDAP_SVC_DN") ?? "";
|
||||
var svcPw = Environment.GetEnvironmentVariable("ZB_LDAP_SVC_PW") ?? "";
|
||||
var user = Environment.GetEnvironmentVariable("ZB_LDAP_USER") ?? "";
|
||||
var pw = Environment.GetEnvironmentVariable("ZB_LDAP_PW") ?? "";
|
||||
var userAttr = Environment.GetEnvironmentVariable("ZB_LDAP_USERATTR") ?? "cn";
|
||||
|
||||
// ------------------------------------------------------------------ reachability probe
|
||||
try
|
||||
{
|
||||
using var tcp = new TcpClient();
|
||||
// 3-second connect timeout to keep the test suite snappy when the server is absent
|
||||
var connectTask = tcp.ConnectAsync(server, port);
|
||||
if (!connectTask.Wait(TimeSpan.FromSeconds(3)))
|
||||
Skip.If(true, $"GLAuth not reachable at {server}:{port} (connect timed out).");
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Skip.If(true, $"GLAuth not reachable at {server}:{port}: {ex.Message}");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------ build options
|
||||
var options = new LdapOptions
|
||||
{
|
||||
Enabled = true,
|
||||
Server = server,
|
||||
Port = port,
|
||||
Transport = LdapTransport.None,
|
||||
AllowInsecure = true,
|
||||
SearchBase = baseDn,
|
||||
ServiceAccountDn = svcDn,
|
||||
ServiceAccountPassword = svcPw,
|
||||
UserNameAttribute = userAttr,
|
||||
// GLAuth returns memberOf by default; keep the library default
|
||||
GroupAttribute = "memberOf",
|
||||
};
|
||||
|
||||
// ------------------------------------------------------------------ exercise the real service
|
||||
// Uses the public single-argument constructor, which wires up NovellLdapConnectionFactory
|
||||
// internally — no test seam involved.
|
||||
var svc = new LdapAuthService(options);
|
||||
var result = await svc.AuthenticateAsync(user, pw, default);
|
||||
|
||||
// ------------------------------------------------------------------ assertions
|
||||
Assert.True(result.Succeeded,
|
||||
$"Authentication failed: {result.Failure} (server={server}:{port}, user={user})");
|
||||
Assert.NotEmpty(result.Groups);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user