diff --git a/include/class_objects.inc b/include/class_objects.inc index cc4e807de63a9c1c8310c26fa45585b4c6c8a1ea..9d4cb560d84f51f8a6d1ac89ae188e57b9da4f2b 100644 --- a/include/class_objects.inc +++ b/include/class_objects.inc @@ -42,7 +42,7 @@ class objects * * \return The list of objects as an associative array (keys are dns) */ - static function ls ($types, $attrs = NULL, $ou = NULL, $filter = '', $checkAcl = FALSE, $scope = 'subtree') + static function ls ($types, $attrs = NULL, $ou = NULL, $filter = '', $checkAcl = FALSE, $scope = 'subtree', $templateSearch = FALSE) { global $ui, $config; @@ -105,7 +105,7 @@ class objects } try { - $ldap = static::search($types, $search_attrs, $ou, $filter, $checkAcl, $scope, FALSE, $partialFilterAcls); + $ldap = static::search($types, $search_attrs, $ou, $filter, $checkAcl, $scope, $templateSearch, $partialFilterAcls); } catch (NonExistingBranchException $e) { return array(); } @@ -166,10 +166,10 @@ class objects * * \return The number of objects of type $type in $ou */ - static function count ($types, $ou = NULL, $filter = '', $checkAcl = FALSE) + static function count ($types, $ou = NULL, $filter = '', $checkAcl = FALSE, $templateSearch = FALSE) { try { - $ldap = static::search($types, array('dn'), $ou, $filter, $checkAcl, 'subtree', FALSE, $partialFilterAcls); + $ldap = static::search($types, array('dn'), $ou, $filter, $checkAcl, 'subtree', $templateSearch, $partialFilterAcls); if (!empty($partialFilterAcls)) { throw new FusionDirectoryException('Not enough rights to use "'.$partialFilterAcls[0][1].'" in filter'); } diff --git a/include/class_templateHandling.inc b/include/class_templateHandling.inc index 54c5f8ec7528cb2b9591fddcb289621f5d744421..d149e0e788ac6d3896713ab33c38f085a094fcde 100644 --- a/include/class_templateHandling.inc +++ b/include/class_templateHandling.inc @@ -45,17 +45,19 @@ class templateHandling /*! \brief Translate template attrs into $attrs as if taken from LDAP */ public static function fieldsFromLDAP (array $template_attrs) { - unset($template_attrs['fdTemplateField']['count']); - sort($template_attrs['fdTemplateField']); $attrs = array(); - foreach ($template_attrs['fdTemplateField'] as $field) { - preg_match('/^([^:]+):(.*)$/s', $field, $m); - if (isset($attrs[$m[1]])) { - $attrs[$m[1]][] = $m[2]; - $attrs[$m[1]]['count']++; - } else { - $attrs[$m[1]] = array($m[2]); - $attrs[$m[1]]['count'] = 1; + if (isset($template_attrs['fdTemplateField'])) { + unset($template_attrs['fdTemplateField']['count']); + sort($template_attrs['fdTemplateField']); + foreach ($template_attrs['fdTemplateField'] as $field) { + preg_match('/^([^:]+):(.*)$/s', $field, $m); + if (isset($attrs[$m[1]])) { + $attrs[$m[1]][] = $m[2]; + $attrs[$m[1]]['count']++; + } else { + $attrs[$m[1]] = array($m[2]); + $attrs[$m[1]]['count'] = 1; + } } } return $attrs; diff --git a/include/management/class_ListingEntry.inc b/include/management/class_ListingEntry.inc new file mode 100644 index 0000000000000000000000000000000000000000..694fc3c26c34a3d466201b1acb00d1d1368226d6 --- /dev/null +++ b/include/management/class_ListingEntry.inc @@ -0,0 +1,91 @@ +<?php +/* + This code is part of FusionDirectory (http://www.fusiondirectory.org/) + Copyright (C) 2017-2018 FusionDirectory + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +class ListingEntry implements ArrayAccess +{ + public $dn; + public $row; + public $type; + private $attrs; + protected $listing; + + public function __construct(managementListing $listing, $type, $dn, array $attrs, $row = NULL) { + $this->listing = $listing; + $this->type = $type; + $this->dn = $dn; + $this->attrs = $attrs; + $this->row = $row; + } + + public function offsetSet($offset, $value) { + if (is_null($offset)) { + $this->container[] = $value; + } else { + $this->attrs[$offset] = $value; + } + } + + public function offsetExists($offset) { + return isset($this->attrs[$offset]); + } + + public function offsetUnset($offset) { + unset($this->attrs[$offset]); + } + + public function offsetGet($offset) { + return (isset($this->attrs[$offset]) ? $this->attrs[$offset] : NULL); + } + + public function getPid() + { + return $this->listing->pid; + } + + public function isTemplate() + { + return preg_match('/^template_/', $this->type); + } + + public function getTemplatedType() + { + return preg_replace('/^template_/', '', $this->type); + } + + public function getTemplatedFields() + { + return templateHandling::fieldsFromLDAP($this->attrs); + } + + public function checkAcl($acls) + { + global $ui; + + $infos = objects::infos($this->getTemplatedType()); + $rights = $ui->get_permissions($this->dn, $infos['aclCategory'].'/'.($this->isTemplate() ? 'template' : $infos['mainTab'])); + foreach (str_split($acls) as $acl) { + if (strpos($rights, $acl) === FALSE) { + return FALSE; + } + } + + return TRUE; + } +} diff --git a/include/management/class_management.inc b/include/management/class_management.inc index 3991119fc3131db6c700fe41e4a44853cf5b4bbd..6e09ef3cba069b850c83abe1ec6691575f0659fe 100644 --- a/include/management/class_management.inc +++ b/include/management/class_management.inc @@ -53,6 +53,8 @@ class management public $neededAttrs = array(); + public static $skipTemplates = TRUE; + // Whether to display a header or not. protected $skipHeader = FALSE; @@ -444,6 +446,36 @@ class management return $str; } + function handleTemplateApply ($cancel = FALSE) + { + if (static::$skipTemplates) { + return; + } + if ($cancel) { + $msgs = array(); + } else { + $msgs = $this->tabObject->save(); + } + if (count($msgs)) { + msg_dialog::displayChecks($msgs); + return; + } else { + if (!$cancel) { + @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dn, 'Template applied!'); + } + del_lock($this->dn); + if (empty($this->dns)) { + $this->closeDialogs(); + } else { + $this->last_tabObject = $this->tabObject; + $this->tabObject = NULL; + $this->dn = array_shift($this->dns); + $this->dialogObject->setNextTarget($this->dn); + $this->dialogObject->save_object(); + } + } + } + /* Action handlers */ /*! @@ -485,14 +517,11 @@ class management $target = array_pop($action['targets']); - $type = $this->listing->getType($target); - if ($type === NULL) { - trigger_error('Could not find type for '.$target.', open canceled'); + $entry = $this->listing->getEntry($target); + if ($entry === NULL) { + trigger_error('Could not find '.$target.', open canceled'); return; } - //~ if (preg_match('/^template_/', $type) && !static::$skipTemplates) { - //~ $type = preg_replace('/^template_/', '', $type); - //~ } // Get the dn of the object and create lock $this->dn = $target; @@ -503,7 +532,7 @@ class management add_lock ($this->dn, $ui->dn); // Open object - $this->openTabObject(objects::open($this->dn, $type), $this->dn); + $this->openTabObject(objects::open($this->dn, $entry->getTemplatedType()), $this->dn); @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dn, 'Edit entry initiated'); if (isset($action['subaction'])) { if ($this->handleSubAction($action) == FALSE) { @@ -518,10 +547,10 @@ class management */ function cancelEdit() { - //~ if (($this->tabObject instanceOf simpleTabs) && ($this->dialogObject instanceOf templateDialog)) { - //~ $this->handleTemplateApply(TRUE); - //~ return; - //~ } + if (($this->tabObject instanceOf simpleTabs) && ($this->dialogObject instanceOf templateDialog)) { + $this->handleTemplateApply(TRUE); + return; + } $this->remove_lock(); $this->closeDialogs(); } @@ -533,11 +562,11 @@ class management */ function saveChanges() { - //~ if (($this->tabObject instanceOf simpleTabs) && ($this->dialogObject instanceOf templateDialog)) { - //~ $this->tabObject->save_object(); - //~ $this->handleTemplateApply(); - //~ return; - //~ } + if (($this->tabObject instanceOf simpleTabs) && ($this->dialogObject instanceOf templateDialog)) { + $this->tabObject->save_object(); + $this->handleTemplateApply(); + return; + } if ($this->tabObject instanceOf simpleTabs) { $this->tabObject->save_object(); $msgs = $this->tabObject->save(); @@ -594,14 +623,9 @@ class management // Check permissons for each target foreach ($action['targets'] as $dn) { - $type = $this->listing->getType($dn); - //~ if (preg_match('/^template_/', $type) && !static::$skipTemplates) { - //~ $type = preg_replace('/^template_/', '', $type); - //~ } + $entry = $this->listing->getEntry($dn); try { - $info = objects::infos($type); - $acl = $ui->get_permissions($dn, $info['aclCategory'].'/'.$info['mainTab']); - if (preg_match('/d/', $acl)) { + if ($entry->checkAcl('d')) { $this->dns[] = $dn; } else { $disallowed[] = $dn; @@ -625,19 +649,15 @@ class management $objects = array(); foreach ($this->dns as $dn) { $entry = $this->listing->getEntry($dn); - $type = $entry->type; - if (preg_match('/^template_/', $type) && !static::$skipTemplates) { - $type = preg_replace('/^template_/', '', $type); - $info = objects::infos($type); - $info['nameAttr'] = 'cn'; - } else { - $info = objects::infos($type); + $infos = objects::infos($entry->getTemplatedType()); + if ($entry->isTemplate()) { + $infos['nameAttr'] = 'cn'; } $objects[] = array( - 'name' => $entry[$info['nameAttr']], + 'name' => $entry[$infos['nameAttr']], 'dn' => $dn, - 'icon' => $info['icon'], - 'type' => $info['name'] + 'icon' => $infos['icon'], + 'type' => $infos['name'] ); } add_lock ($this->dns, $ui->dn); @@ -659,20 +679,14 @@ class management @DEBUG (DEBUG_TRACE, __LINE__, __FUNCTION__, __FILE__, $this->dns, 'Entry deletion confirmed'); foreach ($this->dns as $dn) { - $type = $this->listing->getType($dn); - if (empty($type)) { + $entry = $this->listing->getEntry($dn); + if (empty($entry)) { continue; } - //~ if (preg_match('/^template_/', $type) && !static::$skipTemplates) { - //~ $type = preg_replace('/^template_/', '', $type); - //~ } - $infos = objects::infos($type); - // Check permissions, are we allowed to remove this object? - $acl = $ui->get_permissions($dn, $infos['aclCategory'].'/'.$infos['mainTab']); - if (preg_match('/d/', $acl)) { + if ($entry->checkAcl('d')) { // Delete the object $this->dn = $dn; - $this->openTabObject(objects::open($this->dn, $type), $this->dn); + $this->openTabObject(objects::open($this->dn, $entry->getTemplatedType()), $this->dn); $this->tabObject->delete(); // Remove the lock for the current object. diff --git a/include/management/class_managementAction.inc b/include/management/class_managementAction.inc index b3ef2870af04474f8632451311919346480af7fb..e2c2f712f8bd884ecf455850ef2e7a072291932a 100644 --- a/include/management/class_managementAction.inc +++ b/include/management/class_managementAction.inc @@ -136,7 +136,7 @@ class Action } // Skip the entry completely if there's no permission to execute it - if (!$this->hasPermission($entry->dn, $entry->type)) { + if (!$this->hasPermission($entry->dn, $entry->getTemplatedType(), $entry->isTemplate())) { return '<img src="images/empty.png" alt=" " class="center optional"/>'; } @@ -148,7 +148,7 @@ class Action ' title="'.$this->label.'" alt="'.$this->label.'" name="listing_'.$this->name.'_'.$entry->row.'"/>'; } - function hasPermission($dn, $type) + function hasPermission($dn, $type, $template) { global $ui; @@ -160,7 +160,11 @@ class Action $checkAcl = $ui->get_permissions($dn, $module, $m[1]); $acl = $m[2]; } else { - $module = $infos['aclCategory'].'/'.$infos['mainTab']; + if ($template) { + $module = $infos['aclCategory'].'/template'; + } else { + $module = $infos['aclCategory'].'/'.$infos['mainTab']; + } $checkAcl = $ui->get_permissions($dn, $module, '0'); } diff --git a/include/management/class_managementColumn.inc b/include/management/class_managementColumn.inc index e0442a44b47b46771f91e5311fbb40932a6cb5e4..3f527a6a7762d94128dc3db82e4fc8b5b39890fd 100644 --- a/include/management/class_managementColumn.inc +++ b/include/management/class_managementColumn.inc @@ -27,6 +27,8 @@ class StringColumn protected $label; protected $type = 'string'; + protected $templateAttribute = NULL; + /* management class instance */ protected $parent = NULL; @@ -36,6 +38,11 @@ class StringColumn $this->label = $label; } + function setTemplateAttribute($attribute) + { + $this->templateAttribute = $attribute; + } + function setParent(managementListing $parent) { $this->parent = $parent; @@ -79,8 +86,12 @@ class StringColumn function renderCell(ListingEntry $entry) { - if (isset($this->attribute) && isset($entry[$this->attribute])) { - return htmlentities($entry[$this->attribute], ENT_COMPAT, 'UTF-8'); + $attribute = $this->attribute; + if (isset($this->templateAttribute) && $entry->isTemplate()) { + $attribute = $this->templateAttribute; + } + if (isset($attribute) && isset($entry[$attribute])) { + return htmlentities($entry[$attribute], ENT_COMPAT, 'UTF-8'); } else { return ' '; } @@ -155,8 +166,12 @@ class LinkColumn extends StringColumn { function renderCell(ListingEntry $entry) { - if (isset($entry[$this->attribute])) { - return '<a href="?plug='.$_GET['plug'].'&PID='.$entry->getPid().'&act=listing_edit_'.$entry->row.'" title="'.$entry->dn.'">'.htmlentities($entry[$this->attribute], ENT_COMPAT, 'UTF-8').'</a>'; + $attribute = $this->attribute; + if (isset($this->templateAttribute) && $entry->isTemplate()) { + $attribute = $this->templateAttribute; + } + if (isset($entry[$attribute])) { + return '<a href="?plug='.$_GET['plug'].'&PID='.$entry->getPid().'&act=listing_edit_'.$entry->row.'" title="'.$entry->dn.'">'.htmlentities($entry[$attribute], ENT_COMPAT, 'UTF-8').'</a>'; } else { return ' '; } @@ -172,7 +187,10 @@ class ObjectTypeColumn extends StringColumn function renderCell(ListingEntry $entry) { - if ($entry->type) { + if ($entry->isTemplate()) { + $infos = objects::infos($entry->getTemplatedType()); + return '<img class="center" title="'.$entry->dn.'" src="'.htmlentities('geticon.php?context=devices&icon=template&size=16', ENT_COMPAT, 'UTF-8').'" alt="'.sprintf(_('%s template'), $infos['name']).'"/>'; + } elseif ($entry->type) { $infos = objects::infos($entry->type); return '<img class="center" title="'.$entry->dn.'" src="'.htmlentities($infos['icon'], ENT_COMPAT, 'UTF-8').'" alt="'.$infos['name'].'"/>'; } else { @@ -215,7 +233,7 @@ class PropertiesColumn extends StringColumn { global $config; - $infos = objects::infos($entry->type); + $infos = objects::infos($entry->getTemplatedType()); static $tabs = array(); @@ -239,11 +257,13 @@ class PropertiesColumn extends StringColumn 'alt="'.$pInfos['plShortName'].'" title="'.$pInfos['plShortName'].'" '. 'name="listing_edit_tab_'.$infos['mainTab'].'_'.$entry->row.'"/>'; if (!empty($entry)) { - //~ if (in_array_ics ('fdTemplate', $attrs['objectClass'])) { - //~ $attrs = templateHandling::fieldsFromLDAP($attrs); - //~ } + if ($entry->isTemplate()) { + $attrs = $entry->getTemplatedFields(); + } else { + $attrs = $entry; + } foreach ($tabs[$entry->type] as $class => $tab) { - if ($tab->is_this_account($entry)) { + if ($tab->is_this_account($attrs)) { $pInfos = pluglist::pluginInfos($class); if (isset($pInfos['plSmallIcon'])) { $result .= '<input class="center" type="image" src="'.htmlentities($pInfos['plSmallIcon'], ENT_COMPAT, 'UTF-8').'" '. diff --git a/include/management/class_managementListing.inc b/include/management/class_managementListing.inc index ad90979be3b08b13f8ff536f0ffe07882d4dbadf..2c3fb8b48495828d93a2abc324918de9d80a1432 100644 --- a/include/management/class_managementListing.inc +++ b/include/management/class_managementListing.inc @@ -114,48 +114,6 @@ class entrySortIterator implements Iterator { } } -class ListingEntry implements ArrayAccess -{ - public $dn; - public $row; - public $type; - private $attrs; - protected $listing; - - public function __construct(managementListing $listing, $type, $dn, array $attrs, $row = NULL) { - $this->listing = $listing; - $this->type = $type; - $this->dn = $dn; - $this->attrs = $attrs; - $this->row = $row; - } - - public function offsetSet($offset, $value) { - if (is_null($offset)) { - $this->container[] = $value; - } else { - $this->attrs[$offset] = $value; - } - } - - public function offsetExists($offset) { - return isset($this->attrs[$offset]); - } - - public function offsetUnset($offset) { - unset($this->attrs[$offset]); - } - - public function offsetGet($offset) { - return (isset($this->attrs[$offset]) ? $this->attrs[$offset] : NULL); - } - - public function getPid() - { - return $this->listing->pid; - } -} - /*! * \brief This class handles the entries list for a management instance */ @@ -167,8 +125,6 @@ class managementListing //~ var $departmentBrowser = FALSE; //~ var $departmentRootVisible = FALSE; public $multiSelect = TRUE; - //~ var $template; - //~ var $headline; protected $base; protected $sortDirection = NULL; @@ -263,6 +219,8 @@ class managementListing foreach ($this->columns as $column) { $column->setParent($this); } + + $this->columns[1]->setTemplateAttribute('cn'); } /*! @@ -467,36 +425,6 @@ class managementListing $result .= '</script>'; return $result; - - //~ $smarty = get_smarty(); - //~ $smarty->assign("usePrototype", "true"); - //~ $smarty->assign("FILTER", $this->filter->render()); - //~ $smarty->assign("SIZELIMIT", print_sizelimit_warning()); - //~ $smarty->assign("LIST", $result); - //~ $smarty->assign("MULTISELECT", $this->multiSelect); - - //~ // Assign navigation elements - //~ $nav = $this->renderNavigation(); - //~ foreach ($nav as $key => $html) { - //~ $smarty->assign($key, $html); - //~ } - - //~ // Assign action menu / base - //~ $smarty->assign("ACTIONS", $this->renderActionMenu()); - //~ $smarty->assign("BASE", $this->renderBase()); - - //~ // Assign summary - //~ $smarty->assign("HEADLINE", $this->headline); - - //~ // Try to load template from plugin the folder first... - //~ $file = get_template_path($this->xmlData['definition']['template'], TRUE); - - //~ // ... if this fails, try to load the file from the theme folder. - //~ if (!file_exists($file)) { - //~ $file = get_template_path($this->xmlData['definition']['template']); - //~ } - - //~ return $smarty->fetch($file); } /*! @@ -617,6 +545,15 @@ class managementListing foreach ($entries as $dn => $entry) { $this->entries[$dn] = new ListingEntry($this, $type, $dn, $entry, $row++); } + + if (!$this->parent::$skipTemplates) { + $entries = objects::ls($type, $attrsAsked, 'ou=templates,'.$base, '', TRUE, 'one', TRUE); + + $this->objectTypeCount['template_'.$type] = count($entries); + foreach ($entries as $dn => $entry) { + $this->entries[$dn] = new ListingEntry($this, 'template_'.$type, $dn, $entry, $row++); + } + } } /* Store the order of the entries to access them by index later */ $this->entriesIndex = array_keys($this->entries); diff --git a/plugins/admin/users/class_userManagement.inc b/plugins/admin/users/class_userManagement.inc index af2c2d11445ed4d196437dbe0e394df79dfed207..b4471d766e8a27c7522aa5a0d540f0bee207d5dd 100644 --- a/plugins/admin/users/class_userManagement.inc +++ b/plugins/admin/users/class_userManagement.inc @@ -82,7 +82,7 @@ class LockAction extends Action } // Skip the entry completely if there's no permission to execute it - if (!$this->hasPermission($entry->dn, $entry->type)) { + if (!$this->hasPermission($entry->dn, $entry->getTemplatedType(), $entry->isTemplate())) { return '<img src="images/empty.png" alt=" " class="center optional"/>'; } @@ -104,6 +104,8 @@ class userManagement extends management { public $neededAttrs = array('userPassword' => '1'); + public static $skipTemplates = FALSE; + static function plInfo() { return array(