views:

305

answers:

2

I control access to some of my static web resources with some PHP logic. Because directory-based authorization through the webserver is not suitable or easily possible.

A combination of things determines whether access is granted or denied. And these rules change from time to time.

In the beginning it was a simple regex path match, and a check of one session variable. It's more complicated now as there's a few more variables involved.

I'm wondering how to go about refactoring this so it's quick and easy to change the rules. When it was a simple "if this AND this, then deliver, else 403." it was fine to do it in straight PHP. Now the conditions are more complex and there's a couple levels of nesting each with common but slightly different conditions within. This is all easy enough to refactor, but it's not the most intuitive and easy to update.

I'm thinking of one of two things.

  1. Establish classes for each of the top level of conditions and use a Strategy Factory to pick the right one authorize. Derive them all from a base class containing the common bits and overload whatever's necessary. I think this could still be prone to some shuffling around when some conditions change.

  2. Make a simple engine that iterates a 2d array of ordered rules sort of like firewall rules. Something like: <allow|deny>, <auth_group>, <path_regex>, <other vars>

I haven't fully thought this one through but it seems like it would be easier to update and also to read as a human.

What would you do? Is there an established pattern or library I can use for this?

I faced this similar problem in another app some time ago. Where I wanted an easy to update way of chaining rules and outcomes together based on several levels of conditions. This isn't as complicated as that app, but I'd be interested to hear about patterns people use to solve this kind of problem.

A: 

You could also use a small logic engine (think prolog) to easily state facts and rules which would allow you to quickly query wether or not access to a resource should be allowed. Logic based rule engines like this are often very efficient and should allow you to very easily model a solution for this kind of problem domain.

kasperjj
+1  A: 

You might want to check out Zend_Acl, which is an object-oriented PHP class to manage hierarchies of privileges on hierarchies of resources. You might not be able to use this component as is, but it could give you some insight into how you want to implement your own system.

Zend_Acl is part of the Zend Framework PHP 5 class library, but like many classes in ZF, Zend_Acl can be used independently. There's no need to use the rest of Zend Framework.

Bill Karwin