[Cs-webapplibs-commits] SF.net SVN: cs-webapplibs:[175] trunk/0.3
Status: Beta
Brought to you by:
crazedsanity
From: <cra...@us...> - 2010-06-23 13:46:04
|
Revision: 175 http://cs-webapplibs.svn.sourceforge.net/cs-webapplibs/?rev=175&view=rev Author: crazedsanity Date: 2010-06-23 13:45:57 +0000 (Wed, 23 Jun 2010) Log Message: ----------- Better enumeration of permission bits + testing & removal of misleading example. /docs/example_genericPermission.php [DELETED]: * removed unnecessary (misleading) example. /tests/testOfCSGenericPermissions.php: * new tests: -- check if user is member of a group after user_group record created -- create permission by type array, enumerating user/group/other perms for sanity checking. -- test to ensure permission doesn't already exist before creating. -- check has_*_permission() for several users to mostly ensure that everything is working as intended. /abstract/cs_genericUserGroup.abstract.class.php: * get_user_groups(): -- minor comment change -- wording change on exception * is_group_member() [NEW]: -- determines if a user is member of a given groupId, instead of having to manually check user's entire group list. /cs_genericPermission.class.php: * ADDED HEADERS: -- __construct() -- parse_permission_string() -- build_permission_string() -- create_object() -- create_permission() -- get_object() -- get_permission() -- get_object_by_id() -- get_permission_by_id() * build_permission_string(): -- use evaluate_perm_value() instead of arbitrary check when deciding between "-" and the given permission bit (r/w/x) * check_permission() [NEW]: -- retrieves a permission list for the given user for the given object. * get_permission_list() [NEW]: -- returns an array of permission bits based on type (u/g/o) * evaluate_perm_value() [NEW]: -- determine if a particular bit's value is true/false (defaults to true, keeping in line with PHP's true/false evaluation). * permission_exists() [NEW]: -- true/false determination of whether or not a permission exists. -- NOTE::: this is just like using a try/catch around get_permission() where an exception means false; it is just a simpler approach. * has_read_permission() [NEW]: -- true/false whether user has read permission for the given named object. * has_write_permission() [NEW]: -- true/false if user has write permission for given named object. * has_execute_permission() [NEW]: -- true/false if user has execute permission for given named object. Modified Paths: -------------- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php trunk/0.3/cs_genericPermission.class.php trunk/0.3/tests/testOfCSGenericPermissions.php Removed Paths: ------------- trunk/0.3/docs/example_genericPermission.php Modified: trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php =================================================================== --- trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/abstract/cs_genericUserGroup.abstract.class.php 2010-06-23 13:45:57 UTC (rev 175) @@ -57,15 +57,28 @@ $retval = $this->db->run_query($sql, 'group_id'); } catch(Exception $e) { - throw new exception(__METHOD__ .":: failed to locate group (". $groupName ."), DETAILS::: ". $e->getMessage()); + throw new exception(__METHOD__ .":: failed to locate groups for user_id=(". $userId ."), DETAILS::: ". $e->getMessage()); } } else { throw new exception(__METHOD__ .":: invalid or non-numeric user_id (". $userId .")"); } return($retval); - }//end get_group() + }//end get_user_groups() //============================================================================ + + + //============================================================================ + public function is_group_member($userId, $groupId) { + $groupList = $this->get_user_groups($userId); + $retval = false; + if(isset($groupList[$groupId])) { + $retval = true; + } + return($retval); + }//end is_group_member() + //============================================================================ + } ?> Modified: trunk/0.3/cs_genericPermission.class.php =================================================================== --- trunk/0.3/cs_genericPermission.class.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/cs_genericPermission.class.php 2010-06-23 13:45:57 UTC (rev 175) @@ -29,6 +29,9 @@ protected $keys = array(); //============================================================================ + /** + * Generic permission system based on *nix filesystem permissions. + */ public function __construct(cs_phpDB $db) { $this->db = $db; parent::__construct($db); @@ -63,6 +66,9 @@ //============================================================================ + /** + * Parses a string like 'rwxr-xr--' into keys for the database. + */ protected function parse_permission_string($string) { $this->_sanityCheck(); if(is_string($string) && strlen($string) == 9) { @@ -87,6 +93,9 @@ //============================================================================ + /** + * Create permission string based on an array (the opposite of parse_permission_string()) + */ protected function build_permission_string(array $perms) { $this->_sanityCheck(); if(is_array($perms) && count($perms) >= count($this->keys)) { @@ -94,9 +103,11 @@ foreach($this->keys as $dbColName) { if(isset($perms[$dbColName])) { //get the last character of the column name. - $permChar = substr($dbColName, -1); - if($perms[$dbColName] === false || !strlen($perms[$dbColName]) || $perms[$dbColName] === '-' || $perms[$dbColName] === 'f') { - + $thisPermChar = substr($dbColName, -1); + if($this->evaluate_perm_value($perms[$dbColName], $thisPermChar)) { + $permChar = substr($dbColName, -1); + } + else { $permChar = '-'; } $retval .= $permChar; @@ -116,6 +127,9 @@ //============================================================================ + /** + * Same as create_permission(). + */ public function create_object($name, $userId, $groupId, $permString) { return($this->create_permission($name, $userId, $groupId, $permString)); }//end create_object() @@ -124,6 +138,9 @@ //============================================================================ + /** + * Creates a permission object record. + */ public function create_permission($name, $userId, $groupId, $permString) { if(is_string($name) && strlen($name) && is_numeric($userId) && $userId >= 0 && is_numeric($groupId) && $groupId >= 0) { $cleanStringArr = array( @@ -165,6 +182,9 @@ //============================================================================ + /** + * Same as get_permission(). + */ public function get_object($name) { return($this->get_permission($name)); }//end get_object() @@ -173,6 +193,9 @@ //============================================================================ + /** + * Retrieves a permission object by name from the database, exception on failure. + */ public function get_permission($name) { try { $name = $this->gfObj->cleanString($name, 'sql', 0); @@ -190,6 +213,9 @@ //============================================================================ + /** + * Same as get_permission_by_id(). + */ public function get_object_by_id($objectId) { return($this->get_permission_by_id($objectId)); }//end get_object_by_id() @@ -198,6 +224,9 @@ //============================================================================ + /** + * Retrieves a permission object from the database based on an ID. + */ public function get_permission_by_id($permId) { try { if(!is_null($permId) && is_numeric($permId)) { @@ -215,5 +244,159 @@ return($retval); }//end get_permission_by_id() //============================================================================ + + + + //============================================================================ + /** + * Check available permissions... + */ + public function check_permission($objectName, $userId) { + $availablePerms = array( + 'r' => false, + 'w' => false, + 'x' => false + ); + + try { + //get the object. + $permission = $this->get_permission($objectName); + + //now figure out what permissions they have. + if($permission['user_id'] == $userId) { + //it is the owner, determine based on the permissions with the 'u_' prefix. + $availablePerms = $this->get_permission_list($permission, 'u'); + } + elseif($this->is_group_member($userId, $permission['group_id'])) { + //group member, use the 'g_' permissions. + $availablePerms = $this->get_permission_list($permission, 'g'); + } + else { + //not owner OR group member, use the 'o_' permissions + $availablePerms = $this->get_permission_list($permission, 'o'); + } + } + catch(Exception $e) { + //consider logging this... maybe based on some internal variable. + } + + return($availablePerms); + }//end check_permission() + //============================================================================ + + + + //============================================================================ + /** + * Creates an array of permission bits based on user/group/other from the given + * permission data (i.e. the return from get_permission()). + */ + protected function get_permission_list(array $permData, $type) { + $retval = array(); + if(in_array($type, array('u', 'g', 'o'))) { + foreach($this->keys as $myKey) { + if(preg_match('/'. $type .'_[rwx]$/',$myKey)) { + //chop the last character off (i.e. 'r' from 'u_r') + $myPermChar = substr($myKey, -1); + #$retval[$myPermChar] = $this->gfObj->interpret_bool($permData[$myKey], array('f', 't')); + $retval[$myPermChar] = $this->evaluate_perm_value($permData[$myKey], $type); + } + } + } + else { + throw new exception(__METHOD__ .":: invalid type (". $type ."), must be u/g/o"); + } + + return($retval); + }//end get_permission_list() + //============================================================================ + + + + //============================================================================ + /** + * Evaluate the value in a permission bit as true (allowed) or false (disallowed). + */ + protected function evaluate_perm_value($val=null) { + + if($val === '-' || $val === false || $val === 'f' || $val === 0 || $val === '0' || !strlen($val)) { + $retval = false; + } + else { + $retval = true; + } + return($retval); + }//end evaluate_perm_value + //============================================================================ + + + + //============================================================================ + /** + * Determines if a permission record exists (based on name). + */ + public function permission_exists($permName) { + try { + $info = $this->get_permission($permName); + $retval = false; + if(is_array($info)) { + $retval = true; + } + } + catch(Exception $e) { + $retval = false; + } + + return($retval); + }//end permission_exists() + //============================================================================ + + + + //============================================================================ + /** + * If user has read permission for the given named permission/object. + */ + public function has_read_permission($userId, $permName) { + $myPerms = $this->check_permission($permName, $userId); + $retval = false; + if($myPerms['r'] === true) { + $retval = true; + } + return($retval); + }//end has_read_permission() + //============================================================================ + + + + //============================================================================ + /** + * If user has write permission for the given named permission/object. + */ + public function has_write_permission($userId, $permName) { + $myPerms = $this->check_permission($permName, $userId); + $retval = false; + if($myPerms['w'] === true) { + $retval = true; + } + return($retval); + }//end has_write_permission() + //============================================================================ + + + + //============================================================================ + /** + * If user has execute permission for the given named permission/object. + */ + public function has_execute_permission($userId, $permName) { + $myPerms = $this->check_permission($permName, $userId); + $retval = false; + if($myPerms['x'] === true) { + $retval = true; + } + return($retval); + }//end has_execute_permission() + //============================================================================ } ?> Deleted: trunk/0.3/docs/example_genericPermission.php =================================================================== --- trunk/0.3/docs/example_genericPermission.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/docs/example_genericPermission.php 2010-06-23 13:45:57 UTC (rev 175) @@ -1,53 +0,0 @@ -<?php - -//instantiate the permission object with a database & the proper UID. -$permObj = new cs_genericUserPermission($page->db, $_SESSION['uid']); - - -//Creating Permissions/Groups -{ - //create a group. - $permObj->create_group("blogs"); - - //define default permissions for the group. - //NOTE::: the "false" entries can be technically excluded, as the default is false. - $perms = array( - 'view' => true, - 'create' => true, - 'edit' => true, - 'set_timestamp' => true, - 'update_timestamp' => false, - 'delete_entry' => false, - 'set_draft' => true, - 'update_to_draft' => false - ); - $permObj->set_group_perms("blogs", $perms); - - //set specific permissions for a user. - //NOTE::: if the group or permission doesn't exist, this will throw an exception. - $permObj->set_user_perm("blogs", "update_timestamp"); -} - - -//Checking Permissions/Groups -{ - //get a list of permissions... - $perms = $permObj->get_user_permissions(); - - //check if the user is part of a group... in this case, the "blogs" group. - $isGroupMember = $permObj->check_group_membership("blogs"); - - //Pull all available permissions for a group... again, the "blogs" group. - $allBlogsPerms = $permObj->get_group_perms("blogs"); - - //check permissions for a specific "group" (or "object")... in this case, "can the user create a blog?" - $hasPermission = $permObj->check_permission("blogs", "create"); - - - //a more advanced check, involving membership in multiple cascading groups (unimplemented)... "can the user administratively view blogs?" - //NOTE::: the code in this method would have to allow an unlimited number of arguments (minimum 2), where the last one is the permission name. - #$permObj->check_cascading_permission("admin", "blogs", "view"); -} - - -?> Modified: trunk/0.3/tests/testOfCSGenericPermissions.php =================================================================== --- trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-21 17:56:47 UTC (rev 174) +++ trunk/0.3/tests/testOfCSGenericPermissions.php 2010-06-23 13:45:57 UTC (rev 175) @@ -123,6 +123,7 @@ { $newId = $perm->create_user_group($this->validUsers[$myKey]['uid'],1); $this->assertTrue(is_numeric($newId)); + $this->assertTrue($perm->is_group_member($this->validUsers[$myKey]['uid'],1)); $ugList = $perm->get_user_groups($this->validUsers[$myKey]['uid']); $this->assertTrue(is_array($ugList)); @@ -152,6 +153,23 @@ 'o_w' => '-', 'o_x' => 'x' ); + $permByType = array( + 'u' => array( + 'r' => true, + 'w' => true, + 'x' => true + ), + 'g' => array( + 'r' => false, + 'w' => false, + 'x' => false + ), + 'o' => array( + 'r' => false, + 'w' => false, + 'x' => true + ) + ); $permString = 'rwx-----x'; $this->assertEqual(strlen($perm->make_perm_string($myPermArr)),9); @@ -160,16 +178,23 @@ $this->assertEqual(array_keys($perm->parse_perm_string($permString)), array_keys($myPermArr)); $this->assertEqual($perm->make_perm_string($perm->parse_perm_string($permString)), $permString); $this->assertEqual(array_keys($perm->parse_perm_string($perm->make_perm_string($myPermArr))), array_keys($myPermArr)); + + $this->assertEqual($perm->get_perm_list($myPermArr,'u'), $permByType['u']); + $this->assertEqual($perm->get_perm_list($myPermArr,'g'), $permByType['g']); + $this->assertEqual($perm->get_perm_list($myPermArr,'o'), $permByType['o']); } //create some permissions. { $userKeys = array_keys($this->validUsers); $myUser = $this->validUsers[$userKeys[0]]; + $myUid = $myUser['uid']; - $usePermString = 'rwxrw-rw-'; + $usePermString = 'rwxrw-r--'; $usePermName = __METHOD__ .'/test1'; - $permId = $perm->create_permission($usePermName, $myUser['uid'], 1, $usePermString); + $this->assertFalse($perm->permission_exists($usePermName)); + $permId = $perm->create_permission($usePermName, $myUid, 1, $usePermString); + $this->assertTrue($perm->permission_exists($usePermName)); $this->assertTrue(is_numeric($permId)); //the method 'build_permissions_string()' should disregard extra indices in the array & build the string. @@ -177,6 +202,29 @@ $this->assertEqual($perm->make_perm_string($perm->get_object_by_id($permId)), $usePermString); $this->assertEqual($perm->make_perm_string($perm->get_permission($usePermName)), $usePermString); $this->assertEqual($perm->make_perm_string($perm->get_object($usePermName)), $usePermString); + + //check to make sure individual permission requests work as expected. + $this->assertTrue($perm->has_read_permission($myUid, $usePermName)); + $this->assertTrue($perm->has_write_permission($myUid, $usePermName)); + $this->assertTrue($perm->has_execute_permission($myUid, $usePermName)); + + //make sure "anonymous" permissions are correct. + $this->assertTrue($perm->has_read_permission(0,$usePermName)); + $this->assertFalse($perm->has_write_permission(0,$usePermName)); + $this->assertFalse($perm->has_execute_permission(0,$usePermName)); + + //put a second user into the proper user_group, then test group permissions. + $secondUser = $this->validUsers[$userKeys[1]]['uid']; + $this->assertTrue(is_numeric($perm->create_user_group($secondUser, 1))); + $this->assertTrue($perm->has_read_permission($secondUser, $usePermName)); + $this->assertTrue($perm->has_write_permission($secondUser, $usePermName)); + $this->assertFalse($perm->has_execute_permission($secondUser, $usePermName)); + + //test a THIRD user (non-zero uid), make sure they are subject to the same permissions as anonymous (uid=0) + $thirdUser = $this->validUsers[$userKeys[2]]['uid']; + $this->assertEqual($perm->has_read_permission(0,$usePermName), $perm->has_read_permission($thirdUser,$usePermName)); + $this->assertEqual($perm->has_write_permission(0,$usePermName), $perm->has_write_permission($thirdUser,$usePermName)); + $this->assertEqual($perm->has_execute_permission(0,$usePermName), $perm->has_execute_permission($thirdUser,$usePermName)); } }//end test_permissions //-------------------------------------------------------------------------- @@ -199,5 +247,9 @@ public function parse_perm_string($string) { return($this->parse_permission_string($string)); } + + public function get_perm_list(array $permData, $type) { + return($this->get_permission_list($permData, $type)); + } } ?> This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site. |