<?php
/**
+ * ACL (Access Control List) administration page.
+ *
* Copyright 2000-2008 The Horde Project (http://www.horde.org/)
*
* See the enclosed file COPYING for license information (GPL). If you
* @author Eric Garrido <ekg2002@columbia.edu>
*/
-@define('IMP_BASE', dirname(__FILE__));
-require_once IMP_BASE . '/lib/base.php';
-require_once 'Horde/IMAP/ACL.php';
-
-$prefs_url = IMP::prefsURL(true);
+require_once dirname(__FILE__) . '/lib/base.php';
/* Redirect back to the options screen if ACL is not enabled. */
-if ($prefs->isLocked('acl') ||
- !(isset($_SESSION['imp']['acl']) && is_array($_SESSION['imp']['acl']))) {
+$prefs_url = IMP::prefsURL(true);
+if ($prefs->isLocked('acl') || empty($_SESSION['imp']['acl'])) {
$notification->push(_("Folder sharing is not enabled."), 'horde.error');
header('Location: ' . $prefs_url);
exit;
}
-$params = array(
- 'hostspec' => $_SESSION['imp']['server'],
- 'password' => Secret::read(IMP::getAuthKey(), $_SESSION['imp']['pass']),
- 'port' => $_SESSION['imp']['port'],
- 'protocol' => $_SESSION['imp']['protocol'],
- 'username' => $_SESSION['imp']['user'],
-);
-
-if (isset($_SESSION['imp']['acl']['params'])) {
- $params = array_merge($params, $_SESSION['imp']['acl']['params']);
-}
-
-$ACLDriver = &IMAP_ACL::singleton($_SESSION['imp']['acl']['driver'], $params);
-
-/* Check selected driver is supported. Redirect to options screen with
- * error message if not. */
-$error = (!$ACLDriver->isSupported())
- ? _("This server does not support sharing folders.")
- : $ACLDriver->getError();
-
-if ($error) {
- $notification->push($error, 'horde.error');
+try {
+ $ACLDriver = &IMP_IMAP_ACL::singleton();
+} catch (Exception $e) {
+ $notification->push($error, _("This server does not support sharing folders."));
header('Location: ' . $prefs_url);
exit;
}
$protected = $ACLDriver->getProtected();
/* Run through the action handlers. */
-$actionID = Util::getFormData('actionID');
$ok_form = true;
-switch ($actionID) {
+switch (Util::getFormData('actionID')) {
case 'imp_acl_set':
if (!$folder) {
$notification->push(_("No folder selected."), 'horde.error');
if ($new_user) {
/* Each ACL is submitted with the acl as the value. Reverse the hash
- mapping for createACL(). */
+ mapping for editACL(). */
$new_acl = array_flip($new_acl);
- $result = $ACLDriver->createACL($folder, $new_user, $new_acl);
+ $result = $ACLDriver->editACL($folder, $new_user, $new_acl);
if (is_a($result, 'PEAR_Error')) {
$notification->push($result);
} elseif (!count($new_acl)) {
$imp_folder = &IMP_Folder::singleton();
$rights = $ACLDriver->getRights();
-$rightsTitles = $ACLDriver->getRightsTitles();
if (empty($folder)) {
$folder = 'INBOX';
}
$curr_acl = $ACLDriver->getACL($folder);
-$canEdit = $ACLDriver->canEdit($folder, $_SESSION['imp']['user']);
-
-if (is_a($curr_acl, 'PEAR_Error')) {
- $notification->push($curr_acl, 'horde_error');
- $curr_acl = array();
-}
+$canEdit = $ACLDriver->canEdit($folder, $_SESSION['imp']['uniquser']);
require_once 'Horde/Prefs/UI.php';
$result = Horde::loadConfiguration('prefs.php', array('prefGroups', '_prefs'), 'imp');
$t->set('aclnavcell', Util::bufferOutput(array('Prefs_UI', 'generateNavigationCell'), 'acl'));
$t->set('changefolder', Horde::link('#', _("Change Folder"), 'smallheader', '', 'ACLFolderChange(true); return false;'));
$t->set('sharedimg', Horde::img('shared.png', _("Change Folder")));
-$t->set('options', IMP::flistSelect(array('selected' => $folder));
+$t->set('options', IMP::flistSelect(array('selected' => $folder)));
$t->set('current', sprintf(_("Current access to %s"), IMP::displayFolder($folder)));
$t->set('folder', $folder);
$t->set('noacl', !count($curr_acl));
/* Create table of each ACL option for each user granted permissions,
* enabled indicates the right has been given to the user */
foreach (array_keys($rights) as $val) {
- $entry['rule'][] = array('val' => $val, 'enabled'=> isset($rule{$val}));
+ $entry['rule'][] = array('val' => $val, 'enabled' => isset($rule[$val]));
}
$cval[] = $entry;
}
$new_user_field .= "\n</select>";
}
$t->set('new_user', $new_user_field);
+
$rightsTitlesval = array();
-foreach ($rightsTitles as $right => $desc) {
+foreach ($rights as $right => $val) {
$rightsval[] = array(
'right' => $right,
- 'desc' => $desc
+ 'desc' => $val['desc']
);
}
+
$t->set('rights', $rightsval);
$t->set('width', round(100 / (count($rightsval) + 1)) . '%');
$t->set('prefsurl', $prefs_url);
--- /dev/null
+<?php
+/**
+ * Contains functions related to managing IMAP Access Control Lists.
+ *
+ * Copyright 2003-2008 The Horde Project (http://www.horde.org/)
+ *
+ * See the enclosed file COPYING for license information (LGPL). If you
+ * did not receive this file, see http://www.fsf.org/copyleft/lgpl.html.
+ *
+ * @author Chris Hastie <imp@oak-wood.co.uk>
+ * @package IMP
+ */
+class IMP_IMAP_ACL
+{
+ /**
+ * Hash containing the list of possible rights and a human readable
+ * description of each.
+ *
+ * @var array
+ */
+ protected $_rightsList;
+
+ /**
+ * Array containing user names that cannot have their access rights
+ * changed.
+ *
+ * @var boolean
+ */
+ protected $_protected;
+
+ /**
+ * Attempts to return a reference to a concrete object instance.
+ * It will only create a new instance if no instance currently exists.
+ *
+ * This method must be invoked as:
+ * $var = &IMP_IMAP_ACL::singleton()
+ *
+ * @return IMP_IMAP_ACL The created concrete instance.
+ */
+ static public function &singleton($driver, $params = array())
+ {
+ static $instance;
+
+ if (!isset($instance)) {
+ $instances = new IMP_IMAP_ACL();
+ }
+
+ return $instances[$signature];
+ }
+
+ /**
+ * Constructor.
+ */
+ function __construct()
+ {
+ if ($_SESSION['imp']['protocol'] != 'imap') {
+ throw new Exception(_("ACL requires an IMAP server."));
+ }
+
+ $capability = $GLOBALS['imp_imap']->ob->queryCapability('ACL');
+ if (!$capability) {
+ throw new Exception(_("IMAP server does not support ACLs."));
+ }
+
+ $rfc4314 = $GLOBALS['imp_imap']->ob->queryCapability('RIGHTS');
+
+ $this->_protected = array($GLOBALS['imp_imap']->ob->getParam('username'));
+
+ $this->_rightsList = array(
+ 'l' => array(
+ 'desc' => _("List - user can see the folder"),
+ 'title' => _("List")
+ ),
+ 'r' => array(
+ 'desc' => _("Read messages"),
+ 'title' => _("Read")
+ ),
+ 's' => array(
+ 'desc' => _("Mark with Seen/Unseen flags"),
+ 'title' => _("Mark (Seen)")
+ ),
+ 'w' => array(
+ 'desc' => _("Mark with other flags (e.g. Important/Answered)"),
+ 'title' => _("Mark (Other)")
+ ),
+ 'i' => array(
+ 'desc' => _("Insert messages"),
+ 'title' => _("Insert")
+ ),
+ 'p' => array(
+ 'desc' => _("Post to this folder (not enforced by IMAP)"),
+ 'title' => _("Post")
+ ),
+ 'a' => array(
+ 'desc' => _("Administer - set permissions for other users"),
+ 'title' => _("Administer")
+ )
+ );
+
+ if ($rfc4314) {
+ // RFC 4314 compliant rights
+ $this->_rightsList = array_merge($this->_rightsList, array(
+ 'k' => array(
+ 'desc' => _("Create sub folders"),
+ 'title' => _("Create Folders")
+ ),
+ 'x' => array(
+ 'desc' => _("Delete sub folders"),
+ 'title' => _("Delete Folders")
+ ),
+ 't' => array(
+ 'desc' => _("Delete messages"),
+ 'title' => _("Delete")
+ ),
+ 'e' => array(
+ 'desc' => _("Purge messages"),
+ 'title' => _("Purge")
+ )
+ ));
+ } else {
+ // RFC 2086 compliant rights
+ $this->_rightsList = array_merge($this->_rightsList, array(
+ 'c' => array(
+ 'desc' =>_("Create sub folders"),
+ 'title' => _("Create Folder")
+ ),
+ 'd' => array(
+ 'desc' => _("Delete and purge messages"),
+ 'title' => _("Delete/Purge")
+ )
+ ));
+ }
+ }
+
+ /**
+ * Attempts to retrieve the existing ACL for a mailbox from the server.
+ *
+ * @param string $mbox The mailbox to get the ACL for.
+ *
+ * @return array A hash containing information on the ACL.
+ */
+ public function getACL($mbox)
+ {
+ try {
+ return $GLOBALS['imp_imap']->ob->getACL($mbox);
+ } catch (Horde_Imap_Client_Exception $e) {
+ // return PEAR::raiseError(_("Could not retrieve ACL"));
+ return array();
+ }
+ }
+
+ /**
+ * Edits an ACL on the server.
+ *
+ * @param string $mbox The mailbox on which to edit the ACL.
+ * @param string $user The user to grant rights to.
+ * @param array $acl The keys of which are the
+ * rights to be granted (see RFC 2086).
+ *
+ * @return mixed True on success, PEAR_Error on error.
+ */
+ public function editACL($mbox, $user, $acl)
+ {
+ try {
+ $GLOBALS['imp_imap']->ob->setACL($mbox, $user, array('rights' => $acl));
+ return true;
+ } catch (Horde_Imap_Client_Exception $e) {
+ return PEAR::raiseError(sprintf(_("Couldn't give user \"%s\" the following rights for the folder \"%s\": %s"), $user, $mbox, implode('', $acl)));
+ }
+ }
+
+ /**
+ * Can a user edit the ACL for this mailbox?
+ *
+ * @param string $mbox The mailbox name.
+ * @param string $user A user name.
+ *
+ * @return boolean True if $user has 'a' right
+ */
+ public function canEdit($mbox, $user)
+ {
+ try {
+ $rights = $GLOBALS['imp_imap']->ob->listACLRights($mbox, $user);
+ foreach ($rights as $val) {
+ if (strpos($val, 'a') !== false) {
+ return true;
+ }
+ }
+ return false;
+ } catch (Horde_Imap_Client_Exception $e) {
+ return false;
+ }
+ }
+
+ /**
+ * TODO
+ */
+ public function getRights()
+ {
+ return $this->_rightsList;
+ }
+
+ /**
+ * TODO
+ */
+ public function getProtected()
+ {
+ return $this->_protected;
+ }
+
+}