ACL fixes - everything should work again in IMP
authorMichael M Slusarz <slusarz@curecanti.org>
Thu, 4 Feb 2010 06:10:43 +0000 (23:10 -0700)
committerMichael M Slusarz <slusarz@curecanti.org>
Thu, 4 Feb 2010 06:10:43 +0000 (23:10 -0700)
framework/Imap_Client/lib/Horde/Imap/Client/Base.php
framework/Imap_Client/lib/Horde/Imap/Client/Cclient.php
framework/Imap_Client/lib/Horde/Imap/Client/Cclient/Pop3.php
framework/Imap_Client/lib/Horde/Imap/Client/Mock.php
framework/Imap_Client/lib/Horde/Imap/Client/Socket.php
framework/Imap_Client/lib/Horde/Imap/Client/Socket/Pop3.php
imp/acl.php
imp/config/prefs.php.dist
imp/lib/Imap/Acl.php
imp/templates/acl/acl.html
imp/themes/screen.css

index 97a52c6..31c7388 100644 (file)
@@ -2565,7 +2565,7 @@ abstract class Horde_Imap_Client_Base
      * support the IMAP ACL extension (RFC 2086/4314).
      *
      * @param string $mailbox     A mailbox. Either in UTF7-IMAP or UTF-8.
-     * @param string $identifier  The identifier to alter. Either in UTF7-IMAP
+     * @param string $identifier  The identifier to query. Either in UTF7-IMAP
      *                            or UTF-8.
      *
      * @return array  An array with two elements: 'required' (a list of
@@ -2588,7 +2588,7 @@ abstract class Horde_Imap_Client_Base
      * Get ACL rights for a given mailbox/identifier.
      *
      * @param string $mailbox     A mailbox (UTF7-IMAP).
-     * @param string $identifier  The identifier to alter (UTF7-IMAP).
+     * @param string $identifier  The identifier to query (UTF7-IMAP).
      *
      * @return array  An array of rights (keys: 'required' and 'optional').
      * @throws Horde_Imap_Client_Exception
index 25cf447..dfa46d3 100644 (file)
@@ -1627,9 +1627,12 @@ class Horde_Imap_Client_Cclient extends Horde_Imap_Client_Base
      */
     protected function _listACLRights($mailbox, $identifier)
     {
+        $retval = array('optional' => array(), 'required' => array());
         $acl = $this->getACL($mailbox);
-        // @todo - Does this return 'optional' information?
-        return isset($acl[$identifier]) ? $acl[$identifier] : array();
+        if (isset($acl[$identifier])) {
+            $retval['optional'] = $acl[$identifier];
+        }
+        return $retval;
     }
 
     /**
index d5f3716..c57ddc3 100644 (file)
@@ -449,7 +449,7 @@ class Horde_Imap_Client_Cclient_Pop3 extends Horde_Imap_Client_Cclient
      * Get ACL rights for a given mailbox/identifier.
      *
      * @param string $mailbox     A mailbox (UTF7-IMAP).
-     * @param string $identifier  The identifier (UTF7-IMAP).
+     * @param string $identifier  The identifier to query (UTF7-IMAP).
      *
      * @throws Horde_Imap_Client_Exception
      */
index d143b71..4df43a8 100644 (file)
@@ -799,7 +799,7 @@ class Horde_Imap_Client_Mock extends Horde_Imap_Client_Base
      * Get ACL rights for a given mailbox/identifier.
      *
      * @param string $mailbox    A mailbox (UTF7-IMAP).
-     * @param string $identifier The identifier to alter (UTF7-IMAP).
+     * @param string $identifier The identifier to query (UTF7-IMAP).
      *
      * @return array  An array of rights (keys: 'required' and 'optional').
      * @throws Horde_Imap_Client_Exception
index cad32a9..da389d7 100644 (file)
@@ -3094,7 +3094,7 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
      * Get ACL rights for a given mailbox/identifier.
      *
      * @param string $mailbox     A mailbox (UTF7-IMAP).
-     * @param string $identifier  The identifier (US-ASCII).
+     * @param string $identifier  The identifier to query (UTF7-IMAP)
      *
      * @return array  An array of rights (keys: 'required' and 'optional').
      * @throws Horde_Imap_Client_Exception
@@ -3116,7 +3116,7 @@ class Horde_Imap_Client_Socket extends Horde_Imap_Client_Base
     protected function _parseListRights($data)
     {
         // Ignore mailbox and identifier arguments
-        $this->_temp['myrights'] = array(
+        $this->_temp['listaclrights'] = array(
             'required' => str_split($data[2]),
             'optional' => array_slice($data, 3)
         );
index d9c5326..40fba7e 100644 (file)
@@ -1166,7 +1166,7 @@ class Horde_Imap_Client_Socket_Pop3 extends Horde_Imap_Client_Base
      * Get ACL rights for a given mailbox/identifier.
      *
      * @param string $mailbox     A mailbox (UTF7-IMAP).
-     * @param string $identifier  The identifier (UTF7-IMAP).
+     * @param string $identifier  The identifier to query (UTF7-IMAP).
      *
      * @throws Horde_Imap_Client_Exception
      */
index d4caf71..b4e03ad 100644 (file)
@@ -17,114 +17,107 @@ Horde_Registry::appInit('imp');
 
 /* Redirect back to the options screen if ACL is not enabled. */
 $prefs_url = Horde::getServiceLink('options', 'imp');
-if ($prefs->isLocked('acl') || empty($_SESSION['imp']['acl'])) {
+if ($prefs->isLocked('acl') || empty($_SESSION['imp']['imap']['acl'])) {
     $notification->push('Folder sharing is not enabled.', 'horde.error');
     header('Location: ' . $prefs_url);
     exit;
 }
 
 try {
-    $ACLDriver = $injector->getInstance('IMP_Imap_Acl');
+    $ACL = $injector->getInstance('IMP_Imap_Acl');
 } catch (Horde_Exception $e) {
     $notification->push(_("This server does not support sharing folders."), 'horde.error');
     header('Location: ' . $prefs_url);
     exit;
 }
 
-$acls = Horde_Util::getFormData('acl');
-$folder = Horde_Util::getFormData('folder');
-$new_user = Horde_Util::getFormData('new_user');
-if ($new_user) {
-    $new_acl = Horde_Util::getFormData('new_acl');
-    /* Check to see if $new_user already has an acl on the folder. */
-    if (isset($acls[$new_user])) {
-        $acls[$new_user] = $new_acl;
-        $new_user = '';
-    }
+$vars = Horde_Variables::getDefaultVariables();
+
+/* Check to see if $vars->new_user already has an acl on the folder. */
+if ($vars->new_user && isset($vars->acl[$vars->new_user])) {
+    $vars->acl[$vars->new_user] = $vars->new_acl;
+    $vars->new_user = '';
 }
 
-$protected = $ACLDriver->getProtected();
+$protected = $ACL->getProtected();
 
 /* Run through the action handlers. */
-$ok_form = true;
-switch (Horde_Util::getFormData('actionID')) {
+switch ($vars->actionID) {
 case 'imp_acl_set':
-    if (!$folder) {
+    if (!$vars->folder) {
         $notification->push(_("No folder selected."), 'horde.error');
-        $ok_form = false;
+        break;
     }
 
-    if ($new_user) {
-        /* Each ACL is submitted with the acl as the value. Reverse the hash
-           mapping for editACL(). */
-        $new_acl = array_flip($new_acl);
+    if ($vars->new_user) {
         try {
-            $ACLDriver->editACL($folder, $new_user, $new_acl);
-            if (!count($new_acl)) {
-                $notification->push(sprintf(_("All rights on folder \"%s\" successfully removed for user \"%s\"."), $folder, $new_user), 'horde.success');
+            $ACL->editACL($vars->folder, $vars->new_user, $vars->new_acl);
+            if (count($vars->new_acl)) {
+                $notification->push(sprintf(_("User \"%s\" successfully given the specified rights for the folder \"%s\"."), $vars->new_user, $vars->folder), 'horde.success');
             } else {
-                $notification->push(sprintf(_("User \"%s\" successfully given the specified rights for the folder \"%s\"."), $new_user, $folder), 'horde.success');
+                $notification->push(sprintf(_("All rights on folder \"%s\" successfully removed for user \"%s\"."), $vars->folder, $vars->new_user), 'horde.success');
             }
         } catch (Horde_Exception $e) {
             $notification->push($e);
         }
     }
 
-    if ($ok_form) {
-        $current_acl = $ACLDriver->getACL($folder);
-        foreach ($acls as $user => $acl) {
-            if ($acl) {
-                $acl = array_flip($acl);
-                /* We had to have an empty value submitted to make sure all
-                   users with acls were sent back, so we can remove those
-                   without checkmarks. */
-                unset($acl['']);
-            } else {
-                $acl = array();
-            }
+    $curr_acl = $ACL->getACL($vars->folder);
+    foreach ($vars->acl as $user => $acl) {
+        if ($acl) {
+            $acl = array_flip($acl);
+            /* We had to have an empty value submitted to make sure all
+               users with acls were sent back, so we can remove those
+               without checkmarks. */
+            unset($acl['']);
+        } else {
+            $acl = array();
+        }
 
-            if (!$user) {
-                $notification->push(_("No user specified."), 'horde.error');
-                continue;
-            }
+        if (!$user) {
+            $notification->push(_("No user specified."), 'horde.error');
+            continue;
+        }
 
-            if (in_array($user, $protected)) {
-                if ($acl) {
-                    $notification->push(sprintf(_("Rights for user \"%s\" cannot be modified."), $user), 'horde.error');
-                }
-                continue;
+        if (in_array($user, $protected)) {
+            if ($acl) {
+                $notification->push(sprintf(_("Rights for user \"%s\" cannot be modified."), $user), 'horde.error');
             }
+            continue;
+        }
 
-            /* Check to see if ACL didn't change */
-            if ((isset($current_acl[$user])) &&
-                (array_keys($current_acl[$user]) == array_keys($acl))) {
-                continue;
-            }
+        /* Check to see if ACL didn't change */
+        if ((isset($curr_acl[$user])) &&
+            (array_keys($curr_acl[$user]) == array_keys($acl))) {
+            continue;
+        }
 
-            try {
-                $ACLDriver->editACL($folder, $user, $acl);
-                if (!count($acl)) {
-                    $notification->push(sprintf(_("All rights on folder \"%s\" successfully removed for user \"%s\"."), $folder, $user), 'horde.success');
-                } else {
-                    $notification->push(sprintf(_("User \"%s\" successfully given the specified rights for the folder \"%s\"."), $user, $folder), 'horde.success');
-                }
-            } catch (Horde_Exception $e) {
-                $notification->push($e);
+        try {
+            unset($curr_acl);
+            $ACL->editACL($vars->folder, $user, $acl);
+            if (!count($acl)) {
+                $notification->push(sprintf(_("All rights on folder \"%s\" successfully removed for user \"%s\"."), $vars->folder, $user), 'horde.success');
+            } else {
+                $notification->push(sprintf(_("User \"%s\" successfully given the specified rights for the folder \"%s\"."), $user, $vars->folder), 'horde.success');
             }
+        } catch (Horde_Exception $e) {
+            $notification->push($e);
         }
     }
     break;
 }
 
 $imp_folder = $injector->getInstance('IMP_Folder');
-$rights = $ACLDriver->getRights();
+$rights = $ACL->getRights();
 
-if (empty($folder)) {
-    $folder = 'INBOX';
+if (empty($vars->folder)) {
+    $vars->folder = 'INBOX';
 }
 
-$curr_acl = $ACLDriver->getACL($folder);
-$canEdit = $ACLDriver->canEdit($folder, Horde_Auth::getAuth());
+if (!isset($curr_acl)) {
+    $curr_acl = $ACL->getACL($vars->folder);
+}
+$canEdit = $ACL->canEdit($vars->folder, Horde_Auth::getAuth());
 
 $chunk = Horde_Util::nonInputVar('chunk');
 Horde_Prefs_Ui::generateHeader('imp', null, null, $chunk);
@@ -136,10 +129,9 @@ $t->set('aclurl', Horde::applicationUrl('acl.php'));
 $t->set('forminput', Horde_Util::formInput());
 $t->set('aclnavcell', Horde_Util::bufferOutput(array('Horde_Prefs_Ui', 'generateNavigationCell'), 'imp', 'acl'));
 $t->set('changefolder', Horde::link('#', _("Change Folder"), 'smallheader', '', '', '', '', array('id' => 'changefolder')));
-$t->set('sharedimg', Horde::img('shared.png', _("Change 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('options', IMP::flistSelect(array('selected' => $vars->folder)));
+$t->set('current', sprintf(_("Current access to %s"), IMP::displayFolder($vars->folder)));
+$t->set('folder', $vars->folder);
 $t->set('noacl', !count($curr_acl));
 $t->set('maxrule', 1);
 if (!$t->get('noacl')) {
@@ -155,7 +147,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' => in_array($val, $rule));
         }
         $cval[] = $entry;
     }
@@ -184,7 +176,8 @@ $rightsTitlesval = array();
 foreach ($rights as $right => $val) {
     $rightsval[] = array(
         'right' => $right,
-        'desc' => $val['desc']
+        'desc' => $val['desc'],
+        'title' => $val['title']
     );
 }
 
index 6b04362..88a1118 100644 (file)
@@ -27,7 +27,7 @@ if (!$is_pop3) {
         );
 }
 
-if (!empty($_SESSION['imp']['acl'])) {
+if (!empty($_SESSION['imp']['imap']['acl'])) {
     $prefGroups['acl'] = array(
         'column' => _("General Options"),
         'label' => _("Share Folders"),
index aff704f..d7fcc43 100644 (file)
@@ -39,13 +39,10 @@ class IMP_Imap_Acl
             throw new Horde_Exception(_("ACL requires an IMAP server."));
         }
 
-        $capability = $GLOBALS['imp_imap']->ob()->queryCapability('ACL');
-        if (!$capability) {
+        if (!$GLOBALS['imp_imap']->ob()->queryCapability('ACL')) {
             throw new Horde_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(
@@ -79,7 +76,7 @@ class IMP_Imap_Acl
             )
         );
 
-        if ($rfc4314) {
+        if ($GLOBALS['imp_imap']->ob()->queryCapability('RIGHTS')) {
             // RFC 4314 compliant rights
             $this->_rightsList = array_merge($this->_rightsList, array(
                 'k' => array(
@@ -119,7 +116,7 @@ class IMP_Imap_Acl
      *
      * @param string $mbox  The mailbox to get the ACL for.
      *
-     * @return array  A hash containing information on the ACL.
+     * @return array  See Horde_Imap_Client_Base::getACL().
      * @throws Horde_Exception
      */
     public function getACL($mbox)
@@ -136,15 +133,14 @@ class IMP_Imap_Acl
      *
      * @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).
+     * @param array $acl    The rights to be granted.
      *
      * @throws Horde_Exception
      */
     public function editACL($mbox, $user, $acl)
     {
         try {
-            $GLOBALS['imp_imap']->ob()->setACL($mbox, $user, array('rights' => $acl));
+            $GLOBALS['imp_imap']->ob()->setACL($mbox, $user, array('remove' => empty($acl), 'rights' => implode('', $acl)));
         } catch (Horde_Imap_Client_Exception $e) {
             throw new Horde_Exception(sprintf(_("Couldn't give user \"%s\" the following rights for the folder \"%s\": %s"), $user, $mbox, implode('', $acl)));
         }
@@ -156,25 +152,27 @@ class IMP_Imap_Acl
      * @param string $mbox  The mailbox name.
      * @param string $user  A user name.
      *
-     * @return boolean  True if $user has 'a' right
+     * @return boolean  True if $user has 'a' right.
      */
     public function canEdit($mbox, $user)
     {
         try {
             $rights = $GLOBALS['imp_imap']->ob()->listACLRights($mbox, $user);
+            $rights = array_merge($rights['required'], $rights['optional']);
             foreach ($rights as $val) {
                 if (strpos($val, 'a') !== false) {
                     return true;
                 }
             }
-            return false;
-        } catch (Horde_Imap_Client_Exception $e) {
-            return false;
-        }
+        } catch (Horde_Imap_Client_Exception $e) {}
+
+        return false;
     }
 
     /**
-     * TODO
+     * Return list of rights available on the server.
+     *
+     * @return array  Rights list.
      */
     public function getRights()
     {
@@ -182,7 +180,9 @@ class IMP_Imap_Acl
     }
 
     /**
-     * TODO
+     * Returns list of protected users.
+     *
+     * @return array  List of protected users.
      */
     public function getProtected()
     {
index 92d9927..9fd0a26 100644 (file)
@@ -11,7 +11,7 @@
  <ul>
   <li>
    <label for="aclfolder" class="hidden"><gettext>Change Folder</gettext></label>
-   <tag:changefolder /><tag:sharedimg /></a> <select id="aclfolder" name="folder"><tag:options /></select>
+   <tag:changefolder /><span class="folderImg"></span></a> <select id="aclfolder" name="folder"><tag:options /></select>
   </li>
  </ul>
  <span class="smallheader"><tag:current /></span>
  <th class="item" width="<tag:width />">
   <h3><strong><gettext>User</gettext></strong></h3>
  </th>
- <loop:rights>
+<loop:rights>
  <th class="item" width="<tag:width />">
-  <h3><strong><tag:rights.desc /></strong></h3>
+  <h4><strong><span title="<tag:rights.desc />"><tag:rights.title /></span></strong></h4>
  </th>
- </loop:rights>
+</loop:rights>
 </tr>
 <loop:curr_acl>
 <tr>
  <td class="item"><tag:curr_acl.index /><input id="<tag:curr_acl.index />" type="hidden" name="acl[<tag:curr_acl.index />][]" value="" /></td>
- <loop:curr_acl.rule>
+<loop:curr_acl.rule>
  <td class="item" align="center">
   <label class="hidden" for="<tag:curr_acl.index />:<tag:curr_acl.rule.val />">Rule <tag:curr_acl.rule.val /> for user <tag:curr_acl.index /></label>
   <input type="checkbox" class="checkbox" id="<tag:curr_acl.index />:<tag:curr_acl.rule.val />"
   <if:curr_acl.disabled> disabled="disabled"<else:curr_acl.disabled><if:canedit> name="acl[<tag:curr_acl.index />][]" value="<tag:curr_acl.rule.val />"<else:canedit> disabled="disabled"</else:canedit></if:canedit></else:curr_acl.disabled></if:curr_acl.disabled><if:curr_acl.rule.enabled> checked="checked"</if:curr_acl.rule.enabled> />
  </td>
- </loop:curr_acl.rule>
+</loop:curr_acl.rule>
 </tr>
 </loop:curr_acl>
 
  <td class="item">
   <label for="new_user" class="hidden">New User</label><tag:new_user />
  </td>
- <loop:rights>
+<loop:rights>
  <td class="item" align="center">
   <label class="hidden" for="new_user:<tag:rights.right />">Rule <tag:rights.right /> for the new user</label><input id="new_user:<tag:rights.right />" type="checkbox" name="new_acl[]" value="<tag:rights.right />" class="checkbox" />
  </td>
- </loop:rights>
+</loop:rights>
 </tr>
 <tr>
  <td>&nbsp;</td>
index 4baaabc..a09f45b 100644 (file)
@@ -598,7 +598,7 @@ div.mimeStatusMessage, div.mimePartInfo {
 }
 
 /* Other images. */
-.downloadAtc, .downloadZipAtc, .saveImgAtc, .printAtc, .closeImg, .deleteImg, .foldersImg, .searchuiImg, .reloadImg {
+.downloadAtc, .downloadZipAtc, .saveImgAtc, .printAtc, .closeImg, .deleteImg, .folderImg, .foldersImg, .searchuiImg, .reloadImg {
     display: -moz-inline-stack;
     display: inline-block;
     height: 16px;