From 38a4cd7b1580f2ba782f463c0580d40ea4a00490 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?C=C3=B4me=20Chilliet?= <come.chilliet@fusiondirectory.org>
Date: Thu, 20 Aug 2020 11:27:13 +0200
Subject: [PATCH] :sparkles: feat(management) Search also in template cn from
 search field

issue #6107
---
 include/class_ldapFilter.inc                  | 30 +++++++++++++++++--
 include/class_objects.inc                     |  7 ++++-
 include/management/class_managementFilter.inc |  6 +++-
 3 files changed, 39 insertions(+), 4 deletions(-)

diff --git a/include/class_ldapFilter.inc b/include/class_ldapFilter.inc
index 005a31e57..9e2ddf6fc 100644
--- a/include/class_ldapFilter.inc
+++ b/include/class_ldapFilter.inc
@@ -232,14 +232,19 @@ class ldapFilterLeaf extends ldapFilter
   }
 }
 
-function fdTemplateFilter ($filter)
+/* Converts a filter object to search for templates */
+function fdTemplateFilter (ldapFilter $filter)
 {
   if ($filter instanceof ldapFilterLeaf) {
     if ($filter->isDnFilter()) {
       return $filter;
     } elseif ($filter->getOperator() == '=') {
       $subparts = $filter->getSubparts();
-      return new ldapFilterLeaf('fdTemplateField', '=', $subparts[0].':'.$subparts[1]);
+      if ($subparts[0] == '_template_cn') {
+        return new ldapFilterLeaf('cn', '=', $subparts[1]);
+      } else {
+        return new ldapFilterLeaf('fdTemplateField', '=', $subparts[0].':'.$subparts[1]);
+      }
     } else {
       trigger_error('Not able to adapt this filter for templates');
     }
@@ -253,3 +258,24 @@ function fdTemplateFilter ($filter)
   }
   return $filter;
 }
+
+/* Removes parts specific to templates from a search filter */
+function fdNoTemplateFilter (ldapFilter $filter)
+{
+  if ($filter instanceof ldapFilterLeaf) {
+    if (!$filter->isDnFilter()) {
+      $subparts = $filter->getSubparts();
+      if ($subparts[0] == '_template_cn') {
+        return FALSE;
+      }
+    }
+  } else {
+    $subparts = $filter->getSubparts();
+    foreach ($subparts as &$subpart) {
+      $subpart = fdNoTemplateFilter($subpart);
+    }
+    unset($subpart);
+    return new ldapFilter($filter->getOperator(), array_filter($subparts));
+  }
+  return $filter;
+}
diff --git a/include/class_objects.inc b/include/class_objects.inc
index 68b1b6795..9646b52f0 100644
--- a/include/class_objects.inc
+++ b/include/class_objects.inc
@@ -36,9 +36,10 @@ class objects
    *  depending if you want a single value or an array of values. 'raw' means untouched LDAP value and is only useful for dns.
    *  Other values are considered to be 1. 'b64' means an array of base64 encoded values and is mainly useful through webservice for binary attributes.
    * \param string  $ou the LDAP branch to search in, base will be used if it is NULL
-   * \param string  $filter an additional filter to use in the LDAP search.
+   * \param string  $filter an additional filter to use in the LDAP search. (Might use special _template_cn field to search in template cn).
    * \param boolean $checkAcl should ACL be ignored or checked? Defaults to FALSE.
    * \param string  $scope scope, defaults to subtree. When using one, be careful what you put in $ou.
+   * \param boolean $templateSearch Whether to search for templates or normal objects.
    *
    * \return The list of objects as an associative array (keys are dns)
    */
@@ -283,6 +284,7 @@ class objects
         }
         $filterObject     = ldapFilter::parse($filter);
         $filterAttributes = $filterObject->listUsedAttributes();
+        unset($filterAttributes['_template_cn']);
         foreach ($filterAttributes as $acl) {
           $category = $ui->getAttributeCategory($types[0], $acl);
           if ($category === FALSE) {
@@ -310,6 +312,9 @@ class objects
         ]
       );
       $filter = "$templateFilterObject";
+    } else {
+      $filterObject = fdNoTemplateFilter(ldapFilter::parse($filter));
+      $filter       = "$filterObject";
     }
     $ldap->cd($ou);
     $ldap->search($filter, $search_attrs, $scope);
diff --git a/include/management/class_managementFilter.inc b/include/management/class_managementFilter.inc
index e0e36e705..b6fb054d3 100644
--- a/include/management/class_managementFilter.inc
+++ b/include/management/class_managementFilter.inc
@@ -204,7 +204,11 @@ class managementFilter
         if (preg_match('/^\(.+\)$/', $this->search)) {
           $elementFilters[] = $this->search;
         } else {
-          $elementFilters[] = '(|('.implode('=*'.$this->search.'*)(', $this->searchAttributes[$type]).'=*'.$this->search.'*))';
+          $searchAttributesTmp    = $this->searchAttributes[$type];
+          if ($this->showTemplates) {
+            $searchAttributesTmp[]  = '_template_cn';
+          }
+          $elementFilters[] = '(|('.implode('=*'.ldap_escape_f($this->search).'*)(', $searchAttributesTmp).'=*'.ldap_escape_f($this->search).'*))';
         }
       }
 
-- 
GitLab