views:

3329

answers:

4

I need to add user roles and permission system into my web application built using PHP/MySQL. I want to have this functionality:
1- One root user can create sub-roots, groups, rules and normal users( all privilegis) .
2- Sub-roots can create only rules, permissions and users for his/her own group ( no groups).
3- A user can access either content created by him or his group, based on the permission assigned to him, by group root.

I need the system to be flexible enough, so that new roles and permissions are assigned to content.
I have a users table storing group key along with other information. Currently I am using two feilds in each content table i.e. createdBy and CreatedByGroup, and using that as the point whether a certain user has permissions. But its not flexible enough, because for every new content, I have to go throug all data updates and permission updates. Please help me by discussing your best practices for schema design.

+1  A: 

I wrote a 100% flexible php permission system a while ago. I've been meaning to finish the Ajax administrator that was part of it but the project was canceled before I got to that. It's pretty much proof of concept right now as the only backend it supports is sqlite, but putting in a new one isn't hard. I have a spec on how it works but I can't put files here - mail me on roel dot vanhout at gmail dot com and I'll send it to you to evaluate. If it fits for your requirements I can send you the code, too.

Roel
+2  A: 

The pattern that suits your needs is called role-based access control.

There are several good implementations in PHP, including Zend_Acl (good documenation), phpGACL and TinyACL. Most frameworks also have their own implementations of an ACL in some form.

Even if you choose to roll your own, it'll help you to review well factored solutions such as those.

Eran Galperin
A: 

I had a slightly different structure, but it should be able to serve as a reference.

Each user has a 'Role', 'GroupID' associate with it, and Group table for which the GroupID refers to. Then I have 3 permission table.

PermissionMaster(FormName),

PermissionChild(PermissionMasterID, PermissionName, Desc, DefaultValue, DependOn) and

PermissionGroupChild(GroupID, PermissionChildID, Allow)

PermissionMasster holds the name/form/module for which the permission refers to. PermissionChild will list all the possible permission available for each Master, such as 'Create', 'View', 'Edit', 'Delete', and description (I didn't have this on the first version, and it started to get confusing when where's too many permission setup even for 1 module). I allow add more child as to specifically refer to some function like 'ChangeTimeStamp', which would allow slightly more permission then 'Edit'

Then PermissionGroupChild is the link between PermissionChild and Group table. Every group will have a set of PermissionChild copied and set with default setting. Then I had a permission class which does the table query and check for each user. I only load it during login. Then in every form/module, I check for it's appropriate permission and applies the UI properly.

As for role, I only use it at the Login configuration page. Smaller Role value means higher ranked. So user can only see itself and those of Role value higher than itself. He/she can edit those of lower rank than itself but not similar.

faulty
A: 

You might not want groups of permissions. Instead create user groups, give user groups permissions, and put users in groups. Users should also be able to override permissions from the groups they are in. Deny should always override grant where a user is in more than one group with the pemission.

In summary:

  • User has zero or more permissions (grany, deny)
  • User is in zero or more groups
  • Group has zero or more permissions (grant, deny)
Neil Barnwell