Sign in to edit and +1 items.
Login required
Download

Embedded LDAP Server Plugin

(0)
Author(s) Luke Daley
Current Release 0.1.8   (1 year ago)
Grails Version 1.1 > *
Tags
Dependency
compile ":ldap-server:0.1.8"
Allows the embedding of an LDAP directory (via ApacheDS) for testing purposes
Last updated by admin 3 years ago
grails install-plugin ldap-server
Last updated by ldaley 3 years ago
This plugin allows you to embed one or more LDAP servers right in your Grails application. This can be extremely useful for developing and testing applications that work with LDAP enabled directories.

The plugin uses ApacheDS 1.5.4 as the directory implementation.

Features

  • Data is transient
  • Revertable directory state
  • Automatic loading of user defined static data
  • Automatic loading of user defined custom schema
  • Support for loading templated LDIF fixtures
  • Support for loading arbitrary LDIF (file, dir of .ldif files, or a string of LDIF)
  • Dynamic reloading of directories on static data, schema or config change
  • Servers available as beans in the application context within your application (for getting at data or reverting state)
  • A exists(String dn) server bean method for verifying that an entry exists in the directory
  • A getAt(String dn) server bean method for getting the entry at dn as a Map .
For detail on how to use these features please see the FAQ page.

The data in the directories is transient (i.e. it will not survive across restarts). This is intentional as the plugin was designed to provide "mock" directories to code against.

However, if there is any interest in providing production class embedded directories with this plugin it might be added as a feature.

Last updated by ldaley 2 years ago

How do I create an LDAP server?

LDAP servers are controlled by the application config. Each entry under the key ldapServers is an LDAP server.

Example...

File: grails-app/conf/Config.groovy

ldapServers {
	d1 {
		base = "dc=d1,dc=my,dc=org"
		port = 10400
		indexed = ["objectClass", "uid", "mail"]
	}
	d2 {} // use defaults
}

This will embed 2 LDAP directories in your grails application.

The possible config parameters are:

NameTypeDescriptionDefault 
baseStringThe base component of your directory"dc=grails,dc=org" 
portIntegerThe port to bind the LDAP server to10389 
indexedString[]The attributes in the directory that should be indexed["objectClass", "uid", "ou"] 

How do I add some static data to my directory?

As the directory is starting up, it looks for any *.ldif files in grails-app/ldap-servers/«name»/data and loads them in alphabetical order. Note that «name» is the name of the directory in the config, not the bean name.

How do I customise the schema of my directory?

To do this you need to know a little bit about how ApacheDS manages schema. I strongly recommend reading this article to get some background on this. In short, ApacheDS stores the schema in the directory itself in ou=schema in a certain structure. Apache Directory Studio can export a schema in LDIF suitable for importing into an instance of ApacheDS.

To import this schema into your directory, place it in grails-app/ldap-servers/«name»/schema . Each LDIF file in that directory will be loaded in alphabetical order when the directory is starting up and before any data is loaded. Note that «name» is the name of the directory in the config, not the bean name.

How do I access the server over LDAP?

You can connect to the LDAP server over the port specified in the config and with the following credentials:

userDn = "uid=admin,ou=system"
password = "secret"

How do I access the server bean at runtime?

Each server instance is available as a bean in the application context as «name»LdapServer, where «name» is the name of the directory in the config.

Example...

class MyIntegrationTest extends GroovyTestCase {
	def d1LdapServer
}

Server beans are instances of grails.ldap.server.TransientGrailsLdapServer .

How do I load test data fixtures?

Server beans expose methods to load LDIF files from grails-app/ldap-servers/«name»/fixtures as templates to be inserted into the directory.

Example...

File:grails-app/ldap-servers/d1/fixtures/personTemplate.ldif

dn: cn=${cn},dc=d1,dc=my,dc=org
cn: ${cn}
sn: ${sn}
objectClass: person
objectClass: top
objectClass: organizationalPerson

Then to load the fixture...

d1LdapServer.loadFixture("personTemplate", cn: "test", sn: "person")

Fixtures don't have to be templates, the following would have the same affect...

File:grails-app/ldap-servers/d1/fixtures/person.ldif

dn: cn=test,dc=d1,dc=my,dc=org
cn: test
sn: person
objectClass: person
objectClass: top
objectClass: organizationalPerson

Then to load the fixture...

d1LdapServer.loadFixture("person")

There is also a loadFixtures() variant that can load multiple fixtures at once (with out without templating)...

d1LdapServer.loadFixtures("ou", "person")

The templating is achieved by using Groovy's SimpleTemplateEngine . See this article for more details.

How do I load arbitrary LDIF?

Server beans expose a loadLdif(ldif) method that will add the specified LDIF to the directory.

If the argument is a…

  • File object and is not a directory; it's content is consumed as LDIF.
  • File object and is a directory; all files matching *.ldif in that directory will be consumed.
  • Anything else, the String representation of that object will be consumed as LDIF.

How do I see if an entry exists in the directory?

Server beans expose a exists(String dn) method that will return true if an entry does exist at dn .

Example...

assert d1LdapServer.exists("cn=test,dc=d1,dc=my,dc=org")

How do I retrieve an entry from the directory?

Server beans implement getAt(String dn) which returns a Map of the entry at dn 's values if it exists, or null if it does not.

If the attribute is multi valued by definition (i.e. it's actual attribute definition in the schema), it's values will be in a List . Be careful here because many common attributes that you might think aren't multi valued actually are (e.g 'cn', 'sn').

If the attribute value is binary, it will be a byte[]@, otherwise it will be a @String .

Example...

def user = d1LdapServer["cn=user,dc=d1,dc=my,dc=org"]
assert "user" == entry.cn.first() // cn is a multi valued string attribute
assert entry.usercertificate.first() instanceof byte[] // usercertificate is a multi valued binary attribute

def country = d1LdapServer["c=au,dc=d1,dc=my,dc=org"] assert "au" == entry.countryName // countryName is a single valued string attribute

How do I revert the directory state?

Server beans expose a clean() method which undoes any changes made to the directory since it was loaded . This means that all custom schema and static data will still be there.

d1LdapServer.loadLdif("""
dn: cn=test,dc=d1,dc=my,dc=org
cn: test
sn: person
objectClass: person
objectClass: top
objectClass: organizationalPerson
""")

assert d1LdapServer.exists("cn=test,dc=d1,dc=my,dc=org")) == true

d1LdapServer.clean() // Removing anything added after startup

assert d1LdapServer.exists("cn=test,dc=d1,dc=my,dc=org")) == false

How do I stop/start the server?

You shouldn't need to do this, but if you do there are the following three methods on your server beans...

stop()
start()
restart()

Starting a server includes reloading all custom schema and static data.

Last updated by admin 3 years ago