Monday, October 12, 2009

ActiveLDAP in Scala : LDAP on the JVM, in a shell !

Update: typos only

Until a really recent time, LDAP in the JVM, trougth JNDI API, was a nightmare of usability. Just connecting to an LDAP directory with a simple login/pass was worth a dozen lines of really unatural code (and I'm almost not exagering)

Hopefully, the situation is evolving, and there is several projects willing to provide a better LDAP SDK on the JVM.

Among them, there is UnboundId's one. I started to play with it, and it's quite delighting to be able to use a good API to do your work !

So it gives me an idea : how this SDK could be pimped thanks to Scala to be used in command lines, in a ruby ActiveLDAP fashion ?

And things are coming along really well. It's just a start, but this is an example of a Scala REPL session with my version of Scala ActiveLDAP :


scala> import test.activeldap._
import test.activeldap._

scala> import LdapFilter._
import LdapFilter._

scala> val p = new SimpleAuthLCP(baseDn = "dc=example,dc=org",authDn = 
"cn=admin", authPw = "secret pass")
p: test.activeldap.SimpleAuthLCP = [cn=admin@localhost:389 (base: 
dc=example,dc=org) by password authentication]

scala> val users = new MetaActiveEntry(prefix = "ou=people",  
rdn = "uid" , classes = Set("top","person","organizationalPerson","inetOrgPerson"), 
provider = p )
users: test.activeldap.MetaActiveEntry = test.activeldap.MetaActiveEntry@c85a33

scala> val user = users.find()(0)
user: test.activeldap.ActiveEntry = uid=42,ou=people,dc=example,dc=org

scala> user.details
res28: java.lang.String = Entry(dn='uid=42,ou=people,dc=example,dc=org', 
attributes={Attribute(name=objectClass, values={'inetOrgPerson', 
'organizationalPerson', 'person', 'top'}), 
Attribute(name=sn, values={'Bar'}), Attribute(name=cn, values={'Foo'}), 
Attribute(name=mail, values={'foo@bar.com'}), Attribute(name=uid, values={'42'})})

scala> user("uid") = "43"

scala> user.save

scala> users.find()
res31: Seq[test.activeldap.ActiveEntry] = ArrayBuffer(uid=42,ou=people,dc=example,dc=org,
uid=43,ou=people,dc=example,dc=org)

scala> user("mail") = Seq("foo@bar.com","foo_bar@bar.com")

scala> user.save

scala> users.find(EQ("uid","43"))(0).details
res34: java.lang.String = Entry(dn='uid=43,ou=people,dc=example,dc=org', 
attributes={Attribute(name=objectClass, values={'inetOrgPerson', 
'organizationalPerson', 'person', 'top'}), Attribute(name=sn, values={'Bar'}),
Attribute(name=cn, values={'Foo'}), Attribute(name=mail, values={'foo@bar.com', 
'foo_bar@bar.com'}), Attribute(name=uid, values={'43'})})

scala> user.delete

scala> users.find(EQ("uid","43"))
res36: Seq[test.activeldap.ActiveEntry] = ArrayBuffer()


scala> 

There is a really nice feature brought by Scala 2.8 for this kind of API: named and default parameters. I  used it in the previous sessions to define the connection: host and port were not provided (default to localhost:389),  but you can specify them if you need :

 scala> val p = new SimpleAuthLCP(
        | authDn = "cn=manager",
        | authPw = "secret password",
        | host = "an.other.host.com",
        | port = "1389",
        | baseDn = "dc=company,dc=com"
        | )

It's just a begining, and there is a lot of other nice features from Ruby ActiveLDAP that could be added...

3 comments:

dirmngr

Thanks for using the UnboundID LDAP SDK. I've only used it very briefly with Scala to verify that it worked and write a simple application, but it's definitely a language that I think I want to look into more.

Please let us know if you have any suggestions for improvement or run into any problems with it.

Daniel

For consistency sake, LDAP ought to always appear in upper case, as it is an initial (Lightweight Directory Access Protocol).

Also, "there" instead of "their" in the second paragraph. I don't like to be a nit-picker, but it is bothering me for some reason. :-)

Fanf

@Daniel : typo corrected, thanks.

For the LDAP case, I'm still not sure of the capitalization, at least in my code. I try to strictly follow camel case (yes, I'm a Java guy, that's part of my folklore), but it may be not definitive. I know that OpenDS and UnboundID use "LDAP" in their code, and ApacheDS use camel case.

In other places, I try to use the full capitalized form to keep the meaning, as you gently remind us.

  © Blogger template 'Minimalist G' by Ourblogtemplates.com 2008

Back to TOP