Page 1 of 2
I need a bitwise permissions system (I think)
Posted: Thu Dec 14, 2006 6:02 pm
by Luke
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?
Posted: Thu Dec 14, 2006 6:16 pm
by feyd
Why do you need a bitwise permission system? You're going to use OOP yes? Then just use boolean properties.
Posted: Thu Dec 14, 2006 6:33 pm
by Luke
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.
Posted: Thu Dec 14, 2006 6:34 pm
by RobertGonzalez
Bitwise permissions can develop problems that you might not see now. What is the structure of your permissions? Maybe there is a better way to do it.
Posted: Thu Dec 14, 2006 6:48 pm
by Luke
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.
Posted: Thu Dec 14, 2006 6:51 pm
by RobertGonzalez
So will each level be a subset of the level above it?
Posted: Thu Dec 14, 2006 6:55 pm
by Luke
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...

Posted: Thu Dec 14, 2006 6:57 pm
by Begby
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)
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= 0010000
Lets look at what happens when we add up the numbers
Code: Select all
2 + 8 = 0001010
16 + 1 = 0010001
1 + 2 + 4 + 8 + 16 = 0011111
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
Code: 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' }.
Posted: Thu Dec 14, 2006 7:03 pm
by RobertGonzalez
What happens when you want to add a permission in between 4 and 8?
Posted: Thu Dec 14, 2006 7:03 pm
by Begby
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.
Posted: Thu Dec 14, 2006 7:03 pm
by Luke
wow... what an
excellent explanation. Thank you... that makes sense now.

Posted: Thu Dec 14, 2006 7:04 pm
by Begby
Everah wrote:What happens when you want to add a permission in between 4 and 8?
You don't add a permission between 4 and 8, you add it at the end. The order of the permissions is meaningless.
Posted: Thu Dec 14, 2006 7:05 pm
by Luke
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.
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.
Posted: Thu Dec 14, 2006 7:07 pm
by Begby
The Ninja Space Goat wrote: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.
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.
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!
Posted: Thu Dec 14, 2006 10:03 pm
by Kieran Huggins
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):
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 */}
Hope that gets you started.
Cheers,
Kieran