Notion de droits d'accès par groupes
Par défaut, les droits d'accès wakka sont gérés par individu (
*,
+,
PrenomNom? dans les permissions). Pour rajouter la notion de groupe, il suffit de peu de choses.
Le principe est le suivant : dans les permissions apparaît une nouvelle forme de droit d'accès :
@nom_du_groupe. On peut donc maintenant écrire, pour les droits en lecture/ecritue/commentaires :
@nom_du_groupe (pour autoriser) ou
!@nom_du_groupe (pour interdire).
On fournit 2 actions :
- {{listgroups}} qui affiche les membres de tous les groupes, avec des liens sur une page EditGroup pour modifier chaque groupe.
- La page EditGroup utilise l'action {{editgroup}} pour modifier les utilisateurs membres du groupe. Dans le wakka.config.php, on précise le nom du groupe qui a le droit d'appeler cette action, sinon toute la "sécurité" de cette manipulation est remise en cause (il suffit d'appeler cette action dans le BacASable et hop tout le monde peut s'amuser à modifier les groupes...).
Le deuxième point pose un problème d'oeuf et de poule : quand on met en place cette manipulation, aucun groupe admins n'est encore défini, et donc l'action {{editgroup}} interdit toute création/modification de groupe, y compris celle du groupe admins... Il faut donc le faire à la main en sql (cf ci-dessous).
Marche à suivre :
- rajouter une table wikini_groups dans la base mysql :
USE la_base_wikini; -- En general ce sera "wikini" ici
CREATE TABLE `wikini_groups` (
`grname` varchar(80) NOT NULL default '',
`grmember` varchar(80) NOT NULL default '',
PRIMARY KEY (`grname`,`grmember`)
);
- rajouter un premier utilisateur dedans (problème de l'oeuf/poule). A vous de spécialiser le admins (en acord avec le config wakka.config.php ci-dessous) et le PrenomNom? :
INSERT INTO wikini_groups SET grname='admins', grmember='PrenomNom';
- Modifier le fichier wakka.php à la racine :
diff -ruN wikini/wakka.php wikinfo/wakka.php
--- wikini/wakka.php 2003-07-06 22:44:40.000000000 +0200
+++ wikinfo/wakka.php 2004-01-04 16:14:00.000000000 +0100
@@ -480,6 +481,51 @@
if ($this->LoadAcl($tag, $privilege, 0)) $this->Query("update ".$this->config["table_prefix"]."acls set list = '".mysql_escape_string(trim(str_replace("\r", "", $list)))."' where page_tag = '".mysql_escape_string($tag)."' and privilege = '".mysql_escape_string($privilege)."' limit 1");
else $this->Query("insert into ".$this->config["table_prefix"]."acls set list = '".mysql_escape_string(trim(str_replace("\r", "", $list)))."', page_tag = '".mysql_escape_string($tag)."', privilege = '".mysql_escape_string($privilege)."'");
}
+
+ // Return the associative array, key=group name, value=list of
+ // logins in group
+ function LoadGroup($grname = "")
+ {
+ if ($grname)
+ $query = "select * from ".$this->config["table_prefix"]."groups where grname = '".$grname."'order by grname asc, grmember asc";
+ else
+ $query = "select * from ".$this->config["table_prefix"]."groups order by grname asc, grmember asc";
+ $r = $this->Query($query);
+ if (! $r)
+ return 0;
+ // Group by lines
+ $grps = array();
+ while (list ($grname, $grmb) = mysql_fetch_row($r))
+ $grps[$grname] .= $grmb."\n";
+ mysql_free_result($r);
+ return $grps;
+ }
+
+ // Save the list of users in the group
+ function SaveGroup($grname, $userslist)
+ {
+ $grname = trim($grname);
+ $lst = explode("\n", $userslist);
+ $this->Query("delete from ".$this->config["table_prefix"]."groups where grname='".$grname."'", $this->dblink);
+ foreach ($lst as $login)
+ {
+ $login = trim($login);
+ if (! $login)
+ continue;
+
+ mysql_query("insert into ".$this->config["table_prefix"]."groups set grname = '".mysql_escape_string($grname)."', grmember = '".mysql_escape_string($login)."'", $this->dblink);
+ }
+ }
+
+ // return true if user is in the given group
+ function UserInGroup($group, $user = "")
+ {
+ if (!$user)
+ $user = $this->GetUserName();
+
+ return $this->LoadSingle("select grname from ".$this->config["table_prefix"]."groups where grname = '".mysql_escape_string($group)."' and grmember =
'".mysql_escape_string($user)."'");
+ }
+
// returns true if $user (defaults to current user) has access to $privilege on $page_tag (defaults to current page)
function HasAccess($privilege, $tag = "", $user = "")
{
@@ -520,6 +566,22 @@
// everyone
case "*":
return !$negate;
+ // a group entry
+ case "@":
+ {
+ if (! preg_match("/^[@](.*)$/",
+ $line, $matches))
+ break;
+ $line = $matches[1];
+ if (!$this->UserInGroup($line))
+ {
+ return $negate;
+ }
+ else
+ {
+ return !$negate;
+ }
+ }
// aha! a user entry.
case "+":
if (!$this->LoadUser($user))
- fichier handlers/page/acls.php
- fichier actions/listgroups.php
<?php
if ($grps = $this->LoadGroup(""))
{
echo "<div class=\"grouplist\">\n";
foreach ($grps as $grname => $grmembers)
{
$grmembers = str_replace("\n", " ", $grmembers);
echo $this->Link("EditGroup", "&group=$grname", "$grname")." . . . ".$grmembers."<br />\n";
}
echo "</div>\n";
}
?>
- fichier actions/editgroup.php
<?php
if (! $this->UserInGroup($this->config["admin_group"]))
{
echo "<h3>Erreur: Vous n'êtes pas dans le groupe autorisé à administrer les groupes</h3>\n";
}
else if ($_POST)
{
$grname = trim($_POST["group"]);
$grmembers = $_POST["group_members"];
if ($grname)
{
$this->SaveGroup($grname, $grmembers);
echo "<h3>Members for group ".$grname." updated !</h3>";
}
else
{
echo "<h3>Error: empty group name</h3>";
}
}
else if (trim($_REQUEST["group"]))
{
$grname = trim($_REQUEST["group"]);
$grps = $this->LoadGroup($grname);
$grmembers = trim($grps[$grname]);
?>
<h3>Liste des membres du
<?php echo $grmembers?"":"<b>NOUVEAU</b>"; ?>
groupe
<?php echo $grname; ?> :
</h3>
<?php echo $this->FormOpen("") ?>
<td valign="top" style="padding-right: 20px">
<input type="hidden" name="group"
value="<?php echo $grname; ?>">
<textarea name="group_members" rows="4" cols="20"><?php echo trim($grmembers); ?></textarea>
<br />
<input type="submit" value="Enregistrer" style="width: 120px" accesskey="s">
<input type="button" value="Annuler" onClick="history.back();" style="width: 120px">
<?php
print($this->FormClose());
}
else
{
echo "<h3>Erreur: le nom du groupe à créer est vide !</h3>\n";
}
?>
- Indiquer le nom du groupe qui a le droit de gérer les groupes. Modifier le wakka.config.php :
"admin_group" => "admins",
Un exemple de page d'accueil pour l'administration des groupes :
Un exemple de page EditGroup :
Et voilà.
--
DavidDecotigny
Merci pour cette contribution --
DavidDelon
Pourrais tu mettre le wakka.php (et autre) modifié en ligne? --
Nicephore17
Il manquait le bouton submit dans l'exemple de la page d'Administartion des Groupes, je me suis permis de le rajouter.
--
YoannAubry?
Suggestions
Il serait bien de mettre un bouton type "submit" pour ajouter un groupe...on cherche comment faire pour valider l'ajout d'un nouveau groupe. --
GarfieldFr
Thomas :
Comment faire pour empêcher que la fonction recherche n'affiche pas aux visiteurs et membres du groupe X les pages dont les seuls à pouvoir la lire sont les membres du Groupe Y ? Merci
J'ai résolu mon problème à la barbare en rajoutant ça au début de textsearch.php :
$notdisplayed = array("RSS",
"EspaceTraducteur",
"EspaceAdministrateur",
"Feedbacks",
"Nom_dautre_page....");
Puis j'ai changé ça :
foreach ($results as $i => $page)
{
if ( !in_array($page['tag'], $notdisplayed) ) echo "<li>", $this->ComposeLinkToPage($page["tag"]), "</li>\n";
}
Mais maintenant je me demande si ce code n'a pas un bug ? Bien que toutes mes pages ont * comme droit pour les commentaires, seuls les inscrits peuvent poster, pourquoi ? C'est très très fâcheux surtout que j'ai ouvert mon site et que je n'avais pas vu ce problème... J'ai éssayé de comprendre comment le script fonctionnait à ce niveau : d'abord appel à addcomment.php qui apellera
SavePage?() (fonction que je n'ai normalement pas modifié) qui appelle elle même
HasAccess?() que j'ai du modifier par contre. Quelqu'un a une idée ? Merci
Finalement le problème ne vient pas de là. Je me suis aperçu que mon wikini modifié code ne passait pas cette vérification contenue dans
SavePage?() :
if ($this->HasAccess?("write", $tag)) alors je l'ai raplancée par
if ($this->HasAccess?("write", $tag) OR $comment_on != "")
Bug ?
Il me semble qu'il ya un bug dans le code, car, si l'on positionne plusieurs groupes pour une même page, il s'arrête au premier groupe rencontré. Si l'utilisateur n'est pas dans ce groupe, fini.
+ case "@":
+ {
+ if (! preg_match("/^[@](.*)$/",
+ $line, $matches))
+ break;
+ $line = $matches[1];
+ if (!$this->UserInGroup($line))
+ {
+ return $negate;
+ }
+ else
+ {
+ return !$negate;
+ }
+ }
Pour moi, c'est pas bon chez moi, il faudrait plutôt faire :
+ case "@":
+ {
+ if (! preg_match("/^[@](.*)$/",
+ $line, $matches))
+ break;
+ $line = $matches[1];
+ if ($this->UserInGroup($line))
+ {
+ return !$negate;
+ }
+ }
--
FabriceLuraine?: Un
break est nécessaire après le deuxième
if pour éviter que les blocs suivants du
switch ne soient exécutés (en particulier le
case "+") :
<?php
/*...*/
case "@":
{
if (! preg_match("/^[@](.*)$/",
$line, $matches))
break;
$line = $matches[1];
if ($this->UserInGroup($line))
{
return !$negate;
}
/* + */ break;
}
/*...*/
?>
Renvois
On verra les
DiscussionsGroupesDUtilisateurs.