Wikini

ACLGroup

PagePrincipale :: DerniersChangements :: DerniersCommentaires :: ParametresUtilisateur :: Vous êtes ec2-54-196-2-131.compute-1.amazonaws.com

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 :

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 :
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`)
);

INSERT INTO wikini_groups SET grname='admins', grmember='PrenomNom';

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))

diff -ruN wikini/handlers/page/acls.php wikinfo/handlers/page/acls.php
--- wikini/handlers/page/acls.php       2003-05-26 14:30:33.000000000 +0200
+++ wikinfo/handlers/page/acls.php      2004-01-04 20:26:53.000000000 +0100
@@ -33,7 +33,28 @@
                ?>
                <h3>Liste des droits d'accés de la page  <?php echo  $this->ComposeLinkToPage($this->GetPageTag()) ?></h3><!-- Access Control Lists for-->
                <br />
-
+<i>Pour chaque droit d'accès, les règles sont lues de bas en
+   haut, à raison de <b>exactement une seule règle par ligne</b>. En l'absence
de règle, l'accès est refusé à tout le monde. Syntaxe :
+<ul>
+<li><tt>NomUtilisateur</tt> : Droit d'accès
+       (lecture/écriture/commentaires) accordé à
+       <tt>NomUtilisteur</tt></li>
+<li><tt>@legroupe</tt> : Droit d'accès accordé au groupe
+       <tt>legroupe</tt></li>
+<li><tt>*</tt> : Droit d'accès accordé à tout le monde</li>
+<li><tt>+</tt> : Droit d'accès accordé uniquement aux personnes
+  identifiées</li>
+<li><tt>!NomUtilisateur</tt> : Droit d'accès refusé à
+       <tt>NomUtilisteur</tt></li>
+<li><tt>!@legroupe</tt> : Droit d'accès refusé au groupe
+       <tt>legroupe</tt></li>
+<li><tt>!*</tt> : Droit d'accès refusé à tout le monde</li>
+<li><tt>!+</tt> : Droit d'accès refusé aux personnes
+  identifiées</li>
+</ul>
+</i>
+               <br />
+
                <?php echo  $this->FormOpen("acls") ?>
                <table border="0" cellspacing="0" cellpadding="0">
                        <tr>

<?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";
}

?>

<?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";
}
?>

"admin_group" => "admins",



Un exemple de page d'accueil pour l'administration des groupes :
====== Gestion des groupes ======
 - ** Modification/suppression des groupes :**
  Cliquer sur le nom du groupe pour le modifier :
  {{listgroups}}
 - ** Créer un nouveau groupe :**
  ""<form action="wakka.php">
Indiquer le nom de la page à créer :
<input type="hidden" name="wiki" value="EditGroup" />
<input name="group" size="15" class="text" />
<input type="submit" name="Submit" value="Envoyer" />
</form>""


Un exemple de page EditGroup :
{{editgroup}}
//Pour supprimer un groupe, il suffit de supprimer (touche DEL) tous les utilisateurs de la boîte ci-dessus.//


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.


Il n'y a pas de commentaire sur cette page. [Afficher commentaires/formulaire]