From c5a6da4a84b59c55bfee86c1862724a61a5f8914 Mon Sep 17 00:00:00 2001 From: Sebastian Mendel Date: Tue, 28 Jul 2026 20:21:46 +0200 Subject: [PATCH] fix: keep test scaffolding out of the binary and bump the toolchain gosec became blocking in the shared workflow and flagged G103 (audit unsafe) in internal/server/test_helpers.go. The file has no _test suffix, so it compiled into package server: the mock LDAP client, the fixture builder and its reflect+unsafe write to ldap.Object's unexported dn field all shipped in the production binary, reachable by nothing but reachable all the same. Split it. LDAPClient is the only declaration production code uses (2 call sites), so it moves to ldap_client.go; MockLDAP, NewMockLDAP, setObjectDN and newTestServer move to test_helpers_test.go. unsafe and reflect are now compiled into the test binary only. No suppression comment: gosec runs without -tests, so the finding is gone because the code is gone from the build, not because it was silenced. The unsafe write itself stays as-is. simple-ldap-go writes Object.dn only in objectFromEntry when decoding a directory response and exposes no constructor taking a DN, so a fixture cannot be built through its public API. govulncheck was failing too, on four stdlib advisories. Move the module to go 1.26 with toolchain go1.26.5, matching ofelia. Verified with go1.26.5: gosec 0 issues, govulncheck reports 0 affecting vulnerabilities, go vet clean, tests pass, and no production file imports unsafe. Signed-off-by: Sebastian Mendel --- go.mod | 4 +++- internal/server/ldap_client.go | 13 +++++++++++++ .../{test_helpers.go => test_helpers_test.go} | 13 +++++-------- 3 files changed, 21 insertions(+), 9 deletions(-) create mode 100644 internal/server/ldap_client.go rename internal/server/{test_helpers.go => test_helpers_test.go} (91%) diff --git a/go.mod b/go.mod index 9c23401..b3d6e85 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,8 @@ module raybeam -go 1.25.1 +go 1.26 + +toolchain go1.26.5 require ( github.com/go-ldap/ldap/v3 v3.4.14 diff --git a/internal/server/ldap_client.go b/internal/server/ldap_client.go new file mode 100644 index 0000000..33ed25d --- /dev/null +++ b/internal/server/ldap_client.go @@ -0,0 +1,13 @@ +package server + +import ( + ldap "github.com/netresearch/simple-ldap-go" +) + +// LDAPClient interface defines the LDAP operations needed by the server. +// This interface allows for mock implementations in tests. +type LDAPClient interface { + FindUserBySAMAccountName(sAMAccountName string) (*ldap.User, error) + FindUsersBySAMAccountNames(sAMAccountNames []string) ([]*ldap.User, error) + CheckPasswordForSAMAccountName(sAMAccountName, password string) (*ldap.User, error) +} diff --git a/internal/server/test_helpers.go b/internal/server/test_helpers_test.go similarity index 91% rename from internal/server/test_helpers.go rename to internal/server/test_helpers_test.go index 00e85a9..86aa8ef 100644 --- a/internal/server/test_helpers.go +++ b/internal/server/test_helpers_test.go @@ -11,14 +11,6 @@ import ( "go.etcd.io/bbolt" ) -// LDAPClient interface defines the LDAP operations needed by the server. -// This interface allows for mock implementations in tests. -type LDAPClient interface { - FindUserBySAMAccountName(sAMAccountName string) (*ldap.User, error) - FindUsersBySAMAccountNames(sAMAccountNames []string) ([]*ldap.User, error) - CheckPasswordForSAMAccountName(sAMAccountName, password string) (*ldap.User, error) -} - // MockLDAP implements LDAPClient for testing. type MockLDAP struct { users map[string]*ldap.User @@ -26,6 +18,11 @@ type MockLDAP struct { } // setObjectDN uses reflection to set the DN field in an ldap.Object (which has unexported fields). +// +// simple-ldap-go exposes no constructor that takes a DN — Object.dn is written +// only by objectFromEntry when decoding a directory response — so a fixture +// cannot be built through the public API. This lives in a _test.go file so the +// unsafe write is compiled into the test binary only. func setObjectDN(obj interface{}, dn string) { // Get the reflect.Value of the object v := reflect.ValueOf(obj).Elem()