From: Michael M Slusarz Date: Wed, 10 Dec 2008 08:48:35 +0000 (-0700) Subject: Move ACL code into IMP. X-Git-Url: https://git.internetallee.de/?a=commitdiff_plain;h=9eedf194fe5b873e6248de4478ccff2d2bcef863;p=horde.git Move ACL code into IMP. Lots of cleanup - move all code into one file - use Horde_Imap_Client object to interact with the IMAP server. First attempt and guaranteed this doesn't work (I don't have a way to test right now) but at least all the parts are there for future development. --- diff --git a/imp/acl.php b/imp/acl.php index e16030cb3..edb805c7c 100644 --- a/imp/acl.php +++ b/imp/acl.php @@ -1,5 +1,7 @@ */ -@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; } @@ -64,9 +44,8 @@ if ($new_user) { $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'); @@ -75,9 +54,9 @@ case 'imp_acl_set': 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)) { @@ -133,19 +112,13 @@ case 'imp_acl_set': $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'); @@ -165,7 +138,7 @@ $t->set('forminput', Util::formInput()); $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)); @@ -183,7 +156,7 @@ if (!$t->get('noacl')) { /* 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; } @@ -209,13 +182,15 @@ if (empty($_SESSION['imp']['admin'])) { $new_user_field .= "\n"; } $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); diff --git a/imp/lib/IMAP/ACL.php b/imp/lib/IMAP/ACL.php new file mode 100644 index 000000000..6ed8436be --- /dev/null +++ b/imp/lib/IMAP/ACL.php @@ -0,0 +1,211 @@ + + * @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; + } + +}