tags:

views:

37

answers:

3

Hi! What would be the best way to grant certain actions/permissions to users based on their group? Let's say there are 3 groups - user, admin and accountant. User can do action1, admin - action1,2,3 ,accountant - action1 and 2. Could it be like this:

if(group == user){ action1(); //function }
if(group == admin){ action1(); action2(); action3(); }
if(group == accountant){ action1(); action2(); }

All actions would be stored in functions.php file and then included in the page. Would it be a good idea or there is much better solution for this?

A: 

Can a user be part of more than one group? If not, make a table in your database:

Group
group_id   INT (for sorting)
group_name VARCHAR
user_id    INT

Otherwise, make a table Group | group_id, group_name and a table Group_User_affiliation | group_id, user_id

Obviously adapt these to your naming scheme.

If you already have an OOP approach (with a User class), then add a field .group. Otherwise, create functions such as STRING get_group(INT $user_id), which then query the database.

Christian Mann
+1  A: 

Using comparators such as

if (admin) {do x}
else if (user) {do y}

Is a bad idea as it is inflexible and doesn't scale well.

There are a few options. If your permissions are hierarchical, meaning that one user can do everything and lower users have less permissions than the user above e.g.

admin - 1, 2, 3
accountant - 1, 2
user - 1

Then you can give them numbers and say

if (permissionValue => 500)
{
    action2();
}

And have a table:

admin        1000
accountant   500
user         250

This allows you to add in a new user type (say moderator) between the admin and accountant, but will not work if you have:

admin        1, 2, 3
accountant   1, 2
moderator    1, 3
user         1

As the permissions for moderator and accountant are on the same level.

By far the best solution is using bitwise operators and assigning binary values to your protected areas.

Take a simple example where a user can read content, a moderator can read and write content, and an admin can read, write and delete content. You would have the following table (the values are constructed using bitwise or operator)

Users:          Read    Write    Delete
admin:     7 - (0b001 | 0b010 |  0b100)  = 0b111 = 7
moderator: 3 - (0b001 | 0b010 |  NO   )  = 0b011 = 3
user:      1 - (0b001 | NO    |  NO   )  = 0b001 = 1

You can then do:

//Permissions:
define('READ', 1);
define('WRITE', 2);
define('DELETE', 4);

if ($userPermissions & READ)
{
    //Allowed to Read
}


if ($userPermissions & WRITE)
{
    //Show write form
}

These are examples of bitwise operators. It means if x contains bit y return true. For the write function

User         Permission
User            Write
1        &        2
0b001    &      0b010 -- returns false
Admin           Write
7        &        2
0b111    &      0b010 -- returns true

In the first example, 0b001 does not contain the bit 0b010 so returns false. 0b111 does contain the bit 0b010 and returns true.

Read more Here

Gazler
A: 

I'd make another two tables in database, say permissions with just 2 fields - id and name, well maybe plus 1 more - title (for human reading). And the second one - groups_permissions. Then just add some permissions, for example: 'action_one', 'action_two', 'and_another_action'

Then in php itself check for permissions like this:

if ( has_permission('action_one') ) {
    action_one();
}

This method, perhaps, a little overhead for a task with only 3 groups, but it proves to be useful if more groups later added.

Alternately I know of a hardcoded method where you create a config file and list permissions like this:

$permissions['admin'] = array('create_all', 'delete_all', 'update_all', 'ban_users', 'etc.');
$permissions['moderator'] = array('update', 'delete');
$permissions['user'] = array('view_members_area', 'create_post', 'update_own', 'etc');

And as in method above check for permission via function before calling an action

L.I.A. Ant.