From 9cb1ebc5179c0b2e66bf8d7576ae3ed9eb01e5d9 Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Mon, 31 Jan 2022 10:55:34 +0100 Subject: [PATCH 01/11] remove warning --- PhpRbac/src/PhpRbac/core/lib/nestedset/full.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php b/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php index b2a2616..6f6c289 100644 --- a/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php +++ b/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php @@ -12,13 +12,13 @@ function deleteConditional($ConditionString); function childrenConditional($ConditionString); - function descendantsConditional($AbsoluteDepths=false,$ConditionString); + function descendantsConditional($ConditionString,$AbsoluteDepths=false); function leavesConditional($ConditionString=null); function pathConditional($ConditionString); function depthConditional($ConditionString); function parentNodeConditional($ConditionString); - function siblingConditional($SiblingDistance=1,$ConditionString); + function siblingConditional($ConditionString,$SiblingDistance=1); /**/ } /** @@ -118,7 +118,7 @@ function depthConditional($ConditionString,$Rest=null) * @param string $Rest optional, rest of variables to fill in placeholders of condition string, one variable for each ? in condition * @return Array Node on success, null on failure */ - function siblingConditional($SiblingDistance=1,$ConditionString,$Rest=null) + function siblingConditional($ConditionString,$SiblingDistance=1,$Rest=null) { $Arguments=func_get_args(); $ConditionString=$ConditionString; //prevent warning @@ -224,7 +224,7 @@ function deleteSubtreeConditional($ConditionString,$Rest=null) * @return Rowset including Depth field * @seealso children */ - function descendantsConditional($AbsoluteDepths=false,$ConditionString,$Rest=null) + function descendantsConditional($ConditionString,$AbsoluteDepths=false,$Rest=null) { if (!$AbsoluteDepths) $DepthConcat="- (sub_tree.innerDepth )"; From dbbb1bcbb18fdcb53c96b1c3b03051e50778ee1b Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Mon, 31 Jan 2022 10:55:50 +0100 Subject: [PATCH 02/11] change repo in composer --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index e79fddb..afc7f1c 100644 --- a/composer.json +++ b/composer.json @@ -28,7 +28,7 @@ }, "repositories" : [{ "type" : "vcs", - "url" : "https://github.com/OWASP/rbac.git" + "url" : "https://github.com/fldei101/rbac.git" } ] } From 598044125227f8bc6fe70f314737abfee3bd026e Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Wed, 16 Mar 2022 11:51:33 +0100 Subject: [PATCH 03/11] make construct more general --- PhpRbac/src/PhpRbac/Rbac.php | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/PhpRbac/src/PhpRbac/Rbac.php b/PhpRbac/src/PhpRbac/Rbac.php index 0002cf2..87e9f51 100644 --- a/PhpRbac/src/PhpRbac/Rbac.php +++ b/PhpRbac/src/PhpRbac/Rbac.php @@ -13,7 +13,7 @@ */ class Rbac { - public function __construct($unit_test = '') + public function __construct($ProvidedHostname=false, $ProvidedDbname=false, $ProvidedUsername=false, $ProvidedPassword=false, $ProvidedAdapter=false, $unit_test = '') { if ((string) $unit_test === 'unit_test') { require_once dirname(dirname(__DIR__)) . '/tests/database/database.config'; @@ -21,6 +21,12 @@ public function __construct($unit_test = '') require_once dirname(dirname(__DIR__)) . '/database/database.config'; } + if($ProvidedHostname) $host = $ProvidedHostname; + if($ProvidedDbname) $dbname = $dbname; + if($ProvidedUsername) $user = $ProvidedUsername; + if($ProvidedPassword) $pass = $ProvidedPassword; + if($adapter) $adapter = $ProvidedAdapter; + require_once 'core/lib/Jf.php'; $this->Permissions = Jf::$Rbac->Permissions; From e156649c37962f253a663d0f06df8eec7bebe7f4 Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Wed, 16 Mar 2022 11:58:06 +0100 Subject: [PATCH 04/11] add tableprefix --- PhpRbac/src/PhpRbac/Rbac.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/PhpRbac/src/PhpRbac/Rbac.php b/PhpRbac/src/PhpRbac/Rbac.php index 87e9f51..5110653 100644 --- a/PhpRbac/src/PhpRbac/Rbac.php +++ b/PhpRbac/src/PhpRbac/Rbac.php @@ -13,7 +13,7 @@ */ class Rbac { - public function __construct($ProvidedHostname=false, $ProvidedDbname=false, $ProvidedUsername=false, $ProvidedPassword=false, $ProvidedAdapter=false, $unit_test = '') + public function __construct($ProvidedHostname=false, $ProvidedDbname=false, $ProvidedUsername=false, $ProvidedPassword=false, $ProvidedAdapter=false, $ProvidedTablePrefix=false, $unit_test = '') { if ((string) $unit_test === 'unit_test') { require_once dirname(dirname(__DIR__)) . '/tests/database/database.config'; @@ -25,7 +25,8 @@ public function __construct($ProvidedHostname=false, $ProvidedDbname=false, $Pro if($ProvidedDbname) $dbname = $dbname; if($ProvidedUsername) $user = $ProvidedUsername; if($ProvidedPassword) $pass = $ProvidedPassword; - if($adapter) $adapter = $ProvidedAdapter; + if($ProvidedAdapter) $adapter = $ProvidedAdapter; + if($ProvidedTablePrefix) $tablePrefix = $ProvidedTablePrefix; require_once 'core/lib/Jf.php'; From 4772ca861e2913d4c15f3190571d92388346c4c0 Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Wed, 16 Mar 2022 12:42:16 +0100 Subject: [PATCH 05/11] bugfix naming --- PhpRbac/src/PhpRbac/Rbac.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PhpRbac/src/PhpRbac/Rbac.php b/PhpRbac/src/PhpRbac/Rbac.php index 5110653..88decf0 100644 --- a/PhpRbac/src/PhpRbac/Rbac.php +++ b/PhpRbac/src/PhpRbac/Rbac.php @@ -22,7 +22,7 @@ public function __construct($ProvidedHostname=false, $ProvidedDbname=false, $Pro } if($ProvidedHostname) $host = $ProvidedHostname; - if($ProvidedDbname) $dbname = $dbname; + if($ProvidedDbname) $dbname = $ProvidedDbname; if($ProvidedUsername) $user = $ProvidedUsername; if($ProvidedPassword) $pass = $ProvidedPassword; if($ProvidedAdapter) $adapter = $ProvidedAdapter; From e2412579a78c5c79405553c1a26f9ebfdd3b1a8c Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Thu, 21 Jul 2022 12:38:33 +0200 Subject: [PATCH 06/11] add wildcard --- PhpRbac/src/PhpRbac/Rbac.php | 20 +- PhpRbac/src/PhpRbac/core/lib/rbac.php | 762 +++++++++++++------------- 2 files changed, 387 insertions(+), 395 deletions(-) diff --git a/PhpRbac/src/PhpRbac/Rbac.php b/PhpRbac/src/PhpRbac/Rbac.php index 88decf0..bf91082 100644 --- a/PhpRbac/src/PhpRbac/Rbac.php +++ b/PhpRbac/src/PhpRbac/Rbac.php @@ -1,4 +1,5 @@ tablePrefix(); } + + public function getWildcardPermissionList($search) + { + return Jf::$Rbac->getWildcardPermissionList($search); + } } /** @} */ // End group phprbac */ diff --git a/PhpRbac/src/PhpRbac/core/lib/rbac.php b/PhpRbac/src/PhpRbac/core/lib/rbac.php index 9c2dc3e..74068fe 100644 --- a/PhpRbac/src/PhpRbac/core/lib/rbac.php +++ b/PhpRbac/src/PhpRbac/core/lib/rbac.php @@ -1,6 +1,6 @@ getAttribute(PDO::ATTR_DRIVER_NAME)=="sqlite"; + $Adapter = get_class(Jf::$Db); + return $Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME) == "sqlite"; } protected function isMySql() { - $Adapter=get_class(Jf::$Db); - return $Adapter == "mysqli" or ($Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME)=="mysql"); + $Adapter = get_class(Jf::$Db); + return $Adapter == "mysqli" or ($Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME) == "mysql"); } } @@ -72,8 +72,8 @@ abstract protected function type(); function add($Title, $Description, $ParentID = null) { if ($ParentID === null) - $ParentID = $this->rootId (); - return (int)$this->{$this->type ()}->insertChildData ( array ("Title" => $Title, "Description" => $Description ), "ID=?", $ParentID ); + $ParentID = $this->rootId(); + return (int)$this->{$this->type()}->insertChildData(array("Title" => $Title, "Description" => $Description), "ID=?", $ParentID); } /** @@ -89,39 +89,35 @@ function add($Title, $Description, $ParentID = null) */ function addPath($Path, array $Descriptions = null) { - if ($Path[0] !== "/") - throw new \Exception ("The path supplied is not valid."); - - $Path = substr ( $Path, 1 ); - $Parts = explode ( "/", $Path ); - $Parent = 1; - $index = 0; - $CurrentPath = ""; - $NodesCreated = 0; - - foreach ($Parts as $p) - { - if (isset ($Descriptions[$index])) - $Description = $Descriptions[$index]; - else - $Description = ""; - $CurrentPath .= "/{$p}"; - $t = $this->pathId($CurrentPath); - if (! $t) - { - $IID = $this->add($p, $Description, $Parent); - $Parent = $IID; - $NodesCreated++; - } - else - { - $Parent = $t; - } - - $index += 1; - } - - return (int)$NodesCreated; + if ($Path[0] !== "/") + throw new \Exception("The path supplied is not valid."); + + $Path = substr($Path, 1); + $Parts = explode("/", $Path); + $Parent = 1; + $index = 0; + $CurrentPath = ""; + $NodesCreated = 0; + + foreach ($Parts as $p) { + if (isset($Descriptions[$index])) + $Description = $Descriptions[$index]; + else + $Description = ""; + $CurrentPath .= "/{$p}"; + $t = $this->pathId($CurrentPath); + if (!$t) { + $IID = $this->add($p, $Description, $Parent); + $Parent = $IID; + $NodesCreated++; + } else { + $Parent = $t; + } + + $index += 1; + } + + return (int)$NodesCreated; } /** @@ -131,8 +127,8 @@ function addPath($Path, array $Descriptions = null) */ function count() { - $Res = Jf::sql ( "SELECT COUNT(*) FROM {$this->tablePrefix()}{$this->type()}" ); - return (int)$Res [0] ['COUNT(*)']; + $Res = Jf::sql("SELECT COUNT(*) FROM {$this->tablePrefix()}{$this->type()}"); + return (int)$Res[0]['COUNT(*)']; } /** @@ -144,13 +140,13 @@ function count() */ public function returnId($entity = null) { - if (substr ($entity, 0, 1) == "/") { - $entityID = $this->pathId($entity); - } else { - $entityID = $this->titleId($entity); - } + if (substr($entity, 0, 1) == "/") { + $entityID = $this->pathId($entity); + } else { + $entityID = $this->titleId($entity); + } - return $entityID; + return $entityID; } /** @@ -165,39 +161,38 @@ public function pathId($Path) { $Path = "root" . $Path; - if ($Path [strlen ( $Path ) - 1] == "/") - $Path = substr ( $Path, 0, strlen ( $Path ) - 1 ); - $Parts = explode ( "/", $Path ); + if ($Path[strlen($Path) - 1] == "/") + $Path = substr($Path, 0, strlen($Path) - 1); + $Parts = explode("/", $Path); $Adapter = get_class(Jf::$Db); - if ($Adapter == "mysqli" or ($Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME)=="mysql")) { - $GroupConcat="GROUP_CONCAT(parent.Title ORDER BY parent.Lft SEPARATOR '/')"; - } elseif ($Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME)=="sqlite") { - $GroupConcat="GROUP_CONCAT(parent.Title,'/')"; + if ($Adapter == "mysqli" or ($Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME) == "mysql")) { + $GroupConcat = "GROUP_CONCAT(parent.Title ORDER BY parent.Lft SEPARATOR '/')"; + } elseif ($Adapter == "PDO" and Jf::$Db->getAttribute(PDO::ATTR_DRIVER_NAME) == "sqlite") { + $GroupConcat = "GROUP_CONCAT(parent.Title,'/')"; } else { - throw new \Exception ("Unknown Group_Concat on this type of database: {$Adapter}"); + throw new \Exception("Unknown Group_Concat on this type of database: {$Adapter}"); } - $res = Jf::sql ( "SELECT node.ID,{$GroupConcat} AS Path + $res = Jf::sql("SELECT node.ID,{$GroupConcat} AS Path FROM {$this->tablePrefix()}{$this->type()} AS node, {$this->tablePrefix()}{$this->type()} AS parent WHERE node.Lft BETWEEN parent.Lft AND parent.Rght AND node.Title=? GROUP BY node.ID HAVING Path = ? - ", $Parts [count ( $Parts ) - 1], $Path ); + ", $Parts[count($Parts) - 1], $Path); if ($res) - return $res [0] ['ID']; + return $res[0]['ID']; else return null; - // TODO: make the below SQL work, so that 1024 limit is over + // TODO: make the below SQL work, so that 1024 limit is over $QueryBase = ("SELECT n0.ID \nFROM {$this->tablePrefix()}{$this->type()} AS n0"); $QueryCondition = "\nWHERE n0.Title=?"; - for($i = 1; $i < count ( $Parts ); ++ $i) - { + for ($i = 1; $i < count($Parts); ++$i) { $j = $i - 1; $QueryBase .= "\nJOIN {$this->tablePrefix()}{$this->type()} AS n{$i} ON (n{$j}.Lft BETWEEN n{$i}.Lft+1 AND n{$i}.Rght)"; $QueryCondition .= "\nAND n{$i}.Title=?"; @@ -206,14 +201,14 @@ public function pathId($Path) $QueryCondition .= "\nAND nn{$i}.Lft IS NULL"; } $Query = $QueryBase . $QueryCondition; - $PartsRev = array_reverse ( $Parts ); - array_unshift ( $PartsRev, $Query ); + $PartsRev = array_reverse($Parts); + array_unshift($PartsRev, $Query); - print_ ( $PartsRev ); - $res = call_user_func_array ( "Jf::sql", $PartsRev ); + //print_r($PartsRev); + $res = call_user_func_array("Jf::sql", $PartsRev); if ($res) - return $res [0] ['ID']; + return $res[0]['ID']; else return null; } @@ -226,7 +221,7 @@ public function pathId($Path) */ public function titleId($Title) { - return $this->{$this->type ()}->getID ( "Title=?", $Title ); + return $this->{$this->type()}->getID("Title=?", $Title); } /** @@ -236,8 +231,8 @@ public function titleId($Title) */ protected function getRecord($ID) { - $args = func_get_args (); - return call_user_func_array ( array ($this->{$this->type ()}, "getRecord" ), $args ); + $args = func_get_args(); + return call_user_func_array(array($this->{$this->type()}, "getRecord"), $args); } /** @@ -248,9 +243,9 @@ protected function getRecord($ID) */ function getTitle($ID) { - $r = $this->getRecord ( "ID=?", $ID ); + $r = $this->getRecord("ID=?", $ID); if ($r) - return $r ['Title']; + return $r['Title']; else return null; } @@ -263,18 +258,18 @@ function getTitle($ID) */ function getPath($ID) { - $res = $this->{$this->type ()}->pathConditional ( "ID=?", $ID ); - $out = null; - if (is_array ( $res )) - foreach ( $res as $r ) - if ($r ['ID'] == 1) - $out = '/'; - else - $out .= "/" . $r ['Title']; - if (strlen ( $out ) > 1) - return substr ( $out, 1 ); - else - return $out; + $res = $this->{$this->type()}->pathConditional("ID=?", $ID); + $out = null; + if (is_array($res)) + foreach ($res as $r) + if ($r['ID'] == 1) + $out = '/'; + else + $out .= "/" . $r['Title']; + if (strlen($out) > 1) + return substr($out, 1); + else + return $out; } /** @@ -285,11 +280,11 @@ function getPath($ID) */ function getDescription($ID) { - $r = $this->getRecord ( "ID=?", $ID ); - if ($r) - return $r ['Description']; - else - return null; + $r = $this->getRecord("ID=?", $ID); + if ($r) + return $r['Description']; + else + return null; } /** @@ -302,15 +297,15 @@ function getDescription($ID) */ function edit($ID, $NewTitle = null, $NewDescription = null) { - $Data = array (); + $Data = array(); if ($NewTitle !== null) - $Data ['Title'] = $NewTitle; + $Data['Title'] = $NewTitle; if ($NewDescription !== null) - $Data ['Description'] = $NewDescription; + $Data['Description'] = $NewDescription; - return $this->{$this->type ()}->editData ( $Data, "ID=?", $ID ) == 1; + return $this->{$this->type()}->editData($Data, "ID=?", $ID) == 1; } /** @@ -322,7 +317,7 @@ function edit($ID, $NewTitle = null, $NewDescription = null) */ function children($ID) { - return $this->{$this->type ()}->childrenConditional ( "ID=?", $ID ); + return $this->{$this->type()}->childrenConditional("ID=?", $ID); } /** @@ -334,11 +329,11 @@ function children($ID) */ function descendants($ID) { - $res = $this->{$this->type ()}->descendantsConditional(/* absolute depths*/false, "ID=?", $ID ); - $out = array (); - if (is_array ( $res )) - foreach ( $res as $v ) - $out [$v ['Title']] = $v; + $res = $this->{$this->type()}->descendantsConditional(/* absolute depths*/false, "ID=?", $ID); + $out = array(); + if (is_array($res)) + foreach ($res as $v) + $out[$v['Title']] = $v; return $out; } @@ -349,7 +344,7 @@ function descendants($ID) */ function depth($ID) { - return $this->{$this->type ()}->depthConditional ( "ID=?", $ID ); + return $this->{$this->type()}->depthConditional("ID=?", $ID); } /** @@ -361,7 +356,7 @@ function depth($ID) */ function parentNode($ID) { - return $this->{$this->type ()}->parentNodeConditional ( "ID=?", $ID ); + return $this->{$this->type()}->parentNodeConditional("ID=?", $ID); } /** @@ -376,20 +371,19 @@ function parentNode($ID) */ function reset($Ensure = false) { - if ($Ensure !== true) - { - throw new \Exception ("You must pass true to this function, otherwise it won't work."); + if ($Ensure !== true) { + throw new \Exception("You must pass true to this function, otherwise it won't work."); return; } - $res = Jf::sql ( "DELETE FROM {$this->tablePrefix()}{$this->type()}" ); + $res = Jf::sql("DELETE FROM {$this->tablePrefix()}{$this->type()}"); $Adapter = get_class(Jf::$Db); if ($this->isMySql()) - Jf::sql ( "ALTER TABLE {$this->tablePrefix()}{$this->type()} AUTO_INCREMENT=1 " ); + Jf::sql("ALTER TABLE {$this->tablePrefix()}{$this->type()} AUTO_INCREMENT=1 "); elseif ($this->isSQLite()) - Jf::sql ( "delete from sqlite_sequence where name=? ", $this->tablePrefix () . "{$this->type()}" ); + Jf::sql("delete from sqlite_sequence where name=? ", $this->tablePrefix() . "{$this->type()}"); else - throw new \Exception ( "Rbac can not reset table on this type of database: {$Adapter}" ); - $iid = Jf::sql ( "INSERT INTO {$this->tablePrefix()}{$this->type()} (Title,Description,Lft,Rght) VALUES (?,?,?,?)", "root", "root",0,1 ); + throw new \Exception("Rbac can not reset table on this type of database: {$Adapter}"); + $iid = Jf::sql("INSERT INTO {$this->tablePrefix()}{$this->type()} (Title,Description,Lft,Rght) VALUES (?,?,?,?)", "root", "root", 0, 1); return (int)$res; } @@ -407,27 +401,25 @@ function reset($Ensure = false) */ function assign($Role, $Permission) { - if (is_numeric($Role)) - { - $RoleID = $Role; - } else { - if (substr($Role, 0, 1) == "/") - $RoleID = Jf::$Rbac->Roles->pathId($Role); - else - $RoleID = Jf::$Rbac->Roles->titleId($Role); - } - - if (is_numeric($Permission)) - { - $PermissionID = $Permission; - } else { - if (substr($Permission, 0, 1) == "/") - $PermissionID = Jf::$Rbac->Permissions->pathId($Permission); - else - $PermissionID = Jf::$Rbac->Permissions->titleId($Permission); - } - - return Jf::sql("INSERT INTO {$this->tablePrefix()}rolepermissions + if (is_numeric($Role)) { + $RoleID = $Role; + } else { + if (substr($Role, 0, 1) == "/") + $RoleID = Jf::$Rbac->Roles->pathId($Role); + else + $RoleID = Jf::$Rbac->Roles->titleId($Role); + } + + if (is_numeric($Permission)) { + $PermissionID = $Permission; + } else { + if (substr($Permission, 0, 1) == "/") + $PermissionID = Jf::$Rbac->Permissions->pathId($Permission); + else + $PermissionID = Jf::$Rbac->Permissions->titleId($Permission); + } + + return Jf::sql("INSERT INTO {$this->tablePrefix()}rolepermissions (RoleID,PermissionID,AssignmentDate) VALUES (?,?,?)", $RoleID, $PermissionID, Jf::time()) >= 1; } @@ -443,25 +435,23 @@ function assign($Role, $Permission) */ function unassign($Role, $Permission) { - if (is_numeric($Role)) - { - $RoleID = $Role; - } else { - if (substr($Role, 0, 1) == "/") - $RoleID = Jf::$Rbac->Roles->pathId($Role); - else - $RoleID = Jf::$Rbac->Roles->titleId($Role); - } - - if (is_numeric($Permission)) - { - $PermissionID = $Permission; - } else { - if (substr($Permission, 0, 1) == "/") - $PermissionID = Jf::$Rbac->Permissions->pathId($Permission); - else - $PermissionID = Jf::$Rbac->Permissions->titleId($Permission); - } + if (is_numeric($Role)) { + $RoleID = $Role; + } else { + if (substr($Role, 0, 1) == "/") + $RoleID = Jf::$Rbac->Roles->pathId($Role); + else + $RoleID = Jf::$Rbac->Roles->titleId($Role); + } + + if (is_numeric($Permission)) { + $PermissionID = $Permission; + } else { + if (substr($Permission, 0, 1) == "/") + $PermissionID = Jf::$Rbac->Permissions->pathId($Permission); + else + $PermissionID = Jf::$Rbac->Permissions->titleId($Permission); + } return Jf::sql("DELETE FROM {$this->tablePrefix()}rolepermissions WHERE RoleID=? AND PermissionID=?", $RoleID, $PermissionID) == 1; @@ -477,21 +467,20 @@ function unassign($Role, $Permission) */ function resetAssignments($Ensure = false) { - if ($Ensure !== true) - { - throw new \Exception ("You must pass true to this function, otherwise it won't work."); + if ($Ensure !== true) { + throw new \Exception("You must pass true to this function, otherwise it won't work."); return; } - $res = Jf::sql ( "DELETE FROM {$this->tablePrefix()}rolepermissions" ); + $res = Jf::sql("DELETE FROM {$this->tablePrefix()}rolepermissions"); $Adapter = get_class(Jf::$Db); if ($this->isMySql()) - Jf::sql ( "ALTER TABLE {$this->tablePrefix()}rolepermissions AUTO_INCREMENT =1 " ); + Jf::sql("ALTER TABLE {$this->tablePrefix()}rolepermissions AUTO_INCREMENT =1 "); elseif ($this->isSQLite()) - Jf::sql ( "delete from sqlite_sequence where name=? ", $this->tablePrefix () . "_rolepermissions" ); + Jf::sql("delete from sqlite_sequence where name=? ", $this->tablePrefix() . "_rolepermissions"); else - throw new \Exception ( "Rbac can not reset table on this type of database: {$Adapter}" ); - $this->assign ( $this->rootId(), $this->rootId()); + throw new \Exception("Rbac can not reset table on this type of database: {$Adapter}"); + $this->assign($this->rootId(), $this->rootId()); return $res; } } @@ -512,107 +501,103 @@ function resetAssignments($Ensure = false) */ class RbacManager extends JModel { - function __construct() - { - $this->Users = new RbacUserManager (); - $this->Roles = new RoleManager (); - $this->Permissions = new PermissionManager (); - } - - /** - * - * @var \Jf\PermissionManager - */ - public $Permissions; - - /** - * - * @var \Jf\RoleManager - */ - public $Roles; - - /** - * - * @var \Jf\RbacUserManager - */ - public $Users; - - /** - * Assign a role to a permission. - * Alias for what's in the base class - * - * @param string|integer $Role - * Id, Title or Path - * @param string|integer $Permission - * Id, Title or Path - * @return boolean - */ - function assign($Role, $Permission) - { - return $this->Roles->assign($Role, $Permission); - } - - /** - * Prepared statement for check query - * - * @var BaseDatabaseStatement - */ - private $ps_Check = null; - - /** - * Checks whether a user has a permission or not. - * - * @param string|integer $Permission - * you can provide a path like /some/permission, a title, or the - * permission ID. - * in case of ID, don't forget to provide integer (not a string - * containing a number) - * @param string|integer $UserID - * User ID of a user - * - * @throws RbacPermissionNotFoundException - * @throws RbacUserNotProvidedException - * @return boolean - */ - function check($Permission, $UserID = null) - { - if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); - - // convert permission to ID - if (is_numeric ( $Permission )) - { - $PermissionID = $Permission; - } - else - { - if (substr ( $Permission, 0, 1 ) == "/") - $PermissionID = $this->Permissions->pathId ( $Permission ); - else - $PermissionID = $this->Permissions->titleId ( $Permission ); - } - - // if invalid, throw exception - if ($PermissionID === null) - throw new RbacPermissionNotFoundException ( "The permission '{$Permission}' not found." ); - - if ($this->isSQLite()) - { - $LastPart="AS Temp ON ( TR.ID = Temp.RoleID) + function __construct() + { + $this->Users = new RbacUserManager(); + $this->Roles = new RoleManager(); + $this->Permissions = new PermissionManager(); + } + + /** + * + * @var \Jf\PermissionManager + */ + public $Permissions; + + /** + * + * @var \Jf\RoleManager + */ + public $Roles; + + /** + * + * @var \Jf\RbacUserManager + */ + public $Users; + + /** + * Assign a role to a permission. + * Alias for what's in the base class + * + * @param string|integer $Role + * Id, Title or Path + * @param string|integer $Permission + * Id, Title or Path + * @return boolean + */ + function assign($Role, $Permission) + { + return $this->Roles->assign($Role, $Permission); + } + + /** + * Prepared statement for check query + * + * @var BaseDatabaseStatement + */ + private $ps_Check = null; + + /** + * Checks whether a user has a permission or not. + * + * @param string|integer $Permission + * you can provide a path like /some/permission, a title, or the + * permission ID. + * in case of ID, don't forget to provide integer (not a string + * containing a number) + * @param string|integer $UserID + * User ID of a user + * + * @throws RbacPermissionNotFoundException + * @throws RbacUserNotProvidedException + * @return boolean + */ + function check($Permission, $UserID = null) + { + if ($UserID === null) + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); + + // convert permission to ID + if (is_numeric($Permission)) { + $PermissionID = $Permission; + } else { + if (substr($Permission, 0, 1) == "/") + $PermissionID = $this->Permissions->pathId($Permission); + else + $PermissionID = $this->Permissions->titleId($Permission); + } + + // if invalid, throw exception + if ($PermissionID === null) + throw new RbacPermissionNotFoundException("The permission '{$Permission}' not found."); + + if ($this->isSQLite()) { + $LastPart = "AS Temp ON ( TR.ID = Temp.RoleID) WHERE TUrel.UserID=? AND Temp.ID=?"; - } - else //mysql - { - $LastPart="ON ( TR.ID = TRel.RoleID) + } else //mysql + { + $LastPart = "ON ( TR.ID = TRel.RoleID) WHERE TUrel.UserID=? AND TPdirect.ID=?"; - } - $Res=Jf::sql ( "SELECT COUNT(*) AS Result + } + $Res = Jf::sql( + "SELECT COUNT(*) AS Result FROM {$this->tablePrefix()}userroles AS TUrel @@ -623,54 +608,68 @@ function check($Permission, $UserID = null) JOIN {$this->tablePrefix()}permissions AS TP ON ( TPdirect.Lft BETWEEN TP.Lft AND TP.Rght) JOIN {$this->tablePrefix()}rolepermissions AS TRel ON (TP.ID=TRel.PermissionID) ) $LastPart", - $UserID, $PermissionID ); - - return $Res [0] ['Result'] >= 1; - } - - /** - * Enforce a permission on a user - * - * @param string|integer $Permission - * path or title or ID of permission - * - * @param integer $UserID - * - * @throws RbacUserNotProvidedException - */ + $UserID, + $PermissionID + ); + + return $Res[0]['Result'] >= 1; + } + + function getWildcardPermissionList($search) + { + $Res = Jf::sql( + "SELECT Title + FROM + {$this->tablePrefix()}permissions + WHERE Title LIKE :permission", + "{$search}%" + ); + return $Res; + } + + /** + * Enforce a permission on a user + * + * @param string|integer $Permission + * path or title or ID of permission + * + * @param integer $UserID + * + * @throws RbacUserNotProvidedException + */ function enforce($Permission, $UserID = null) { - if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); + if ($UserID === null) + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); - if (! $this->check($Permission, $UserID)) { - header('HTTP/1.1 403 Forbidden'); - die("Forbidden: You do not have permission to access this resource."); - } + if (!$this->check($Permission, $UserID)) { + header('HTTP/1.1 403 Forbidden'); + die("Forbidden: You do not have permission to access this resource."); + } - return true; + return true; } - /** - * Remove all roles, permissions and assignments - * mostly used for testing - * - * @param boolean $Ensure - * must set or throws error - * @return boolean - */ - function reset($Ensure = false) - { - if ($Ensure !== true) { - throw new \Exception ("You must pass true to this function, otherwise it won't work."); - return; - } - - $res = true; - $res = $res and $this->Roles->resetAssignments ( true ); - $res = $res and $this->Roles->reset ( true ); - $res = $res and $this->Permissions->reset ( true ); - $res = $res and $this->Users->resetAssignments ( true ); + /** + * Remove all roles, permissions and assignments + * mostly used for testing + * + * @param boolean $Ensure + * must set or throws error + * @return boolean + */ + function reset($Ensure = false) + { + if ($Ensure !== true) { + throw new \Exception("You must pass true to this function, otherwise it won't work."); + return; + } + + $res = true; + $res = $res and $this->Roles->resetAssignments(true); + $res = $res and $this->Roles->reset(true); + $res = $res and $this->Permissions->reset(true); + $res = $res and $this->Users->resetAssignments(true); return $res; } @@ -706,7 +705,7 @@ protected function type() function __construct() { - $this->permissions = new FullNestedSet ( $this->tablePrefix () . "permissions", "ID", "Lft", "Rght" ); + $this->permissions = new FullNestedSet($this->tablePrefix() . "permissions", "ID", "Lft", "Rght"); } /** @@ -720,11 +719,11 @@ function __construct() */ function remove($ID, $Recursive = false) { - $this->unassignRoles ( $ID ); - if (! $Recursive) - return $this->permissions->deleteConditional ( "ID=?", $ID ); + $this->unassignRoles($ID); + if (!$Recursive) + return $this->permissions->deleteConditional("ID=?", $ID); else - return $this->permissions->deleteSubtreeConditional ( "ID=?", $ID ); + return $this->permissions->deleteSubtreeConditional("ID=?", $ID); } /** @@ -736,8 +735,8 @@ function remove($ID, $Recursive = false) */ function unassignRoles($ID) { - $res = Jf::sql ( "DELETE FROM {$this->tablePrefix()}rolepermissions WHERE - PermissionID=?", $ID ); + $res = Jf::sql("DELETE FROM {$this->tablePrefix()}rolepermissions WHERE + PermissionID=?", $ID); return (int)$res; } @@ -755,24 +754,21 @@ function roles($Permission, $OnlyIDs = true) if (!is_numeric($Permission)) $Permission = $this->returnId($Permission); - if ($OnlyIDs) - { - $Res = Jf::sql ( "SELECT RoleID AS `ID` FROM - {$this->tablePrefix()}rolepermissions WHERE PermissionID=? ORDER BY RoleID", $Permission ); - - if (is_array ( $Res )) - { - $out = array (); - foreach ( $Res as $R ) - $out [] = $R ['ID']; + if ($OnlyIDs) { + $Res = Jf::sql("SELECT RoleID AS `ID` FROM + {$this->tablePrefix()}rolepermissions WHERE PermissionID=? ORDER BY RoleID", $Permission); + + if (is_array($Res)) { + $out = array(); + foreach ($Res as $R) + $out[] = $R['ID']; return $out; - } - else + } else return null; } else { - return Jf::sql ( "SELECT `TP`.ID, `TP`.Title, `TP`.Description FROM {$this->tablePrefix()}roles AS `TP` + return Jf::sql("SELECT `TP`.ID, `TP`.Title, `TP`.Description FROM {$this->tablePrefix()}roles AS `TP` LEFT JOIN {$this->tablePrefix()}rolepermissions AS `TR` ON (`TR`.RoleID=`TP`.ID) - WHERE PermissionID=? ORDER BY TP.ID", $Permission ); + WHERE PermissionID=? ORDER BY TP.ID", $Permission); } } } @@ -808,7 +804,7 @@ protected function type() function __construct() { $this->type = "roles"; - $this->roles = new FullNestedSet ( $this->tablePrefix () . "roles", "ID", "Lft", "Rght" ); + $this->roles = new FullNestedSet($this->tablePrefix() . "roles", "ID", "Lft", "Rght"); } /** @@ -822,12 +818,12 @@ function __construct() */ function remove($ID, $Recursive = false) { - $this->unassignPermissions ( $ID ); - $this->unassignUsers ( $ID ); - if (! $Recursive) - return $this->roles->deleteConditional ( "ID=?", $ID ); + $this->unassignPermissions($ID); + $this->unassignUsers($ID); + if (!$Recursive) + return $this->roles->deleteConditional("ID=?", $ID); else - return $this->roles->deleteSubtreeConditional ( "ID=?", $ID ); + return $this->roles->deleteSubtreeConditional("ID=?", $ID); } /** @@ -839,8 +835,8 @@ function remove($ID, $Recursive = false) */ function unassignPermissions($ID) { - $r = Jf::sql ( "DELETE FROM {$this->tablePrefix()}rolepermissions WHERE - RoleID=? ", $ID ); + $r = Jf::sql("DELETE FROM {$this->tablePrefix()}rolepermissions WHERE + RoleID=? ", $ID); return $r; } @@ -853,8 +849,8 @@ function unassignPermissions($ID) */ function unassignUsers($ID) { - return Jf::sql ( "DELETE FROM {$this->tablePrefix()}userroles WHERE - RoleID=?", $ID ); + return Jf::sql("DELETE FROM {$this->tablePrefix()}userroles WHERE + RoleID=?", $ID); } /** @@ -870,7 +866,7 @@ function unassignUsers($ID) */ function hasPermission($Role, $Permission) { - $Res = Jf::sql ( " + $Res = Jf::sql(" SELECT COUNT(*) AS Result FROM {$this->tablePrefix()}rolepermissions AS TRel JOIN {$this->tablePrefix()}permissions AS TP ON ( TP.ID= TRel.PermissionID) @@ -892,8 +888,8 @@ function hasPermission($Role, $Permission) the above section returns all the parents of (the path to) our permission, so if one of our role or its descendants has an assignment to any of them, we're good. */ - ", $Role, $Role, $Permission ); - return $Res [0] ['Result'] >= 1; + ", $Role, $Role, $Permission); + return $Res[0]['Result'] >= 1; } /** @@ -908,25 +904,22 @@ function hasPermission($Role, $Permission) */ function permissions($Role, $OnlyIDs = true) { - if (! is_numeric ($Role)) - $Role = $this->returnId($Role); - - if ($OnlyIDs) - { - $Res = Jf::sql ( "SELECT PermissionID AS `ID` FROM {$this->tablePrefix()}rolepermissions WHERE RoleID=? ORDER BY PermissionID", $Role ); - if (is_array ( $Res )) - { - $out = array (); - foreach ( $Res as $R ) - $out [] = $R ['ID']; + if (!is_numeric($Role)) + $Role = $this->returnId($Role); + + if ($OnlyIDs) { + $Res = Jf::sql("SELECT PermissionID AS `ID` FROM {$this->tablePrefix()}rolepermissions WHERE RoleID=? ORDER BY PermissionID", $Role); + if (is_array($Res)) { + $out = array(); + foreach ($Res as $R) + $out[] = $R['ID']; return $out; - } - else + } else return null; } else { - return Jf::sql ( "SELECT `TP`.ID, `TP`.Title, `TP`.Description FROM {$this->tablePrefix()}permissions AS `TP` + return Jf::sql("SELECT `TP`.ID, `TP`.Title, `TP`.Description FROM {$this->tablePrefix()}permissions AS `TP` LEFT JOIN {$this->tablePrefix()}rolepermissions AS `TR` ON (`TR`.PermissionID=`TP`.ID) - WHERE RoleID=? ORDER BY TP.ID", $Role ); + WHERE RoleID=? ORDER BY TP.ID", $Role); } } } @@ -960,27 +953,24 @@ class RbacUserManager extends JModel */ function hasRole($Role, $UserID = null) { - if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); + if ($UserID === null) + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); - if (is_numeric ( $Role )) - { + if (is_numeric($Role)) { $RoleID = $Role; - } - else - { - if (substr ( $Role, 0, 1 ) == "/") - $RoleID = Jf::$Rbac->Roles->pathId ( $Role ); + } else { + if (substr($Role, 0, 1) == "/") + $RoleID = Jf::$Rbac->Roles->pathId($Role); else - $RoleID = Jf::$Rbac->Roles->titleId ( $Role ); + $RoleID = Jf::$Rbac->Roles->titleId($Role); } - $R = Jf::sql ( "SELECT * FROM {$this->tablePrefix()}userroles AS TUR + $R = Jf::sql("SELECT * FROM {$this->tablePrefix()}userroles AS TUR JOIN {$this->tablePrefix()}roles AS TRdirect ON (TRdirect.ID=TUR.RoleID) JOIN {$this->tablePrefix()}roles AS TR ON (TR.Lft BETWEEN TRdirect.Lft AND TRdirect.Rght) WHERE - TUR.UserID=? AND TR.ID=?", $UserID, $RoleID ); + TUR.UserID=? AND TR.ID=?", $UserID, $RoleID); return $R !== null; } @@ -997,11 +987,10 @@ function hasRole($Role, $UserID = null) */ function assign($Role, $UserID = null) { - if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); + if ($UserID === null) + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); - if (is_numeric($Role)) - { + if (is_numeric($Role)) { $RoleID = $Role; } else { if (substr($Role, 0, 1) == "/") @@ -1010,10 +999,10 @@ function assign($Role, $UserID = null) $RoleID = Jf::$Rbac->Roles->titleId($Role); } - $res = Jf::sql ( "INSERT INTO {$this->tablePrefix()}userroles + $res = Jf::sql("INSERT INTO {$this->tablePrefix()}userroles (UserID,RoleID,AssignmentDate) VALUES (?,?,?) - ", $UserID, $RoleID, Jf::time () ); + ", $UserID, $RoleID, Jf::time()); return $res >= 1; } @@ -1030,22 +1019,20 @@ function assign($Role, $UserID = null) */ function unassign($Role, $UserID = null) { - if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); - - if (is_numeric($Role)) - { - $RoleID = $Role; + if ($UserID === null) + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); - } else { + if (is_numeric($Role)) { + $RoleID = $Role; + } else { - if (substr($Role, 0, 1) == "/") - $RoleID = Jf::$Rbac->Roles->pathId($Role); - else - $RoleID = Jf::$Rbac->Roles->titleId($Role); - } + if (substr($Role, 0, 1) == "/") + $RoleID = Jf::$Rbac->Roles->pathId($Role); + else + $RoleID = Jf::$Rbac->Roles->titleId($Role); + } - return Jf::sql("DELETE FROM {$this->tablePrefix()}userroles WHERE UserID=? AND RoleID=?", $UserID, $RoleID) >= 1; + return Jf::sql("DELETE FROM {$this->tablePrefix()}userroles WHERE UserID=? AND RoleID=?", $UserID, $RoleID) >= 1; } /** @@ -1060,15 +1047,15 @@ function unassign($Role, $UserID = null) */ function allRoles($UserID = null) { - if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); + if ($UserID === null) + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); - return Jf::sql ( "SELECT TR.* + return Jf::sql("SELECT TR.* FROM {$this->tablePrefix()}userroles AS `TRel` JOIN {$this->tablePrefix()}roles AS `TR` ON (`TRel`.RoleID=`TR`.ID) - WHERE TRel.UserID=?", $UserID ); + WHERE TRel.UserID=?", $UserID); } /** @@ -1082,10 +1069,10 @@ function allRoles($UserID = null) function roleCount($UserID = null) { if ($UserID === null) - throw new \RbacUserNotProvidedException ("\$UserID is a required argument."); + throw new \RbacUserNotProvidedException("\$UserID is a required argument."); - $Res = Jf::sql ( "SELECT COUNT(*) AS Result FROM {$this->tablePrefix()}userroles WHERE UserID=?", $UserID ); - return (int)$Res [0] ['Result']; + $Res = Jf::sql("SELECT COUNT(*) AS Result FROM {$this->tablePrefix()}userroles WHERE UserID=?", $UserID); + return (int)$Res[0]['Result']; } /** @@ -1098,21 +1085,20 @@ function roleCount($UserID = null) */ function resetAssignments($Ensure = false) { - if ($Ensure !== true) - { - throw new \Exception ("You must pass true to this function, otherwise it won't work."); + if ($Ensure !== true) { + throw new \Exception("You must pass true to this function, otherwise it won't work."); return; } - $res = Jf::sql ( "DELETE FROM {$this->tablePrefix()}userroles" ); + $res = Jf::sql("DELETE FROM {$this->tablePrefix()}userroles"); $Adapter = get_class(Jf::$Db); if ($this->isMySql()) - Jf::sql ( "ALTER TABLE {$this->tablePrefix()}userroles AUTO_INCREMENT =1 " ); + Jf::sql("ALTER TABLE {$this->tablePrefix()}userroles AUTO_INCREMENT =1 "); elseif ($this->isSQLite()) - Jf::sql ( "delete from sqlite_sequence where name=? ", $this->tablePrefix () . "_userroles" ); + Jf::sql("delete from sqlite_sequence where name=? ", $this->tablePrefix() . "_userroles"); else - throw new \Exception ("Rbac can not reset table on this type of database: {$Adapter}"); - $this->assign ( "root", 1 /* root user */ ); + throw new \Exception("Rbac can not reset table on this type of database: {$Adapter}"); + $this->assign("root", 1 /* root user */); return $res; } } From 35f95dd81c3b125d6946baf5d0024d4c844a1cee Mon Sep 17 00:00:00 2001 From: Florian Deissenbeck Date: Thu, 21 Jul 2022 13:00:09 +0200 Subject: [PATCH 07/11] bugfix --- PhpRbac/src/PhpRbac/core/lib/rbac.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/PhpRbac/src/PhpRbac/core/lib/rbac.php b/PhpRbac/src/PhpRbac/core/lib/rbac.php index 74068fe..c6dfcda 100644 --- a/PhpRbac/src/PhpRbac/core/lib/rbac.php +++ b/PhpRbac/src/PhpRbac/core/lib/rbac.php @@ -618,11 +618,11 @@ function check($Permission, $UserID = null) function getWildcardPermissionList($search) { $Res = Jf::sql( - "SELECT Title + "SELECT TPdirect.Title FROM - {$this->tablePrefix()}permissions - WHERE Title LIKE :permission", - "{$search}%" + {$this->tablePrefix()}permissions AS TPdirect + WHERE TPdirect.Title LIKE ?", + $search . "%" ); return $Res; } From f93a9f4b4324db8a5e686f8a104a31b5f053941b Mon Sep 17 00:00:00 2001 From: JWalczak <32653379+q-u-o-s-a@users.noreply.github.com> Date: Tue, 30 Apr 2024 16:48:54 +0200 Subject: [PATCH 08/11] Update composer.json --- composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/composer.json b/composer.json index afc7f1c..43fc607 100644 --- a/composer.json +++ b/composer.json @@ -1,5 +1,5 @@ { - "name" : "owasp/phprbac", + "name" : "parcelone/phprbac", "type" : "library", "description" : "PHP-RBAC is the de-facto authorization library for PHP. It provides developers with NIST Level 2 Standard Role Based Access Control and more, in the fastest implementation yet.", "keywords" : [ From 55738e60f718f56bcf80560b27c9d4111a50bc64 Mon Sep 17 00:00:00 2001 From: JWalczak <32653379+q-u-o-s-a@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:08:13 +0200 Subject: [PATCH 09/11] fix: warning: Undefined variable $DepthConcat --- PhpRbac/src/PhpRbac/core/lib/nestedset/full.php | 1 + 1 file changed, 1 insertion(+) diff --git a/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php b/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php index 6f6c289..8dd30e1 100644 --- a/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php +++ b/PhpRbac/src/PhpRbac/core/lib/nestedset/full.php @@ -226,6 +226,7 @@ function deleteSubtreeConditional($ConditionString,$Rest=null) */ function descendantsConditional($ConditionString,$AbsoluteDepths=false,$Rest=null) { + $DepthConcat = ""; if (!$AbsoluteDepths) $DepthConcat="- (sub_tree.innerDepth )"; $Arguments=func_get_args(); From d50f701bde02240650d563559813c498220d62c3 Mon Sep 17 00:00:00 2001 From: JWalczak <32653379+q-u-o-s-a@users.noreply.github.com> Date: Tue, 30 Apr 2024 17:48:56 +0200 Subject: [PATCH 10/11] fix call for changeing php 8 param order --- PhpRbac/src/PhpRbac/core/lib/rbac.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PhpRbac/src/PhpRbac/core/lib/rbac.php b/PhpRbac/src/PhpRbac/core/lib/rbac.php index c6dfcda..0195cf7 100644 --- a/PhpRbac/src/PhpRbac/core/lib/rbac.php +++ b/PhpRbac/src/PhpRbac/core/lib/rbac.php @@ -329,7 +329,7 @@ function children($ID) */ function descendants($ID) { - $res = $this->{$this->type()}->descendantsConditional(/* absolute depths*/false, "ID=?", $ID); + $res = $this->{$this->type()}->descendantsConditional("ID=?", $ID, false); $out = array(); if (is_array($res)) foreach ($res as $v) From a5cfeed58c29e5d1b8bfb83194ef676717617a75 Mon Sep 17 00:00:00 2001 From: JWalczak <32653379+q-u-o-s-a@users.noreply.github.com> Date: Sun, 23 Jun 2024 23:40:55 +0200 Subject: [PATCH 11/11] fix descendantsConditional, since argument order broke method --- PhpRbac/src/PhpRbac/core/lib/rbac.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/PhpRbac/src/PhpRbac/core/lib/rbac.php b/PhpRbac/src/PhpRbac/core/lib/rbac.php index 0195cf7..45d9ea1 100644 --- a/PhpRbac/src/PhpRbac/core/lib/rbac.php +++ b/PhpRbac/src/PhpRbac/core/lib/rbac.php @@ -329,7 +329,7 @@ function children($ID) */ function descendants($ID) { - $res = $this->{$this->type()}->descendantsConditional("ID=?", $ID, false); + $res = $this->{$this->type()}->descendantsConditional("ID=?", false, $ID); $out = array(); if (is_array($res)) foreach ($res as $v)