From cb726db08b10b2b9becb096ec597973412f265f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?C=C3=B4me=20Chilliet?= <come@opensides.be> Date: Tue, 5 Jul 2016 10:05:31 +0200 Subject: [PATCH] Fixes #4970 Trying to fix the way base ACL is handled and to allow use of templates in any base --- include/class_CopyPasteHandler.inc | 6 ++-- include/class_template.inc | 5 +++- include/class_userinfo.inc | 20 ++++++------- include/simpleplugin/class_attribute.inc | 11 ++++--- include/simpleplugin/class_simplePlugin.inc | 33 +++++++++++++++++++-- 5 files changed, 52 insertions(+), 23 deletions(-) diff --git a/include/class_CopyPasteHandler.inc b/include/class_CopyPasteHandler.inc index fb0fb71c4..f410e1940 100644 --- a/include/class_CopyPasteHandler.inc +++ b/include/class_CopyPasteHandler.inc @@ -221,11 +221,11 @@ class CopyPasteHandler $msgs = $entry['object']->check(); /* To copy an object we require full read access to the object category */ - $copy_acl = preg_match("/r/", $ui->has_complete_category_acls($entry['dn'], $entry['tab_acl_category'])); + $copy_acl = preg_match("/r/", $ui->get_complete_category_acls($entry['dn'], $entry['tab_acl_category'])); /* In order to copy an object we require read an delete acls */ - $cut_acl = preg_match("/d/", $ui->has_complete_category_acls($entry['dn'], $entry['tab_acl_category'])); - $cut_acl &= preg_match("/r/", $ui->has_complete_category_acls($entry['dn'], $entry['tab_acl_category'])); + $cut_acl = preg_match("/d/", $ui->get_complete_category_acls($entry['dn'], $entry['tab_acl_category'])); + $cut_acl &= preg_match("/r/", $ui->get_complete_category_acls($entry['dn'], $entry['tab_acl_category'])); /* Check permissions */ if ($entry['method'] == "copy" && !$copy_acl) { diff --git a/include/class_template.inc b/include/class_template.inc index 7838b6095..525e38260 100644 --- a/include/class_template.inc +++ b/include/class_template.inc @@ -49,6 +49,7 @@ class template $this->dn = $dn; list($this->attrs, $depends) = plugin::tpl_fetch_template($this->dn); $this->needed = plugin::tpl_needed_attrs($this->attrs, $depends); + $this->needed[] = 'base'; if ($targetdn === NULL) { $this->tabObject = objects::create($this->type); } else { @@ -79,6 +80,7 @@ class template { list($this->attrs, $depends) = plugin::tpl_fetch_template($this->dn); $this->needed = plugin::tpl_needed_attrs($this->attrs, $depends); // This is needed because it removes %askme% values from attrs + $this->needed[] = 'base'; $this->tabObject = objects::create($this->type); $tempTabObject = objects::open($this->dn, $this->type); /* Used to know which tab is activated */ foreach ($tempTabObject->by_object as $class => &$plugin) { @@ -145,6 +147,7 @@ class template $smarty = get_smarty(); $sections = array(); $posted = array(); + $smarty->assign('baseACL', 'rw'); foreach ($this->tabObject->by_object as $class => &$plugin) { if (!isset($this->attributes[$class])) { continue; @@ -153,7 +156,7 @@ class template foreach ($this->attributes[$class] as $attr) { if ($plugin->attributesAccess[$attr]->getAclInfo() !== FALSE) { // We assign ACLs so that attributes can use them in their template code - $smarty->assign($plugin->attributesAccess[$attr]->getAcl()."ACL", $plugin->getacl($plugin->attributesAccess[$attr]->getAcl())); + $smarty->assign($plugin->attributesAccess[$attr]->getAcl().'ACL', $plugin->getacl($plugin->attributesAccess[$attr]->getAcl())); } $plugin->attributesAccess[$attr]->renderAttribute($attributes, FALSE); } diff --git a/include/class_userinfo.inc b/include/class_userinfo.inc index 879ebfe63..81a981416 100644 --- a/include/class_userinfo.inc +++ b/include/class_userinfo.inc @@ -311,7 +311,7 @@ class userinfo */ function is_copyable($dn, $object, $class) { - return preg_match("/r/", $this->has_complete_category_acls($dn, $object)); + return preg_match("/r/", $this->get_complete_category_acls($dn, $object)); } @@ -329,7 +329,7 @@ class userinfo function is_cutable($dn, $object, $class) { $remove = preg_match("/d/", $this->get_permissions($dn, $object."/".$class)); - $read = preg_match("/r/", $this->has_complete_category_acls($dn, $object)); + $read = preg_match("/r/", $this->get_complete_category_acls($dn, $object)); return ($remove && $read); } @@ -345,7 +345,7 @@ class userinfo */ function is_pasteable($dn, $object) { - return preg_match("/w/", $this->has_complete_category_acls($dn, $object)); + return preg_match("/w/", $this->get_complete_category_acls($dn, $object)); } @@ -365,8 +365,8 @@ class userinfo } $r = $w = TRUE; foreach ($object as $category) { - $w &= preg_match("/w/", $this->has_complete_category_acls($dn, $category)); - $r &= preg_match("/r/", $this->has_complete_category_acls($dn, $category)); + $w &= preg_match("/w/", $this->get_complete_category_acls($dn, $category)); + $r &= preg_match("/r/", $this->get_complete_category_acls($dn, $category)); } return ($r && $w); } @@ -388,7 +388,7 @@ class userinfo } $r = TRUE; foreach ($object as $category) { - $r &= preg_match("/r/", $this->has_complete_category_acls($dn, $category)); + $r &= preg_match("/r/", $this->get_complete_category_acls($dn, $category)); } return $r; } @@ -783,7 +783,7 @@ class userinfo * * \return string return acl combined with boolean AND */ - function has_complete_category_acls($dn, $category) + function get_complete_category_acls($dn, $category) { global $config; $acl = "rwcdm"; @@ -793,7 +793,7 @@ class userinfo trigger_error("category must be string"); $acl = ""; } else { - if (!isset($this->result_cache['has_complete_category_acls'][$dn][$category])) { + if (!isset($this->result_cache['get_complete_category_acls'][$dn][$category])) { if (isset($config->data['CATEGORIES'][$category])) { foreach ($config->data['CATEGORIES'][$category]['classes'] as $oc) { /* Skip objectClass '0' (e.g. user/0) get_permissions will ever return '' ?? */ @@ -808,9 +808,9 @@ class userinfo } else { $acl = ""; } - $this->result_cache['has_complete_category_acls'][$dn][$category] = $acl; + $this->result_cache['get_complete_category_acls'][$dn][$category] = $acl; } else { - $acl = $this->result_cache['has_complete_category_acls'][$dn][$category]; + $acl = $this->result_cache['get_complete_category_acls'][$dn][$category]; } } return $acl; diff --git a/include/simpleplugin/class_attribute.inc b/include/simpleplugin/class_attribute.inc index 310c13c18..4e16c3da2 100644 --- a/include/simpleplugin/class_attribute.inc +++ b/include/simpleplugin/class_attribute.inc @@ -1872,7 +1872,7 @@ class BaseSelectorAttribute extends Attribute if ($desc === NULL) { $desc = _('Object base'); } - parent::__construct($label, $desc, 'base', FALSE, ''); + parent::__construct($label, $desc, 'base', FALSE, '', 'base'); $this->setInLdap(FALSE); $this->ou = $ou; } @@ -1914,13 +1914,12 @@ class BaseSelectorAttribute extends Attribute { if (!$this->disabled && $this->isVisible()) { /* Refresh base */ - if ($this->plugin->acl_is_moveable($this->value) || - ($this->plugin->dn == 'new' && $this->plugin->acl_is_createable($this->value))) { + if ($this->plugin->acl_is_moveable($this->value) || ($this->plugin->dn == 'new')) { if (!$this->baseSelector->update()) { if ($this->plugin->dn == 'new') { - msg_dialog::display(_('Error'), msgPool::permMove($this->plugin->dn), ERROR_DIALOG); - } else { msg_dialog::display(_('Error'), msgPool::permCreate(), ERROR_DIALOG); + } else { + msg_dialog::display(_('Error'), msgPool::permMove($this->plugin->dn), ERROR_DIALOG); } } if ($this->value != $this->baseSelector->getBase()) { @@ -1958,7 +1957,7 @@ class BaseSelectorAttribute extends Attribute parent::setValue($value); if (is_object($this->plugin)) { /* Set the new acl base */ - if ($this->plugin->dn == "new") { + if ($this->plugin->dn == 'new') { $this->plugin->set_acl_base($this->value); } diff --git a/include/simpleplugin/class_simplePlugin.inc b/include/simpleplugin/class_simplePlugin.inc index 645dfb0f1..0fac16418 100644 --- a/include/simpleplugin/class_simplePlugin.inc +++ b/include/simpleplugin/class_simplePlugin.inc @@ -169,7 +169,8 @@ class simplePlugin extends plugin 'attrs' => array( '_template_cn' => new StringAttribute( _('Template name'), _('This is the name of the template'), - '_template_cn', TRUE + '_template_cn', TRUE, + '', 'template_cn' ) ) ), @@ -431,10 +432,36 @@ class simplePlugin extends plugin return $this->header.$smarty->fetch($this->templatePath); } + function attr_is_writeable($attr) + { + if ($attr->getLdapName() == 'base') { + if (!$this->acl_skip_write() && (!$this->initially_was_account || $this->acl_is_moveable() || $this->acl_is_removeable())) { + return TRUE; + } else { + return FALSE; + } + } + return $this->acl_is_writeable($attr->getAcl(), $this->acl_skip_write()); + } + function renderAttributes($readOnly = FALSE) { + global $ui; $smarty = get_smarty(); + if ($this->is_template) { + $smarty->assign('template_cnACL', $ui->get_permissions($this->acl_base, $this->acl_category.'template', 'template_cn', $this->acl_skip_write())); + } + + /* Handle rights to modify the base */ + if (isset($this->attributesAccess['base'])) { + if ($this->attr_is_writeable($this->attributesAccess['base'])) { + $smarty->assign('baseACL', 'rw'); + } else { + $smarty->assign('baseACL', 'r'); + } + } + $sections = array(); foreach ($this->attributesInfo as $section => $sectionInfo) { $legend = $sectionInfo['name']; @@ -585,7 +612,7 @@ class simplePlugin extends plugin // A first pass that loads the post values foreach ($this->attributesInfo as $section => &$sectionInfo) { foreach ($sectionInfo['attrs'] as &$attr) { - if ($this->acl_is_writeable($attr->getAcl(), $this->acl_skip_write())) { + if ($this->attr_is_writeable($attr)) { // Each attribute know how to read its value from POST $attr->loadPostValue(); } @@ -596,7 +623,7 @@ class simplePlugin extends plugin // A second one that applies them. That allow complex stuff such as attribute disabling foreach ($this->attributesInfo as $section => &$sectionInfo) { foreach ($sectionInfo['attrs'] as &$attr) { - if ($this->acl_is_writeable($attr->getAcl(), $this->acl_skip_write())) { + if ($this->attr_is_writeable($attr)) { // Each attribute know how to read its value from POST $attr->applyPostValue(); } -- GitLab