Saturday, September 29, 2007

Building Things with high order functions...

One thing that always surprise me, is code that extensively uses high order function or let's call that "functions that returns functions" (may be known also as "closure")...
What can I, myself, do with such things ?
After a little time reading and thinking, and reading and reading, I designed a really simple usage of all of this. I'll create some helper functions to build xml tags...

-module(tags).
-export([tags/1]).

tags(Elem) ->
fun(X) ->
"<" ++ Elem ++ ">" ++ X ++ "</" ++ Elem ++ ">"
end.


Let me explain:
  • Elem will be the enclosing tag
  • X is the parameter the function will receive at call time

The module in action:

1> c(tags).
{ok,tags}
2> Div = tags:tags("div").
#Fun<tags.0.28130594>
3> Div("html text").
"<div>html text</div>"
4>

'tags:tags' returns a function that will create div tags...

Now you're able to build a list of functions that will create valid output, without knowing the real syntax. You can see 'tags:tags' as a function that abstract the final notation of an element of your choice.

For example, building a 'title' tags is done by :

Title = tags:tags("title").

Building a list of functions for your language can be done like this:

lists:map(fun tags:tags/1, ["title", "div", "p", "ul", "li", "script"]).

Tuesday, September 11, 2007

Erlang LDAP support and Active Directory

Where I work now, LDAP and Active Directory are used everywhere, since this is a nice idea and everybody is used to it, I have the obligation to use the same framework for users authentication...
Once there's a central authentication mecanism somewhere it would be idiotic to not use it :p

This is why I started looking the Erlang LDAP support...

Everybody knows that erlang is really good at doing ASN1, but more people may not know that this feature is very very powerful... And while using the LDAP protocol this is really a killer feature, because once all ELDAP.* generated files are written you have access to the full power of LDAPv3...

I was idling a little on #erlang and talked a bit about LDAP and finally 'etnt' shows me the 'eldap' module... The first article I found was the one on Trapexit.org.
Since I use CEAN to work I just need to do

cean:install(eldap).

To get the 'eldap' module installed, I also use the developer cean package so I can retrieve source files aka *.erl files...

Then comes problems...
I wasn't able to connect to any of both servers. I was able to see that the tcp connection was correct but that the module don't want to bind (LDAP meaning).

I then activate the debug level (really nice feature):

eldap:debug_level("ldap", 2).

After that everything becomes clearer... The 'check_Pkt/1' fun incorrectly drop the packet !
I modified the fun, and make it returns 'ok'. Right after that every connection (bind) attempt worked flawlessly...

Another thing I need to do was searching DN from a DN attributes, this cannot be done by anything else than a 'distinguishedNameMatch' only available with an 'ExtensibleMatch':

Performing ExtensibleMatch (LDAPv3):
We need to add this line into the 'v_filter/1' fun:

v_filter({extensibleMatch, AV}) -> {extensibleMatch, AV};

The rest is fully handled by the ASN1 part...

Making an ExtensibleMatch part 2:

Base = "dc=example,dc=com".
Filter = {extensibleMatch, {'MatchingRuleAssertion',"2.5.13.1", "CN", "Username", false}}
eldap:search("ldap", [ Base, Filter ]).


While this query perfectly works with OpenLdap it doesn't with Active Directory !
In fact AD closes the connection directly... (May be a bug ?)

Sticky