I need a bitwise permissions system (I think)
Moderator: General Moderators
I need a bitwise permissions system (I think)
I am building an application large enough that it needs a robust permissions system. I have read this thread once viewtopic.php?t=43510&start=15&postdays ... ons+system and will read it thoroughly again, but the math just doesn't make sense to me. Is there somebody willing to explain to me in sub-laymen's terms how a bitwise permissions system works?
see this is exactly why there was the (I think) attached to the end of the thread title. I did some searching around and that seemed to be the solution that was recommended. I just need to be able to assign permissions to groups as well as users, and I've read in a few places (and my knowledge about permissions is far from expansive) that one-to-one relationships between users and permissions is bad.
- RobertGonzalez
- Site Administrator
- Posts: 14293
- Joined: Tue Sep 09, 2003 6:04 pm
- Location: Fremont, CA, USA
I will have a handful of "admins" which have (more or less) full access to the system. These will be myself and the owner of the application, and maybe a few others (so I may need some access as an admin that they do not have). Then there will be "members" which can move about the application, but their access is severely limited, BUT they can be granted "Team leader" status, which allows emailing access and a few other "team" administration rights. Then there is "Project Leader" status. There are projects that the team can partake in, and this member would be the "leader" of the project. He would need some rights that not everybody has. And lastly "Team Co-leader" status, which is just a step down from "Team Leader". There will also need to be room for expansion.
- RobertGonzalez
- Site Administrator
- Posts: 14293
- Joined: Tue Sep 09, 2003 6:04 pm
- Location: Fremont, CA, USA
yes, but each level will need to be granted or restricted privileges on top of their "set" privileges. So let's say there is a "Team Leader". All team leaders have the following rights:
Email My Team,
Email Admins,
Edit My Team Settings
Add My Team to Projects
but I've decided I really like "Team Leader" "Steve" so I let him have this right as well...
"Add events to event calendar"
That's the part where I have issues...
Email My Team,
Email Admins,
Edit My Team Settings
Add My Team to Projects
but I've decided I really like "Team Leader" "Steve" so I let him have this right as well...
"Add events to event calendar"
That's the part where I have issues...
I use bitwise permissions, perhaps one of these guys will explain to both of us why its a bad idea.
Even if you don't use it, it is something that is good to know in case you are looking at someone else's code or maybe knowing the drawbacks can see uses for it. The advantage is you can store multiple true/false properties for an entity in a single field. You might recognize fields like this in some databases you see. Often they are referred to as flags.
You setup permissions as powers of 2, like this (its a bit clearer to put them in hex, but don't worry about that right now)
One thing to notice is that with powers of two, when you look at them in binary, look like this
Lets look at what happens when we add up the numbers
Imagine a row of light switches, adding up the numbers is kinda like switching some of the lightswitches on. Now consider the bitwise operator '&'. This does a binary comparison where it compares the bits one by one by one between two numbers. If the bits are 1 in both numbers, then the bit in the result in the same spot will also be one, otherwise the bit will be zero. That might be confusing so look at this
Ok, so hopefully that will clear it up a bit in laymanese. How this works in real life is you can create a set of permission with binary values, like read, write, delete, and move. Then you can add them up. So if user X has read/write you would say $rights = READ + WRITE. To check if that user had READ access you would do if( $rights & READ ) { echo 'has read' }.
Even if you don't use it, it is something that is good to know in case you are looking at someone else's code or maybe knowing the drawbacks can see uses for it. The advantage is you can store multiple true/false properties for an entity in a single field. You might recognize fields like this in some databases you see. Often they are referred to as flags.
You setup permissions as powers of 2, like this (its a bit clearer to put them in hex, but don't worry about that right now)
Code: Select all
define( 'TACO', 1 ) ;
define( 'POTATO_CHIP', 2 ) ;
define( 'PIZZA', 4 ) ;
define( 'MEATLOAF', 8 ) ;
// or in a class in PHP 5 that (this is nice because it doesn't pollute the namespace)
class food
{
const TACO = 1 ;
const POTATO_CHIP = 2 ;
const PIZZA = 4 ;
const MEATLOAF = 8 ;
}One thing to notice is that with powers of two, when you look at them in binary, look like this
Code: Select all
1 = 0000001
2 = 0000010
4 = 0000100
8 = 0001000
16= 0010000Code: Select all
2 + 8 = 0001010
16 + 1 = 0010001
1 + 2 + 4 + 8 + 16 = 0011111Code: Select all
$foods = food::TACO + food::PIZZA ; // This is 1+4, so the binary is 0000101
$result1 = food::TACO & $foods ;
/*
This does a binary comparison like
0000101
0000001
The value in $result1 is
0000001
because there is a one in the last column in both numbers
*/
$result2 = food::MEATLOAF & $foods ;
/*
0000101
0001000
This time the value in $result 2 is
0000000
because no ones match in any column
*/Ok, so hopefully that will clear it up a bit in laymanese. How this works in real life is you can create a set of permission with binary values, like read, write, delete, and move. Then you can add them up. So if user X has read/write you would say $rights = READ + WRITE. To check if that user had READ access you would do if( $rights & READ ) { echo 'has read' }.
- RobertGonzalez
- Site Administrator
- Posts: 14293
- Joined: Tue Sep 09, 2003 6:04 pm
- Location: Fremont, CA, USA
From your last response it looks like you might want to research ACLs. There are some libraries out there that will do what you want to accomplish. Google it. You can assign rights at the group level and also the user level and it will assign to the user the most restrictive rights. This is something that you can accomplish with bitwise operators too but you can probably get by with an existing library.
phpgacl is the only one I've found. I've always had a difficult time with ACL systems, but then again I haven't tried messing with any for a while. I understand at least 50% more than I did a few months back, so let's see if I get it now.Begby wrote:From your last response it looks like you might want to research ACLs. There are some libraries out there that will do what you want to accomplish. Google it. You can assign rights at the group level and also the user level and it will assign to the user the most restrictive rights. This is something that you can accomplish with bitwise operators too but you can probably get by with an existing library.
Cake has one too that is simpler. I think codeigniter might also. You can probably ninja some code from one of those, you are THE ninja space goat after all!The Ninja Space Goat wrote:phpgacl is the only one I've found. I've always had a difficult time with ACL systems, but then again I haven't tried messing with any for a while. I understand at least 50% more than I did a few months back, so let's see if I get it now.Begby wrote:From your last response it looks like you might want to research ACLs. There are some libraries out there that will do what you want to accomplish. Google it. You can assign rights at the group level and also the user level and it will assign to the user the most restrictive rights. This is something that you can accomplish with bitwise operators too but you can probably get by with an existing library.
- Kieran Huggins
- DevNet Master
- Posts: 3635
- Joined: Wed Dec 06, 2006 4:14 pm
- Location: Toronto, Canada
- Contact:
I would use named permission array templates, then merging them for the final permission array. They're easier to see in code then $perm='0000110101101010'; An example (for forum posts):
Hope that gets you started.
Cheers,
Kieran
Code: Select all
// level 1: default permissions
$default = array(
'posting' => 'no',
'reading' => 'yes',
'deleting' => 'no',
'editing' => 'no',
'moderating'=> 'no',
'use_html' => 'no'
);
// level 2: role templates
$user = array( // everyone is a user (how cynical!)
'posting' => 'yes'
);
$moderator = array( // is also a user
'editing' => 'yes',
'moderating'=> 'yes'
);
$admin = array( // is also a user
'editing' => 'yes',
'moderating'=> 'yes',
'deleting'=> 'yes'
);
// level 3: individual account permissions
$frank = array(
'use_html' => 'yes', // we're enabling html for frank
'editing' => 'no' // but we don't trust him to edit
);
// now we create frank's total permission set: (frank is a moderator)
$franks_permissions = array_merge($default,$user,$moderator,$frank);
// print out frank's permissions:
print_r($franks_permissions);
/* output:
Array
(
[posting] => yes
[reading] => yes
[deleting] => no
[editing] => no
[moderating] => yes
[use_html] => yes
)
*/
// awesome - that's exactly what I wanted
// example permission check: can frank post html?
if($franks_permissions['use_html']='yes'){/* yes he can */}Cheers,
Kieran