Policy Areas & Permissions

April 21st, 2008 | by admin | |

When I started designing my security, I wanted to be able to control what my users saw and could ‘do’ on each page. For example, I didn’t want my less experienced users being able to see and modify content that wasn’t created by them (ie. MY content). I don’t want two hours of writing to disappear because someone with a login was browsing around and wanted to see what the ‘delete’ button would do :-)

So to combat this threat, I do several things. Before I begin explaining however, please take a look at Figure 1 which shows you in visual terms, the security module of my CMS.



Figure 1 - tables for security system based on policy areas, roles and permissions

Permissions

As an administrator of my CMS, I want different areas to be identifiable BY the system, so that in turn, different security can be applied to the given Member depending on what screen they are viewing. For example: A Member viewing a category information screen will be treated different to a Member viewing a security permissions screen (I may not even want my Member to see security permissions at all!).

I wanted to do this since some previous development I had done with security in content management systems. Previously I just had permissions such as ‘admin’ and ’staff’, and allowed ‘admin’ members to see additional content that ’staff’ users could not. This didn’t work very well because sooner or later a staff member was working on a project and needed access to something that only administrators could see. So I was forced to give that user full admin access. You need to keep in mind that admin user in this case meant control of everything, as you were either staff or admin, no other form of control existed. Not fun.
You need to be able to say that user X can see this part of the system and can add/modify, but not delete data. So you firstly need to know what PERMISSIONS you want in your system. I suggestion view all/view own/modify and delete as a starting point. But you can break it down further into add/update/delete etc. or even further into add own/add all/ etc.

Roles

If you were reading that last part, you might be thinking to yourself:

“But what if my system grows and I suddenly have 100+ members in my system.”

That’s a lot of members to be going through and manually assigning permissions to each and every screen in your system. The smart thing may be to start with security roles (Eg. Admin, General User, Guest), then assign Members to those Roles. You can then map those Roles to screens in your system, which will in turn dictate what Members with said Role can/cannot do via Permissions.

Policy Areas

Even with Roles, you may have quite a few screens in your system and you may not want to assign a unique identifier to each page so that you can control every little detail that goes on in your system. And that’s fair enough. What can you do in these cases? Well, instead of identifying each and every page in your system, group them into Policy Areas (or Modules). For example, you may have a page category (1) list, (2) add, (3) update and (4) information screen. Group all of those pages into a ‘page category’ Policy Area. Map that Policy Area to Roles and assign Permissions that way. Certainly less programming and management than assigning each and every page for a given user with different permissions.

I took this approach in my CMS and it has worked very well so far.

An example of my CMSs Permissions, mapped to Roles and Policy Areas is as follows:

To setup Policy Areas in my system, I created a database table (as seen earlier) for the various areas of my system, but in code I need a way to map pages to that table, so I use PHP constants to do this mapping to make things easier for me while coding to identify the various policy areas.

If my SQL is setup as follows …

INSERT INTO `policy_area` (id, name, created_date, recordstatus) VALUES (1, 'Member', NULL, 'A');
INSERT INTO `policy_area` (id, name, created_date, recordstatus) VALUES (2, 'Person', NULL, 'A');
INSERT INTO `policy_area` (id, name, created_date, recordstatus) VALUES (3, 'Page', NULL, 'A');
INSERT INTO `policy_area` (id, name, created_date, recordstatus) VALUES (4, 'Menu Item', NULL, 'A');
INSERT INTO `policy_area` (id, name, created_date, recordstatus) VALUES (5, 'Page Category', NULL, 'A');
INSERT INTO `policy_area` (id, name, created_date, recordstatus) VALUES (6, 'Role', NULL, 'A');

I map the database info to my PHP constants ,,,

<?php
#module constants, mapped to Policy_Area database table policy_id
define("MODULE_MEMBER", 1);
define("MODULE_PERSON", 2);
define("MODULE_PAGE", 3);
define("MODULE_MENU_ITEM", 4);
define("MODULE_PAGE_CATEGORY", 5);
define("MODULE_ROLE", 6);
?>

Then to check if a user has the given permissions, I have a function in my Member class, which I call as follows (Example, when I need to check if the given user has delete permissions for the Page Policy Area:

<?php
#does user have delete permissions?
if(!Member::has_policy_area_delete_permissions(MODULE_PAGE,Session_Manager::get_role())){
   #no permissions, stop them from deleting
}
?>

Having this link between static data (ie. the constants) and the dynamic data (the policy area table) allows me to establish and dynamically control security permissions for a given policy area. The static data is required in this case because I need to manually link constants (used to identify a module) to a given page in my system. The other way do to this would be to have unique IDs for each page, but in this case I have grouped pages into modules instead. This takes less work to manage, which is why it appeals to me :-)

Post a Comment