Bonjour,

Dans le cadre de tests de montée en version GLPI 0.83 vers 0.84, j'ai
rencontré une régression dans l'application des règles "Automatic user
assignment" sur l'affectation des entités à partir d'une expression régulière
vérifiant le DN de l'utilisateur.

Le résultat de cette régression est que les entités affectées par expression
régulière se retrouvent tronquées (ex: Entité 11 => Entité 1, Entité 25 =>
Entité 2).

Je pense avoir réglé ce problème avec le patch ci-joint [0001-fix-and-clean-
ruleright-code.patch] applicable sur la
révision 21240 et la 0.84-RC3.

En parcourant le code relatif à ces règles (cf. inc/user.class.php,
inc/ruleright.class.php et inc/entity.class.php), j'ai aussi tenté d'améliorer 
certains points qui rendait la compréhension de ces règles compliquées :

- Le résultat de la méthode RuleRight::executeActions() renvoie actuellement 3
  tableaux nommés différemment en fonction de la présence d'entités et/ou de
  profils, qui sont ensuite traités différemment dans la fonction
  User::applyRightRules().
  J'ai simplifié le retour de la fonction RuleRight::executeActions() en ne
  renvoyant qu'un seul tableau et en déléguant les diverses conditions
  d'affectation uniquement à la méthode User::applyRightRules().

- La boucle foreach sur les résultats d'une expression régulière, dans
  RuleRight::executeActions() à la ligne 164 de inc/ruleright.class.php,
  suggère qu'il est possible d'affecter plusieurs entités avec une seule
  règle.
  Or je n'ai pas réussi à trouver comment configurer une règle permettant ce
  type de résultat puisque l'interface ne permet qu'une seule affectation
  d'entité par regexp.
  De plus, les résultats des critères regexp sont combinées (cf. ligne 1144
  dans inc/rule.class.php) en un seul tableau et le foreach ne fera qu'une
  seule passe peu importe le nombre de critères regexp utilisés.

.Exemple de règle:
==================
Logical Operator: AND

Criteria:
- (LDAP)Distinguished Name | regular expression matches | /(OU=Développeurs)/
- (LDAP)Distinguished Name | regular expression matches | /(OU=Laboratoire)/

Actions:
- Entity based on LDAP information | Assign value from regexp | #0

Input:
[userdn] => CN=Kevin Roy,OU=Développeurs,OU=Laboratoire,DC=teclib,DC=info

Result:
[RuleRight::executeActions()] => Array
(
   [this->regex_results] => Array
       (
           [0] => Array
               (
                   [0] => OU=Développeurs
                   [1] => OU=Laboratoire
               )
       )
)

==================

  J'ai donc remplacé cette boucle par une simple condition en me basant sur le
  cas "regex_result" de la méthode Rule::executeActions() qui traite la
  variable regex_results de cette même manière et qui est la plus récente
  source de code traitant de ce sujet.

Merci d'avance pour vos futurs retours sur ce patch,
Cheers,
-- 
Kevin 'kiniou' Roy
From 00ac8dabe4616d33801b35c5290cdbfd55a2fa1a Mon Sep 17 00:00:00 2001
From: Kevin Roy <kin...@gmail.com>
Date: Fri, 28 Jun 2013 14:31:12 +0200
Subject: [PATCH] fix (and clean) ruleright code

On import or synchronization, some rules were doing wrong entities assignment.
In order to solve this issue and also to make the code understandable for further contribution, I've
tried to simplify the different parts i've managed to understand.
---
 inc/ruleright.class.php | 112 +++++++++++++++++++-----------------------------
 inc/user.class.php      |  91 +++++++++++++++------------------------
 2 files changed, 78 insertions(+), 125 deletions(-)

diff --git a/inc/ruleright.class.php b/inc/ruleright.class.php
index 6e7f7f3..f3e2de3 100644
--- a/inc/ruleright.class.php
+++ b/inc/ruleright.class.php
@@ -119,10 +119,9 @@ class RuleRight extends Rule {
    function executeActions($output, $params) {
       global $CFG_GLPI;
 
-      $entity       = '';
-      $right        = '';
+      $entity       = array();
+      $profile      = 0;
       $is_recursive = 0;
-      $continue     = true;
       $output_src   = $output;
 
       if (count($this->actions)) {
@@ -132,7 +131,7 @@ class RuleRight extends Rule {
                case "assign" :
                   switch ($action->fields["field"]) {
                      case "entities_id" :
-                        $entity = $action->fields["value"];
+                        $entity[] = $action->fields["value"];
                         break;
 
                      case "profiles_id" :
@@ -155,80 +154,55 @@ class RuleRight extends Rule {
                   break;
 
                case "regex_result" :
-                  switch ($action->fields["field"]) {
-                     case "_affect_entity_by_dn" :
-                     case "_affect_entity_by_tag" :
-                     case "_affect_entity_by_domain" :
-                     case "_affect_entity_by_completename" :
-                        $entity = array();
-                        foreach ($this->regex_results as $regex_result) {
-                           $res = RuleAction::getRegexResultById($action->fields["value"],
-                                                                 $regex_result);
-                           if ($res != null) {
-                              switch ($action->fields["field"]) {
-                                 case "_affect_entity_by_dn" :
-                                    $entity_found = Entity::getEntityIDByDN($res);
-                                    break;
-
-                                 case "_affect_entity_by_tag" :
-                                    $entity_found = Entity::getEntityIDByTag($res);
-                                    break;
-
-                                 case "_affect_entity_by_domain" :
-                                    $entity_found = Entity::getEntityIDByDomain($res);
-                                    break;
-
-                                 case "_affect_entity_by_completename" :
-                                    $res          = Toolbox::unclean_cross_side_scripting_deep($res);
-                                    $entity_found = Entity::getEntityIDByCompletename($res);
-                                    break;
-
-                                 default:
-                                    $entity_found = -1;
-                                    break;
-                              }
-
-                              //If an entity was found
-                              if ($entity_found > -1) {
-                                 $entity[] = $entity_found;
-                              }
-                           }
+                  $entity = array();
+                  if (isset($this->regex_results[0]) ) {
+                     $regex_result = $this->regex_results[0];
+                     $res = RuleAction::getRegexResultById($action->fields["value"],
+                                                           $regex_result);
+                     if ($res != null) {
+                        switch ($action->fields["field"]) {
+                           case "_affect_entity_by_dn" :
+                              $entity_found = Entity::getEntityIDByDN($res);
+                              break;
+
+                           case "_affect_entity_by_tag" :
+                              $entity_found = Entity::getEntityIDByTag($res);
+                              break;
+
+                           case "_affect_entity_by_domain" :
+                              $entity_found = Entity::getEntityIDByDomain($res);
+                              break;
+
+                           case "_affect_entity_by_completename" :
+                              $res          = Toolbox::unclean_cross_side_scripting_deep($res);
+                              $entity_found = Entity::getEntityIDByCompletename($res);
+                              break;
+
+                           default:
+                              $entity_found = -1;
+                              break;
                         }
 
-                        if (!count($entity)) {
-                           //Not entity assigned : action processing must be stopped for this rule
-                           $continue = false;
+                        //If an entity was found
+                        if ($entity_found > -1) {
+                           $entity[] = $entity_found;
                         }
-                        break;
-                  } // switch (field)
+                     }
+                  }
                   break;
 
             } // switch (action_type)
-         } // foreach (action)
-      } // count (actions)
 
-      if ($continue) {
-         //Nothing to be returned by the function :
-         //Store in session the entity and/or right
-         if (($entity != '')
-             && ($right != '')) {
-            $output["_ldap_rules"]["rules_entities_rights"][] = array($entity, $right,
-                                                                      $is_recursive);
-         } else if ($entity != '') {
-
-            if (!is_array($entity)) {
-              $entities_array                            = array($entity, $is_recursive);
-              $output["_ldap_rules"]["rules_entities"][] = array($entities_array);
-
-            //If it comes from a regex with multiple results
-            } else {
-               $output["_ldap_rules"]["rules_entities"][] = $entity;
-            }
+         } // foreach (action)
 
-         } else if ($right != '') {
-            $output["_ldap_rules"]["rules_rights"][] = $right;
-         }
+      } // count (actions)
 
+      if (count($entity)> 0) {
+         $output["_ldap_rules"]["results"][] =  array(
+                                                   "entities_id"  => $entity,
+                                                   "is_recursive" => $is_recursive,
+                                                   "profiles_id"  => $right
+                                                );
          return $output;
       }
       return $output_src;
diff --git a/inc/user.class.php b/inc/user.class.php
index a2d08d7..15d8292 100644
--- a/inc/user.class.php
+++ b/inc/user.class.php
@@ -759,75 +759,54 @@ class User extends CommonDBTM {
              && count($this->input["_ldap_rules"])) {
 
             //and add/update/delete only if it's necessary !
-            if (isset($this->input["_ldap_rules"]["rules_entities_rights"])) {
-               $entities_rules = $this->input["_ldap_rules"]["rules_entities_rights"];
+            if (isset($this->input["_ldap_rules"]["results"])) {
+               $rules_results = $this->input["_ldap_rules"]["results"];
             } else {
-               $entities_rules = array();
-            }
-
-            if (isset($this->input["_ldap_rules"]["rules_entities"])) {
-               $entities = $this->input["_ldap_rules"]["rules_entities"];
-            } else {
-               $entities = array();
-            }
-
-            if (isset($this->input["_ldap_rules"]["rules_rights"])) {
-               $rights = $this->input["_ldap_rules"]["rules_rights"];
-            } else {
-               $rights = array();
+               $rules_results = array();
             }
 
             $retrieved_dynamic_profiles = array();
 
-            //For each affectation -> write it in DB
-            foreach ($entities_rules as $entity) {
-               //Multiple entities assignation
-               if (is_array($entity[0])) {
-                  foreach ($entity[0] as $tmp => $ent) {
-                     $affectation['entities_id']  = $ent;
-                     $affectation['profiles_id']  = $entity[1];
-                     $affectation['is_recursive'] = $entity[2];
-                     $affectation['users_id']     = $this->fields['id'];
-                     $affectation['is_dynamic']   = 1;
-
-                     $retrieved_dynamic_profiles[] = $affectation;
-                  }
-               } else {
-                  $affectation['entities_id']   = $entity[0];
-                  $affectation['profiles_id']   = $entity[1];
-                  $affectation['is_recursive']  = $entity[2];
-                  $affectation['users_id']      = $this->fields['id'];
-                  $affectation['is_dynamic']    = 1;
+            foreach ( $rules_results as $result ) {
 
-                  $retrieved_dynamic_profiles[] = $affectation;
+               $profiles_id = 0;
+               //Get Profile from action if any
+               if ( $result['profiles_id'] > 0 ) {
+                  $profiles_id = $result['profiles_id'];
+               } else {
+                  //If no profile from action, retrieve the default profile
+                  if ( $profile_def = Profile::getDefault() ) {
+                     $profiles_id = $profile_def;
+                  };
                }
-            }
 
-            if ((count($entities) > 0)
-                && (count($rights) == 0)) {
-               if ($def_prof = Profile::getDefault()) {
-                  $rights[] = $def_prof;
+               //If there are neither entities nor profiles, we continue the loop to the next
+               //action.
+               if(   count($result['entities_id']) == 0
+                     or $profiles_id == 0 ) {
+                  continue;
                }
-            }
 
-            if ((count($rights) > 0)
-                && (count($entities) > 0)) {
-               foreach ($rights as $right) {
-                  foreach ($entities as $entity_tab) {
-                     foreach ($entity_tab as $entity) {
-                        $affectation['entities_id']   = $entity[0];
-                        $affectation['profiles_id']   = $right;
-                        $affectation['users_id']      = $this->fields['id'];
-                        $affectation['is_recursive']  = $entity[1];
-                        $affectation['is_dynamic']    = 1;
-
-                        $retrieved_dynamic_profiles[] = $affectation;
-                     }
-                  }
+               /*****
+                * We loop through 'entities_id' list returned by RuleRight::executeActions()
+                * ... though IMHO there can only be one entity affected by one rule at a time
+                * and therefore we shouldn't use a foreach loop.
+                *                                                 -- Kevin 'kiniou' Roy
+                *****/
+
+               foreach ($result['entities_id'] as $entities_id) {
+
+                  $assignment = array();
+                  $assignment['users_id'] = $this->fields['id'];
+                  $assignment['is_dynamic'] = 1;
+                  $assignment['is_recursive'] = $result['is_recursive'];
+                  $assignment['profiles_id'] = $profiles_id;
+                  $assignment["entities_id"] = $entities_id;
+                  $retrieved_dynamic_profiles[] = $assignment;
                }
             }
 
-            // Compare retrived profiles to existing ones : clean arrays to do purge and add
+            // Compare retrieved profiles to existing ones : clean arrays to do purge and add
             if (count($retrieved_dynamic_profiles)) {
                foreach ($retrieved_dynamic_profiles as $keyretr => $retr_profile) {
                   $found = false;
-- 
1.8.3.1

_______________________________________________
Glpi-dev mailing list
Glpi-dev@gna.org
https://mail.gna.org/listinfo/glpi-dev

Reply via email to