Files
DomFramework/authzgroups.php
2014-11-20 15:54:23 +00:00

617 lines
25 KiB
PHP

<?php
/** DomFramework
@package domframework
@author Dominique Fournier <dominique@fournier38.fr> */
require_once ("domframework/dblayer.php");
/** All the needed functions to authorize or deny access to an authenticated
user by its groups membership */
class authzgroups
{
public $tableprefix = "";
private $dbObject = null;
private $dbGroup = null;
private $dbGroupMember = null;
private $dbRight = null;
public $debug = 0;
/////////////////////
// USER RIGHTS //
/////////////////////
/** Return an array with all the rights of the user in the module.
Cache this information to be quicker with next requests
Remove the entries where path is not at least readable */
public function userrightsget ($module, $user)
{
// if (isset ($_SESSION["domframework"]["authzgroups"][$module][$user]))
// return $_SESSION["domframework"]["authzgroups"][$module][$user];
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
// Do the SQL request in hard to be more performant on jointures
$req = "SELECT o.object,MAX(r.right) AS right
FROM ".$this->tableprefix."authzright AS r,
".$this->tableprefix."authzobject AS o,
".$this->tableprefix."authzgroup AS g,
".$this->tableprefix."authzgroupmember AS gm
WHERE r.idgroup=g.idgroup AND r.idobject=o.idobject AND gm.idgroup=g.idgroup
AND gm.user=:user AND g.module=:module
GROUP BY o.object
ORDER BY o.object";
if ($this->debug) echo "$req\n";
try
{
$st = $this->dbObject->db->prepare ($req);
}
catch (Exception $e)
{
if ($this->dbObject->debug) echo "DEBUG : PREPARE ERROR ! Return FALSE".
$e->getMessage()."\n";
throw new Exception ($e->getMessage(), 500);
}
$st->bindValue (":user", $user);
$st->bindValue (":module", $module);
$rc = $st->execute ();
if ($rc === false)
{
if ($this->dbObject->debug) echo "DEBUG : EXECUTE ERROR ! Return FALSE\n";
}
$res = array ();
while ($d = $st->fetch (PDO::FETCH_ASSOC))
$res[$d["object"]] = $d["right"];
// Transform the numerical rights to RO/RW
foreach ($res as $k=>$r)
{
switch ($r)
{
case "2": $res[$k] = "RW"; break;
case "1": $res[$k] = "RO"; break;
default:
throw new Exception (dgettext ("domframework",
"Unknown right stored"), 500);
}
}
if (isset ($_SESSION))
$_SESSION["domframework"]["authzgroups"][$module][$user] = $res;
return $res;
}
/** Return the right defined for this user in the module for one object */
public function allow ($module, $user, $object)
{
$ressource = $this->userrightsget ($module, $user);
// The complete tree should not be readable for the user : it can have
// access to a card, but not to all the cards (group -> reject,
// group/XXX->allow)
/*// Limit to allowed trees : if a member of the path is not recorded (is
// unreadable), return NO.
// Can be the last entry (the complete object) too
$path = explode ("/", $object);
$completePath = "/";
foreach ($path as $k=>$p)
{
if ($k>1)
$completePath .= "/";
$completePath .= "$p";
if (! isset ($ressource[$completePath]))
{
if ($this->debug)
echo "DEBUG allow : REJECT because $completePath is not found\n";
return "NO";
}
}*/
if (! isset ($ressource[$object]))
return "NO";
return $ressource[$object];
}
/////////////////////////
// DATABASE STORAGE //
/////////////////////////
/** Connect to the database before using it */
public function connect ($dsn, $username=null, $password=null,
$driver_options=null)
{
$this->dbObject = new dblayer ($dsn, $username, $password, $driver_options);
$this->dbObject->debug = $this->debug;
$this->dbObject->table = "authzobject";
$this->dbObject->prefix = $this->tableprefix;
$this->dbObject->fields = array (
"idobject"=>array ("integer", "not null", "autoincrement"),
"module"=> array ("varchar", "255", "not null"),
"object"=> array ("varchar", "255", "not null"),
"comment"=> array ("varchar", "255"));
$this->dbObject->primary = "idobject";
$this->dbObject->unique = array ("idobject", array ("object", "module"));
$this->dbObject->titles = array ("idobject"=>_("idobject"),
"module"=>_("Module"),
"object"=>_("Object"),
"comment"=>_("Comment"));
$this->dbGroup = new dblayer ($dsn, $username, $password, $driver_options);
$this->dbGroup->debug = $this->debug;
$this->dbGroup->table = "authzgroup";
$this->dbGroup->prefix = $this->tableprefix;
$this->dbGroup->fields = array (
"idgroup"=>array ("integer", "not null", "autoincrement"),
"module"=> array ("varchar", "255", "not null"),
"group"=> array ("varchar", "255", "not null"),
"comment"=>array ("varchar", "255"));
$this->dbGroup->primary = "idgroup";
$this->dbGroup->unique = array ("idgroup", array ("module","group"));
$this->dbGroup->titles = array ("idgroup"=>_("idgroup"),
"module"=>_("Module"),
"group"=>_("Group"),
"comment"=>_("Comment"));
$this->dbGroupMember = new dblayer ($dsn, $username, $password,
$driver_options);
$this->dbGroupMember->debug = $this->debug;
$this->dbGroupMember->table = "authzgroupmember";
$this->dbGroupMember->prefix = $this->tableprefix;
$this->dbGroupMember->fields = array (
"idgroupmember"=>array ("integer", "not null", "autoincrement"),
"user"=> array ("varchar", "255", "not null"),
"idgroup"=> array ("integer", "not null"),
"comment"=> array ("varchar", "255"));
$this->dbGroupMember->primary = "idgroupmember";
$this->dbGroupMember->unique = array ("idgroupmember",
array ("user","idgroup"));
$this->dbGroupMember->foreign = array (
"idgroup"=>array ("authzgroup", "idgroup",
"ON UPDATE CASCADE ON DELETE CASCADE"));
$this->dbRight = new dblayer ($dsn, $username, $password, $driver_options);
$this->dbRight->debug = $this->debug;
$this->dbRight->table = "authzright";
$this->dbRight->prefix = $this->tableprefix;
$this->dbRight->fields = array (
"idright"=> array ("integer", "not null", "autoincrement"),
"idgroup"=> array ("integer", "not null"),
"idobject"=>array ("integer", "not null"),
"right"=> array ("integer", "not null"), // 1=RO,2=RW
"comment"=> array ("varchar", "255"));
$this->dbRight->primary = "idright";
$this->dbRight->unique = array ("idright", array ("idgroup","idobject"));
$this->dbRight->foreign = array (
"idgroup"=> array ("authzgroup", "idgroup",
"ON UPDATE CASCADE ON DELETE CASCADE"),
"idobject"=>array ("authzobject", "idobject",
"ON UPDATE CASCADE ON DELETE CASCADE"),
);
return TRUE;
}
/** Create the tables in the database to store the datas */
public function createTables ()
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
if ($this->dbGroupMember == null)
throw new Exception (dgettext ("domframework",
"DB for GroupMember is not connected"),
500);
if ($this->dbRight == null)
throw new Exception (dgettext ("domframework",
"DB for Right is not connected"), 500);
$tables = array ("Object", "Group", "GroupMember", "Right");
foreach ($tables as $table)
{
try
{
$class= "db$table";
$this->$class->createTable ();
}
catch (Exception $e)
{
echo $e->getMessage()."\n";
}
}
return TRUE;
}
/////////////////
// OBJECTS //
/////////////////
/** Add a new object to object list
Return the idobject created */
public function objectAdd ($module, $object, $comment="")
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
// TODO : Check parameters before saving them
return $this->dbObject->insert (array ("module"=>$module,
"object"=>$object,
"comment"=>$comment));
}
/** Remove an object from database and all the rights using it */
public function objectDel ($module, $object)
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
$idobjects = $this->objectRead ($module, $object);
if (! isset ($idobjects[0]["idobject"]))
throw new Exception (dgettext ("domframework",
"Wanted object not found"), 404);
return $this->dbObject->delete ($idobjects[0]["idobject"]);
}
/** Remove an object from database and all the rights using it */
public function objectDelByID ($module, $idobject)
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
$idobjects = $this->objectReadByID ($module, $idobject);
if (! isset ($idobjects[0]["idobject"]))
throw new Exception (dgettext ("domframework",
"Wanted object not found"), 404);
return $this->dbObject->delete ($idobjects[0]["idobject"]);
}
/** Update an object in the database */
public function objectUpdate ($module, $object, $newobject, $newcomment="")
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
$idobjects = $this->objectRead ($module, $object);
if (! isset ($idobjects[0]["idobject"]))
throw new Exception (dgettext ("domframework",
"Wanted object not found"), 404);
return $this->dbObject->update ($idobjects[0]["idobject"],
array ("object"=>$newobject,
"comment"=>$newcomment));
}
/** Update an object in the database */
public function objectUpdateByID ($module, $idobject, $newobject,
$newcomment="")
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
$idobjects = $this->objectReadByID ($module, $idobject);
if (! isset ($idobjects[0]["idobject"]))
throw new Exception (dgettext ("domframework",
"Wanted object not found"), 404);
return $this->dbObject->update ($idobjects[0]["idobject"],
array ("object"=>$newobject,
"comment"=>$newcomment));
}
/** Return an array with all the available objects in the module, or only
one object if $object is provided */
public function objectRead ($module, $object=null)
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
$select[] = array ("module", $module);
if ($object !== null)
$select[] = array ("object", $object);
return $this->dbObject->read ($select);
}
/** Return an array with all the available objects in the module, or only
one object if $object is provided */
public function objectReadByID ($module, $idobject=null)
{
if ($this->dbObject == null)
throw new Exception (dgettext ("domframework",
"DB for Object is not connected"), 500);
$select[] = array ("module", $module);
if ($idobject !== null)
$select[] = array ("idobject", $idobject);
return $this->dbObject->read ($select);
}
/** Return an array containing the titles of the table translating in the user
language */
public function objectTitles ()
{
return $this->dbObject->titles;
}
/** Check if the provided datas are compilant with the object specification
@return array The errors found in the datas */
public function objectVerify ($datas, $idobject=false)
{
return $this->dbObject->verify ($datas, $idobject);
}
////////////////
// GROUPS //
////////////////
/** Add a new group to group list
Return the idgroup created */
public function groupAdd ($module, $group, $comment="")
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
// TODO : Check parameters before saving them
return $this->dbGroup->insert (array ("module"=>$module,
"group"=>$group,
"comment"=>$comment));
}
/** Remove an group from database and all the rights using it */
public function groupDel ($module, $group)
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
$idgroups = $this->groupRead ($module, $group);
if (! isset ($idgroups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
return $this->dbGroup->delete ($idgroups[0]["idgroup"]);
}
/** Remove an group from database and all the rights using it */
public function groupDelByID ($module, $idgroup)
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
$idgroups = $this->groupReadByID ($module, $idgroup);
if (! isset ($idgroups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
return $this->dbGroup->delete ($idgroups[0]["idgroup"]);
}
/** Update an group in the database */
public function groupUpdate ($module, $group, $newgroup, $comment="")
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
$idgroups = $this->groupRead ($module, $group);
if (! isset ($idgroups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
return $this->dbGroup->update ($idgroups[0]["idgroup"],
array ("group"=>$newgroup,
"comment"=>$comment));
}
/** Update an group in the database */
public function groupUpdateByID ($module, $idgroup, $newgroup, $comment="")
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
$idgroups = $this->groupReadByID ($module, $idgroup);
if (! isset ($idgroups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
return $this->dbGroup->update ($idgroups[0]["idgroup"],
array ("group"=>$newgroup,
"comment"=>$comment));
}
/** Return an array with all the available groups in the module */
public function groupRead ($module, $group=null)
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
$select[] = array ("module", $module);
if ($group !== null)
$select[] = array ("group", $group);
return $this->dbGroup->read ($select);
}
public function groupReadByID ($module, $idgroup)
{
if ($this->dbGroup == null)
throw new Exception (dgettext ("domframework",
"DB for Group is not connected"), 500);
$select[] = array ("module", $module);
$select[] = array ("idgroup", $idgroup);
return $this->dbGroup->read ($select);
}
/** Return an array containing the titles of the table translating in the user
language */
public function groupTitles ()
{
return $this->dbGroup->titles;
}
/** Check if the provided datas are compilant with the group specification
@return array The errors found in the datas */
public function groupVerify ($datas, $idgroup=false)
{
return $this->dbGroup->verify ($datas, $idgroup);
}
//////////////////////
// GROUP MEMBER //
//////////////////////
/** Add a new groupmember to groupmember list
Return the idgroupmember created */
public function groupmemberAdd ($module, $group, $user, $comment="")
{
if ($this->dbGroupMember == null)
throw new Exception (dgettext ("domframework",
"DB for GroupMember is not connected"),
500);
$groups = $this->groupRead ($module, $group);
if (! isset ($groups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
return $this->dbGroupMember->insert (array (
"user"=>$user,
"idgroup"=>$groups[0]["idgroup"],
"comment"=>$comment));
}
/** Remove an groupmember from database and all the rights using it */
public function groupmemberDel ($module, $group, $user)
{
if ($this->dbGroupMember == null)
throw new Exception (dgettext ("domframework",
"DB for GroupMember is not connected"),
500);
$groups = $this->groupRead ($module, $group);
if (! isset ($groups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
$groupsMembers = $this->dbGroupMember->read (array (
array ("user",$user),
array ("idgroup",$groups[0]["idgroup"])));
if (! isset ($groupsMembers[0]["idgroupmember"]))
throw new Exception (dgettext ("domframework",
"Wanted GroupMember not found"), 404);
return $this->dbGroupMember->delete ($groupsMembers[0]["idgroupmember"]);
}
/** Update an groupmember in the database */
public function groupmemberUpdate ($module, $group, $user, $comment="")
{
die ("This function is not available : contact us if you need it\n");
}
/** Return an array with all the groups where the user is in and in the module
*/
public function groupmemberReadUser ($module, $user)
{
if ($this->dbGroupMember == null)
throw new Exception (dgettext ("domframework",
"DB for GroupMember is not connected"),
500);
$idgrouptmps = $this->groupRead ($module);
// Create an array with idgroup=>group
$idgroups = array ();
foreach ($idgrouptmps as $val)
$idgroups[$val["idgroup"]] = $val["group"];
$select = array ();
$select[] = array ("user", $user);
$idgroupmembers = $this->dbGroupMember->read ($select);
$res = array ();
foreach ($idgroupmembers as $idmembers)
{
$res[$idmembers["idgroup"]] = $idgroups[$idmembers["idgroup"]];
}
return $res;
}
/** Return an array with all the available users in the group and in the
module */
public function groupmemberReadGroup ($module, $group)
{
if ($this->dbGroupMember == null)
throw new Exception (dgettext ("domframework",
"DB for GroupMember is not connected"),
500);
$groups = $this->groupRead ($module, $group);
if (! isset ($groups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
$select[] = array ("idgroup", $groups[0]["idgroup"]);
return $this->dbGroupMember->read ($select, array ("user"));
}
////////////////
// RIGHTS //
////////////////
/** Add a new right to right list
Return the idright created */
public function rightAdd ($module, $group, $object, $right, $comment="")
{
if ($this->dbRight == null)
throw new Exception (dgettext ("domframework",
"DB for Right is not connected"), 500);
switch ($right)
{
case "RW": $right=2;break;
case "RO": $right=1;break;
default:
throw new Exception (dgettext ("domframework",
"Unknown right provided (RO/RW only)"),
500);
}
$groups = $this->groupRead ($module, $group);
if (! isset ($groups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
$objects = $this->objectRead ($module, $object);
if (! isset ($objects[0]["idobject"]))
throw new Exception (dgettext ("domframework",
"Wanted object not found"), 404);
return $this->dbRight->insert (array ("idgroup"=>$groups[0]["idgroup"],
"idobject"=>$objects[0]["idobject"],
"right"=>$right,
"comment"=>$comment));
}
/** Remove an right from database and all the rights using it */
public function rightDel ($module, $group, $object)
{
if ($this->dbRight == null)
throw new Exception (dgettext ("domframework",
"DB for Right is not connected"), 500);
$idrights = $this->rightRead ($module, $group, $object);
if (!isset ($idrights[0]["idright"]))
throw new Exception (dgettext ("domframework",
"Wanted right not found"), 404);
return $this->dbRight->delete ($idrights[0]["idright"]);
}
/** Update an right in the database */
public function rightUpdate ($module, $group, $object, $newright,
$newcomment="")
{
if ($this->dbRight == null)
throw new Exception (dgettext ("domframework",
"DB for Right is not connected"), 500);
switch ($newright)
{
case "RW": $newright=2;break;
case "RO": $newright=1;break;
default:
throw new Exception (dgettext ("domframework",
"Unknown right provided (RO/RW only)"),
500);
}
$idrights = $this->rightRead ($module, $group, $object);
if (!isset ($idrights[0]["idright"]))
throw new Exception (dgettext ("domframework",
"Wanted right not found"), 404);
return $this->dbRight->update ($idrights[0]["idright"],
array ("right"=>$newright,
"comment"=>$newcomment));
}
/** Return an array with all the available rights in the module, or the
right if provided */
public function rightRead ($module, $group, $object)
{
if ($this->dbRight == null)
throw new Exception (dgettext ("domframework",
"DB for Right is not connected"), 500);
$groups = $this->groupRead ($module, $group);
if (! isset ($groups[0]["idgroup"]))
throw new Exception (dgettext ("domframework",
"Wanted group not found"), 404);
$objects = $this->objectRead ($module, $object);
if (! isset ($objects[0]["idobject"]))
throw new Exception (dgettext ("domframework",
"Wanted object not found"), 404);
$select[] = array ("idgroup",$groups[0]["idgroup"]);
$select[] = array ("idobject",$objects[0]["idobject"]);
return $this->dbRight->read ($select);
}
}