Page 1 of 1

Access Control

Posted: Tue Feb 16, 2010 2:10 pm
by Cirdan
I'm working on a CMS for my gaming clan, and am working on a new access control scheme. Previously, the access was granted based on the rank of the user. This is good for controlling access to major things such as admin interfaces, moderation, and member-only functions. But if I want to get more detailed and let some people access a certain function, and not others, I would have to create a specialized group which seems too clunky to me.

After some more thinking, I thought that this new scheme could be perfect. The way the site is broken up is basically into modules and pages/actions(can't really think of a good name. Sometimes it's an action, other times its just a page). For example, Forum would be a module, and Thread would be an action. So my access control idea is to use a hierarchical namespace system. Each action would define it's access namespace.

It would be setup like "Module:Page:Action:ID".
So to view a board on the forum, the namespace would be "Forum:Board:View:4". The ID is simply the id of the resource in mysql. It's mainly there to provide more information and really deep control if I want it. Because it's tree, the ID is mostly optional. When the system wants to check access it would simply travel through the namespace to determine access. There are three possible settings for each section: Denied, Accessible, and not set. If a section is set as "not set" then it will rely on the access of the parent section.

My problem is this:

How do I represent this in MySQL? I was considering putting a big TEXT field in the users table, and just have all of that user's specific credentials in there listed by entire namespace, comma separated. I could also have groups setup, so I don't have to go through each user and control their credentials, I could just assign them a group in addition to their personal credentials. If the namespace is contained within this credential field, then access is granted. Otherwise it is blocked. I'm not sure how efficient it would be parsing a big block of text like that would be.

How would I represent the default accessibility? I'm not sure how I would store the default access settings in MySQL. Would I be able to set it up like a tree with parent-child relationships?

Re: Access Control

Posted: Tue Feb 16, 2010 2:49 pm
by AbraCadaver
Why not a separate field for each in a user and group permissions table? This can get very complicated, but here is a very simple way.

user_perms
perm_id user_id priority module page action item access

group_perms
perm_id group_id priority module page action item access

In addition I would have a little more granularity in the access levels. At a minimum: NONE, READ, WRITE, DELETE

As for default permissions you could use * or ANY or ALL in specific permissions.

Normally user permissions would override group, so if John is in group Users and users have access NONE for something but John has access READ, then he can view it. Aside from that you can use the priority field to determine which permissions take priority and so you can use the first match with the lowest priority.

In this example group_id 1 is Admins and 2 is Users, * is anyone:

group_perms

Code: Select all

perm_id     group_id    priority    module  page    action  item    access
1           1           0           Forum   Board   View    *       DELETE
2           2           1           Forum   Board   View    *       WRITE
3           *           2           Forum   Board   View    *       READ
I guess you could also combine into one field but it may make the queries more complex:

group_perms

Code: Select all

perm_id     group_id    priority    item                access
1           1           0           Forum:Board:View:*  DELETE
2           2           1           Forum:Board:View:*  WRITE
3           *           2           Forum:Board:View:*  READ
Just a thought to spark ideas.

Re: Access Control

Posted: Tue Feb 16, 2010 3:05 pm
by JNettles
I was considering putting a big TEXT field in the users table, and just have all of that user's specific credentials in there listed by entire namespace, comma separated.
I would tend to shy away from something like this, though there's nothing to say that it wouldn't work. I would shift credentials into its own table, then create a new authorization record for each group that an individual user belongs to (ie: members, mods, admins, members_one, members_two).

So user Jimmy (id = 15) has his record in the users table and then five more in user_acl....

Code: Select all

[u]id[/u]          [u]user_id[/u]       [u]group_id[/u]
233            15           2
234            15           3
235            15           6
236            15           9
Then, on a request you can pull all of Jimmy's attached group id's and check security for each of them (which you could keep in a groups table).

It all depends on how complex you want your permissions to be and how easily you want to be able to maintain them and define relations between them. My above example might seem overly obtuse and redundant (why not just store the group numbers in a comma delimited column?) until you get into a situation where you need to get all members of a group, or update all members of a group, in which case you'll be better off with the above relational model.