Still having trouble with permissions

Not for 'how-to' coding questions but PHP theory instead, this forum is here for those of us who wish to learn about design aspects of programming with PHP.

Moderator: General Moderators

User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

in your first scenario, the if is ending at CAN_POST, so that makes sense.

if you're going to use if / else if blocks like that, you just need to make sure you order them correctly (highest to lowest).

I'm trying to think of a scenario when that would be necessary and drawing blanks.

Also the user's permission level would not be added up like that (I know you probably did it for the sake of demonstration, but it would already be predetermined). He'll need to have some kind of translation table (not even necessarily in a db) that identifies what role each user level means.

a more practical example would be something like this:

Code: Select all

// find out if this is a moderator and if the edit post button should be displayed:
if($_SESSION['user_level'] & CAN_EDIT)
  echo "<input type=\"button\" value=\"Edit Post\" onClick=\"eatBacon()\">";
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

so you would add them up in a class or something?

Code: Select all

<?php
class Permissions
{
    const CAN_POST = 2;
    const CAN_EDIT = 4;
    const CAN_MAIL_HIS_UNDERWEAR_TO_JAPAN = 8;
    public function hasPermission($user, $permission)
    {
        // Check permissions
    }
}
?>
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

you could certainly do that though I'd create a public property for the user's level or instantiate it with the object so you don't have to pass it as an argument every time.

Code: Select all

$perm = new Permissions($_SESSION['user_level']);
//or
$perm = new Permissions();
$perm->user_level = $_SESSION['user_level'];

if($perm->hasPermission(5))
    // whatever
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I don't know guys... binary is cool and everything, and it stores in a huge INT in your database, but just try selecting users who can mail their underwear to japan from a database... Makes more sense to have a permissions table...

Also, binary permissions are just that: binary. Yes or No. You can't have options or values or anything.

If you don't like arrays, why not objects?

If you created user objects, you could support default permissions easily, and you could also have permission "functions"... by using the magic __get and __set methods:

Code: Select all

class user {

	var $_conditions = array();

	function __construct($user_id){
		// get conditions and permissions from the database based on userid, group memberships, assigned roles, etc

		// we'll inject what a few might look like here
		$_conditions['can_mail_underwear_to_japan'] = "date('l')!='Tuesday'"; // can't mail underwear to japan on a Tuesday
		var $can_eat_noodles_sideways = TRUE;
		var $post_limit = '5';
	}

	function __get($perm){
		// return conditional permission if there is one
		if(in_array($perm,$_conditions)) return eval($_conditions[$perm]); 

		// return object var if there is one
		$obj_vars = get_object_vars($this);
		if(in_array($attr,array_keys($obj_vars))) return $obj_vars[$attr];
	}

}

$frank = new user('42');

// so if it's Tuesday
echo $frank['can_mail_underwear_to_japan']; // FALSE
echo $frank['can_eat_noodles_sideways']; // TRUE
echo $frank['post_limit']; // 5

// but on Wednesday
echo $frank['can_mail_underwear_to_japan']; // TRUE
echo $frank['can_eat_noodles_sideways']; // TRUE
if($frank['post_limit']>$posts){ /* YES */ }
Last edited by Kieran Huggins on Wed Jan 03, 2007 5:22 pm, edited 1 time in total.
User avatar
Burrito
Spockulator
Posts: 4715
Joined: Wed Feb 04, 2004 8:15 pm
Location: Eden, Utah

Post by Burrito »

I don't have time to sort through your code atm but as for selecting users with a given permission level...MySQL also supports bitwise operators
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

So how would this be applied to multiple sections of a site, ala something like this?

Code: Select all

Section A: HR
Section B: Finance
Section C: Purchasing
Section D: IS
Section E: Customer Service
Now within each section, a user can be assigned rights that are one or a combination of the following:

Code: Select all

Add content
Edit content
Delete content
Reassign content

Add files
Delete files
Reorder files
Reassign files

Add users
Delete users
Edit users
Regroup users

Etc...
How do you apply bitwise permissions to this type of scenario?

Sorry Ninja, I couldn't resist this evil temptation to use you as my Ninja Scape Goat (as it relates to starting a thread that I hijack).
User avatar
Luke
The Ninja Space Mod
Posts: 6424
Joined: Fri Aug 05, 2005 1:53 pm
Location: Paradise, CA

Post by Luke »

that's a fantastic question and one I should have asked. :wink:
User avatar
Kieran Huggins
DevNet Master
Posts: 3635
Joined: Wed Dec 06, 2006 4:14 pm
Location: Toronto, Canada
Contact:

Post by Kieran Huggins »

I would create usergroups, and give those groups default permissions for each section. Each user could belong to one or more groups, their permissions being the merged set of those along with their personal permissions.

Sally is in marketing, so she would have marketing's permissions merged with her own (if she has any special permissions).

Bob is in IT and Finance, so he has the combined permissions for those departments. (+ his own, if any)

Does that make sense?
User avatar
Christopher
Site Administrator
Posts: 13596
Joined: Wed Aug 25, 2004 7:54 pm
Location: New York, NY, US

Post by Christopher »

First, I don't think you can get around having to be specific about each permission, such as Section HR_Add, HR_Edit and Finance_Add, Finance_Edit. If you want the granularity of control then you need the specificity.

I use a system somewhere between the bitmask and Kieran's yes/no schemes -- probably just because I am lazy. I don't like having to make sure that the defines have always been included/updated, so I just use the string constants. So array('Section HR_Add', 'HR_Edit', 'Finance_Add') allows those permissions. And I don't use the yes/no states ... if a values is in the array it is yes, if not it is no. They can be merged, intersected and unioned as needed with the array functions. It is slower than the bit check because it uses array functions, but I can have any number of values without monkeying around with bit fields. They are easy to store in db tables either in separate records or together (I usually pipe delimit and explode()).
(#10850)
User avatar
RobertGonzalez
Site Administrator
Posts: 14293
Joined: Tue Sep 09, 2003 6:04 pm
Location: Fremont, CA, USA

Post by RobertGonzalez »

Thanks guys. I appreciate the input (hopefully it is useful to Ninja as well :oops:).
Post Reply