Skip to content

Commit

Permalink
Adding LoadLdif
Browse files Browse the repository at this point in the history
  • Loading branch information
jespino committed Jan 24, 2024
1 parent af9191c commit 9ec5e34
Show file tree
Hide file tree
Showing 3 changed files with 115 additions and 1 deletion.
17 changes: 17 additions & 0 deletions docs/modules/openldap.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,20 @@ for OpenLDAP. E.g. `testcontainers.WithImage("bitnami/openldap:2.6.6")`.
### Container Methods

The OpenLDAP container exposes the following methods:

#### ConnectionString

This method returns the connection string to connect to the OpenLDAP container, using the `1389` port.

<!--codeinclude-->
[Get connection string](../../modules/openldap/openldap_test.go) inside_block:connectionString
<!--/codeinclude-->

#### LoadLdif

This method loads an ldif file in the OpenLDAP server.
It returns and error if there is any problem with the ldif file loading process.

<!--codeinclude-->
[Load ldif](../../modules/openldap/openldap_test.go) inside_block:loadLdif
<!--/codeinclude-->
30 changes: 29 additions & 1 deletion modules/openldap/openldap.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,9 @@ package openldap

import (
"context"
"errors"
"fmt"
"io"
"net"

"github.com/testcontainers/testcontainers-go"
Expand All @@ -19,8 +21,12 @@ const (
// OpenLDAPContainer represents the OpenLDAP container type used in the module
type OpenLDAPContainer struct {
testcontainers.Container
adminUsername string
adminPassword string
rootDn string
}

// ConnectionString returns the connection string for the OpenLDAP container
func (c *OpenLDAPContainer) ConnectionString(ctx context.Context, args ...string) (string, error) {
containerPort, err := c.MappedPort(ctx, "1389/tcp")
if err != nil {
Expand All @@ -36,6 +42,23 @@ func (c *OpenLDAPContainer) ConnectionString(ctx context.Context, args ...string
return connStr, nil
}

// LoadLdif loads an ldif file into the OpenLDAP container
func (c *OpenLDAPContainer) LoadLdif(ctx context.Context, ldif []byte) error {
err := c.CopyToContainer(ctx, ldif, "/tmp/ldif.ldif", 0o755)
if err != nil {
return err
}
code, output, err := c.Exec(ctx, []string{"ldapadd", "-H", "ldap://localhost:1389", "-x", "-D", fmt.Sprintf("cn=%s,%s", c.adminUsername, c.rootDn), "-w", c.adminPassword, "-f", "/tmp/ldif.ldif"})
if err != nil {
return err
}
if code != 0 {
data, _ := io.ReadAll(output)
return errors.New(string(data))
}
return nil
}

// WithAdminUsername sets the initial admin username to be created when the container starts
// It is used in conjunction with WithAdminPassword to set a username and its password.
// It will create the specified user with admin power.
Expand Down Expand Up @@ -91,5 +114,10 @@ func RunContainer(ctx context.Context, opts ...testcontainers.ContainerCustomize
return nil, err
}

return &OpenLDAPContainer{Container: container}, nil
return &OpenLDAPContainer{
Container: container,
adminUsername: req.Env["LDAP_ADMIN_USERNAME"],
adminPassword: req.Env["LDAP_ADMIN_PASSWORD"],
rootDn: req.Env["LDAP_ROOT"],
}, nil
}
69 changes: 69 additions & 0 deletions modules/openldap/openldap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,9 @@ func TestOpenLDAPWithDifferentRoot(t *testing.T) {
}
})

// connectionString {
connectionString, err := container.ConnectionString(ctx)
// }
if err != nil {
t.Fatal(err)
}
Expand All @@ -90,3 +92,70 @@ func TestOpenLDAPWithDifferentRoot(t *testing.T) {
t.Fatal(err)
}
}

func TestOpenLDAPWithLdif(t *testing.T) {
ctx := context.Background()

container, err := RunContainer(ctx, testcontainers.WithImage("bitnami/openldap:2.6.6"))
if err != nil {
t.Fatal(err)
}

// Clean up the container after the test is complete
t.Cleanup(func() {
if err := container.Terminate(ctx); err != nil {
t.Fatalf("failed to terminate container: %s", err)
}
})

// loadLdif {
ldif := `
dn: uid=test.user,ou=users,dc=example,dc=org
changetype: add
objectclass: iNetOrgPerson
cn: Test User
sn: Test
mail: test.user@example.org
userPassword: Password1
`

err = container.LoadLdif(ctx, []byte(ldif))
// }
if err != nil {
t.Fatal(err)
}

connectionString, err := container.ConnectionString(ctx)
if err != nil {
t.Fatal(err)
}

client, err := ldap.DialURL(connectionString)
if err != nil {
t.Fatal(err)
}
defer client.Close()

// First bind with a read only user
err = client.Bind("cn=admin,dc=example,dc=org", "adminpassword")
if err != nil {
t.Fatal(err)
}

result, err := client.Search(&ldap.SearchRequest{
BaseDN: "uid=test.user,ou=users,dc=example,dc=org",
Scope: ldap.ScopeWholeSubtree,
Filter: "(objectClass=*)",
Attributes: []string{"dn"},
})
if err != nil {
t.Fatal(err)
}

if len(result.Entries) != 1 {
t.Fatal("Invalid number of entries returned", result.Entries)
}
if result.Entries[0].DN != "uid=test.user,ou=users,dc=example,dc=org" {
t.Fatal("Invalid entry returned", result.Entries[0].DN)
}
}

0 comments on commit 9ec5e34

Please sign in to comment.