It’s been a busy few months. I’ve been busy at Totsy.com a startup that is taking the best of Lithium, MongoDB, and my time. If you want the lowdown of what I’m talking about check out the slides from Mitch Pirtle CTO at Totsy.

To the business at hand – Simple ACL with Lithium and MongoDB. Let’s get down to it!

The heart of this ACL functionality rests with the Li3 Router. With the Router you can connect a URL to a specific Class::action. This is handy when you want to have /login route to app\controllers\UsersController::login(). Of course, your routes can become more complicated and robust with a little regex goodness. Take a look at a default route for example:

    Router::connect('/{:controller}/{:action}/{:args}');

When going to the url http://yourapp.com/users/login/23423  then Li3 will map to the users controller, login action (or method) and pass the 23423 as the argument or input to that method. That’s all we really need to hookup a route and in turn give us the ability to setup ACL.

If there are no routes hooked up in your app/config/routes.php then requests will go nowhere. Without some default routes hooked up you’ll app will be sitting dead without anywhere to go. This is the perfect time to setup an ACL. How do we get this all going?

The next step is to call upon MongoDB. With MongoDB we can embed an array with the route and parameter into a mongo document object. I would embed this array with the user document that has the information used for login. This way, you can pull the entire document with one query from Mongo. Too simple to be true? Lets take a step by step approach:

1) Hook up your code in routes.php to loop through the document pulled from your user document:

    if (isset($session['acls'])) {
        foreach ($session['acls'] as $acl) {
             Router::connect($acl['route'], $acl['connection']);
        }
    }

Note that in my app I put the necessary information in the users session after they successfully login.

2) Embed the acls array as part of your user document schema. For example:

{
    "_id" : ObjectId("4c8d53e0ce64e5f449992400"),
    "created_date" : "Sun Sep 12 2010 18:27:44 GMT-0400 (EDT)",
    "email" : "test@lcs.com",
    "firstname" : "Test",
    "lastname" : "User",
    "password" : "b119670d125b0bd4271b25ce39fa166bc3bf79a0",
    "acls" : [
        {
            "route" : "/orders",
            "connection":"Orders::index"
        },
        {
           "route" : "/posts/view/{:item:[a-z0-9\-]+}",
           "connection":"Events::view"
        }
    ]
}

3) Do a happy dance because you’re done!!!

With a little admin work you can put together groups and more robust configurations for ACL.  At the end of the day all you really need to do is loop through an array of routes and connections and you’ll have the exact ACL you need to keep everyone in order.

Posted in PHP.