A while ago I posted a question regarding pre-built security infrastructure that I could use. At the time, I envisioned something the like of Windows's ACLs, where you can define permissions on individual objects. At hindsight, I think that I was very naive.
Here are a few requirements that I had to deal with in recent projects:
- you are only allowed to handle cases for customers in your assigned regions.
- you may only order fixes for products that you have purchased - in fact, you may not even see fixes for products that you don't own, because they may contain a fix for something that will not be fixed in your version.
- One of the more complex can be express as this meta permission scheme: Employees in HR department can have privileges from the Personal Permission Tree, as well as a manager to their direct reports. HR department has no privileges in the Assignments Permission Tree, only a manager has it, and only for direct reports, at most two level down.
- Temporal permissions - you may see this employee salary between 2002-01-01 to 2003-04-13.
- Temporal permissions with a twist - you may see this employee salary between 2002-01-01 to 2003-04-13, but you are allowed to modified them only up to three months ago.
Are they security? are they business logic? Then you have the weird cascading rules, including anything from permission on this object goes up two levels and down one, but on this object it goes up one level and down four. What about limitation permissions? For this object type, you have access to everything, unless you have been assigned some objects, in which case you are limited to only those.
From the user stand point, they are both. In fact, some of those are so extremely annoying permission scheme, intended to cover the 0.2% edge cases, and I am pretty sure that they will never be fully utilized. Nevertheless, they are core to the way the client think about their business, and they are certainly first class business concerns which has quite an affect on the business.
Because security is such a complex topic, and because it touches so intimately with the business requirements, I have found that I often need to tie it into the business concerns. Specifically, it is often advisable to tie it into the query infrastructure, since loading everything and then filtering by security has quite a few disadvantages (paging falls flat on its face, so does aggregate queries, performance can be affected in many scenarios, etc).
So, I don't think that there is a real generic solution, at least not if your application doesn't fall into the roles & permissions style, but I have built a nice solution for the current requirements. I still get confused by the requirements, and I spent a while the other day debugging why it didn't work as expected, to realize that my expectation were incorrect and in fact it was behaving 100% correctly.
Disregarding my inability to consider six interwoven different permissions schemes at a single point, the solution is actually a very good one and I am please by it, although I still cringe a bit when I go over the code. A query really shouldn't take more than three pages. :-)