diff --git a/.github/workflows/pr.yml b/.github/workflows/pr.yml index 3c283d1d..b6f49806 100644 --- a/.github/workflows/pr.yml +++ b/.github/workflows/pr.yml @@ -24,6 +24,9 @@ jobs: - name: Version run: go version + - name: Setup local directory server + run: make local-server + - name: Build, Validate, and Test run: | cd ${{ matrix.directory }} diff --git a/Makefile b/Makefile index 0a414a0e..23b6bc5f 100644 --- a/Makefile +++ b/Makefile @@ -1,56 +1,58 @@ -.PHONY: default install build test quicktest fmt vet lint +.PHONY: default install build test quicktest fmt vet lint -# List of all release tags "supported" by our current Go version -# E.g. ":go1.1:go1.2:go1.3:go1.4:go1.5:go1.6:go1.7:go1.8:go1.9:go1.10:go1.11:go1.12:" -GO_RELEASE_TAGS := $(shell go list -f ':{{join (context.ReleaseTags) ":"}}:' runtime) +default: fmt vet lint build quicktest -# Only use the `-race` flag on newer versions of Go (version 1.3 and newer) -ifeq (,$(findstring :go1.3:,$(GO_RELEASE_TAGS))) - RACE_FLAG := -else - RACE_FLAG := -race -cpu 1,2,4 +CONTAINER_CMD := $(shell command -v podman 2>/dev/null) +ifeq ($(CONTAINER_CMD),) + CONTAINER_CMD := $(shell command -v docker 2>/dev/null) endif -# Run `go vet` on Go 1.12 and newer. For Go 1.5-1.11, use `go tool vet` -ifneq (,$(findstring :go1.12:,$(GO_RELEASE_TAGS))) - GO_VET := go vet \ - -atomic \ - -bool \ - -copylocks \ - -nilfunc \ - -printf \ - -rangeloops \ - -unreachable \ - -unsafeptr \ - -unusedresult \ - . -else ifneq (,$(findstring :go1.5:,$(GO_RELEASE_TAGS))) - GO_VET := go tool vet \ - -atomic \ - -bool \ - -copylocks \ - -nilfunc \ - -printf \ - -shadow \ - -rangeloops \ - -unreachable \ - -unsafeptr \ - -unusedresult \ - . -else - GO_VET := @echo "go vet skipped -- not supported on this version of Go" +# Check if we found either command +ifeq ($(CONTAINER_CMD),) + $(error Neither podman nor docker found in PATH) endif -default: fmt vet lint build quicktest - install: go get -t -v ./... build: go build -v ./... -test: - go test -v $(RACE_FLAG) -cover ./... +LDAP_ADMIN_DN := cn=admin,dc=example,dc=com +LDAP_ADMIN_PASSWORD := admin123 +LDAP_BASE_DN := dc=example,dc=com +LDAP_URL := ldap://127.0.0.1:389 +CONTAINER_NAME := go-ldap-test + +local-server: + -$(CONTAINER_CMD) rm -f -t 10 $(CONTAINER_NAME) + $(CONTAINER_CMD) \ + run \ + --rm \ + -d \ + --name $(CONTAINER_NAME) \ + --hostname "$(CONTAINER_NAME).example.com" \ + -p "127.0.0.1:3389:389" \ + -p "127.0.0.1:3636:636" \ + -e LDAP_ORGANISATION="Example Inc" \ + -e LDAP_DOMAIN="example.com" \ + -e LDAP_ADMIN_PASSWORD="$(LDAP_ADMIN_PASSWORD)" \ + -e LDAP_TLS_VERIFY_CLIENT="never" \ + docker.io/osixia/openldap:1.5.0 + + @echo "Waiting for LDAP server to be ready..." + @$(CONTAINER_CMD) exec $(CONTAINER_NAME) /bin/sh -c 'until ldapsearch -x -H $(LDAP_URL) -b "$(LDAP_BASE_DN)" -D "$(LDAP_ADMIN_DN)" -w $(LDAP_ADMIN_PASSWORD) > /dev/null 2>&1; do echo "LDAP server not ready yet, waiting..."; sleep 2; done' + @echo "LDAP server is ready!" + + @echo "Configuring anonymous access..." + @$(CONTAINER_CMD) exec $(CONTAINER_NAME) /bin/sh -c 'echo "dn: olcDatabase={1}mdb,cn=config\nchangetype: modify\nreplace: olcAccess\nolcAccess: {0}to * by * read" | ldapmodify -Y EXTERNAL -H ldapi:///' + + $(CONTAINER_CMD) cp -a ./testdata $(CONTAINER_NAME):/ + @echo "Loading LDIF files..." + @$(CONTAINER_CMD) exec $(CONTAINER_NAME) /bin/sh -c 'for file in /testdata/*.ldif; do echo "Processing $$file..."; cat "$$file" | ldapadd -v -x -H $(LDAP_URL) -D "$(LDAP_ADMIN_DN)" -w $(LDAP_ADMIN_PASSWORD); done' + +delete-container: + -$(CONTAINER_CMD) rm -f -t 10 $(CONTAINER_NAME) quicktest: go test ./... @@ -71,7 +73,17 @@ fmt: fi vet: - $(GO_VET) + go vet \ + -atomic \ + -bool \ + -copylocks \ + -nilfunc \ + -printf \ + -rangeloops \ + -unreachable \ + -unsafeptr \ + -unusedresult \ + ./... # https://github.com/golang/lint # go get github.com/golang/lint/golint diff --git a/testdata/01_Organizational_Units.ldif b/testdata/01_Organizational_Units.ldif new file mode 100755 index 00000000..4ec72af7 --- /dev/null +++ b/testdata/01_Organizational_Units.ldif @@ -0,0 +1,7 @@ +dn: ou=people,dc=example,dc=com +objectClass: organizationalUnit +ou: people + +dn: ou=groups,dc=example,dc=com +objectClass: organizationalUnit +ou: groups diff --git a/testdata/02_Groups.ldif b/testdata/02_Groups.ldif new file mode 100644 index 00000000..f0962f85 --- /dev/null +++ b/testdata/02_Groups.ldif @@ -0,0 +1,7 @@ +dn: cn=DistributionList,ou=groups,dc=example,dc=com +objectClass: groupOfNames +objectClass: top +cn: DistributionList +member: +member: cn=DoeJo,ou=people,dc=example,dc=com +member: cn=MustermannMa,ou=people,dc=example,dc=com diff --git a/testdata/02_People.ldif b/testdata/02_People.ldif new file mode 100644 index 00000000..131e76ed --- /dev/null +++ b/testdata/02_People.ldif @@ -0,0 +1,21 @@ +dn: cn=DoeJo,ou=people,dc=example,dc=com +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: DoeJo +sn: Doe +displayName: Doe, John +givenName: John +mail: John.Doe@example.com + +dn: cn=MustermannMa,ou=people,dc=example,dc=com +objectClass: inetOrgPerson +objectClass: organizationalPerson +objectClass: person +objectClass: top +cn: MustermannMa +sn: Mustermann +displayName: Mustermann, Max +givenName: Max +mail: Max.Mustermann@example.com diff --git a/v3/ldap_test.go b/v3/ldap_test.go index 5b96e039..ce83b278 100644 --- a/v3/ldap_test.go +++ b/v3/ldap_test.go @@ -10,16 +10,16 @@ import ( ) const ( - ldapServer = "ldap://ldap.itd.umich.edu:389" - ldapsServer = "ldaps://ldap.itd.umich.edu:636" - baseDN = "dc=umich,dc=edu" + ldapServer = "ldap://127.0.0.1:3389" + ldapsServer = "ldaps://127.0.0.1:3636" + baseDN = "dc=example,dc=com" ) var filter = []string{ - "(cn=cis-fac)", - "(&(owner=*)(cn=cis-fac))", - "(&(objectclass=rfc822mailgroup)(cn=*Computer*))", - "(&(objectclass=rfc822mailgroup)(cn=*Mathematics*))", + "(cn=DoeJo)", + "(&(sn=Doe)(givenName=John))", + "(|(sn=Doe)(givenName=Max*))", + "(objectClass=inetOrgPerson)", } var attributes = []string{ @@ -258,9 +258,9 @@ func TestCompare(t *testing.T) { } defer l.Close() - const dn = "cn=math mich,ou=User Groups,ou=Groups,dc=umich,dc=edu" + const dn = "cn=DoeJo,ou=people,dc=example,dc=com" const attribute = "cn" - const value = "math mich" + const value = "DoeJo" sr, err := l.Compare(dn, attribute, value) if err != nil {