summary | shortlog | log | commit | commitdiff | tree
raw | patch | inline | side by side (parent: a4ba270)
raw | patch | inline | side by side (parent: a4ba270)
author | cajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Thu, 6 Aug 2009 12:37:27 +0000 (12:37 +0000) | ||
committer | cajus <cajus@594d385d-05f5-0310-b6e9-bd551577e9d8> | |
Thu, 6 Aug 2009 12:37:27 +0000 (12:37 +0000) |
git-svn-id: https://oss.gonicus.de/repositories/gosa/trunk@13981 594d385d-05f5-0310-b6e9-bd551577e9d8
gosa-core/ihtml/themes/default/filter/users.tpl | [new file with mode: 0644] | patch | blob |
gosa-core/include/class_filter.inc | [new file with mode: 0755] | patch | blob |
gosa-core/include/class_filterLDAP.inc | [new file with mode: 0755] | patch | blob |
diff --git a/gosa-core/ihtml/themes/default/filter/users.tpl b/gosa-core/ihtml/themes/default/filter/users.tpl
--- /dev/null
@@ -0,0 +1,40 @@
+<div class="contentboxh">
+ <p class="contentboxh">
+ <img src="images/launch.png" align="right" alt="[F]">Filter
+ </p>
+</div>
+
+<div class="contentboxb">
+ <div style="border-top:1px solid #AAAAAA"></div>
+ {$ALPHABET}
+ <div style="border-top:1px solid #AAAAAA"></div>
+ {$TEMPLATE} {t}Show templates{/t}<br>
+ {$GENERIC} {t}Show functional users{/t}<br>
+ {$MAIL} {t}Show mail users{/t}<br>
+ {$POSIX} {t}Show POSIX users{/t}<br>
+ {$SAMBA} {t}Show samba users{/t}<br>
+ <div style="border-top:1px solid #AAAAAA"></div>
+ {$SCOPE}
+
+ <table summary="" style="width:100%;border-top:1px solid #B0B0B0;">
+ <tr>
+ <td>
+ <label for="Regex">
+ <img alt="Zeige die Benutzer, auf die Folgendes passt" src="images/lists/search.png" align=middle>
+ </label>
+ </td>
+ <td width="99%">
+ {$NAME}
+ </td>
+ </tr>
+ </table>
+
+ <table summary="" width="100%" style="background:#EEEEEE;border-top:1px solid #B0B0B0;">
+ <tr>
+ <td width="100%" align="right">
+ {$APPLY}
+ </td>
+ </tr>
+ </table>
+
+</div>
diff --git a/gosa-core/include/class_filter.inc b/gosa-core/include/class_filter.inc
--- /dev/null
@@ -0,0 +1,398 @@
+<?php
+
+class filter {
+
+ var $xmlData;
+ var $elements= array();
+ var $elementValues= array();
+ var $alphabetElements= array();
+ var $search;
+ var $definition;
+ var $category= "";
+ var $objectStorage= array();
+ var $objectBase= "";
+ var $base= "";
+ var $bases= array();
+ var $scope= "";
+ var $query;
+ var $baseMode= false;
+ var $scopeMode= "auto";
+ var $alphabet= null;
+ var $templatePath= "";
+ var $target= "";
+
+ function filter($filename)
+ {
+ if (!$this->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= "<input class='filter_textfield' name='$element' type='text' size='30' maxlength='30' value='".$this->elementValues[$element]."'>";
+ return $result;
+ }
+
+
+ function getCheckbox($element)
+ {
+ $checked= "";
+ if ($this->elementValues[$element] == "true") {
+ $checked= " checked";
+ }
+
+ $result= "<input class='filter_checkbox' name='$element' type='checkbox' onClick='document.mainform.submit();' value='true'$checked>";
+ return $result;
+ }
+
+
+ function getCombobox($element)
+ {
+ $result= "<select name='".$element->tag."' size='1' onClick='document.mainform.submit();'>";
+ foreach ($element->value as $key=>$value) {
+ $selected= "";
+ if ($this->elementValues[(string)$element->tag] == $value->key) {
+ $selected= " selected";
+ }
+ $result.= "<option value='".$value->key."'$selected>{t}".$value->set."{/t}</option>";
+ }
+ $result.= "</select>";
+
+ 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= "<select name='currentMainBase' onChange='mainform.submit()' size='1'>";
+
+ foreach ($this->bases as $key=>$value) {
+ $selected= "";
+ if ($key == $this->base) {
+ $selected= " selected";
+ }
+ $result.= "<option value='".$key."'$selected>".$value."</option>";
+ }
+ $result.= "</select>";
+
+ 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.= "<tr>";
+ }
+
+ $ch = mb_substr($characters, $i, 1, "UTF8");
+ $alphabet.= "<td><a class=\"alphaselect\" href=\"main.php?plug=".
+ validate($_GET['plug'])."&filter=".$ch."\"> ".$ch." </a></td>";
+
+ if ($c++ == $columns){
+ $alphabet.= "</tr>";
+ $c= 0;
+ }
+ }
+
+ /* Fill remaining cells */
+ while ($c++ <= $columns){
+ $alphabet.= "<td> </td>";
+ }
+
+ /* Save alphabet */
+ $this->alphabet= "<table width='100%'>$alphabet</table>";
+
+ return ($this->alphabet);
+ }
+
+
+ function renderApply()
+ {
+ return ("<input type='submit' name='apply' value='"._("Apply filter")."'>");
+ }
+
+
+ function renderScope()
+ {
+ $checked= $this->scope == "sub"?" checked":"";
+ return "<input type='checkbox' name='SCOPE' value='1' onClick='document.mainform.submit();'$checked> "._("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 ("<input type='hidden' name='FILTER_LOADED' value='1'>".$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
--- /dev/null
@@ -0,0 +1,237 @@
+<?php
+
+class filterLDAP {
+
+ static function query($base, $scope, $filter, $attributes, $category, $objectStorage= "", $objectBase= "")
+ {
+ global $config;
+
+ echo "Base: $base<br>";
+ echo "Scope: $scope<br>";
+ echo "filter: $filter<br>";
+ 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);
+ }
+
+}
+
+?>