Sinatra, an Exchange Server, and an Employee Roster

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.

$ruby ad.rb

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 /attributeWeAreSearchingIn/searchTerm.
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!

If you want to know more about Sinatra, be sure to visit SitePoint’s Jump Start books site. We’ll be releasing Jump Start Sinatra early next year….

Free book: Jump Start HTML5 Basics

Grab a free copy of one our latest ebooks! Packed with hints and tips on HTML5's most powerful new features.

  • http://about.me/ejstembler Edward J. Stembler

    Great article and resource!

    A year or so ago, I added LDAP authentication to an enterprise Ruby on Rails application hosted on Windows which I work on, and found the existing resources to be sparse.

    Here’s a snippet I extracted which authenticates a Ruby on Rails User model via LDAP and saves their LDAP photo if they have one:

    https://gist.github.com/4156208

    • http://johnivanoff.com John Ivanoff

      Edward, Thank you. What’s really difficult is filtering out by user account control values. There are a ton of them.
      I’ll have to keep your gist handy.