diff --git a/PhpRbac/src/PhpRbac/Rbac.php b/PhpRbac/src/PhpRbac/Rbac.php index 0002cf2..b998c2d 100644 --- a/PhpRbac/src/PhpRbac/Rbac.php +++ b/PhpRbac/src/PhpRbac/Rbac.php @@ -33,14 +33,14 @@ public function assign($role, $permission) return Jf::$Rbac->assign($role, $permission); } - public function check($permission, $user_id) + public function check($permission, $user_id, $recurse = false) { - return Jf::$Rbac->check($permission, $user_id); + return Jf::$Rbac->check($permission, $user_id, $recurse); } - public function enforce($permission, $user_id) + public function enforce($permission, $user_id, $recurse = false) { - return Jf::$Rbac->enforce($permission, $user_id); + return Jf::$Rbac->enforce($permission, $user_id, $recurse); } public function reset($ensure = false) diff --git a/PhpRbac/src/PhpRbac/core/lib/rbac.php b/PhpRbac/src/PhpRbac/core/lib/rbac.php index 9c2dc3e..8eb8c24 100644 --- a/PhpRbac/src/PhpRbac/core/lib/rbac.php +++ b/PhpRbac/src/PhpRbac/core/lib/rbac.php @@ -569,12 +569,15 @@ function assign($Role, $Permission) * containing a number) * @param string|integer $UserID * User ID of a user + * @param bool $Recurse + * Use when $Permission is a path, allow system to recursively + * find permission * * @throws RbacPermissionNotFoundException * @throws RbacUserNotProvidedException * @return boolean */ - function check($Permission, $UserID = null) + function check($Permission, $UserID = null, $Recurse = false) { if ($UserID === null) throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); @@ -586,10 +589,15 @@ function check($Permission, $UserID = null) } else { - if (substr ( $Permission, 0, 1 ) == "/") + if (substr ( $Permission, 0, 1 ) == "/") { $PermissionID = $this->Permissions->pathId ( $Permission ); - else + if ($PermissionID === null && $Recurse) { + $newPath = implode('/', explode('/', $Permission, -1)); + return $this->check($newPath, $UserID, true); + } + } else { $PermissionID = $this->Permissions->titleId ( $Permission ); + } } // if invalid, throw exception @@ -636,14 +644,18 @@ function check($Permission, $UserID = null) * * @param integer $UserID * + * @param bool $Recurse + * Use when $Permission is a path, allow system to recursively + * find permission + * * @throws RbacUserNotProvidedException */ - function enforce($Permission, $UserID = null) + function enforce($Permission, $UserID = null, $Recurse = false) { if ($UserID === null) throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); - if (! $this->check($Permission, $UserID)) { + if (! $this->check($Permission, $UserID, $Recurse)) { header('HTTP/1.1 403 Forbidden'); die("Forbidden: You do not have permission to access this resource."); } diff --git a/PhpRbac/tests/src/RbacManagerTest.php b/PhpRbac/tests/src/RbacManagerTest.php index 99bc9bd..dba9751 100644 --- a/PhpRbac/tests/src/RbacManagerTest.php +++ b/PhpRbac/tests/src/RbacManagerTest.php @@ -141,12 +141,12 @@ public function testManagerCheckTitle() public function testManagerCheckPath() { self::$rbac->Permissions->addPath('/permissions_1/permissions_2/permissions_3'); - $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2/permissions_3'); + $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2'); self::$rbac->Roles->addPath('/roles_1/roles_2/roles_3'); $role_id_1 = self::$rbac->Roles->pathId('/roles_1/roles_2/roles_3'); - self::$rbac->Roles->assign($role_id_1, 3); + self::$rbac->Roles->assign($role_id_1, $perm_id_1); self::$rbac->Users->assign($role_id_1, 5); $result = self::$rbac->check('/permissions_1/permissions_2', 5); @@ -154,6 +154,41 @@ public function testManagerCheckPath() $this->assertTrue($result); } + public function testManagerCheckRecursivePath() + { + self::$rbac->Permissions->addPath('/permissions_1/permissions_2'); + $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2'); + + self::$rbac->Roles->addPath('/roles_1/roles_2/roles_3'); + $role_id_1 = self::$rbac->Roles->pathId('/roles_1/roles_2/roles_3'); + + self::$rbac->Roles->assign($role_id_1, $perm_id_1); + self::$rbac->Users->assign($role_id_1, 5); + + $result = self::$rbac->check('/permissions_1/permissions_2/permissons_3', 5, true); + + $this->assertTrue($result); + } + + /** + * @expectedException RbacPermissionNotFoundException + */ + + public function testManagerCheckNonRecursivePath() + { + self::$rbac->Permissions->addPath('/permissions_1/permissions_2'); + $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2'); + + self::$rbac->Roles->addPath('/roles_1/roles_2/roles_3'); + $role_id_1 = self::$rbac->Roles->pathId('/roles_1/roles_2/roles_3'); + + self::$rbac->Roles->assign($role_id_1, $perm_id_1); + self::$rbac->Users->assign($role_id_1, 5); + + self::$rbac->check('/permissions_1/permissions_2/permissons_3', 5, false); + + } + public function testManagerCheckBadPermBadUserFalse() { $result = self::$rbac->check(5, 5); @@ -222,12 +257,12 @@ public function testManagerEnforceTitle() public function testManagerEnforcePath() { self::$rbac->Permissions->addPath('/permissions_1/permissions_2/permissions_3'); - $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2/permissions_3'); + $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2'); self::$rbac->Roles->addPath('/roles_1/roles_2/roles_3'); $role_id_1 = self::$rbac->Roles->pathId('/roles_1/roles_2/roles_3'); - self::$rbac->Roles->assign($role_id_1, 3); + self::$rbac->Roles->assign($role_id_1, $perm_id_1); self::$rbac->Users->assign($role_id_1, 5); $result = self::$rbac->enforce('/permissions_1/permissions_2', 5); @@ -235,6 +270,22 @@ public function testManagerEnforcePath() $this->assertTrue($result); } + public function testManagerEnforceRecursivePath() + { + self::$rbac->Permissions->addPath('/permissions_1/permissions_2'); + $perm_id_1 = self::$rbac->Permissions->pathId('/permissions_1/permissions_2'); + + self::$rbac->Roles->addPath('/roles_1/roles_2/roles_3'); + $role_id_1 = self::$rbac->Roles->pathId('/roles_1/roles_2/roles_3'); + + self::$rbac->Roles->assign($role_id_1, $perm_id_1); + self::$rbac->Users->assign($role_id_1, 5); + + $result = self::$rbac->enforce('/permissions_1/permissions_2/permissions_3', 5, true); + + $this->assertTrue($result); + } + /** * @expectedException RbacUserNotProvidedException */