Three great tastes that taste great together
You have an Exchange Server and you need an employee roster. You might be thinking, “We’ll just create a database for that.” Let’s really think about that. If you do, then you have two databases to update when the employees change. Why don’t we just use the Exchange Server? You might wonder “How would one do that?” I’m glad you asked.
All we really need to do is read the Active Directory database which is an LDAP server. An LDAP server has directory services that may provide any organized set of records, often with a hierarchical structure, such as a corporate electronic mail directory. Similarly, a telephone directory is a list of subscribers with an address and a phone number.
As you might’ve guessed, there’s a Gem for that. It’s called net/ldap. Let’s combine this gem with our friend Sinatra and see how to get this done.
Once the gems are installed, how do we get started? This is where I found the code to get me started.
This will search the Exchange Server for my name and it will return everything it knows about me.
Save the file and start the server.
It will print out a TON information because I know I exist in the Exchange Server. Feel free to replace my name with a name you know that is in Active Directory.
Now we can see what’s available for us to use.
I’m pretty sure we would want to see a list of employee names. Let’s go with that “CN” value, which stands for Common Name. Actually, this LDAP attribute can be made up from givenName joined to SN, surname or last name. How would you look for all entries in CN?
Save the file and restart the server.
Isn’t it pretty? Notice I replaced my name with an asterisk (*).
Now we are showing names for every entry. Let’s add their department to the output. Look back and find the attribute for that.
Ready to see if it works? Restart your server.
‘method_missing’: undefined method ‘department’ OK, so that entry doesn’t have a department. We are working with objects here. Yes everything is an object, but seriously, we are returning true “objects,” not “array objects.” How would you check to see if a department method exists?
Restart the server, again. Are your fingers crossed?
It appears that a lot of entries don’t have departments.
So what can we do with all this power? I guess we should have thought of that before we started coding. See how important that is?
In terms of pretty URLs, why don’t we do something like
Well, we really don’t want to use CN to look for a person. We can use “people”, like
/people/john. That will return all the people (CN) that start with “john”.
How do you think we would filter names?
Yes, you would pass the params[:id] into the filter line.
We have also put the code in a
get method. Run it, open a browser, and go to 127.0.0.1:4567/people/john In the terminal you’ll see the output, if there are any Johns in the Exchange Server. If not replace John with a name you know is in there
Let’s move the output from the terminal to the web browser.
Sales Department Please.
What about filtering on departments? How would you code that? I know what I would do.
Yes, copy, paste, and make a couple of changes.
Restart the server and go to 127.0.0.1:4567/department/sales You’ll see everyone in the Sales department.
The stakeholders are going crazy with requests for different search attributes. Before we know it, there is a huge file with a lot of redundant code. It is time to re-factor.
We will need to restart the server. If I go to 127.0.0.1:4567/location/dallas, in the browser I will see everyone in the Dallas office.
Now you just one place to maintain employees. We could also make this into an API, or wire up a mobile app. Possibilities are endless!
John is a Dallas-based front-end/back-end web developer with 15+ years experience. His professional growth has come from big corporate day jobs and weekend freelance. His is enjoys working the Ruby the most these days and has even added pain to the process by developing Rails for Windows! He’s had many years of enjoyment with Cold Fusion and has strong background in web standards.