Commit 89d9e573 authored by Côme Chilliet's avatar Côme Chilliet
Browse files

Fixes # Cleaned up ACL edition dialog a bit more

parent 1cb56893
......@@ -1118,7 +1118,7 @@ class config {
unset($plInfo);
$this->data['CATEGORIES']['all'] = array(
'classes' => array('all'),
'description' => '* '._("All categories"),
'description' => '* '._('All categories'),
'objectClass' => array(),
);
/* Extract categories definitions from object types */
......@@ -1236,7 +1236,7 @@ class config {
}
}
unset($plInfo);
asort($this->data['CATEGORIES']);
ksort($this->data['CATEGORIES']);
foreach ($this->data['CATEGORIES'] as $name => &$infos) {
$infos['classes'] = array_unique($infos['classes']);
if (!isset($infos['description'])) {
......
......@@ -124,9 +124,8 @@ class msg_dialog
*/
public static function displayChecks($messages)
{
/* Assemble the message array to a plain string */
foreach ($messages as $error) {
msg_dialog::display(_("Error"), $error, ERROR_DIALOG);
msg_dialog::display(_('Error'), $error, ERROR_DIALOG);
}
}
......
{if $dialogState eq 'create'}
<h1>{t}List of available ACL categories{/t}</h1>
{$aclList}
<hr/>
<div style="text-align:right;margin-top:5px">
{render acl=$gosaAclTemplateACL}
<input type="submit" name="submit_new_acl" value="{msgPool type=applyButton}"/>
&nbsp;
{/render}
<input type="submit" name="cancel_new_acl" value="{msgPool type=cancelButton}"/>
</div>
{/if}
{if $dialogState eq 'edit'}
<h1>{$headline}</h1>
{render acl=$gosaAclTemplateACL}
{$aclSelector}
{/render}
<hr/>
<div style="text-align:right;margin-top:5px">
{render acl=$gosaAclTemplateACL}
<input type="submit" name="submit_edit_acl" value="{msgPool type=applyButton}"/>
&nbsp;
{/render}
<input type="submit" name="cancel_edit_acl" value="{msgPool type=cancelButton}"/>
</div>
{/if}
<h1>{$headline}</h1>
{$aclEdition}
{if $dialogState eq 'create'}
<p class="plugbottom">
<input type="submit" name="add_finish" value="{msgPool type=applyButton}"/>
<input type="submit" name="add_cancel" value="{msgPool type=cancelButton}"/>
</p>
{/if}
{if $dialogState eq 'edit'}
<p class="plugbottom">
<input type="submit" name="submit_edit_acl" value="{msgPool type=applyButton}"/>
<input type="submit" name="cancel_edit_acl" value="{msgPool type=cancelButton}"/>
</>
{/if}
<?php
/*
This code is part of FusionDirectory (http://www.fusiondirectory.org/)
Copyright (C) 2003 Cajus Pollmeier
Copyright (C) 2011-2015 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.
*/
/* ACL categories list */
class ACLEditionDialog extends GenericDialog
{
protected $initialAclValue;
protected $dialogState = 'create';
protected $aclObject = '';
protected $aclContents = array();
protected $savedAclContents = array();
function __construct($simplePlugin, &$attribute, $acl = NULL)
{
$this->attribute = $attribute;
$this->initialAclValue = $acl;
/* New entry gets presets... */
if ($acl === NULL) {
$this->aclContents = array();
} else {
$this->aclContents = $acl;
}
}
function handle_finish ()
{
$this->attribute->addValue($this->aclContents);
return FALSE;
}
function handle_cancel ()
{
if ($this->initialAclValue !== NULL) {
$this->attribute->addValue($this->initialAclValue);
}
return FALSE;
}
function save_object()
{
global $config;
$new_acl = array();
foreach ($_POST as $name => $post) {
/* Actions... */
if (preg_match('/^cat_edit_.*_x/', $name)) {
$this->aclObject = preg_replace('/^cat_edit_([^_]+)_.*$/', '\1', $name);
$this->dialogState = 'edit';
foreach ($config->data['CATEGORIES'][$this->aclObject]['classes'] as $oc) {
if (isset($this->aclContents[$oc])) {
$this->savedAclContents[$oc] = $this->aclContents[$oc];
}
if (isset($this->aclContents[$this->aclObject.'/'.$oc])) {
$this->savedAclContents[$this->aclObject.'/'.$oc] = $this->aclContents[$this->aclObject.'/'.$oc];
}
}
break;
}
if (preg_match('/^cat_del_.*_x/', $name)) {
$idx = preg_replace('/^cat_del_([^_]+)_.*$/', '\1', $name);
foreach ($config->data['CATEGORIES'][$idx]['classes'] as $key) {
unset($this->aclContents["$idx/$key"]);
}
break;
}
/* ACL checkbox saving... */
if (preg_match('/^acl_([^_]+)_(.*)_([^_yx])$/', $name, $matches)) {
$object = $matches[1];
$attribute = $matches[2];
$value = $matches[3];
/* Skip for detection entry */
if ($object == 'dummy') {
continue;
}
/* Ordinary ACL */
if (!isset($new_acl[$object])) {
$new_acl[$object] = array();
}
if (isset($new_acl[$object][$attribute])) {
$new_acl[$object][$attribute] .= $value;
} else {
$new_acl[$object][$attribute] = $value;
}
}
}
/* Only be interested in new acl's, if we're in the right _POST place */
if (isset($_POST['acl_dummy_0_0_0']) && ($this->aclObject != '') && is_array($config->data['CATEGORIES'][$this->aclObject])) {
foreach ($config->data['CATEGORIES'][$this->aclObject]['classes'] as $oc) {
unset($this->aclContents[$oc]);
unset($this->aclContents[$this->aclObject.'/'.$oc]);
if (isset($new_acl[$oc])) {
$this->aclContents[$oc] = $new_acl[$oc];
}
if (isset($new_acl[$this->aclObject.'/'.$oc])) {
$this->aclContents[$this->aclObject.'/'.$oc] = $new_acl[$this->aclObject.'/'.$oc];
}
}
}
if ($this->dialogState == 'edit') {
/* Cancel edit acl? */
if (isset($_POST['cancel_edit_acl'])) {
$this->dialogState = 'create';
foreach ($config->data['CATEGORIES'][$this->aclObject]['classes'] as $oc) {
if (isset($this->savedAclContents[$oc])) {
$this->aclContents[$oc] = $this->savedAclContents[$oc];
}
if (isset($this->savedAclContents[$this->aclObject.'/'.$oc])) {
$this->aclContents[$this->aclObject.'/'.$oc] = $this->savedAclContents[$this->aclObject.'/'.$oc];
}
}
}
/* Save edit acl? */
if (isset($_POST['submit_edit_acl'])) {
$this->dialogState = 'create';
}
}
}
function dialog_execute ()
{
global $config;
$this->save_object();
/* Create templating instance */
$smarty = get_smarty();
$smarty->assign('usePrototype', 'true');
if ($this->dialogState == 'create') {
/* Draw list */
$aclList = new divSelectBox('aclList');
$aclList->setHeight('auto');
/* Add settings for all categories to the (permanent) list */
foreach ($config->data['CATEGORIES'] as $section => $infos) {
if (($section != 'all') && (count($infos['classes']) == 1)) {
/* Hide empty categories */
continue;
}
$summary = array();
foreach ($infos['classes'] as $oc) {
if (isset($this->aclContents[$oc]) && count($this->aclContents[$oc]) && isset($this->aclContents[$oc][0]) &&
$this->aclContents[$oc][0] != '') {
$summary[] = $oc;
continue;
}
if (isset($this->aclContents["$section/$oc"]) && count($this->aclContents["$section/$oc"])) {
$summary[] = $oc;
continue;
}
if (isset($this->aclContents[$oc]) && !isset($this->aclContents[$oc][0]) && count($this->aclContents[$oc])) {
$summary[] = $oc;
}
}
/* Set summary... */
if (empty($summary)) {
$summary = '<i>'._('No ACL settings for this category').'</i>';
} else {
$summary = sprintf(_('ACL for these objects: %s'), join(', ', $summary));
}
$action = '<input class="center" type="image" src="geticon.php?context=actions&amp;icon=document-edit&amp;size=16"
alt="'._('Edit').'" name="cat_edit_'.$section.'" title="'._('Edit category ACL').'"/>'.
'<input class="center" type="image" src="geticon.php?context=actions&amp;icon=edit-delete&amp;size=16"
alt="'._('Delete').'" name="cat_del_'.$section.'" title="'._('Reset category ACL').'"/>';
$field1 = array('html' => $infos['description'], 'attach' => 'style="width:140px"');
$field2 = array('html' => $summary);
$field3 = array('html' => $action, 'attach' => 'style="border-right:0px;width:40px"');
$aclList->AddEntry(array($field1, $field2, $field3));
}
$smarty->assign('headline', _('List of available ACL categories'));
$smarty->assign('aclEdition', $aclList->DrawList());
} elseif ($this->dialogState == 'edit') {
/* Collect objects for selected category */
$aclObjects = array();
foreach ($config->data['CATEGORIES'][$this->aclObject]['classes'] as $idx => $class) {
if ($idx == 0) {
continue;
}
$pInfos = pluglist::pluginInfos($class);
$aclObjects[$this->aclObject.'/'.$class] = $pInfos['plShortName'];
}
if ($this->aclObject == 'all') {
$aclObjects['all'] = _('All objects in current subtree');
}
$smarty->assign('headline', sprintf(_('Edit ACL for "%s"'), $config->data['CATEGORIES'][$this->aclObject]['description']));
$smarty->assign('aclEdition', $this->buildAclSelector($aclObjects));
}
/* Show main page */
$smarty->assign('dialogState', $this->dialogState);
return $smarty->fetch(get_template_path('acleditiondialog.tpl', dirname(__FILE__)));
}
/*!
* \brief Create a checkbox
*
* \param String $name Name of the acl checkbox
* \param String $text Label for the checkbox
* \param boolean $state
*
* \return String containing checkbox
*/
function mkchkbx($name, $text, $state = FALSE)
{
$tname = preg_replace('/[^a-z0-9]/i', '_', $name);
return '<input id="acl_'.$tname.'" type="checkbox" name="acl_'.$name.'"'.($state ? ' checked="checked"' : '').'/>'."\n".
'<label for="acl_'.$tname.'">'.$text.'</label>'."\n";
}
/*!
* \brief Make a read and write box
*
* \param String $name Name of the box
* \param String $state
*
* \return String containing checkbox
*/
function mkrwbx($name, $state = '')
{
$rstate = (preg_match('/r/', $state) ? ' checked="checked"' : '');
$wstate = (preg_match('/w/', $state) ? ' checked="checked"' : '');
$tname = preg_replace('/[^a-z0-9]/i', '_', $name);
return '<input id="acl_'.$tname.'_r" type="checkbox" name="acl_'.$name.'_r"'.$rstate.'/>'."\n".
'<label for="acl_'.$tname.'_r">'._('read').'</label>'."\n".
'<input id="acl_'.$tname.'_w" type="checkbox" name="acl_'.$name.'_w"'.$wstate.'/>'."\n".
'<label for="acl_'.$tname.'_w">'._('write').'</label>'."\n";
}
/*!
* \brief Build an acl selector form
*
* \param Array $list
*
* \return the acl selector form
*/
function buildAclSelector($list)
{
global $config;
$display = '<input type="hidden" name="acl_dummy_0_0_0" value="1"/>';
$cols = 3;
$tmp = session::global_get('plist');
$plist = $tmp->info;
asort($plist);
/* Add select all/none buttons */
$style = 'style="width:100px;"';
$display .= '<input '.$style.' type="button" name="toggle_all_create" onClick="acl_toggle_all(\'_0_c$\');" value="Toggle C"/>';
$display .= '<input '.$style.' type="button" name="toggle_all_move" onClick="acl_toggle_all(\'_0_m$\');" value="Toggle M"/>';
$display .= '<input '.$style.' type="button" name="toggle_all_remove" onClick="acl_toggle_all(\'_0_d$\');" value="Toggle D"/> - ';
$display .= '<input '.$style.' type="button" name="toggle_all_read" onClick="acl_toggle_all(\'_0_r$\');" value="Toggle R"/>';
$display .= '<input '.$style.' type="button" name="toggle_all_write" onClick="acl_toggle_all(\'_0_w$\');" value="Toggle W"/> - ';
$display .= '<input '.$style.' type="button" name="toggle_all_sub_read" onClick="acl_toggle_all(\'[^0]_r$\');" value="R+"/>';
$display .= '<input '.$style.' type="button" name="toggle_all_sub_write" onClick="acl_toggle_all(\'[^0]_w$\');" value="W+"/>';
$display .= '<br/>';
$style = 'style="width:50px;"';
$display .= '<input '.$style.' type="button" name="set_true_all_create" onClick="acl_set_all(\'_0_c$\',true);" value="C+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_create" onClick="acl_set_all(\'_0_c$\',false);" value="C-"/>';
$display .= '<input '.$style.' type="button" name="set_true_all_move" onClick="acl_set_all(\'_0_m$\',true);" value="M+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_move" onClick="acl_set_all(\'_0_m$\',false);" value="M-"/>';
$display .= '<input '.$style.' type="button" name="set_true_all_remove" onClick="acl_set_all(\'_0_d$\',true);" value="D+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_remove" onClick="acl_set_all(\'_0_d$\',false);" value="D-"/> - ';
$display .= '<input '.$style.' type="button" name="set_true_all_read" onClick="acl_set_all(\'_0_r$\',true);" value="R+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_read" onClick="acl_set_all(\'_0_r$\',false);" value="R-"/>';
$display .= '<input '.$style.' type="button" name="set_true_all_write" onClick="acl_set_all(\'_0_w$\',true);" value="W+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_write" onClick="acl_set_all(\'_0_w$\',false);" value="W-"/> - ';
$display .= '<input '.$style.' type="button" name="set_true_all_read" onClick="acl_set_all(\'[^0]_r$\',true);" value="R+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_read" onClick="acl_set_all(\'[^0]_r$\',false);" value="R-"/>';
$display .= '<input '.$style.' type="button" name="set_true_all_write" onClick="acl_set_all(\'[^0]_w$\',true);" value="W+"/>';
$display .= '<input '.$style.' type="button" name="set_false_all_write" onClick="acl_set_all(\'[^0]_w$\',false);" value="W-"/>';
$list = acl::sort_by_priority($list);
foreach ($list as $key => $name) {
/* Create sub acl if it does not exist */
if (!isset($this->aclContents[$key])) {
$this->aclContents[$key] = array();
}
if (!isset($this->aclContents[$key][0])) {
$this->aclContents[$key][0] = '';
}
$currentAcl = $this->aclContents[$key];
/* Get the overall plugin acls */
$overall_acl = '';
if (isset($currentAcl[0])) {
$overall_acl = $currentAcl[0];
}
// Detect configured plugins
$expand = ((count($currentAcl) > 1) || ($currentAcl[0] != ''));
/* Object header */
$tname = preg_replace('/[^a-z0-9]/i', '_', $key);
if ($expand) {
$back_color = '#C8C8FF';
} else {
$back_color = '#C8C8C8';
}
$display .= '<table style="width:100%;border:1px solid #A0A0A0;border-spacing:0;border-collapse:collapse;">'."\n".
' <tr>'."\n".
' <td style="background-color:'.$back_color.';height:1.8em;" colspan='.($cols - 1).'>'.
'<b>'._('Object').': '.$name.'</b>'.
'</td>'."\n".
' <td align="right" style="background-color:'.$back_color.';height:1.8em;">'."\n".
' <input id="show'.$tname.'" type="button" onclick="$(\''.$tname.'\').toggle();" value="'._('Show/hide advanced settings').'"/></td>'."\n".
' </tr>'."\n";
/* Generate options */
$spc = '&nbsp;&nbsp;';
$options = $this->mkchkbx($key.'_0_c', _('Create objects'), preg_match('/c/', $overall_acl)).$spc;
$options .= $this->mkchkbx($key.'_0_m', _('Move objects'), preg_match('/m/', $overall_acl)).$spc;
$options .= $this->mkchkbx($key.'_0_d', _('Remove objects'), preg_match('/d/', $overall_acl)).$spc;
if ($plist[preg_replace('%^.*/%', '', $key)]['plSelfModify']) {
$options .= $this->mkchkbx($key.'_0_s', _('Grant permission to owner'), preg_match('/s/', $overall_acl)).$spc;
}
/* Global options */
$more_options = $this->mkchkbx($key.'_0_r', _('read'), preg_match('/r/', $overall_acl)).$spc;
$more_options .= $this->mkchkbx($key.'_0_w', _('write'), preg_match('/w/', $overall_acl));
$display .= ' <tr>'."\n".
' <td style="background-color:#E0E0E0" colspan="'.($cols - 1).'">'.$options.'</td>'."\n".
' <td style="background-color:#D4D4D4">&nbsp;'._('Complete object').': '.$more_options.'</td>'."\n".
' </tr>'."\n";
/* Walk through the list of attributes */
$cnt = 1;
$splist = $plist[preg_replace('%^.*/%', '', $key)]['plProvidedAcls'];
$display .= ' <tr id="tr_'.$tname.'" style="vertical-align:top;height:0px;">'."\n".
' <td colspan="'.$cols.'">'."\n".
' <div id="'.$tname.'" style="overflow:hidden; display:none;vertical-align:top;width:100%;">'."\n".
' <table style="width:100%;border-collapse: collapse;" border="1">'."\n";
foreach ($splist as $attr => $dsc) {
/* Skip pl* attributes, they are internal... */
if (preg_match('/^pl[A-Z]+.*$/', $attr)) {
continue;
}
/* Open table row */
if ($cnt == 1) {
$display .= ' <tr>'."\n";
}
/* Close table row */
if ($cnt == $cols) {
$cnt = 1;
$end = ' </tr>'."\n";
} else {
$cnt++;
$end = '';
}
/* Collect list of attributes */
$state = '';
if (isset($currentAcl[$attr])) {
$state = $currentAcl[$attr];
}
$display .= ' <td style="border:1px solid #A0A0A0;width:'.(int)(100 / $cols).'%">'."\n".
' <b>'.$dsc.'</b> ('.$attr.')<br/>'.$this->mkrwbx($key.'_'.$attr, $state).'</td>'.$end."\n";
}
/* Fill missing td's if needed */
if ((--$cnt != $cols) && ($cnt != 0)) {
$display .= str_repeat(' <td style="border:1px solid #A0A0A0;width:'.(int)(100 / $cols).'%">&nbsp;</td>'."\n", $cols - $cnt);
}
$display .= ' </table>'."\n".
' </div>'."\n".
' </td>'."\n".
' </tr>'."\n";
$display .= '</table><br/>'."\n";
}
return $display;
}
}
......@@ -18,59 +18,24 @@
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
*/
/* ACL categories list */
class ACLDialog extends GenericDialog
{
protected $initialAclValue;
protected $post_cancel = 'cancel_new_acl';
protected $post_finish = 'submit_new_acl';
function __construct($simplePlugin, &$attribute, $acl = NULL)
{
$this->attribute = $attribute;
$this->dialog = new acl_createedit($simplePlugin->config, $acl);
$this->initialAclValue = $acl;
}
function dialog_execute ()
{
$this->dialog->save_object();
return $this->dialog->execute();
}
function handle_finish ()
{
$this->attribute->addValue($this->dialog->getAclEntry());
return FALSE;
}
function handle_cancel ()
{
if ($this->initialAclValue !== NULL) {
$this->attribute->addValue($this->initialAclValue);
}
return FALSE;
}
}
/* complicated stuff */
class ACLsAttribute extends DialogOrderedArrayAttribute
{
protected $order = TRUE;
protected $dialogClass = 'ACLDialog';
protected $dialogClass = 'ACLEditionDialog';
protected function getAttributeArrayValue($key, $value)
{
/* Convert text value to displayable array value */
/* Summarize ACL */
$summary = "";
$summary = '';
foreach ($value as $name => $object) {
if (count($object)) {
$summary .= "$name, ";
$summary .= $name.', ';
}
}
$summary = sprintf(_("Contains settings for these objects: %s"), preg_replace('/, $/', '', $summary));
$summary = sprintf(_('Contains settings for these objects: %s'), preg_replace('/, $/', '', $summary));
return array($summary);
}
......@@ -162,406 +127,4 @@ class aclRole extends simplePlugin
$this->attributesAccess['cn']->setUnique(TRUE);
}
}
class acl_createedit extends simplePlugin
{
var $objectclasses = array('gosaAcl');
/* Helpers */
var $dialogState = 'create';
var $aclObject = '';
var $aclContents = array();
var $savedAclContents = array();
static function plInfo()
{
}
static function getAttributesInfo()
{
return array();
}
function __construct (&$config, $acl = NULL)
{
/* Include config object */
parent::__construct($config, $config->current['BASE']);