Jump to content

Recommended Posts

I'm building a per-page (actually per-module) permission system for a database-driven group->user system, and was wondering how some of you code monkeys out there would implement it.

 

My idea so far is to have a bit-wise permission system divided into blocks. A quick example of what I planned on doing was something like this:

 

Read:		1 (0001)
Write:		2 (0010)
Modify Own:	4 (0100)
Modify All:	8 (1000)

 

And have it divided into blocks... My issue here was on how to organize the blocks. The easiest method I could think of was quads based on the order the modules were installed.

 

Say the modules were installed like so:

1 - images

2 - random uploads

3 - public blog

 

A typical per-page access row would look like

011100011111 or [0111] [0001] [1111]

Where the user would be able to Read Write and Modify their own images, Only read random uploads, and Full access to public blog.

 

This is all fine and dandy, until you delete the 'random uploads' module. You then have to remove bits 5-8 in the entire column. This is pretty straight forward, though it would require me to grab the column from every user with per-page permissions, modify in php, and update. This shouldn't be too big of an issue, though, because per-module access will be directed more towards groups, and will hopefully only be implemented on a small number of users.

 

My big issue here is when i have, say, 20 modules. 20x4 = 80bits = a potentially VERY BIG integer. This could be an issue, considering it well exceeds the maximum size of a BIGINT type field.

 

Alternately, I could have a column dedicated to the permissions for each module and use ALTER TABLE as I add/remove modules. Ideally, this wouldn't be often, if at all... but I like to avoid altering a table once it's been made due to potential performance issues. Am I just being paranoid? Is this a plausible solution?

 

I'd love to hear your thoughts / opinions / responses to this topic. This is my first jump into flexible permission systems, and I want to start on the right foot :)

Link to comment
https://forums.phpfreaks.com/topic/99426-solved-per-page-user-permission-help/
Share on other sites

PHP can do binary arithmetic, so you can just do like this instead:

<?php
define('PERM_READ', 1);
define('PERM_WRITE', 2);
define('PERM_MODIFY_OWN', 4);
define('PERM_MODIFY_ALL', ;

$danielPerms = PERM_READ | PERM_WRITE | PERM_MODIFY_OWN;

if ($danielPerms & PERM_READ) {
echo 'Daniel can read' . PHP_EOL;
}
if ($danielPerms & PERM_WRITE) {
echo 'Daniel can write' . PHP_EOL;
}
if ($danielPerms & PERM_MODIFY_OWN) {
echo 'Daniel can modify own' . PHP_EOL;
}
if ($danielPerms & PERM_WRITE_ALL) {
echo 'Daniel can modify all' . PHP_EOL;
}

var_dump($danielPerms);

$danielPerms = $danielPerms & ~PERM_WRITE;
if ($danielPerms & PERM_WRITE) {
echo 'Daniel can write' . PHP_EOL;
}
else {
echo 'Daniel can no longer write' . PHP_EOL;
}

var_dump($danielPerms);
?>

Output:

Daniel can read
Daniel can write
Daniel can modify own
int(7)
Daniel can no longer write
int(5)

 

As you see, the decimal value doesn't grow very much so it's unlikely that you with this approach will exceed the limits of the size of an integer.

I understand what you're saying, and I'm very familiar with PHP's bitwise operators... but I don't think you get the point

 

Each module this user/group system will allow/deny access to will require it's own 'quartet' (group of 4 bits). If 20 modules are installed, 20x4 quartets = 80 byes = HUGE integer.

 

My original though was to store the user's per-module access in a mysql bigint column. My afterthought was to store each modules 'quartet' in it's own tinyint column.. but it seems like a waste if a very small percentage of the users will be restricted on a per-module basis and 99% of them have x cols of NULL values.

 

I also want to avoid using anything other than bit-by-bit storage. Converting the binary data to a string, ect would be a complete waste.

 

I realize using a BASE2 bitwise permission scheme is a smart way to do it... implementing it into a broader scale is where I'd like some advice.

 

Thanks for the reply, though

Hmm... I'd probably just do:

 

users:

- user_id

- *etc.*

 

modules:

- module_id

- *etc.*

 

permissions:

- user_id

- module_id

- bits

 

Then

SELECT * FROM permissions WHERE user_id = *user_id*;

 

Then have an array in this format:

array(
    module_id => bits
);

 

Then if the key of the current module doesn't exist then they're denied access, otherwise you'd use the set permissions.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.