From 41cb28d90c89c00d2dad8280675497becf101caa Mon Sep 17 00:00:00 2001 From: cajus Date: Thu, 6 Aug 2009 12:37:27 +0000 Subject: [PATCH] Added a filter preparation files git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@13981 594d385d-05f5-0310-b6e9-bd551577e9d8 --- .../ihtml/themes/default/filter/users.tpl | 40 ++ gosa-core/include/class_filter.inc | 398 ++++++++++++++++++ gosa-core/include/class_filterLDAP.inc | 237 +++++++++++ 3 files changed, 675 insertions(+) create mode 100644 gosa-core/ihtml/themes/default/filter/users.tpl create mode 100755 gosa-core/include/class_filter.inc create mode 100755 gosa-core/include/class_filterLDAP.inc diff --git a/gosa-core/ihtml/themes/default/filter/users.tpl b/gosa-core/ihtml/themes/default/filter/users.tpl new file mode 100644 index 000000000..7ef964afd --- /dev/null +++ b/gosa-core/ihtml/themes/default/filter/users.tpl @@ -0,0 +1,40 @@ +
+

+ [F]Filter +

+
+ +
+
+ {$ALPHABET} +
+ {$TEMPLATE} {t}Show templates{/t}
+ {$GENERIC} {t}Show functional users{/t}
+ {$MAIL} {t}Show mail users{/t}
+ {$POSIX} {t}Show POSIX users{/t}
+ {$SAMBA} {t}Show samba users{/t}
+
+ {$SCOPE} + + + + + + +
+ + + {$NAME} +
+ + + + + +
+ {$APPLY} +
+ +
diff --git a/gosa-core/include/class_filter.inc b/gosa-core/include/class_filter.inc new file mode 100755 index 000000000..b0e859650 --- /dev/null +++ b/gosa-core/include/class_filter.inc @@ -0,0 +1,398 @@ +load($filename)) { + die("Cannot parse $filename!"); + } + } + + function load($filename) + { + // Load data into array + $xmlData= simplexml_load_file($filename); + if ($xmlData === false) { + return false; + } + + // Load definition + if (isset($xmlData->definition)) { + foreach ($xmlData->definition as $entry) { + if (!isset($entry->target) || !isset($entry->template)) { + return false; + } + + // Move information + $this->templatePath= (string)$entry->template; + $this->target= (string)$entry->target; + + // One is enough + break; + } + } + + // Load filter + if (isset($xmlData->search)) { + foreach ($xmlData->search as $entry) { + if (!isset($entry->query) || !isset($entry->base) || !isset($entry->scope)) { + return false; + } + + // Move information + $this->baseMode= (string)$entry->base; + $this->scopeMode= (string)$entry->scope; + $this->query= $entry->query; + + // One is enough + break; + } + } + + // Generate formular data + if (isset($xmlData->element)) { + foreach ($xmlData->element as $element) { + + // Ignore elements without type + if (!isset($element->type)) { + next; + } + + $tag= (string)$element->tag; + + // Store element for quick access + $this->elements[$tag] = $element; + + // Preset elementValues with default values if exist + if (isset($element->default)) { + $this->elementValues[$tag] = (string)$element->default; + } else { + $this->elementValues[$tag] = ""; + } + + // Does this element react on alphabet links? + if (isset($element->alphabet) && (string)$element->alphabet == "true") { + $this->alphabetElements[]= $tag; + } + } + } + + // Save definition + if (isset($xmlData->definition)) { + $this->definition = $xmlData->definition; + } + + // Save search + if (isset($xmlData->search)) { + $this->search = $xmlData->search; + } + + return true; + } + + + function getTextfield($element) + { + $result= ""; + return $result; + } + + + function getCheckbox($element) + { + $checked= ""; + if ($this->elementValues[$element] == "true") { + $checked= " checked"; + } + + $result= ""; + return $result; + } + + + function getCombobox($element) + { + $result= ""; + + return $result; + } + + + function getCurrentBase() + { + if (isset($this->search->base) && (string)$this->search->scope != "auto") { + return false; + } + + return $this->base; + } + + + function getCurrentScope() + { + if (isset($this->search->scope) && (string)$this->search->scope != "auto") { + return (string)$this->search->scope; + } + + return $this->scope; + } + + + function setBases($bases) { + $this->bases= $bases; + } + + + function setObjectStorage($storage) { + $this->objectStorage= $storage; + } + + + function setObjectBase($base) { + $this->objectBase= $base; + } + + + function setCategory($category) { + $this->category= $category; + } + + + function setCurrentBase($base) { + $this->base= $base; + } + + + function setCurrentScope($scope) { + $this->scope= $scope; + } + + + function renderBase() + { + $result= ""; + + return $result; + } + + + function renderAlphabet($columns= 10) + { + // Return pre-rendered alphabet if available + if ($this->alphabet) { + return ($this->alphabet); + } + + $characters= _("*ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"); + $alphabet= ""; + $c= 0; + + /* Fill cells with charaters */ + for ($i= 0, $l= mb_strlen($characters, 'UTF8'); $i<$l; $i++){ + if ($c == 0){ + $alphabet.= ""; + } + + $ch = mb_substr($characters, $i, 1, "UTF8"); + $alphabet.= " ".$ch." "; + + if ($c++ == $columns){ + $alphabet.= ""; + $c= 0; + } + } + + /* Fill remaining cells */ + while ($c++ <= $columns){ + $alphabet.= " "; + } + + /* Save alphabet */ + $this->alphabet= "$alphabet
"; + + return ($this->alphabet); + } + + + function renderApply() + { + return (""); + } + + + function renderScope() + { + $checked= $this->scope == "sub"?" checked":""; + return " "._("Search in subtrees"); + } + + + function renderFilter() + { + $smarty= get_smarty(); + $smarty->assign("ALPHABET", $this->renderAlphabet()); + $smarty->assign("APPLY", $this->renderApply()); + $smarty->assign("SCOPE", $this->renderScope()); + $smarty->assign("BASE", $this->renderBase()); + + // Load template and replace elementsHtml[] + foreach ($this->elements as $tag => $element) { + $htmlCode= ""; + switch ($element->type) { + case "textfield": + $htmlCode = $this->getTextfield($tag); + break; + + case "checkbox": + $htmlCode = $this->getCheckbox($tag); + break; + + case "combobox": + $htmlCode = $this->getCombobox($element); + break; + + default: + die ("Unknown element type specified!"); + } + $smarty->assign("$tag", $htmlCode); + } + + // Load template + return ("".$smarty->fetch(get_template_path("filter/$this->templatePath"))); + } + + + function query() + { + global $class_mapping; + $result= array(); + + // Go thru all queries and merge results + foreach ($this->query as $query) { + if (!isset($query->backend) || !isset($query->filter) || !isset($query->attribute)) { + die("No backend specified in search config."); + } + + // Is backend available? + $backend= "filter".(string)$query->backend; + if (!isset($class_mapping["$backend"])) { + die("Invalid backend specified in search config."); + } + + // Load filter and attributes + $filter= $query->filter; + $attributes= array(); + foreach($query->attribute as $attr) { + $attributes[]= (string)$attr; + } + + // Generate final filter + foreach ($this->elements as $tag => $element) { + $e_set= (string)$element->set; + $e_unset= (string)$element->unset; + + if ($this->elementValues[$tag] == "") { + $e_unset= preg_replace('/\$/', $this->elementValues[$tag], $e_unset); + $filter= preg_replace("/\\$$tag/", $e_unset, $filter); + } else { + $e_set= preg_replace('/\$/', $this->elementValues[$tag], $e_set); + $filter= preg_replace("/\\$$tag/", $e_set, $filter); + } + } + + $result= call_user_func(array($backend, 'query'), $this->base, $this->scope, $filter, $attributes, + $this->category, $this->objectStorage, $this->objectBase); + } + + + return ($result); + } + + + function isValid() + { + return (false); + } + + + function update() + { + + /* React on alphabet links if needed */ + if (isset($_GET['filter'])){ + $s= mb_substr(validate($_GET['filter']), 0, 1, "UTF8")."*"; + if ($s == "**"){ + $s= "*"; + } + foreach ($this->alphabetElements as $tag) { + $this->elementValues[$tag]= $s; + } + } + + if (isset($_POST['FILTER_LOADED'])) { + // Load post values and adapt filter, base and scope accordingly - but + // only if we didn't get a _GET + foreach ($this->elements as $tag => $element) { + if (isset($_POST[$tag])){ + $this->elementValues[$tag]= validate($_POST[$tag]); + } else { + $this->elementValues[$tag]= ""; + } + } + } + + // Save base + if (isset($_POST['BASE']) && $this->baseMode == "true") { + $base= validate($_POST['BASE']); + if (isset($this->bases[$base])) { + $this->base= $base; + } + } + + // Save scope if needed + if ($this->scopeMode == "auto") { + $this->scope= isset($_POST['SCOPE'])?"sub":"one"; + } + } + +} + +?> diff --git a/gosa-core/include/class_filterLDAP.inc b/gosa-core/include/class_filterLDAP.inc new file mode 100755 index 000000000..12983d798 --- /dev/null +++ b/gosa-core/include/class_filterLDAP.inc @@ -0,0 +1,237 @@ +"; + echo "Scope: $scope
"; + echo "filter: $filter
"; + print_a($attributes); + + $ldap= $config->get_ldap_link(TRUE); + + $result= filterLDAP::get_list($base, $scope, $filter, $attributes, + $category, $objectStorage, $objectBase, + GL_SUBSEARCH | GL_SIZELIMIT); + return $result; + } + + + static function get_list($base, $scope, $filter, $attributes, $category, + $objectStorage= array(), $objectBase= "", $flags= GL_SUBSEARCH) + { + global $config, $ui; + $departments= array(); + + /* Get LDAP link */ + $ldap= $config->get_ldap_link($flags & GL_SIZELIMIT); + + /* If we do no subsearch, adapt */ + if ($scope != "sub") { + if ($objectBase != "") { + $base= preg_replace('/,$/', '', $objectBase).",".$base; + } elseif (is_string($objectStorage)) { + $base= preg_replace('/,$/', '', $objectStorage).",".$base; + } + } + + /* Set search base to configured base if $base is empty */ + if ($base == ""){ + $base = $config->current['BASE']; + } + $ldap->cd ($base); + + /* Ensure we have an array as storage list */ + if(is_string($objectStorage)){ + $objectStorage = array($objectStorage); + } + + /* Remove ,.*$ ("ou=1,ou=2.." => "ou=1") */ + $sub_bases = array(); + foreach($objectStorage as $key => $sub_base){ + if(empty($sub_base)){ + + /* Subsearch is activated and we got an empty sub_base. + * (This may be the case if you have empty people/group ous). + * Fall back to old get_list(). + * A log entry will be written. */ + if($flags & GL_SUBSEARCH){ + $sub_bases = array(); + break; + }else{ + + /* Do NOT search within subtrees is requested and the sub base is empty. + * Append all known departments that matches the base. */ + $departments[$base] = $base; + } + }else{ + $sub_bases[$key] = preg_replace("/,.*$/","",$sub_base); + } + } + + // If there is no sub_department specified, fall back to old method, get_list(). + if(!count($sub_bases) && !count($departments)){ + + // Log this fall back, it may be an unpredicted behaviour. + if(!count($sub_bases) && !count($departments)){ + new log("debug","all",__FILE__,$attributes, + sprintf("filterLDAP::get_list(): falling back to filterLDAP::get_list_old() because objectStorage is empty.". + " This may slow down GOsa. Filter was: '%s'", $filter)); + } + return (ldapFILTER::get_list_old($filter, $category,$base,$attributes,$flags)); + } + + /* Get all deparments matching the given sub_bases */ + $base_filter= ""; + foreach($sub_bases as $sub_base){ + $base_filter .= "(".$sub_base.")"; + } + $base_filter = "(&(objectClass=organizationalUnit)(|".$base_filter."))"; + $ldap->search($base_filter, array("dn")); + while($attrs = $ldap->fetch()){ + foreach($objectStorage as $sub_dep){ + + /* Only add those departments that match the reuested list of departments. + * + * e.g. sub_deps = array("ou=servers,ou=systems,"); + * + * In this case we have search for "ou=servers" and we may have also fetched + * departments like this "ou=servers,ou=blafasel,..." + * Here we filter out those blafasel departments. + */ + if(preg_match("/".preg_quote($sub_dep, '/')."/",$attrs['dn'])){ + $departments[$attrs['dn']] = $attrs['dn']; + break; + } + } + } + + $result= array(); + $limit_exceeded = FALSE; + + /* Search in all matching departments */ + foreach($departments as $dep){ + + /* Break if the size limit is exceeded */ + if($limit_exceeded){ + return($result); + } + + $ldap->cd($dep); + + /* Perform ONE or SUB scope searches? */ + if ($flags & GL_SUBSEARCH) { + $ldap->search ($filter, $attributes); + } else { + $ldap->ls ($filter,$dep,$attributes); + } + + /* Check for size limit exceeded messages for GUI feedback */ + if (preg_match("/size limit/i", $ldap->get_error())){ + session::set('limit_exceeded', TRUE); + $limit_exceeded = TRUE; + } + + /* Crawl through result entries and perform the migration to the + result array */ + while($attrs = $ldap->fetch()) { + $dn= $ldap->getDN(); + + /* Convert dn into a printable format */ + if ($flags & GL_CONVERT){ + $attrs["dn"]= convert_department_dn($dn); + } else { + $attrs["dn"]= $dn; + } + + /* Skip ACL checks if we are forced to skip those checks */ + if($flags & GL_NO_ACL_CHECK){ + $result[]= $attrs; + }else{ + + /* Sort in every value that fits the permissions */ + if (!is_array($category)){ + $category = array($category); + } + foreach ($category as $o){ + if((preg_match("/\//",$o) && preg_match("/r/",$ui->get_permissions($dn,$o))) || + (!preg_match("/\//",$o) && preg_match("/r/",$ui->get_category_permissions($dn, $o)))){ + $result[]= $attrs; + break; + } + } + } + } + } + + return($result); + } + + + function get_list_old($filter, $category, $base= "", $attributes= array(), $flags= GL_SUBSEARCH) + { + global $config, $ui; + + /* Get LDAP link */ + $ldap= $config->get_ldap_link($flags & GL_SIZELIMIT); + + /* Set search base to configured base if $base is empty */ + if ($base == ""){ + $ldap->cd ($config->current['BASE']); + } else { + $ldap->cd ($base); + } + + /* Perform ONE or SUB scope searches? */ + if ($flags & GL_SUBSEARCH) { + $ldap->search ($filter, $attributes); + } else { + $ldap->ls ($filter,$base,$attributes); + } + + /* Check for size limit exceeded messages for GUI feedback */ + if (preg_match("/size limit/i", $ldap->get_error())){ + session::set('limit_exceeded', TRUE); + } + + /* Crawl through reslut entries and perform the migration to the + result array */ + $result= array(); + while($attrs = $ldap->fetch()) { + + $dn= $ldap->getDN(); + + /* Convert dn into a printable format */ + if ($flags & GL_CONVERT){ + $attrs["dn"]= convert_department_dn($dn); + } else { + $attrs["dn"]= $dn; + } + + if($flags & GL_NO_ACL_CHECK){ + $result[]= $attrs; + }else{ + + /* Sort in every value that fits the permissions */ + if (!is_array($category)){ + $category = array($category); + } + foreach ($category as $o){ + if((preg_match("/\//",$o) && preg_match("/r/",$ui->get_permissions($dn,$o))) || + (!preg_match("/\//",$o) && preg_match("/r/",$ui->get_category_permissions($dn, $o)))){ + $result[]= $attrs; + break; + } + } + } + } + + return ($result); + } + +} + +?> -- 2.30.2