[spip-dev] Suggestion pour le pipeline autoriser

Bonjour,

Le pipeline « autoriser » permet de charger des fonctions
d’autorisations au tout premier appel de la fonction autoriser().

Par exemple, si un plugin doit intervenir
sur les droits d’accès aux rubriques,
il peut définir, via ce pipeline,
la fonction « autoriser_rubrique_voir ».

Si un second plugin doit également intervenir,
de manière différente, sur les droits d’accès aux rubriques,
la fonction « autoriser_rubrique_voir »
figurera dans les deux plugins.
On peut vérifier l’existence de la fonction préalablement,
mais une seule fonction « autoriser_rubrique_voir »
pourra être utilisée.

Face à ce problème, j’ai créé un troisième plugin
intitulé «monPluginAutoriser» qui définit
la fonction «autoriser_rubrique_voir»
et ajoute un pipeline à l’intérieur de cette fonction
(pour l’exemple, je le limite à une seule fonction).

Dans les paramètres passés à ce pipeline,
on ajoute $param['autoriser'] = $autoriser.
Si $param['autoriser'] est à false,
la fonction qui utilisera ce nouveau pipeline doit renvoyer false.
Si $param['autoriser'] est à true,
la fonction qui utilisera ce nouveau pipeline
pourra renvoyer true ou false
en fonction des vérifications qu’elle opère.

L’idée est d’avoir l’équivalent d’une combinaison de clauses « AND ».

Extrait du plugin.xml du plugin « monPluginAutoriser »
<pipeline>
<nom>autoriser</nom>
    <inclure> monAutoriser_pipeline.php</inclure>
</pipeline>

Extrait du fichier monPluginAutoriser_pipeline.php :
// Voir une rubrique
// Surcharge unique de la dist avec ajout d'un pipeline
function autoriser_rubrique_voir($faire, $type, $id, $qui, $opt) {
    $autoriser = true ;
    $param = array('faire'=>$faire,'type'=>$type,'id'=>$id,'qui'=>$qui,'opt'=>$opt);
    
    // Equivalent de la "dist"
    $autoriser = true;

    // Ajout d'un pipeline
    // si la variable 'autoriser' est à false,
    // la fonction dans le pipeline ne doit pas la modifier
    $param['autoriser'] = $autoriser;
    $param = pipeline('monAutorisation_autoriser_rubrique_voir', $param);
    return $param['autoriser'];

}

Par exemple, dans le premier plugin, on utilise le pipeline
"monAutorisation_autoriser_rubrique_voir":
function 1erplugin_monpipe_autoriser_rubrique_voir($param) {
    $type = $param['type'];
    $id = $param['id'];
    $autoriser = $param['autoriser'];
    
    // si la variable 'autoriser' est à false,
    // la présente fonction (dans le pipeline) ne doit pas la modifier
    if ($autoriser) {
        if (!$id) $autoriser = false;
    
        if ($type == 'rubrique' AND …………………………….)
            $autoriser = false;
    }
    
    $param['autoriser'] = $autoriser;
    
    return $param;
}

Idem dans le second plugin (avec des vérifications différentes).

J'ai testé avec succès l'ensemble.

Ne serait-il pas intéressant que le principe
utilisé par le plugin «monPluginAutoriser »
soit intégré dans la fonction inc/autoriser.php ?
Au moins pour les fonctions vérifiant l’autorisation de voir
une rubrique, un article,une brève, un site, un document.

Cordialement

Imberti

Bonjour,

Je suis surpris qu'il n'y ait pas de réactions sur cette proposition.

Bon, j'avais bien lu ce message avec une bonne attention, mais je n'avais certainement pas eu le temps d'y répondre.

Ce n'est pas la première fois que je trouve le système d'autorisation un rien limité et un chainage serait intéressant effectivement...

Les questions qui me viennent sont :
- Est-ce qu'un AND entre tous les liens est suffisant ?
- Comment définir ce pipeline, sachant la multitude de fonctions d'autorisations existantes
- Comment définir qu'un plugin déclare une autorisation...

Si on répond à ces questions, il doit être possible de créer un plugin «autorisations étendues» pour spip 2 , et mettre ça dans spip 2.1...

Cependant. Je me demande si les performances ne prendraient pas un grand coup de ces modifications, a savoir appeler un pipeline à chaque appel de autoriser() quasiment.

Quand on veut donner des autorisations, c'est souvent surtout qu'on a d'abord voulu en retirer.

Par exemple, le plugin "Accès restreint" retire les autorisations sur des zones, puis il faut les redonner aux utilisateurs souhaités.

Ne faudrait-il donc pas plutôt une séquence de deux pipelines, l'un pour cumuler des retraits d'autorisations (des interdictions, donc) puis l'autre pour donner des passe droits ?

Bonjour,

Depuis mon post du 5 novembre, j'ai continué à creuser
le sujet et j'utilise l'approche suivante :
(dist OR cumul_des_OR) AND cumul_des_AND

En pratique, le plugin intitulé «ciautoriser» définit
la fonction «autoriser_rubrique_voir»
et ajoute un pipeline à l’intérieur de cette fonction
(pour l’exemple, je le limite à une seule fonction).

Dans les paramètres passés à ce pipeline,
on ajoute un tableau des autorisations
où chaque ligne comprend un paramètre « autoriser »
égal à true ou false et un paramètre « operateur »
égal à AND ou OR ou dist.
En effet, il faut tenir compte de l'autorisation
donnée par la fonction initiale, la "dist".

Extrait du plugin :
// Voir une rubrique
// Surcharge de la dist avec ajout d'un pipeline
function autoriser_rubrique_voir($faire, $type, $id, $qui, $opt) {
  $param = array('faire'=>$faire,'type'=>$type,
    'id'=>$id,'qui'=>$qui,'opt'=>$opt);
  
  // Equivalent de la "dist"
  $autoriser = true;

  // Ajout d'un pipeline
  $param['autorisations'][]
   = array('autoriser' => $autoriser, 'operateur' => 'dist');
  $param = pipeline('ciautoriser_rubrique_voir', $param);
  
  return ciautoriser_ciresultat($param);
}

Lorsqu'on utilise ce pipeline,
on ajoute au tableau des autorisations,
une ligne avec un paramètre « autoriser »
et un paramètre « operateur ».

Par exemple :
function cirr_ciautoriser_rubrique_voir($param) {
  $type = $param['type'];
  $id = $param['id'];
  $qui = $param['qui'];

  $autoriser = true;

  if (!$id) $autoriser = false;

  if ($type == 'rubrique'
    AND (in_array($qui['statut'], array('0minirezo', '1comite'))
    && ($qui['restreint'] AND $id AND !in_array($id, $qui['restreint']))))
      $autoriser = false;
  
  $param['autorisations'][]
   = array('autoriser' => $autoriser, 'operateur' => 'AND');
  
  return $param;
}

Après avoir été alimenté par les pipelines,
le tableau final est ensuite traité par la fonction
"ciautoriser_ciresultat" de manière à obtenir
la combinaison de clauses suivante :
(dist OR cumul_des_OR) AND cumul_des_AND

Les possibilités sont moindre que lorsque l’on maîtrise
l’ordre de l’écriture d’une combinaison de clauses,
mais en alimentant judicieusement le tableau
cela répond à mon problème.

Cordialement

Imberti

Pour l'instant, j'ai limité le paramètre « operateur »
aux valeurs "AND" ou "OR" ou "dist".

On peut envisager d'aller plus loin,
par exemple avec une valeur "prioritaire_si_true"
etc.

Cordialement

Imberti