Split of Kolab_Session from Kolab_Server.
authorGunnar Wrobel <p@rdus.de>
Mon, 2 Mar 2009 07:06:50 +0000 (07:06 +0000)
committerGunnar Wrobel <p@rdus.de>
Mon, 2 Mar 2009 07:06:50 +0000 (07:06 +0000)
15 files changed:
framework/Kolab_Server/lib/Horde/Kolab/IMAP.php [deleted file]
framework/Kolab_Server/lib/Horde/Kolab/IMAP/cclient.php [deleted file]
framework/Kolab_Server/lib/Horde/Kolab/IMAP/pear.php [deleted file]
framework/Kolab_Server/lib/Horde/Kolab/IMAP/test.php [deleted file]
framework/Kolab_Server/lib/Horde/Kolab/Session.php [deleted file]
framework/Kolab_Server/package.xml
framework/Kolab_Server/test/Horde/Kolab/Server/SessionTest.php [deleted file]
framework/Kolab_Session/lib/Horde/Kolab/IMAP.php [new file with mode: 0644]
framework/Kolab_Session/lib/Horde/Kolab/IMAP/cclient.php [new file with mode: 0644]
framework/Kolab_Session/lib/Horde/Kolab/IMAP/pear.php [new file with mode: 0644]
framework/Kolab_Session/lib/Horde/Kolab/IMAP/test.php [new file with mode: 0644]
framework/Kolab_Session/lib/Horde/Kolab/Session.php [new file with mode: 0644]
framework/Kolab_Session/package.xml [new file with mode: 0644]
framework/Kolab_Session/test/Horde/Kolab/Session/AllTests.php [new file with mode: 0644]
framework/Kolab_Session/test/Horde/Kolab/Session/SessionTest.php [new file with mode: 0644]

diff --git a/framework/Kolab_Server/lib/Horde/Kolab/IMAP.php b/framework/Kolab_Server/lib/Horde/Kolab/IMAP.php
deleted file mode 100644 (file)
index 23e47f1..0000000
+++ /dev/null
@@ -1,138 +0,0 @@
-<?php
-/**
- * @package Kolab_Storage
- *
- */
-
-/**
- * The Horde_Kolab_IMAP class provides a wrapper around two different Kolab IMAP
- * connection types.
- *
- *
- * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @package Kolab_Storage
- */
-class Horde_Kolab_IMAP
-{
-
-    /**
-     * IMAP server to connect to.
-     *
-     * @var string
-     */
-    var $_server;
-
-    /**
-     * IMAP server port to connect to.
-     *
-     * @var int
-     */
-    var $_port;
-
-    /**
-     * IMAP connection.
-     *
-     * @var mixed
-     */
-    var $_imap;
-
-    /**
-     * Connection reuse detection signature.
-     *
-     * @var string
-     */
-    var $_reuse_detection;
-
-    /**
-     * Constructor.
-     *
-     * @param string     $server   Server to connect to
-     * @param int        $port     Port to connect to
-     */
-    function Horde_Kolab_IMAP($server, $port)
-    {
-        $this->_server = $server;
-        $this->_port   = $port;
-    }
-
-    /**
-     * Attempts to return a reference to a concrete Horde_Kolab_IMAP instance.
-     * It will only create a new instance if no Horde_Kolab_IMAP instance
-     * exists.
-     *
-     * @static
-     *
-     * @param string     $server                Server name
-     * @param int        $port                  Port
-     * @param boolean    $annotation_required   Do we actually need
-     *                                          the annotation calls?
-     *
-     * @return Horde_Kolab_IMAP|PEAR_Error The concrete reference.
-     */
-    function &singleton($server, $port, $annotation_required = true)
-    {
-        static $instances = array();
-
-        /**
-         * There are Kolab specific PHP functions available that make the IMAP
-         * access more efficient. If these are detected, or if they are not
-         * required for the current operation, the PHP IMAP implementation
-         * should be used.
-         *
-         * The c-client Kolab driver provides quicker IMAP routines so is
-         * preferable whenever possible.
-         */
-        if ($annotation_required) {
-            if (function_exists('imap_status_current')
-                && function_exists('imap_getannotation')) {
-                $driver = 'cclient';
-            } else {
-                $driver = 'pear';
-            }
-        } else {
-            $driver = 'cclient';
-        }
-
-        if (isset($GLOBALS['KOLAB_TESTING'])) {
-            $driver = 'test';
-        }
-
-        $signature = "$server|$port|$driver";
-        if (!isset($instances[$signature])) {
-            $instances[$signature] = &Horde_Kolab_IMAP::factory($server, $port, $driver);
-        }
-
-        return $instances[$signature];
-    }
-
-    /**
-     * Attempts to return a concrete Horde_Kolab_IMAP instance based on the
-     * available PHP functionality.
-     *
-     * @param string     $server                Server name.
-     * @param int        $port                  Server port.
-     * @param string     $driver                Which driver should we use?
-     *
-     * @return Horde_Kolab_IMAP|PEAR_Error The newly created concrete
-     *                                     Horde_Kolab_IMAP instance.
-     */
-    function &factory($server, $port, $driver = 'cclient')
-    {
-        @include_once dirname(__FILE__) . '/IMAP/' . $driver . '.php';
-
-        $class = 'Horde_Kolab_IMAP_' . $driver;
-        if (class_exists($class)) {
-            $driver = &new $class($server, $port);
-        } else {
-            return PEAR::raiseError(sprintf(_("Failed to load Kolab IMAP driver %s"), $driver));
-        }
-
-        return $driver;
-    }
-}
diff --git a/framework/Kolab_Server/lib/Horde/Kolab/IMAP/cclient.php b/framework/Kolab_Server/lib/Horde/Kolab/IMAP/cclient.php
deleted file mode 100644 (file)
index cab2389..0000000
+++ /dev/null
@@ -1,777 +0,0 @@
-<?php
-/**
- * @package Kolab_Storage
- *
- */
-
-/**
- * The Horde_Kolab_IMAP_Connection_cclient class connects to an IMAP server using
- * the IMAP functionality within PHP.
- *
- *
- * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @package Kolab_Storage
- */
-class Horde_Kolab_IMAP_cclient extends Horde_Kolab_IMAP
-{
-
-    /**
-     * Basic IMAP connection string.
-     *
-     * @var string
-     */
-    var $_base_mbox;
-
-    /**
-     * IMAP connection string that includes the folder.
-     *
-     * @var string
-     */
-    var $_mbox;
-
-    /**
-     * The signature of the current connection.
-     *
-     * @var string
-     */
-    var $_signature;
-
-    /**
-     * IMAP user name.
-     *
-     * @var string
-     */
-    var $_login;
-
-    /**
-     * IMAP password.
-     *
-     * @var string
-     */
-    var $_password;
-
-    /**
-     * Connects to the IMAP server.
-     *
-     * @param string $login     The user account name.
-     * @param string $password  The user password.
-     * @param boolean $tls      Should TLS be used for the connection?
-     *
-     * @return boolean|PEAR_Error  True in case the connection was opened
-     *                             successfully.
-     */
-    function connect($login, $password, $tls = false)
-    {
-        $options = '';
-        if (!$tls) {
-            $options = '/notls';
-        }
-
-        $mbox = '{' . $this->_server . ':' . $this->_port
-            . $options . '}';
-
-        $this->_signature = "$mbox|$login|$password";
-        if ($this->_signature == $this->_reuse_detection) {
-            return true;
-        }
-
-        $this->_mbox = $this->_base_mbox = $mbox;
-        $this->_login = $login;
-        $this->_password = $password;
-        $this->_imap = null;
-
-        $this->_reuse_detection = $this->_signature;
-
-        return true;
-    }
-
-    /**
-     * Lazy connect to the IMAP server.
-     *
-     * @return mixed  True in case the connection was opened successfully, a
-     *                PEAR error otherwise.
-     */
-    function _connect()
-    {
-        $result = @imap_open($this->_base_mbox, $this->_login, $this->_password, OP_HALFOPEN);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Server: %s. Error: %s"), $this->_server, @imap_last_error()));
-        }
-        $this->_imap = $result;
-        return true;
-    }
-
-    /**
-     * Disconnects from the IMAP server. If not really necessary this
-     * should not be called. Once the page got served the connections
-     * should be closed anyhow and if there is a chance to reuse the
-     * connection it should be used.
-     *
-     * @return mixed  True in case the connection was closed successfully, a
-     *                PEAR error otherwise.
-     */
-    function disconnect()
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $this->_reuse_detection = null;
-
-        $result = @imap_close($this->_imap);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Server: %s. Error: %s"), $this->_server, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Opens the given folder.
-     *
-     * @param string $folder  The folder to open.
-     *
-     * @return mixed  True in case the folder was opened successfully, a PEAR
-     *                error otherwise.
-     */
-    function select($folder)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $this->_mbox = $this->_base_mbox . $folder;
-
-        $result = @imap_reopen($this->_imap, $this->_mbox);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Does the given folder exist?
-     *
-     * @param string $folder  The folder to check.
-     *
-     * @return mixed  True in case the folder exists, false otherwise
-     */
-    function exists($folder)
-    {
-        $folders = $this->getMailboxes();
-        if (is_a($folders, 'PEAR_Error')) {
-            return $folders;
-        }
-        return in_array($folder, $folders);
-    }
-
-    /**
-     * Create the specified folder.
-     *
-     * @param string $folder  The folder to create.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function create($folder)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $mbox = $this->_base_mbox . $folder;
-        $result = @imap_createmailbox($this->_imap, $mbox);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Delete the specified folder.
-     *
-     * @param string $folder  The folder to delete.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function delete($folder)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $mbox = $this->_base_mbox . $folder;
-        $result = @imap_deletemailbox($this->_imap, $mbox);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Rename the specified folder.
-     *
-     * @param string $old  The folder to rename.
-     * @param string $new  The new name of the folder.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function rename($old, $new)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_renamemailbox($this->_imap,
-                                      $this->_base_mbox . $old,
-                                      $this->_base_mbox . $new);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $old, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Returns the status of the current folder.
-     *
-     * @return array  An array that contains 'uidvalidity' and 'uidnext'.
-     */
-    function status()
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $status = @imap_status_current($this->_imap, SA_MESSAGES | SA_UIDVALIDITY | SA_UIDNEXT);
-        if (!$status) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_mbox, @imap_last_error()));
-        }
-
-        return array('uidvalidity' => $status->uidvalidity,
-                     'uidnext' => $status->uidnext);
-    }
-
-    /**
-     * Returns the uids of the messages in this folder.
-     *
-     * @return mixed  The message ids or a PEAR error in case of an error.
-     */
-    function getUids()
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $uids = @imap_search($this->_imap, 'UNDELETED', SE_UID);
-        if (!is_array($uids)) {
-            $uids = array();
-        }
-
-        return $uids;
-    }
-
-    /**
-     * Searches the current folder using the given list of search criteria.
-     *
-     * @param string $search_list  A list of search criteria.
-     *
-     * @return mixed  The list of matching message ids or a PEAR error in case
-     *                of an error.
-     */
-    function search($search_list)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_search($this->_imap, $search_list, SE_UID);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_mbox, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Searches the headers of the messages. c-client does not allow using
-     * "HEADER" as it is possible with Net/IMAP, so we need a workaround.
-     *
-     * @param string $field  The name of the header field.
-     * @param string $value  The value that field should match.
-     *
-     * @return mixed  The list of matching message ids or a PEAR error in case
-     *                of an error.
-     */
-    function searchHeaders($field, $value)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $uids = $this->getUids();
-        if (is_a($uids, 'PEAR_Error')) {
-            return $uids;
-        }
-
-        $result = array();
-        foreach ($uids as $uid) {
-            $header = $this->getMessageHeader($uid, false);
-            if (is_a($header, 'PEAR_Error')) {
-                return $header;
-            }
-            $header_array = MIME_Headers::parseHeaders($header);
-            if (isset($header_array[$field]) && $header_array[$field] == $value) {
-                $result[] = $uid;
-            }
-        }
-
-        return $result;
-    }
-
-    /**
-     * Retrieves the message headers for a given message id.
-     *
-     * @param integer $uid            The message id.
-     * @param boolean $peek_for_body  Prefetch the body.
-     *
-     * @return mixed  The message header or a PEAR error in case of an error.
-     */
-    function getMessageHeader($uid, $peek_for_body = true)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $flags = FT_UID;
-        if ($peek_for_body) {
-            $flags |= FT_PREFETCHTEXT;
-        }
-
-        $result = @imap_fetchheader($this->_imap, $uid, $flags);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
-        }
-
-        return $result;
-    }
-
-    /**
-     * Retrieves the message body for a given message id.
-     *
-     * @param integer $uid  The message id.
-     *
-     * @return mixed  The message body or a PEAR error in case of an error.
-     */
-    function getMessageBody($uid)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_body($this->_imap, $uid, FT_UID);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
-        }
-
-        return $result;
-    }
-
-    /**
-     * Retrieves the full message text for a given message id.
-     *
-     * @param integer $uid  The message id.
-     *
-     * @return mixed  The message text or a PEAR error in case of an error.
-     */
-    function getMessage($uid)
-    {
-        $header = $this->getMessageHeader($uid);
-        if (is_a($header, 'PEAR_Error')) {
-            return $header;
-        }
-
-        $body = $this->getMessageBody($uid);
-        if (is_a($body, 'PEAR_Error')) {
-            return $body;
-        }
-
-        return $header . $body;
-    }
-
-    /**
-     * Retrieves a list of mailboxes on the server.
-     *
-     * @return mixed  The list of mailboxes or a PEAR error in case of an
-     *                error.
-     */
-    function getMailboxes()
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $folders = array();
-
-        $result = @imap_list($this->_imap, $this->_base_mbox, '*');
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_base_mbox, @imap_last_error()));
-        }
-
-        $server_len = strlen($this->_base_mbox);
-        foreach ($result as $folder) {
-            if (substr($folder, 0, $server_len) == $this->_base_mbox) {
-                $folders[] = substr($folder, $server_len);
-            }
-        }
-
-        return $folders;
-    }
-
-    /**
-     * Fetches the annotation on a folder.
-     *
-     * @param string $entries        The entry to fetch.
-     * @param string $value          The specific value to fetch.
-     * @param string $mailbox_name   The name of the folder.
-     *
-     * @return mixed  The annotation value or a PEAR error in case of an error.
-     */
-    function getAnnotation($entries, $value, $mailbox_name)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        static $annotations = array();
-
-        $signature = "$this->_signature|$entries|$value|$mailbox_name";
-
-        if (!isset($annotations[$signature])) {
-            $result = @imap_getannotation($this->_imap, $mailbox_name, $entries, $value);
-            if (isset($result[$value])) {
-                $annotations[$signature] = $result[$value];
-            } else {
-                $annotations[$signature] = '';
-            }
-        }
-
-        return $annotations[$signature];
-    }
-
-    /**
-     * Sets the annotation on a folder.
-     *
-     * @param string $entries        The entry to set.
-     * @param array  $values         The values to set
-     * @param string $mailbox_name   The name of the folder.
-     *
-     * @return mixed  True if successfull, a PEAR error otherwise.
-     */
-    function setAnnotation($entries, $values, $mailbox_name)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        foreach ($values as $key => $value) {
-            $result = @imap_setannotation($this->_imap, $mailbox_name, $entries, $key, $value);
-            if (!$result) {
-                return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $mailbox_name, @imap_last_error()));
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Retrieve the access rights from a folder
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     *
-     * @return mixed An array of rights if successfull, a PEAR error
-     * otherwise.
-     */
-    function getACL($folder)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_getacl($this->_imap, $folder);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Retrieve the access rights from a folder not owned by the current user
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     *
-     * @return mixed An array of rights if successfull, a PEAR error
-     * otherwise.
-     */
-    function getMyRights($folder)
-    {
-        if (!function_exists('imap_myrights')) {
-            return PEAR::raiseError(sprintf(_("PHP does not support imap_myrights."), $folder, @imap_last_error()));
-        }
-
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_myrights($this->_imap, $folder);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
-        }
-        return $result;
-
-    }
-
-    /**
-     * Set the access rights for a folder
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     * @param string $user    The user to set the ACLs for
-     * @param string $acl     The ACLs
-     *
-     * @return mixed True if successfull, a PEAR error otherwise.
-     */
-    function setACL($folder, $user, $acl)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_setacl($this->_imap, $folder, $user, $acl);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Delete the access rights for a user.
-     *
-     * @param string $folder  The folder that should be modified.
-     * @param string $user    The user that should get the ACLs removed
-     *
-     * @return mixed True if successfull, a PEAR error otherwise.
-     */
-    function deleteACL($folder, $user)
-    {
-        return $this->setACL($folder, $user, '');
-    }
-
-    /**
-     * Appends a message to the current folder.
-     *
-     * @param string $msg  The message to append.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function appendMessage($msg)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_append($this->_imap, $this->_mbox, $msg);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_mbox, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Copies a message to a new folder.
-     *
-     * @param integer $uid        IMAP message id.
-     * @param string $new_folder  Target folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function copyMessage($uid, $new_folder)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_mail_copy($this->_imap, $uid, $new_folder, CP_UID);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $new_folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Moves a message to a new folder.
-     *
-     * @param integer $uid        IMAP message id.
-     * @param string $new_folder  Target folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function moveMessage($uid, $new_folder)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_mail_move($this->_imap, $uid, $new_folder, CP_UID);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $new_folder, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Deletes messages from the current folder.
-     *
-     * @param integer $uids  IMAP message ids.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function deleteMessages($uids)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        if (!is_array($uids)) {
-            $uids = array($uids);
-        }
-
-        foreach($uids as $uid) {
-            $result = @imap_delete($this->_imap, $uid, FT_UID);
-            if (!$result) {
-                return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Undeletes a message in the current folder.
-     *
-     * @param integer $uid  IMAP message id.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function undeleteMessages($uid)
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_undelete($this->_imap, $uid, FT_UID);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Expunges messages in the current folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function expunge()
-    {
-        if (!isset($this->_imap)) {
-            $result = $this->_connect();
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-
-        $result = @imap_expunge($this->_imap);
-        if (!$result) {
-            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $this->_mbox, @imap_last_error()));
-        }
-        return $result;
-    }
-
-    /**
-     * Return the currently selected mailbox
-     *
-     * @return string  The mailbox currently selected
-     */
-    function current()
-    {
-        return $this->_mbox;
-    }
-}
diff --git a/framework/Kolab_Server/lib/Horde/Kolab/IMAP/pear.php b/framework/Kolab_Server/lib/Horde/Kolab/IMAP/pear.php
deleted file mode 100644 (file)
index dbb7181..0000000
+++ /dev/null
@@ -1,519 +0,0 @@
-<?php
-/**
- * @package Kolab_Storage
- *
- */
-
-/**
- * The Horde_Kolab library requires version >= 1.0.3 of Net_IMAP (i.e. a
- * version that includes support for the ANNOTATEMORE IMAP extension). The
- * latest version of Net_IMAP can be obtained from
- * http://pear.php.net/get/Net_IMAP
- */
-require_once 'Net/IMAP.php';
-
-/**
- * The Horde_Kolab_IMAP_Connection_pear class connects to an IMAP server using the
- * Net_IMAP PEAR package.
- *
- *
- * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
- * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
- * @package Kolab_Storage
- */
-class Horde_Kolab_IMAP_pear extends Horde_Kolab_IMAP
-{
-
-    /**
-     * The signature of the current connection
-     *
-     * @var string
-     */
-    var $_signature;
-
-    /**
-     * Connects to the IMAP server.
-     *
-     * @param string  $login     The user account name.
-     * @param string  $password  The user password.
-     * @param boolean $tls       Should TLS be used for the connection?
-     *
-     * @return mixed  True in case the connection was opened successfully, a
-     *                PEAR error otherwise.
-     */
-    function connect($login, $password, $tls = false)
-    {
-        $this->_signature = $this->_server . '|' . $this->_port . "|$login|$password|$tls";
-
-        // Reuse existing connection?
-        if ($this->_signature == $this->_reuse_detection) {
-            return true;
-        }
-
-        $this->_imap = &new Net_IMAP($this->_server, $this->_port);
-        $result = $this->_imap->login($login, $password, true, false);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
-        $this->_reuse_detection = $this->_signature;
-
-        return true;
-    }
-
-    /**
-     * Disconnects from the IMAP server.
-     *
-     * @return mixed  True in case the connection was closed successfully, a
-     *                PEAR error otherwise.
-     */
-    function disconnect()
-    {
-        $this->_reuse_detection = null;
-        return $this->_imap->disconnect();
-    }
-
-    /**
-     * Opens the given folder.
-     *
-     * @param string $folder  The folder to open
-     *
-     * @return mixed  True in case the folder was opened successfully, a PEAR
-     *                error otherwise.
-     */
-    function select($folder)
-    {
-        return $this->_imap->selectMailbox($folder);
-    }
-
-    /**
-     * Does the given folder exist?
-     *
-     * @param string $folder  The folder to check.
-     *
-     * @return mixed True in case the folder exists, false otherwise
-     */
-    function exists($folder)
-    {
-        return $this->_imap->mailboxExist($folder);
-    }
-
-    /**
-     * Create the specified folder.
-     *
-     * @param string $folder  The folder to create.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function create($folder)
-    {
-        return $this->_imap->createMailbox($folder);
-    }
-
-    /**
-     * Delete the specified folder.
-     *
-     * @param string $folder  The folder to delete.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function delete($folder)
-    {
-        return $this->_imap->deleteMailbox($folder);
-    }
-
-    /**
-     * Rename the specified folder.
-     *
-     * @param string $old  The folder to rename.
-     * @param string $new  The new name of the folder.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function rename($old, $new)
-    {
-        return $this->_imap->renameMailbox($old, $new);
-    }
-
-    /**
-     * Returns the status of the current folder.
-     *
-     * @return array  An array that contains 'uidvalidity' and 'uidnext'.
-     */
-    function status()
-    {
-        $result = array();
-
-        $mailbox = $this->_imap->getCurrentMailbox();
-
-        // Net_IMAP is not very efficent here
-        $ret = $this->_imap->cmdStatus($mailbox, 'UIDVALIDITY');
-        $result['uidvalidity'] = $ret['PARSED']['STATUS']['ATTRIBUTES']['UIDVALIDITY'];
-
-        $ret = $this->_imap->cmdStatus($mailbox, 'UIDNEXT');
-        $result['uidnext'] = $ret['PARSED']['STATUS']['ATTRIBUTES']['UIDNEXT'];
-
-        return $result;
-    }
-
-    /**
-     * Returns the message ids of the messages in this folder.
-     *
-     * @return array  The message ids.
-     */
-    function getUids()
-    {
-        $uids = $this->_imap->search('UNDELETED', true);
-        if (!is_array($uids)) {
-            $uids = array();
-        }
-        return $uids;
-    }
-
-    /**
-     * Searches the current folder using the given list of search criteria.
-     *
-     * @param string $search_list  A list of search criteria.
-     *
-     * @return mixed  The list of matching message ids or a PEAR error in case
-     *                of an error.
-     */
-    function search($search_list, $uidSearch = true)
-    {
-        return $this->_imap->search($search_list, $uidSearch);
-    }
-
-    /**
-     * Searches the headers of the messages.
-     *
-     * @param string $field  The name of the header field.
-     * @param string $value  The value that field should match.
-     *
-     * @return mixed  The list of matching message ids or a PEAR error in case
-     *                of an error.
-     */
-    function searchHeaders($field, $value)
-    {
-        return $this->_imap->search('HEADER "' . $field . '" "' . $value . '"', true);
-    }
-
-    /**
-     * Retrieves the message headers for a given message id.
-     *
-     * @param int $uid                The message id.
-     * @param boolean $peek_for_body  Prefetch the body.
-     *
-     * @return mixed  The message header or a PEAR error in case of an error.
-     */
-    function getMessageHeader($uid, $peek_for_body = true)
-    {
-        $ret = $this->_imap->cmdUidFetch($uid, 'BODY[HEADER]');
-        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
-            return PEAR::raiseError(sprintf(_("Failed fetching headers of IMAP message %s. Error was %s"),
-                                            $uid,
-                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
-        }
-
-        if (isset($ret['PARSED'])) {
-            foreach ($ret['PARSED'] as $msg) {
-                if (isset($msg['EXT']['BODY[HEADER]']['CONTENT'])) {
-                    return $msg['EXT']['BODY[HEADER]']['CONTENT'];
-                }
-            }
-        }
-
-        return '';
-    }
-
-    /**
-     * Retrieves the message body for a given message id.
-     *
-     * @param integet $uid  The message id.
-     *
-     * @return mixed  The message body or a PEAR error in case of an error.
-     */
-    function getMessageBody($uid)
-    {
-        $ret = $this->_imap->cmdUidFetch($uid, 'BODY[TEXT]');
-        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
-            return PEAR::raiseError(sprintf(_("Failed fetching body of IMAP message %s. Error was %s"),
-                                            $uid,
-                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
-        }
-
-        if (isset($ret['PARSED'])) {
-            foreach ($ret['PARSED'] as $msg) {
-                if (isset($msg['EXT']['BODY[TEXT]']['CONTENT'])) {
-                    return $msg['EXT']['BODY[TEXT]']['CONTENT'];
-                }
-            }
-        }
-
-        return '';
-    }
-
-    /**
-     * Retrieves the full message text for a given message id.
-     *
-     * @param integer $uid  The message id.
-     *
-     * @return mixed  The message text or a PEAR error in case of an error.
-     */
-    function getMessage($uid)
-    {
-        $ret = $this->_imap->cmdUidFetch($uid, 'RFC822');
-        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
-            return PEAR::raiseError(sprintf(_("Failed fetching IMAP message %s. Error was %s"),
-                                            $uid,
-                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
-        }
-
-        if (isset($ret['PARSED'])) {
-            foreach ($ret['PARSED'] as $msg) {
-                if (isset($msg['EXT']['RFC822']['CONTENT'])) {
-                    return $msg['EXT']['RFC822']['CONTENT'];
-                }
-            }
-        }
-
-        return '';
-    }
-
-    /**
-     * Retrieves a list of mailboxes on the server.
-     *
-     * @return mixed  The list of mailboxes or a PEAR error in case of an
-     *                error.
-     */
-    function getMailboxes()
-    {
-        return $this->_imap->getMailboxes();
-    }
-
-    /**
-     * Fetches the annotation on a folder.
-     *
-     * @param string $entries       The entry to fetch.
-     * @param string $value         The specific value to fetch.
-     * @param string $mailbox_name  The name of the folder.
-     *
-     * @return mixed  The annotation value or a PEAR error in case of an error.
-     */
-    function getAnnotation($entries, $value, $mailbox_name)
-    {
-        static $annotations = array();
-
-        $signature = "$this->_signature|$entries|$value|$mailbox_name";
-
-        if (!isset($annotations[$signature])) {
-            $annotations[$signature] = $this->_imap->getAnnotation($entries, $value, $mailbox_name);
-        }
-
-        return $annotations[$signature];
-    }
-
-    /**
-     * Sets the annotation on a folder.
-     *
-     * @param string $entries        The entry to set.
-     * @param array  $values         The values to set
-     * @param string $mailbox_name   The name of the folder.
-     *
-     * @return mixed  True if successfull, a PEAR error otherwise.
-     */
-    function setAnnotation($entries, $values, $mailbox_name)
-    {
-        return $this->_imap->setAnnotation($entries, $values, $mailbox_name);
-    }
-
-    /**
-     * Retrieve the access rights from a folder
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     *
-     * @return mixed An array of rights if successfull, a PEAR error
-     * otherwise.
-     */
-    function getACL($folder)
-    {
-        $result = $this->_imap->getACL($folder);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-        $acl = array();
-        foreach ($result as $user) {
-            $acl[$user['USER']] = $user['RIGHTS'];
-        }
-        return $acl;
-    }
-
-    /**
-     * Retrieve the access rights on a folder not owned by the current user
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     *
-     * @return mixed An array of rights if successfull, a PEAR error
-     * otherwise.
-     */
-    function getMyRights($folder)
-    {
-        $result = $this->_imap->getMyRights($folder);
-        return $result;
-    }
-
-    /**
-     * Set the access rights for a folder
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     * @param string $user    The user to set the ACLs for
-     * @param string $acl     The ACLs
-     *
-     * @return mixed True if successfull, a PEAR error otherwise.
-     */
-    function setACL($folder, $user, $acl)
-    {
-        return $this->_imap->setACL($folder, $user, $acl);
-    }
-
-    /**
-     * Delete the access rights for a user.
-     *
-     * @param string $folder  The folder that should be modified.
-     * @param string $user    The user that should get the ACLs removed
-     *
-     * @return mixed True if successfull, a PEAR error otherwise.
-     */
-    function deleteACL($folder, $user)
-    {
-        return $this->_imap->deleteACL($folder, $user);
-    }
-
-    /**
-     * Appends a message to the current folder.
-     *
-     * @param string $msg  The message to append.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function appendMessage($msg)
-    {
-        return $this->_imap->appendMessage($msg);
-    }
-
-    /**
-     * Copies a message to a new folder.
-     *
-     * @param integer $uid        IMAP message id.
-     * @param string $new_folder  Target folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function copyMessage($uid, $new_folder)
-    {
-        $ret = $this->_imap->cmdUidCopy($uid, $new_folder);
-        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
-            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
-                                            $uid,
-                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
-        }
-        return true;
-    }
-
-    /**
-     * Moves a message to a new folder.
-     *
-     * @param integer $uid        IMAP message id.
-     * @param string $new_folder  Target folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function moveMessage($uid, $new_folder)
-    {
-        $result = $this->copyMessage($uid, $new_folder);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
-        $result = $this->deleteMessages($uid);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-
-        $result = $this->expunge();
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-        return true;
-    }
-
-    /**
-     * Deletes messages from the current folder.
-     *
-     * @param integer $uids  IMAP message ids.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function deleteMessages($uids)
-    {
-        if (!is_array($uids)) {
-            $uids = array($uids);
-        }
-
-        foreach ($uids as $uid) {
-            $ret = $this->_imap->cmdUidStore($uid, '+FLAGS.SILENT', '\Deleted');
-            if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
-                return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
-                                                $uid,
-                                                $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
-            }
-        }
-
-        return true;
-    }
-
-    /**
-     * Undeletes a message in the current folder.
-     *
-     * @param integer $uid  IMAP message id.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function undeleteMessages($uid)
-    {
-        $ret = $this->_imap->cmdUidStore($uid, '-FLAGS.SILENT', '\Deleted');
-        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
-            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
-                                            $uid,
-                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
-        }
-        return true;
-    }
-
-    /**
-     * Expunges messages in the current folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function expunge()
-    {
-        return $this->_imap->expunge();
-    }
-
-    /**
-     * Return the currently selected mailbox
-     *
-     * @return string  The mailbox currently selected
-     */
-    function current()
-    {
-        return $this->_imap->getCurrentMailbox();
-    }
-}
diff --git a/framework/Kolab_Server/lib/Horde/Kolab/IMAP/test.php b/framework/Kolab_Server/lib/Horde/Kolab/IMAP/test.php
deleted file mode 100644 (file)
index b95fe39..0000000
+++ /dev/null
@@ -1,727 +0,0 @@
-<?php
-/**
- * @package Kolab_Storage
- *
- */
-
-/**
- * Indicate that a mail has been marked as deleted
- */
-define('KOLAB_IMAP_FLAG_DELETED', 1);
-
-/**
- * The Horde_Kolab_IMAP_Connection_test class simulates an IMAP server for
- * testing purposes.
- *
- *
- * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Storage
- */
-class Horde_Kolab_IMAP_test extends Horde_Kolab_IMAP
-{
-
-    /**
-     * If we are supposed to be connected this holds the user
-     * credentials and some connection details.
-     *
-     * @var string
-     */
-    var $_connected;
-
-    /**
-     * Login of the current user
-     *
-     * @var string
-     */
-    var $_user;
-
-    /**
-     * The data of the mailbox currently opened
-     *
-     * @var array
-     */
-    var $_mbox = null;
-
-    /**
-     * The name of the mailbox currently opened
-     *
-     * @var array
-     */
-    var $_mboxname = null;
-
-    /**
-     * Prepare the dummy server.
-     *
-     * @param string  $login     The user account name.
-     * @param string  $password  The user password.
-     * @param boolean $tls       Should TLS be used for the connection?
-     *
-     * @return mixed  True in case the connection was opened successfully, a
-     *                PEAR error otherwise.
-     */
-    function connect($login, $password, $tls = false)
-    {
-        if (!is_array($GLOBALS['KOLAB_TESTING'])) {
-            /* Simulate an empty IMAP server */
-            $GLOBALS['KOLAB_TESTING'] = array();
-        }
-
-        $tls = ($tls) ? 'tls' : 'notls';
-        $this->_connected = $login . ':' . $password . ':' . $tls;
-        $this->_user = $login;
-        $this->_mbox = null;
-        $this->_mboxname = null;
-    }
-
-    /**
-     * Disconnects from the IMAP server.
-     *
-     * @return mixed  True in case the connection was closed successfully, a
-     *                PEAR error otherwise.
-     */
-    function disconnect()
-    {
-        $this->_connected = null;
-    }
-
-    function _parseFolder($folder)
-    {
-        if (substr($folder, 0, 5) == 'INBOX') {
-            $user = split('@', $this->_user);
-            return 'user/' . $user[0] . substr($folder, 5);
-        }
-        return $folder;
-    }
-
-    /**
-     * Opens the given folder.
-     *
-     * @param string $folder  The folder to open
-     *
-     * @return mixed  True in case the folder was opened successfully, a PEAR
-     *                error otherwise.
-     */
-    function select($folder)
-    {
-        $folder = $this->_parseFolder($folder);
-        if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) {
-            return PEAR::raiseError(sprintf("IMAP folder %s does not exist!", $folder));
-        }
-        $this->_mbox = &$GLOBALS['KOLAB_TESTING'][$folder];
-        $this->_mboxname = $folder;
-        return true;
-    }
-
-    /**
-     * Does the given folder exist?
-     *
-     * @param string $folder  The folder to check.
-     *
-     * @return mixed True in case the folder exists, false otherwise
-     */
-    function exists($folder)
-    {
-        $folder = $this->_parseFolder($folder);
-        if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) {
-            return false;
-        }
-        return true;
-    }
-
-    /**
-     * Create the specified folder.
-     *
-     * @param string $folder  The folder to create.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function create($folder)
-    {
-        $folder = $this->_parseFolder($folder);
-        if (isset($GLOBALS['KOLAB_TESTING'][$folder])) {
-            return PEAR::raiseError(sprintf("IMAP folder %s does already exist!", $folder));
-        }
-        $GLOBALS['KOLAB_TESTING'][$folder] = array(
-            'status' => array(
-                'uidvalidity' => time(),
-                'uidnext' => 1),
-            'mails' => array(),
-            'permissions' => array(),
-            'annotations' => array(),
-        );
-        return true;
-    }
-
-    /**
-     * Delete the specified folder.
-     *
-     * @param string $folder  The folder to delete.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function delete($folder)
-    {
-        $folder = $this->_parseFolder($folder);
-        if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) {
-            return PEAR::raiseError(sprintf("IMAP folder %s does not exist!", $folder));
-        }
-        unset($GLOBALS['KOLAB_TESTING'][$folder]);
-        return true;
-    }
-
-    /**
-     * Rename the specified folder.
-     *
-     * @param string $old  The folder to rename.
-     * @param string $new  The new name of the folder.
-     *
-     * @return mixed True in case the operation was successfull, a
-     *               PEAR error otherwise.
-     */
-    function rename($old, $new)
-    {
-        $old = $this->_parseFolder($old);
-        $new = $this->_parseFolder($new);
-
-        if (!isset($GLOBALS['KOLAB_TESTING'][$old])) {
-            return PEAR::raiseError(sprintf("IMAP folder %s does not exist!", $old));
-        }
-        if (isset($GLOBALS['KOLAB_TESTING'][$new])) {
-            return PEAR::raiseError(sprintf("IMAP folder %s does already exist!", $new));
-        }
-        $GLOBALS['KOLAB_TESTING'][$new] = $GLOBALS['KOLAB_TESTING'][$old];
-        unset($GLOBALS['KOLAB_TESTING'][$old]);
-        return true;
-    }
-
-    /**
-     * Returns the status of the current folder.
-     *
-     * @return array  An array that contains 'uidvalidity' and 'uidnext'.
-     */
-    function status()
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        return $this->_mbox['status'];
-    }
-
-    /**
-     * Returns the message ids of the messages in this folder.
-     *
-     * @return array  The message ids.
-     */
-    function getUids()
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        $uids = array();
-        foreach ($this->_mbox['mails'] as $uid => $mail) {
-            if (!($mail['flags'] & KOLAB_IMAP_FLAG_DELETED)) {
-                $uids[] = $uid;
-            }
-        }
-        return $uids;
-    }
-
-    /**
-     * Searches the current folder using the given list of search criteria.
-     *
-     * @param string $search_list  A list of search criteria.
-     *
-     * @return mixed  The list of matching message ids or a PEAR error in case
-     *                of an error.
-     */
-    function search($search_list, $uidSearch = true)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        $uids = array();
-        if (substr($search_list, 0, 7) == 'SUBJECT') {
-            $needle = '^Subject: ' . substr($search_list, 8);
-            foreach ($this->_mbox['mails'] as $uid => $mail) {
-                if (preg_match($needle, $mail['header'])) {
-                    $uids[] = $uid;
-                }
-            }
-        } else if (substr($search_list, 0, 6) == 'HEADER') {
-            preg_match('([^ ]*) ([^ ]*)', substr($search_list, 7), $matches);
-            $needle = '^' . $matches[0] . ': ' . $matches[1];
-            foreach ($this->_mbox['mails'] as $uid => $mail) {
-                if (preg_match($needle, $mail['header'])) {
-                    $uids[] = $uid;
-                }
-            }
-
-        }
-        return $uids;
-    }
-
-    /**
-     * Searches the headers of the messages.
-     *
-     * @param string $field  The name of the header field.
-     * @param string $value  The value that field should match.
-     *
-     * @return mixed  The list of matching message ids or a PEAR error in case
-     *                of an error.
-     */
-    function searchHeaders($field, $value)
-    {
-        return $this->search('HEADER "' . $field . '" "' . $value . '"', true);
-    }
-
-    /**
-     * Retrieves the message headers for a given message id.
-     *
-     * @param int $uid                The message id.
-     * @param boolean $peek_for_body  Prefetch the body.
-     *
-     * @return mixed  The message header or a PEAR error in case of an error.
-     */
-    function getMessageHeader($uid, $peek_for_body = true)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        if (!isset($this->_mbox['mails'][$uid])) {
-            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-        }
-        return $this->_mbox['mails'][$uid]['header'];
-    }
-
-    /**
-     * Retrieves the message body for a given message id.
-     *
-     * @param integet $uid  The message id.
-     *
-     * @return mixed  The message body or a PEAR error in case of an error.
-     */
-    function getMessageBody($uid)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        if (!isset($this->_mbox['mails'][$uid])) {
-            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-        }
-        return $this->_mbox['mails'][$uid]['body'];
-    }
-
-    /**
-     * Retrieves the full message text for a given message id.
-     *
-     * @param integer $uid  The message id.
-     *
-     * @return mixed  The message text or a PEAR error in case of an error.
-     */
-    function getMessage($uid)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        if (!isset($this->_mbox['mails'][$uid])) {
-            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-        }
-        return $this->_mbox['mails'][$uid]['header'] . $this->_mbox['mails'][$uid]['body'];
-    }
-
-    /**
-     * Retrieves a list of mailboxes on the server.
-     *
-     * @return mixed  The list of mailboxes or a PEAR error in case of an
-     *                error.
-     */
-    function getMailboxes()
-    {
-        $mboxes = array_keys($GLOBALS['KOLAB_TESTING']);
-        $user = split('@', $this->_user);
-        $pattern = '#^user/' . $user[0] . '#';
-        $result = array();
-        foreach ($mboxes as $mbox) {
-            $result[] = preg_replace($pattern, 'INBOX', $mbox);
-        }
-        return $result;
-    }
-
-    /**
-     * Fetches the annotation on a folder.
-     *
-     * @param string $entries       The entry to fetch.
-     * @param string $value         The specific value to fetch.
-     * @param string $mailbox_name  The name of the folder.
-     *
-     * @return mixed  The annotation value or a PEAR error in case of an error.
-     */
-    function getAnnotation($entries, $value, $mailbox_name)
-    {
-        $mailbox_name = $this->_parseFolder($mailbox_name);
-        $old_mbox = null;
-        if ($mailbox_name != $this->_mboxname) {
-            $old_mbox = $this->_mboxname;
-            $result = $this->select($mailbox_name);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        if (!isset($this->_mbox['annotations'][$entries])
-            || !isset($this->_mbox['annotations'][$entries][$value])) {
-            return false;
-        }
-        $annotation = $this->_mbox['annotations'][$entries][$value];
-        if ($old_mbox) {
-            $this->select($old_mbox);
-        }
-        return $annotation;
-    }
-
-    /**
-     * Sets the annotation on a folder.
-     *
-     * @param string $entries        The entry to set.
-     * @param array  $values         The values to set
-     * @param string $mailbox_name   The name of the folder.
-     *
-     * @return mixed  True if successfull, a PEAR error otherwise.
-     */
-    function setAnnotation($entries, $values, $mailbox_name)
-    {
-        $mailbox_name = $this->_parseFolder($mailbox_name);
-        $old_mbox = null;
-        if ($mailbox_name != $this->_mboxname) {
-            $old_mbox = $this->_mboxname;
-            $result = $this->select($mailbox_name);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        if (!isset($this->_mbox['annotations'][$entries])) {
-            $this->_mbox['annotations'][$entries] = array();
-        }
-        foreach ($values as $key => $value) {
-            $this->_mbox['annotations'][$entries][$key] = $value;
-        }
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Retrieve the access rights from a folder
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     *
-     * @return mixed An array of rights if successfull, a PEAR error
-     * otherwise.
-     */
-    function getACL($folder)
-    {
-        $folder = $this->_parseFolder($folder);
-        $old_mbox = null;
-        if ($folder != $this->_mboxname) {
-            $old_mbox = $this->_mboxname;
-            $result = $this->select($folder);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        $acl = $this->_mbox['permissions'];
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return $acl;
-    }
-
-    /**
-     * Retrieve the access rights on a folder not owned by the current user
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     *
-     * @return mixed An array of rights if successfull, a PEAR error
-     * otherwise.
-     */
-    function getMyRights($folder)
-    {
-        $folder = $this->_parseFolder($folder);
-        $old_mbox = null;
-        if ($folder != $this->_mboxname) {
-            $old_mbox = $this->_mboxname;
-            $result = $this->select($folder);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        $acl = '';
-        if (isset($this->_mbox['permissions'][$this->_user])) {
-            $acl = $this->_mbox['permissions'][$this->_user];
-        }
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return $acl;
-    }
-
-    /**
-     * Set the access rights for a folder
-     *
-     * @param string $folder  The folder to retrieve the ACLs from.
-     * @param string $user    The user to set the ACLs for
-     * @param string $acl     The ACLs
-     *
-     * @return mixed True if successfull, a PEAR error otherwise.
-     */
-    function setACL($folder, $user, $acl)
-    {
-        $folder = $this->_parseFolder($folder);
-        $old_mbox = null;
-        if ($folder != $this->_mboxname) {
-            $old_mbox = $this->_mboxname;
-            $result = $this->select($folder);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        $this->_mbox['permissions'][$user] = $acl;
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Delete the access rights for a user.
-     *
-     * @param string $folder  The folder that should be modified.
-     * @param string $user    The user that should get the ACLs removed
-     *
-     * @return mixed True if successfull, a PEAR error otherwise.
-     */
-    function deleteACL($folder, $user)
-    {
-        $folder = $this->_parseFolder($folder);
-        $old_mbox = null;
-        if ($folder != $this->_mboxname) {
-            $old_mbox = $this->_mboxname;
-            $result = $this->select($folder);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        unset($this->_mbox['permissions'][$user]);
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Appends a message to the current folder.
-     *
-     * @param string $msg  The message to append.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function appendMessage($msg)
-    {
-        $split = strpos($msg, "\r\n\r\n");
-        $mail = array('header' => substr($msg, 0, $split + 2),
-                      'body' => substr($msg, $split + 3));
-        return $this->_appendMessage($mail);
-    }
-
-    /**
-     * Appends a message to the current folder.
-     *
-     * @param array $msg  The message to append.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function _appendMessage($msg)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        $mail = array();
-        $mail['flags'] = 0;
-        $mail['header'] = $msg['header'];
-        $mail['body'] = $msg['body'];
-
-
-        $this->_mbox['mails'][$this->_mbox['status']['uidnext']] = $mail;
-        $this->_mbox['status']['uidnext']++;
-        return true;
-    }
-
-    /**
-     * Copies a message to a new folder.
-     *
-     * @param integer $uid        IMAP message id.
-     * @param string $new_folder  Target folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function copyMessage($uid, $new_folder)
-    {
-        $new_folder = $this->_parseFolder($new_folder);
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        if (!isset($this->_mbox['mails'][$uid])) {
-            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-        }
-        $mail = $this->_mbox['mails'][$uid];
-
-        $old_mbox = null;
-        $result = $this->select($new_folder);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-        $this->_appendMessage($mail);
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Moves a message to a new folder.
-     *
-     * @param integer $uid        IMAP message id.
-     * @param string $new_folder  Target folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function moveMessage($uid, $new_folder)
-    {
-        $new_folder = $this->_parseFolder($new_folder);
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-        if (!isset($this->_mbox['mails'][$uid])) {
-            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-        }
-        $mail = $this->_mbox['mails'][$uid];
-        unset($this->_mbox['mails'][$uid]);
-
-        $old_mbox = null;
-        $result = $this->select($new_folder);
-        if (is_a($result, 'PEAR_Error')) {
-            return $result;
-        }
-        $this->_appendMessage($mail);
-        if ($old_mbox) {
-            $result = $this->select($old_mbox);
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-        }
-        return true;
-    }
-
-    /**
-     * Deletes messages from the current folder.
-     *
-     * @param integer $uids  IMAP message ids.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function deleteMessages($uids)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-
-        if (!is_array($uids)) {
-            $uids = array($uids);
-        }
-
-        foreach ($uids as $uid) {
-
-            if (!isset($this->_mbox['mails'][$uid])) {
-                return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-            }
-            $this->_mbox['mails'][$uid]['flags'] |= KOLAB_IMAP_FLAG_DELETED;
-        }
-        return true;
-    }
-
-    /**
-     * Undeletes a message in the current folder.
-     *
-     * @param integer $uid  IMAP message id.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function undeleteMessages($uid)
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-
-        if (!isset($this->_mbox['mails'][$uid])) {
-            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
-        }
-        $this->_mbox['mails'][$uid]['flags'] &= ~KOLAB_IMAP_FLAG_DELETED;
-        return true;
-    }
-
-    /**
-     * Expunges messages in the current folder.
-     *
-     * @return mixed  True or a PEAR error in case of an error.
-     */
-    function expunge()
-    {
-        if (!$this->_mbox) {
-            return PEAR::raiseError("No IMAP folder selected!");
-        }
-
-        $remaining = array();
-        foreach ($this->_mbox['mails'] as $uid => $mail) {
-            if (!($mail['flags'] & KOLAB_IMAP_FLAG_DELETED)) {
-                $remaining[$uid] = $mail;
-            }
-        }
-        $this->_mbox['mails'] = $remaining;
-        return true;
-    }
-
-    /**
-     * Return the currently selected mailbox
-     *
-     * @return string  The mailbox currently selected
-     */
-    function current()
-    {
-        return $this->_mboxname;
-    }
-}
diff --git a/framework/Kolab_Server/lib/Horde/Kolab/Session.php b/framework/Kolab_Server/lib/Horde/Kolab/Session.php
deleted file mode 100644 (file)
index 7f2c131..0000000
+++ /dev/null
@@ -1,357 +0,0 @@
-<?php
-/**
- * The Horde_Kolab_Session class holds additional user details for the current
- * session.
- *
- *
- * PHP version 5
- *
- * @category Kolab
- * @package  Kolab_Server
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Server
- */
-
-/** We need the Auth library */
-require_once 'Horde/Auth.php';
-
-/**
- * The Horde_Kolab_Session class holds additional user details for the current
- * session.
- *
- * The core user credentials (login, pass) are kept within the Auth module and
- * can be retrieved using <code>Auth::getAuth()</code> respectively
- * <code>Auth::getCredential('password')</code>. Any additional Kolab user data
- * relevant for the user session should be accessed via the Horde_Kolab_Session
- * class.
- *
- *
- * Copyright 2008-2009 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.
- *
- * @category Kolab
- * @package  Kolab_Server
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Server
- */
-class Horde_Kolab_Session
-{
-
-    /**
-     * User ID.
-     *
-     * @var string
-     */
-    var $user_id;
-
-    /**
-     * User UID.
-     *
-     * @var string
-     */
-    var $user_uid;
-
-    /**
-     * Primary user mail address.
-     *
-     * @var string
-     */
-    var $user_mail;
-
-    /**
-     * Full name.
-     *
-     * @var string
-     */
-    var $user_name = '';
-
-    /**
-     * True if the Kolab_Server login was successfull.
-     *
-     * @var boolean|PEAR_Error
-     */
-    var $auth;
-
-    /**
-     * The connection parameters for the IMAP server.
-     *
-     * @var array|PEAR_Error
-     */
-    var $_imap_params;
-
-    /**
-     * Our IMAP connection.
-     *
-     * @var Horde_Kolab_IMAP
-     */
-    var $_imap;
-
-    /**
-     * The free/busy server for the current user.
-     *
-     * @var array|PEAR_Error
-     */
-    var $freebusy_server;
-
-    /**
-     * Constructor.
-     *
-     * @param string $user        The session will be setup for the user with
-     *                            this ID.
-     * @param array  $credentials An array of login credentials. For Kolab,
-     *                            this must contain a "password" entry.
-     */
-    function Horde_Kolab_Session($user = null, $credentials = null)
-    {
-        global $conf;
-
-        if (empty($user)) {
-            $user = Auth::getAuth();
-            if (empty($user)) {
-                $user = 'anonymous';
-            } else if (!strpos($user, '@')) {
-                $user = $user . '@' . (!empty($_SERVER['SERVER_NAME']) ?
-                                       $_SERVER['SERVER_NAME'] : 'localhost');
-            }
-        }
-
-        $this->user_id      = $user;
-        $this->_imap_params = array();
-
-        $user_object = null;
-
-        if ($user != 'anonymous') {
-            $server = $this->getServer($user, $credentials);
-            $this->user_uid = $server->uid;
-            $user_object    = $server->fetch();
-
-            if (empty($conf['kolab']['imap']['allow_special_users'])
-                && !is_a($user_object, 'Horde_Kolab_Server_Object_user')) {
-                throw new Horde_Kolab_Server_Exception(_('Access to special Kolab users is denied.'));
-            }
-            if (isset($conf['kolab']['server']['deny_group'])) {
-                $dn = $server->gidForMail($conf['kolab']['server']['deny_group']);
-                if (empty($dn)) {
-                    Horde::logMessage('The Kolab configuratin setting $conf[\'kolab\'][\'server\'][\'deny_group\'] holds a non-existing group!',
-                                      __FILE__, __LINE__, PEAR_LOG_WARNING);
-                } else if (in_array($dn, $user_object->getGroups())) {
-                    throw new Horde_Kolab_Server_Exception(_('You are member of a group that may not login on this server.'));
-                }
-            }
-            if (isset($conf['kolab']['server']['allow_group'])) {
-                $dn = $server->gidForMail($conf['kolab']['server']['allow_group']);
-                if (empty($dn)) {
-                    Horde::logMessage('The Kolab configuratin setting $conf[\'kolab\'][\'server\'][\'allow_group\'] holds a non-existing group!',
-                                      __FILE__, __LINE__, PEAR_LOG_WARNING);
-                } else if (!in_array($dn, $user_object->getGroups())) {
-                    throw new Horde_Kolab_Server_Exception(_('You are no member of a group that may login on this server.'));
-                }
-            }
-                
-            $result = $user_object->get(KOLAB_ATTR_MAIL);
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $this->user_mail = $result;
-            }
-
-            $result = $user_object->get(KOLAB_ATTR_SID);
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $this->user_id = $result;
-            }
-
-            $result = $user_object->get(KOLAB_ATTR_FNLN);
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $this->user_name = $result;
-            }
-
-            $result = $user_object->getServer('imap');
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $server = explode(':', $result, 2);
-                if (!empty($server[0])) {
-                    $this->_imap_params['hostspec'] = $server[0];
-                }
-                if (!empty($server[1])) {
-                    $this->_imap_params['port'] = $server[1];
-                }
-            }
-
-            $result = $user_object->getServer('freebusy');
-            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
-                $this->freebusy_server = $result;
-            }
-        }
-
-        if (empty($this->user_mail)) {
-            $this->user_mail = $user;
-        }
-
-        if (!isset($this->_imap_params['hostspec'])) {
-            if (isset($conf['kolab']['imap']['server'])) {
-                $this->_imap_params['hostspec'] = $conf['kolab']['imap']['server'];
-            } else {
-                $this->_imap_params['hostspec'] = 'localhost';
-            }
-        }
-
-        if (!isset($this->_imap_params['port'])) {
-            if (isset($conf['kolab']['imap']['port'])) {
-                $this->_imap_params['port'] = $conf['kolab']['imap']['port'];
-            } else {
-                $this->_imap_params['port'] = 143;
-            }
-        }
-
-        $this->_imap_params['protocol'] = 'imap/notls/novalidate-cert';
-    }
-
-    /**
-     * Returns the properties that need to be serialized.
-     *
-     * @return array  List of serializable properties.
-     */
-    function __sleep()
-    {
-        $properties = get_object_vars($this);
-        unset($properties['_imap']);
-        $properties = array_keys($properties);
-        return $properties;
-    }
-
-    /**
-     * Get the Kolab Server connection.
-     *
-     * @param string $user        The session will be setup for the user with
-     *                            this ID.
-     * @param array  $credentials An array of login credentials. For Kolab,
-     *                            this must contain a "password" entry.
-     *
-     * @return Horde_Kolab_Server|PEAR_Error The Kolab Server connection.
-     */
-    function &getServer($user = null, $credentials = null)
-    {
-        /** We need the Kolab Server access. */
-        require_once 'Horde/Kolab/Server.php';
-
-        $params = array();
-        if ($this->user_uid) {
-            $params['uid']  = $this->user_uid;
-            $params['pass'] = Auth::getCredential('password');
-        } else if (isset($user)) {
-            $params['user'] = $user;
-            if (isset($credentials['password'])) {
-                $params['pass'] = $credentials['password'];
-            } else {
-                $params['pass'] = Auth::getCredential('password');
-            }
-        }
-        return Horde_Kolab_Server::singleton($params);
-    }
-
-    /**
-     * Get the IMAP connection parameters.
-     *
-     * @return array|PEAR_Error The IMAP connection parameters.
-     */
-    function &getImapParams()
-    {
-        return $this->_imap_params;
-    }
-
-    /**
-     * Create an IMAP connection.
-     *
-     * @return Horde_Kolab_IMAP|PEAR_Error The IMAP connection.
-     */
-    function &getImap()
-    {
-        if (!isset($this->_imap)) {
-
-            $params = $this->getImapParams();
-            if (is_a($params, 'PEAR_Error')) {
-                return $params;
-            }
-
-            /** We need the Kolab IMAP library now. */
-            require_once 'Horde/Kolab/IMAP.php';
-
-            $imap = &Horde_Kolab_IMAP::singleton($params['hostspec'],
-                                                 $params['port'], true, false);
-            if (is_a($imap, 'PEAR_Error')) {
-                return $imap;
-            }
-
-            $result = $imap->connect(Auth::getAuth(),
-                                     Auth::getCredential('password'));
-            if (is_a($result, 'PEAR_Error')) {
-                return $result;
-            }
-            $this->_imap = &$imap;
-        }
-        return $this->_imap;
-    }
-
-    /**
-     * Attempts to return a reference to a concrete Horde_Kolab_Session instance.
-     *
-     * It will only create a new instance if no Horde_Kolab_Session instance
-     * currently exists or if a user ID has been specified that does not match the
-     * user ID/user mail of the current session.
-     *
-     * This method must be invoked as:
-     *   <code>$var = &Horde_Kolab_Session::singleton();</code>
-     *
-     * @param string $user        The session will be setup for the user with
-     *                            this ID.
-     * @param array  $credentials An array of login credentials. For Kolab,
-     *                            this must contain a "password" entry.
-     *
-     * @static
-     *
-     * @return Horde_Kolab_Session  The concrete Session reference.
-     */
-    function &singleton($user = null, $credentials = null, $destruct = false)
-    {
-        static $session;
-
-        if (!isset($session)) {
-            /**
-             * Horde_Kolab_Server currently has no caching so we mainly
-             * cache some user information here as reading this data
-             * may be expensive when running in a multi-host
-             * environment.
-             */
-            require_once 'Horde/SessionObjects.php';
-            $hs      = &Horde_SessionObjects::singleton();
-            $session = $hs->query('kolab_session');
-        }
-
-        if (empty($user)) {
-            $user = Auth::getAuth();
-        }
-
-        if ($destruct || empty($session)
-            || ($user != $session->user_mail && $user != $session->user_id)) {
-            $session = new Horde_Kolab_Session($user, $credentials);
-        }
-
-        register_shutdown_function(array(&$session, 'shutdown'));
-
-        return $session;
-    }
-
-    /**
-     * Stores the object in the session cache.
-     *
-     * @return NULL
-     */
-    function shutdown()
-    {
-        require_once 'Horde/SessionObjects.php';
-        $session = &Horde_SessionObjects::singleton();
-        $session->overwrite('kolab_session', $this, false);
-    }
-
-}
index c341544..81df488 100644 (file)
@@ -39,20 +39,14 @@ http://pear.php.net/dtd/package-2.0.xsd">
  <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
  <notes>
   * Converted the package to Horde 4 / PHP 5.
+  * Split the session driver into a separate package (Kolab_Session).
  </notes>
  <contents>
   <dir name="/">
    <dir name="lib">
     <dir name="Horde">
      <dir name="Kolab">
-      <file name="IMAP.php" role="php" />
-      <dir name="IMAP">
-       <file name="cclient.php" role="php" />
-       <file name="pear.php" role="php" />
-       <file name="test.php" role="php" />
-      </dir> <!-- /lib/Horde/Kolab/IMAP -->
       <file name="Server.php" role="php" />
-      <file name="Session.php" role="php" />
       <dir name="Server">
        <file name="Exception.php" role="php" />
        <file name="ldap.php" role="php" />
@@ -90,7 +84,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
        <file name="ldapTest.php" role="test" />
        <file name="ObjectTest.php" role="test" />
        <file name="ServerTest.php" role="test" />
-       <file name="SessionTest.php" role="test" />
        <file name="testTest.php" role="test" />
        <file name="UserHandlingTest.php" role="test" />
        <file name="UserTest.php" role="test" />
@@ -133,12 +126,7 @@ http://pear.php.net/dtd/package-2.0.xsd">
  </dependencies>
  <phprelease>
   <filelist>
-   <install name="lib/Horde/Kolab/IMAP.php" as="Horde/Kolab/IMAP.php" />
-   <install name="lib/Horde/Kolab/IMAP/cclient.php" as="Horde/Kolab/IMAP/cclient.php" />
-   <install name="lib/Horde/Kolab/IMAP/pear.php" as="Horde/Kolab/IMAP/pear.php" />
-   <install name="lib/Horde/Kolab/IMAP/test.php" as="Horde/Kolab/IMAP/test.php" />
    <install name="lib/Horde/Kolab/Server.php" as="Horde/Kolab/Server.php" />
-   <install name="lib/Horde/Kolab/Session.php" as="Horde/Kolab/Session.php" />
    <install name="lib/Horde/Kolab/Test/Server.php" as="Horde/Kolab/Test/Server.php" />
    <install name="lib/Horde/Kolab/Server/Exception.php" as="Horde/Kolab/Server/Exception.php" />
    <install name="lib/Horde/Kolab/Server/ldap.php" as="Horde/Kolab/Server/ldap.php" />
@@ -163,7 +151,6 @@ http://pear.php.net/dtd/package-2.0.xsd">
    <install name="test/Horde/Kolab/Server/ldapTest.php" as="Horde/Kolab/Server/ldapTest.php" />
    <install name="test/Horde/Kolab/Server/ObjectTest.php" as="Horde/Kolab/Server/ObjectTest.php" />
    <install name="test/Horde/Kolab/Server/ServerTest.php" as="Horde/Kolab/Server/ServerTest.php" />
-   <install name="test/Horde/Kolab/Server/SessionTest.php" as="Horde/Kolab/Server/SessionTest.php" />
    <install name="test/Horde/Kolab/Server/testTest.php" as="Horde/Kolab/Server/testTest.php" />
    <install name="test/Horde/Kolab/Server/UserHandlingTest.php" as="Horde/Kolab/Server/UserHandlingTest.php" />
    <install name="test/Horde/Kolab/Server/UserTest.php" as="Horde/Kolab/Server/UserTest.php" />
diff --git a/framework/Kolab_Server/test/Horde/Kolab/Server/SessionTest.php b/framework/Kolab_Server/test/Horde/Kolab/Server/SessionTest.php
deleted file mode 100644 (file)
index 8312c14..0000000
+++ /dev/null
@@ -1,208 +0,0 @@
-<?php
-/**
- * Test the Kolab session handler.
- *
- * PHP version 5
- *
- * @category Kolab
- * @package  Kolab_Server
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Server
- */
-
-/**
- * The Autoloader allows us to omit "require/include" statements.
- */
-require_once 'Horde/Autoloader.php';
-
-/**
- * Test the Kolab session handler.
- *
- * Copyright 2008-2009 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.
- *
- * @category Kolab
- * @package  Kolab_Server
- * @author   Gunnar Wrobel <wrobel@pardus.de>
- * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
- * @link     http://pear.horde.org/index.php?package=Kolab_Server
- */
-class Horde_Kolab_Server_SessionTest extends Horde_Kolab_Test_Server
-{
-    /**
-     * Test class construction.
-     *
-     * @return NULL
-     */
-    public function testConstructEmpty()
-    {
-        global $conf;
-        $conf['kolab']['imap']['allow_special_users'] = true;
-
-        $session = &Horde_Kolab_Session::singleton();
-
-        $this->assertEquals('anonymous', $session->user_mail);
-
-        $params = $session->getImapParams();
-        $this->assertNoError($params);
-        $this->assertEquals('localhost', $params['hostspec']);
-        $this->assertEquals(143, $params['port']);
-    }
-
-    /**
-     * Test old style class construction.
-     *
-     * @return NULL
-     */
-    public function testConstructSimple()
-    {
-        global $conf;
-        $conf['kolab']['imap']['server']     = 'example.com';
-        $conf['kolab']['imap']['port']       = 200;
-        $conf['kolab']['freebusy']['server'] = 'fb.example.com';
-
-        $session = &new Horde_Kolab_Session();
-        $params  = $session->getImapParams();
-        if (is_a($params, 'PEAR_Error')) {
-            $this->assertEquals('', $params->getMessage());
-        }
-        $this->assertEquals('example.com', $params['hostspec']);
-        $this->assertEquals(200, $params['port']);
-    }
-
-    /**
-     * Test IMAP server retrieval.
-     *
-     * @return NULL
-     */
-    public function testGetServer()
-    {
-        $server = &$this->prepareEmptyKolabServer();
-        $result = $server->add($this->provideBasicUserTwo());
-        $this->assertNoError($result);
-        $this->assertEquals(1, count($GLOBALS['KOLAB_SERVER_TEST_DATA']));
-
-        $session = &Horde_Kolab_Session::singleton('test',
-                                                   array('password' => 'test'));
-
-        $this->assertNoError($session->auth);
-        $this->assertEquals('test@example.org', $session->user_mail);
-
-        $params = $session->getImapParams();
-        $this->assertNoError($params);
-        $this->assertEquals('home.example.org', $params['hostspec']);
-        $this->assertEquals(143, $params['port']);
-        $this->assertEquals('test@example.org', $session->user_mail);
-
-        $session->shutdown();
-
-        $hs = &Horde_SessionObjects::singleton();
-
-        $recovered_session = &$hs->query('kolab_session');
-        $params            = $recovered_session->getImapParams();
-        $this->assertNoError($params);
-        $this->assertEquals('home.example.org', $params['hostspec']);
-        $this->assertEquals(143, $params['port']);
-        $this->assertEquals('test@example.org', $session->user_mail);
-
-        $this->assertEquals('https://fb.example.org/freebusy', $session->freebusy_server);
-    }
-
-    /**
-     * Test retrieving the FreeBusy server for the unauthenticated state.
-     *
-     * @return NULL
-     */
-    public function testGetFreeBusyServer()
-    {
-        $server = &$this->prepareEmptyKolabServer();
-        $result = $server->add($this->provideBasicUserTwo());
-        $this->assertNoError($result);
-        $session = &Horde_Kolab_Session::singleton();
-        $this->assertEquals('', $session->freebusy_server);
-    }
-
-    /**
-     * Test group based login allow implemention.
-     *
-     * @return NULL
-     */
-    public function testLoginAllow()
-    {
-        global $conf;
-        $conf['kolab']['server']['allow_group'] = 'group2@example.org';
-        $conf['kolab']['server']['deny_group'] = null;
-
-        $server = &$this->prepareEmptyKolabServer();
-        $result = $server->add($this->provideBasicUserOne());
-        $this->assertNoError($result);
-        $result = $server->add($this->provideBasicUserTwo());
-        $this->assertNoError($result);
-        $groups = $this->validGroups();
-        foreach ($groups as $group) {
-            $result = $server->add($group[0]);
-            $this->assertNoError($result);
-        }
-
-        $session = &Horde_Kolab_Session::singleton('wrobel',
-                                                   array('password' => 'none'),
-                                                   true);
-
-        $this->assertNoError($session->auth);
-        $this->assertEquals('wrobel@example.org', $session->user_mail);
-
-        try {
-            $session = &Horde_Kolab_Session::singleton('test',
-                                                       array('password' => 'test'),
-                                                       true);
-        } catch (Horde_Kolab_Server_Exception $e) {
-            $this->assertError($e, 'You are no member of a group that may login on this server.');
-        }
-        // FIXME: Ensure that the session gets overwritten
-        //$this->assertTrue(empty($session->user_mail));
-    }
-
-    /**
-     * Test group based login deny implemention.
-     *
-     * @return NULL
-     */
-    public function testLoginDeny()
-    {
-        global $conf;
-        $conf['kolab']['server']['deny_group'] = 'group2@example.org';
-        unset($conf['kolab']['server']['allow_group']);
-
-        $server = &$this->prepareEmptyKolabServer();
-        $result = $server->add($this->provideBasicUserOne());
-        $this->assertNoError($result);
-        $result = $server->add($this->provideBasicUserTwo());
-        $this->assertNoError($result);
-        $groups = $this->validGroups();
-        foreach ($groups as $group) {
-            $result = $server->add($group[0]);
-            $this->assertNoError($result);
-        }
-
-        $session = &Horde_Kolab_Session::singleton('test',
-                                                   array('password' => 'test'),
-                                                   true);
-
-        $this->assertNoError($session->auth);
-        $this->assertEquals('test@example.org', $session->user_mail);
-
-        try {
-            $session = &Horde_Kolab_Session::singleton('wrobel',
-                                                       array('password' => 'none'),
-                                                       true);
-        } catch (Horde_Kolab_Server_Exception $e) {
-            $this->assertError($e, 'You are member of a group that may not login on this server.');
-        }
-        // FIXME: Ensure that the session gets overwritten
-        //$this->assertTrue(empty($session->user_mail));
-    }
-
-}
diff --git a/framework/Kolab_Session/lib/Horde/Kolab/IMAP.php b/framework/Kolab_Session/lib/Horde/Kolab/IMAP.php
new file mode 100644 (file)
index 0000000..23e47f1
--- /dev/null
@@ -0,0 +1,138 @@
+<?php
+/**
+ * @package Kolab_Storage
+ *
+ */
+
+/**
+ * The Horde_Kolab_IMAP class provides a wrapper around two different Kolab IMAP
+ * connection types.
+ *
+ *
+ * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
+ * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @package Kolab_Storage
+ */
+class Horde_Kolab_IMAP
+{
+
+    /**
+     * IMAP server to connect to.
+     *
+     * @var string
+     */
+    var $_server;
+
+    /**
+     * IMAP server port to connect to.
+     *
+     * @var int
+     */
+    var $_port;
+
+    /**
+     * IMAP connection.
+     *
+     * @var mixed
+     */
+    var $_imap;
+
+    /**
+     * Connection reuse detection signature.
+     *
+     * @var string
+     */
+    var $_reuse_detection;
+
+    /**
+     * Constructor.
+     *
+     * @param string     $server   Server to connect to
+     * @param int        $port     Port to connect to
+     */
+    function Horde_Kolab_IMAP($server, $port)
+    {
+        $this->_server = $server;
+        $this->_port   = $port;
+    }
+
+    /**
+     * Attempts to return a reference to a concrete Horde_Kolab_IMAP instance.
+     * It will only create a new instance if no Horde_Kolab_IMAP instance
+     * exists.
+     *
+     * @static
+     *
+     * @param string     $server                Server name
+     * @param int        $port                  Port
+     * @param boolean    $annotation_required   Do we actually need
+     *                                          the annotation calls?
+     *
+     * @return Horde_Kolab_IMAP|PEAR_Error The concrete reference.
+     */
+    function &singleton($server, $port, $annotation_required = true)
+    {
+        static $instances = array();
+
+        /**
+         * There are Kolab specific PHP functions available that make the IMAP
+         * access more efficient. If these are detected, or if they are not
+         * required for the current operation, the PHP IMAP implementation
+         * should be used.
+         *
+         * The c-client Kolab driver provides quicker IMAP routines so is
+         * preferable whenever possible.
+         */
+        if ($annotation_required) {
+            if (function_exists('imap_status_current')
+                && function_exists('imap_getannotation')) {
+                $driver = 'cclient';
+            } else {
+                $driver = 'pear';
+            }
+        } else {
+            $driver = 'cclient';
+        }
+
+        if (isset($GLOBALS['KOLAB_TESTING'])) {
+            $driver = 'test';
+        }
+
+        $signature = "$server|$port|$driver";
+        if (!isset($instances[$signature])) {
+            $instances[$signature] = &Horde_Kolab_IMAP::factory($server, $port, $driver);
+        }
+
+        return $instances[$signature];
+    }
+
+    /**
+     * Attempts to return a concrete Horde_Kolab_IMAP instance based on the
+     * available PHP functionality.
+     *
+     * @param string     $server                Server name.
+     * @param int        $port                  Server port.
+     * @param string     $driver                Which driver should we use?
+     *
+     * @return Horde_Kolab_IMAP|PEAR_Error The newly created concrete
+     *                                     Horde_Kolab_IMAP instance.
+     */
+    function &factory($server, $port, $driver = 'cclient')
+    {
+        @include_once dirname(__FILE__) . '/IMAP/' . $driver . '.php';
+
+        $class = 'Horde_Kolab_IMAP_' . $driver;
+        if (class_exists($class)) {
+            $driver = &new $class($server, $port);
+        } else {
+            return PEAR::raiseError(sprintf(_("Failed to load Kolab IMAP driver %s"), $driver));
+        }
+
+        return $driver;
+    }
+}
diff --git a/framework/Kolab_Session/lib/Horde/Kolab/IMAP/cclient.php b/framework/Kolab_Session/lib/Horde/Kolab/IMAP/cclient.php
new file mode 100644 (file)
index 0000000..cab2389
--- /dev/null
@@ -0,0 +1,777 @@
+<?php
+/**
+ * @package Kolab_Storage
+ *
+ */
+
+/**
+ * The Horde_Kolab_IMAP_Connection_cclient class connects to an IMAP server using
+ * the IMAP functionality within PHP.
+ *
+ *
+ * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
+ * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @package Kolab_Storage
+ */
+class Horde_Kolab_IMAP_cclient extends Horde_Kolab_IMAP
+{
+
+    /**
+     * Basic IMAP connection string.
+     *
+     * @var string
+     */
+    var $_base_mbox;
+
+    /**
+     * IMAP connection string that includes the folder.
+     *
+     * @var string
+     */
+    var $_mbox;
+
+    /**
+     * The signature of the current connection.
+     *
+     * @var string
+     */
+    var $_signature;
+
+    /**
+     * IMAP user name.
+     *
+     * @var string
+     */
+    var $_login;
+
+    /**
+     * IMAP password.
+     *
+     * @var string
+     */
+    var $_password;
+
+    /**
+     * Connects to the IMAP server.
+     *
+     * @param string $login     The user account name.
+     * @param string $password  The user password.
+     * @param boolean $tls      Should TLS be used for the connection?
+     *
+     * @return boolean|PEAR_Error  True in case the connection was opened
+     *                             successfully.
+     */
+    function connect($login, $password, $tls = false)
+    {
+        $options = '';
+        if (!$tls) {
+            $options = '/notls';
+        }
+
+        $mbox = '{' . $this->_server . ':' . $this->_port
+            . $options . '}';
+
+        $this->_signature = "$mbox|$login|$password";
+        if ($this->_signature == $this->_reuse_detection) {
+            return true;
+        }
+
+        $this->_mbox = $this->_base_mbox = $mbox;
+        $this->_login = $login;
+        $this->_password = $password;
+        $this->_imap = null;
+
+        $this->_reuse_detection = $this->_signature;
+
+        return true;
+    }
+
+    /**
+     * Lazy connect to the IMAP server.
+     *
+     * @return mixed  True in case the connection was opened successfully, a
+     *                PEAR error otherwise.
+     */
+    function _connect()
+    {
+        $result = @imap_open($this->_base_mbox, $this->_login, $this->_password, OP_HALFOPEN);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Server: %s. Error: %s"), $this->_server, @imap_last_error()));
+        }
+        $this->_imap = $result;
+        return true;
+    }
+
+    /**
+     * Disconnects from the IMAP server. If not really necessary this
+     * should not be called. Once the page got served the connections
+     * should be closed anyhow and if there is a chance to reuse the
+     * connection it should be used.
+     *
+     * @return mixed  True in case the connection was closed successfully, a
+     *                PEAR error otherwise.
+     */
+    function disconnect()
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $this->_reuse_detection = null;
+
+        $result = @imap_close($this->_imap);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Server: %s. Error: %s"), $this->_server, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Opens the given folder.
+     *
+     * @param string $folder  The folder to open.
+     *
+     * @return mixed  True in case the folder was opened successfully, a PEAR
+     *                error otherwise.
+     */
+    function select($folder)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $this->_mbox = $this->_base_mbox . $folder;
+
+        $result = @imap_reopen($this->_imap, $this->_mbox);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Does the given folder exist?
+     *
+     * @param string $folder  The folder to check.
+     *
+     * @return mixed  True in case the folder exists, false otherwise
+     */
+    function exists($folder)
+    {
+        $folders = $this->getMailboxes();
+        if (is_a($folders, 'PEAR_Error')) {
+            return $folders;
+        }
+        return in_array($folder, $folders);
+    }
+
+    /**
+     * Create the specified folder.
+     *
+     * @param string $folder  The folder to create.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function create($folder)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $mbox = $this->_base_mbox . $folder;
+        $result = @imap_createmailbox($this->_imap, $mbox);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Delete the specified folder.
+     *
+     * @param string $folder  The folder to delete.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function delete($folder)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $mbox = $this->_base_mbox . $folder;
+        $result = @imap_deletemailbox($this->_imap, $mbox);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Rename the specified folder.
+     *
+     * @param string $old  The folder to rename.
+     * @param string $new  The new name of the folder.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function rename($old, $new)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_renamemailbox($this->_imap,
+                                      $this->_base_mbox . $old,
+                                      $this->_base_mbox . $new);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $old, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Returns the status of the current folder.
+     *
+     * @return array  An array that contains 'uidvalidity' and 'uidnext'.
+     */
+    function status()
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $status = @imap_status_current($this->_imap, SA_MESSAGES | SA_UIDVALIDITY | SA_UIDNEXT);
+        if (!$status) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_mbox, @imap_last_error()));
+        }
+
+        return array('uidvalidity' => $status->uidvalidity,
+                     'uidnext' => $status->uidnext);
+    }
+
+    /**
+     * Returns the uids of the messages in this folder.
+     *
+     * @return mixed  The message ids or a PEAR error in case of an error.
+     */
+    function getUids()
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $uids = @imap_search($this->_imap, 'UNDELETED', SE_UID);
+        if (!is_array($uids)) {
+            $uids = array();
+        }
+
+        return $uids;
+    }
+
+    /**
+     * Searches the current folder using the given list of search criteria.
+     *
+     * @param string $search_list  A list of search criteria.
+     *
+     * @return mixed  The list of matching message ids or a PEAR error in case
+     *                of an error.
+     */
+    function search($search_list)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_search($this->_imap, $search_list, SE_UID);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_mbox, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Searches the headers of the messages. c-client does not allow using
+     * "HEADER" as it is possible with Net/IMAP, so we need a workaround.
+     *
+     * @param string $field  The name of the header field.
+     * @param string $value  The value that field should match.
+     *
+     * @return mixed  The list of matching message ids or a PEAR error in case
+     *                of an error.
+     */
+    function searchHeaders($field, $value)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $uids = $this->getUids();
+        if (is_a($uids, 'PEAR_Error')) {
+            return $uids;
+        }
+
+        $result = array();
+        foreach ($uids as $uid) {
+            $header = $this->getMessageHeader($uid, false);
+            if (is_a($header, 'PEAR_Error')) {
+                return $header;
+            }
+            $header_array = MIME_Headers::parseHeaders($header);
+            if (isset($header_array[$field]) && $header_array[$field] == $value) {
+                $result[] = $uid;
+            }
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieves the message headers for a given message id.
+     *
+     * @param integer $uid            The message id.
+     * @param boolean $peek_for_body  Prefetch the body.
+     *
+     * @return mixed  The message header or a PEAR error in case of an error.
+     */
+    function getMessageHeader($uid, $peek_for_body = true)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $flags = FT_UID;
+        if ($peek_for_body) {
+            $flags |= FT_PREFETCHTEXT;
+        }
+
+        $result = @imap_fetchheader($this->_imap, $uid, $flags);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieves the message body for a given message id.
+     *
+     * @param integer $uid  The message id.
+     *
+     * @return mixed  The message body or a PEAR error in case of an error.
+     */
+    function getMessageBody($uid)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_body($this->_imap, $uid, FT_UID);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
+        }
+
+        return $result;
+    }
+
+    /**
+     * Retrieves the full message text for a given message id.
+     *
+     * @param integer $uid  The message id.
+     *
+     * @return mixed  The message text or a PEAR error in case of an error.
+     */
+    function getMessage($uid)
+    {
+        $header = $this->getMessageHeader($uid);
+        if (is_a($header, 'PEAR_Error')) {
+            return $header;
+        }
+
+        $body = $this->getMessageBody($uid);
+        if (is_a($body, 'PEAR_Error')) {
+            return $body;
+        }
+
+        return $header . $body;
+    }
+
+    /**
+     * Retrieves a list of mailboxes on the server.
+     *
+     * @return mixed  The list of mailboxes or a PEAR error in case of an
+     *                error.
+     */
+    function getMailboxes()
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $folders = array();
+
+        $result = @imap_list($this->_imap, $this->_base_mbox, '*');
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_base_mbox, @imap_last_error()));
+        }
+
+        $server_len = strlen($this->_base_mbox);
+        foreach ($result as $folder) {
+            if (substr($folder, 0, $server_len) == $this->_base_mbox) {
+                $folders[] = substr($folder, $server_len);
+            }
+        }
+
+        return $folders;
+    }
+
+    /**
+     * Fetches the annotation on a folder.
+     *
+     * @param string $entries        The entry to fetch.
+     * @param string $value          The specific value to fetch.
+     * @param string $mailbox_name   The name of the folder.
+     *
+     * @return mixed  The annotation value or a PEAR error in case of an error.
+     */
+    function getAnnotation($entries, $value, $mailbox_name)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        static $annotations = array();
+
+        $signature = "$this->_signature|$entries|$value|$mailbox_name";
+
+        if (!isset($annotations[$signature])) {
+            $result = @imap_getannotation($this->_imap, $mailbox_name, $entries, $value);
+            if (isset($result[$value])) {
+                $annotations[$signature] = $result[$value];
+            } else {
+                $annotations[$signature] = '';
+            }
+        }
+
+        return $annotations[$signature];
+    }
+
+    /**
+     * Sets the annotation on a folder.
+     *
+     * @param string $entries        The entry to set.
+     * @param array  $values         The values to set
+     * @param string $mailbox_name   The name of the folder.
+     *
+     * @return mixed  True if successfull, a PEAR error otherwise.
+     */
+    function setAnnotation($entries, $values, $mailbox_name)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        foreach ($values as $key => $value) {
+            $result = @imap_setannotation($this->_imap, $mailbox_name, $entries, $key, $value);
+            if (!$result) {
+                return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $mailbox_name, @imap_last_error()));
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Retrieve the access rights from a folder
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     *
+     * @return mixed An array of rights if successfull, a PEAR error
+     * otherwise.
+     */
+    function getACL($folder)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_getacl($this->_imap, $folder);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Retrieve the access rights from a folder not owned by the current user
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     *
+     * @return mixed An array of rights if successfull, a PEAR error
+     * otherwise.
+     */
+    function getMyRights($folder)
+    {
+        if (!function_exists('imap_myrights')) {
+            return PEAR::raiseError(sprintf(_("PHP does not support imap_myrights."), $folder, @imap_last_error()));
+        }
+
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_myrights($this->_imap, $folder);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
+        }
+        return $result;
+
+    }
+
+    /**
+     * Set the access rights for a folder
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     * @param string $user    The user to set the ACLs for
+     * @param string $acl     The ACLs
+     *
+     * @return mixed True if successfull, a PEAR error otherwise.
+     */
+    function setACL($folder, $user, $acl)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_setacl($this->_imap, $folder, $user, $acl);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Delete the access rights for a user.
+     *
+     * @param string $folder  The folder that should be modified.
+     * @param string $user    The user that should get the ACLs removed
+     *
+     * @return mixed True if successfull, a PEAR error otherwise.
+     */
+    function deleteACL($folder, $user)
+    {
+        return $this->setACL($folder, $user, '');
+    }
+
+    /**
+     * Appends a message to the current folder.
+     *
+     * @param string $msg  The message to append.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function appendMessage($msg)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_append($this->_imap, $this->_mbox, $msg);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $this->_mbox, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Copies a message to a new folder.
+     *
+     * @param integer $uid        IMAP message id.
+     * @param string $new_folder  Target folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function copyMessage($uid, $new_folder)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_mail_copy($this->_imap, $uid, $new_folder, CP_UID);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $new_folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Moves a message to a new folder.
+     *
+     * @param integer $uid        IMAP message id.
+     * @param string $new_folder  Target folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function moveMessage($uid, $new_folder)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_mail_move($this->_imap, $uid, $new_folder, CP_UID);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Folder: %s. Error: %s"), $new_folder, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Deletes messages from the current folder.
+     *
+     * @param integer $uids  IMAP message ids.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function deleteMessages($uids)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        if (!is_array($uids)) {
+            $uids = array($uids);
+        }
+
+        foreach($uids as $uid) {
+            $result = @imap_delete($this->_imap, $uid, FT_UID);
+            if (!$result) {
+                return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Undeletes a message in the current folder.
+     *
+     * @param integer $uid  IMAP message id.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function undeleteMessages($uid)
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_undelete($this->_imap, $uid, FT_UID);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $uid, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Expunges messages in the current folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function expunge()
+    {
+        if (!isset($this->_imap)) {
+            $result = $this->_connect();
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+
+        $result = @imap_expunge($this->_imap);
+        if (!$result) {
+            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"), $this->_mbox, @imap_last_error()));
+        }
+        return $result;
+    }
+
+    /**
+     * Return the currently selected mailbox
+     *
+     * @return string  The mailbox currently selected
+     */
+    function current()
+    {
+        return $this->_mbox;
+    }
+}
diff --git a/framework/Kolab_Session/lib/Horde/Kolab/IMAP/pear.php b/framework/Kolab_Session/lib/Horde/Kolab/IMAP/pear.php
new file mode 100644 (file)
index 0000000..dbb7181
--- /dev/null
@@ -0,0 +1,519 @@
+<?php
+/**
+ * @package Kolab_Storage
+ *
+ */
+
+/**
+ * The Horde_Kolab library requires version >= 1.0.3 of Net_IMAP (i.e. a
+ * version that includes support for the ANNOTATEMORE IMAP extension). The
+ * latest version of Net_IMAP can be obtained from
+ * http://pear.php.net/get/Net_IMAP
+ */
+require_once 'Net/IMAP.php';
+
+/**
+ * The Horde_Kolab_IMAP_Connection_pear class connects to an IMAP server using the
+ * Net_IMAP PEAR package.
+ *
+ *
+ * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
+ * @author  Thomas Jarosch <thomas.jarosch@intra2net.com>
+ * @package Kolab_Storage
+ */
+class Horde_Kolab_IMAP_pear extends Horde_Kolab_IMAP
+{
+
+    /**
+     * The signature of the current connection
+     *
+     * @var string
+     */
+    var $_signature;
+
+    /**
+     * Connects to the IMAP server.
+     *
+     * @param string  $login     The user account name.
+     * @param string  $password  The user password.
+     * @param boolean $tls       Should TLS be used for the connection?
+     *
+     * @return mixed  True in case the connection was opened successfully, a
+     *                PEAR error otherwise.
+     */
+    function connect($login, $password, $tls = false)
+    {
+        $this->_signature = $this->_server . '|' . $this->_port . "|$login|$password|$tls";
+
+        // Reuse existing connection?
+        if ($this->_signature == $this->_reuse_detection) {
+            return true;
+        }
+
+        $this->_imap = &new Net_IMAP($this->_server, $this->_port);
+        $result = $this->_imap->login($login, $password, true, false);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        $this->_reuse_detection = $this->_signature;
+
+        return true;
+    }
+
+    /**
+     * Disconnects from the IMAP server.
+     *
+     * @return mixed  True in case the connection was closed successfully, a
+     *                PEAR error otherwise.
+     */
+    function disconnect()
+    {
+        $this->_reuse_detection = null;
+        return $this->_imap->disconnect();
+    }
+
+    /**
+     * Opens the given folder.
+     *
+     * @param string $folder  The folder to open
+     *
+     * @return mixed  True in case the folder was opened successfully, a PEAR
+     *                error otherwise.
+     */
+    function select($folder)
+    {
+        return $this->_imap->selectMailbox($folder);
+    }
+
+    /**
+     * Does the given folder exist?
+     *
+     * @param string $folder  The folder to check.
+     *
+     * @return mixed True in case the folder exists, false otherwise
+     */
+    function exists($folder)
+    {
+        return $this->_imap->mailboxExist($folder);
+    }
+
+    /**
+     * Create the specified folder.
+     *
+     * @param string $folder  The folder to create.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function create($folder)
+    {
+        return $this->_imap->createMailbox($folder);
+    }
+
+    /**
+     * Delete the specified folder.
+     *
+     * @param string $folder  The folder to delete.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function delete($folder)
+    {
+        return $this->_imap->deleteMailbox($folder);
+    }
+
+    /**
+     * Rename the specified folder.
+     *
+     * @param string $old  The folder to rename.
+     * @param string $new  The new name of the folder.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function rename($old, $new)
+    {
+        return $this->_imap->renameMailbox($old, $new);
+    }
+
+    /**
+     * Returns the status of the current folder.
+     *
+     * @return array  An array that contains 'uidvalidity' and 'uidnext'.
+     */
+    function status()
+    {
+        $result = array();
+
+        $mailbox = $this->_imap->getCurrentMailbox();
+
+        // Net_IMAP is not very efficent here
+        $ret = $this->_imap->cmdStatus($mailbox, 'UIDVALIDITY');
+        $result['uidvalidity'] = $ret['PARSED']['STATUS']['ATTRIBUTES']['UIDVALIDITY'];
+
+        $ret = $this->_imap->cmdStatus($mailbox, 'UIDNEXT');
+        $result['uidnext'] = $ret['PARSED']['STATUS']['ATTRIBUTES']['UIDNEXT'];
+
+        return $result;
+    }
+
+    /**
+     * Returns the message ids of the messages in this folder.
+     *
+     * @return array  The message ids.
+     */
+    function getUids()
+    {
+        $uids = $this->_imap->search('UNDELETED', true);
+        if (!is_array($uids)) {
+            $uids = array();
+        }
+        return $uids;
+    }
+
+    /**
+     * Searches the current folder using the given list of search criteria.
+     *
+     * @param string $search_list  A list of search criteria.
+     *
+     * @return mixed  The list of matching message ids or a PEAR error in case
+     *                of an error.
+     */
+    function search($search_list, $uidSearch = true)
+    {
+        return $this->_imap->search($search_list, $uidSearch);
+    }
+
+    /**
+     * Searches the headers of the messages.
+     *
+     * @param string $field  The name of the header field.
+     * @param string $value  The value that field should match.
+     *
+     * @return mixed  The list of matching message ids or a PEAR error in case
+     *                of an error.
+     */
+    function searchHeaders($field, $value)
+    {
+        return $this->_imap->search('HEADER "' . $field . '" "' . $value . '"', true);
+    }
+
+    /**
+     * Retrieves the message headers for a given message id.
+     *
+     * @param int $uid                The message id.
+     * @param boolean $peek_for_body  Prefetch the body.
+     *
+     * @return mixed  The message header or a PEAR error in case of an error.
+     */
+    function getMessageHeader($uid, $peek_for_body = true)
+    {
+        $ret = $this->_imap->cmdUidFetch($uid, 'BODY[HEADER]');
+        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+            return PEAR::raiseError(sprintf(_("Failed fetching headers of IMAP message %s. Error was %s"),
+                                            $uid,
+                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
+        }
+
+        if (isset($ret['PARSED'])) {
+            foreach ($ret['PARSED'] as $msg) {
+                if (isset($msg['EXT']['BODY[HEADER]']['CONTENT'])) {
+                    return $msg['EXT']['BODY[HEADER]']['CONTENT'];
+                }
+            }
+        }
+
+        return '';
+    }
+
+    /**
+     * Retrieves the message body for a given message id.
+     *
+     * @param integet $uid  The message id.
+     *
+     * @return mixed  The message body or a PEAR error in case of an error.
+     */
+    function getMessageBody($uid)
+    {
+        $ret = $this->_imap->cmdUidFetch($uid, 'BODY[TEXT]');
+        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+            return PEAR::raiseError(sprintf(_("Failed fetching body of IMAP message %s. Error was %s"),
+                                            $uid,
+                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
+        }
+
+        if (isset($ret['PARSED'])) {
+            foreach ($ret['PARSED'] as $msg) {
+                if (isset($msg['EXT']['BODY[TEXT]']['CONTENT'])) {
+                    return $msg['EXT']['BODY[TEXT]']['CONTENT'];
+                }
+            }
+        }
+
+        return '';
+    }
+
+    /**
+     * Retrieves the full message text for a given message id.
+     *
+     * @param integer $uid  The message id.
+     *
+     * @return mixed  The message text or a PEAR error in case of an error.
+     */
+    function getMessage($uid)
+    {
+        $ret = $this->_imap->cmdUidFetch($uid, 'RFC822');
+        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+            return PEAR::raiseError(sprintf(_("Failed fetching IMAP message %s. Error was %s"),
+                                            $uid,
+                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
+        }
+
+        if (isset($ret['PARSED'])) {
+            foreach ($ret['PARSED'] as $msg) {
+                if (isset($msg['EXT']['RFC822']['CONTENT'])) {
+                    return $msg['EXT']['RFC822']['CONTENT'];
+                }
+            }
+        }
+
+        return '';
+    }
+
+    /**
+     * Retrieves a list of mailboxes on the server.
+     *
+     * @return mixed  The list of mailboxes or a PEAR error in case of an
+     *                error.
+     */
+    function getMailboxes()
+    {
+        return $this->_imap->getMailboxes();
+    }
+
+    /**
+     * Fetches the annotation on a folder.
+     *
+     * @param string $entries       The entry to fetch.
+     * @param string $value         The specific value to fetch.
+     * @param string $mailbox_name  The name of the folder.
+     *
+     * @return mixed  The annotation value or a PEAR error in case of an error.
+     */
+    function getAnnotation($entries, $value, $mailbox_name)
+    {
+        static $annotations = array();
+
+        $signature = "$this->_signature|$entries|$value|$mailbox_name";
+
+        if (!isset($annotations[$signature])) {
+            $annotations[$signature] = $this->_imap->getAnnotation($entries, $value, $mailbox_name);
+        }
+
+        return $annotations[$signature];
+    }
+
+    /**
+     * Sets the annotation on a folder.
+     *
+     * @param string $entries        The entry to set.
+     * @param array  $values         The values to set
+     * @param string $mailbox_name   The name of the folder.
+     *
+     * @return mixed  True if successfull, a PEAR error otherwise.
+     */
+    function setAnnotation($entries, $values, $mailbox_name)
+    {
+        return $this->_imap->setAnnotation($entries, $values, $mailbox_name);
+    }
+
+    /**
+     * Retrieve the access rights from a folder
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     *
+     * @return mixed An array of rights if successfull, a PEAR error
+     * otherwise.
+     */
+    function getACL($folder)
+    {
+        $result = $this->_imap->getACL($folder);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        $acl = array();
+        foreach ($result as $user) {
+            $acl[$user['USER']] = $user['RIGHTS'];
+        }
+        return $acl;
+    }
+
+    /**
+     * Retrieve the access rights on a folder not owned by the current user
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     *
+     * @return mixed An array of rights if successfull, a PEAR error
+     * otherwise.
+     */
+    function getMyRights($folder)
+    {
+        $result = $this->_imap->getMyRights($folder);
+        return $result;
+    }
+
+    /**
+     * Set the access rights for a folder
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     * @param string $user    The user to set the ACLs for
+     * @param string $acl     The ACLs
+     *
+     * @return mixed True if successfull, a PEAR error otherwise.
+     */
+    function setACL($folder, $user, $acl)
+    {
+        return $this->_imap->setACL($folder, $user, $acl);
+    }
+
+    /**
+     * Delete the access rights for a user.
+     *
+     * @param string $folder  The folder that should be modified.
+     * @param string $user    The user that should get the ACLs removed
+     *
+     * @return mixed True if successfull, a PEAR error otherwise.
+     */
+    function deleteACL($folder, $user)
+    {
+        return $this->_imap->deleteACL($folder, $user);
+    }
+
+    /**
+     * Appends a message to the current folder.
+     *
+     * @param string $msg  The message to append.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function appendMessage($msg)
+    {
+        return $this->_imap->appendMessage($msg);
+    }
+
+    /**
+     * Copies a message to a new folder.
+     *
+     * @param integer $uid        IMAP message id.
+     * @param string $new_folder  Target folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function copyMessage($uid, $new_folder)
+    {
+        $ret = $this->_imap->cmdUidCopy($uid, $new_folder);
+        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
+                                            $uid,
+                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
+        }
+        return true;
+    }
+
+    /**
+     * Moves a message to a new folder.
+     *
+     * @param integer $uid        IMAP message id.
+     * @param string $new_folder  Target folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function moveMessage($uid, $new_folder)
+    {
+        $result = $this->copyMessage($uid, $new_folder);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        $result = $this->deleteMessages($uid);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+
+        $result = $this->expunge();
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        return true;
+    }
+
+    /**
+     * Deletes messages from the current folder.
+     *
+     * @param integer $uids  IMAP message ids.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function deleteMessages($uids)
+    {
+        if (!is_array($uids)) {
+            $uids = array($uids);
+        }
+
+        foreach ($uids as $uid) {
+            $ret = $this->_imap->cmdUidStore($uid, '+FLAGS.SILENT', '\Deleted');
+            if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+                return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
+                                                $uid,
+                                                $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
+            }
+        }
+
+        return true;
+    }
+
+    /**
+     * Undeletes a message in the current folder.
+     *
+     * @param integer $uid  IMAP message id.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function undeleteMessages($uid)
+    {
+        $ret = $this->_imap->cmdUidStore($uid, '-FLAGS.SILENT', '\Deleted');
+        if (String::upper($ret['RESPONSE']['CODE']) != 'OK') {
+            return PEAR::raiseError(sprintf(_("IMAP error. Message: %s. Error: %s"),
+                                            $uid,
+                                            $ret['RESPONSE']['CODE'] . ', ' . $ret['RESPONSE']['STR_CODE']));
+        }
+        return true;
+    }
+
+    /**
+     * Expunges messages in the current folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function expunge()
+    {
+        return $this->_imap->expunge();
+    }
+
+    /**
+     * Return the currently selected mailbox
+     *
+     * @return string  The mailbox currently selected
+     */
+    function current()
+    {
+        return $this->_imap->getCurrentMailbox();
+    }
+}
diff --git a/framework/Kolab_Session/lib/Horde/Kolab/IMAP/test.php b/framework/Kolab_Session/lib/Horde/Kolab/IMAP/test.php
new file mode 100644 (file)
index 0000000..b95fe39
--- /dev/null
@@ -0,0 +1,727 @@
+<?php
+/**
+ * @package Kolab_Storage
+ *
+ */
+
+/**
+ * Indicate that a mail has been marked as deleted
+ */
+define('KOLAB_IMAP_FLAG_DELETED', 1);
+
+/**
+ * The Horde_Kolab_IMAP_Connection_test class simulates an IMAP server for
+ * testing purposes.
+ *
+ *
+ * Copyright 2007-2009 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  Gunnar Wrobel <wrobel@pardus.de>
+ * @package Kolab_Storage
+ */
+class Horde_Kolab_IMAP_test extends Horde_Kolab_IMAP
+{
+
+    /**
+     * If we are supposed to be connected this holds the user
+     * credentials and some connection details.
+     *
+     * @var string
+     */
+    var $_connected;
+
+    /**
+     * Login of the current user
+     *
+     * @var string
+     */
+    var $_user;
+
+    /**
+     * The data of the mailbox currently opened
+     *
+     * @var array
+     */
+    var $_mbox = null;
+
+    /**
+     * The name of the mailbox currently opened
+     *
+     * @var array
+     */
+    var $_mboxname = null;
+
+    /**
+     * Prepare the dummy server.
+     *
+     * @param string  $login     The user account name.
+     * @param string  $password  The user password.
+     * @param boolean $tls       Should TLS be used for the connection?
+     *
+     * @return mixed  True in case the connection was opened successfully, a
+     *                PEAR error otherwise.
+     */
+    function connect($login, $password, $tls = false)
+    {
+        if (!is_array($GLOBALS['KOLAB_TESTING'])) {
+            /* Simulate an empty IMAP server */
+            $GLOBALS['KOLAB_TESTING'] = array();
+        }
+
+        $tls = ($tls) ? 'tls' : 'notls';
+        $this->_connected = $login . ':' . $password . ':' . $tls;
+        $this->_user = $login;
+        $this->_mbox = null;
+        $this->_mboxname = null;
+    }
+
+    /**
+     * Disconnects from the IMAP server.
+     *
+     * @return mixed  True in case the connection was closed successfully, a
+     *                PEAR error otherwise.
+     */
+    function disconnect()
+    {
+        $this->_connected = null;
+    }
+
+    function _parseFolder($folder)
+    {
+        if (substr($folder, 0, 5) == 'INBOX') {
+            $user = split('@', $this->_user);
+            return 'user/' . $user[0] . substr($folder, 5);
+        }
+        return $folder;
+    }
+
+    /**
+     * Opens the given folder.
+     *
+     * @param string $folder  The folder to open
+     *
+     * @return mixed  True in case the folder was opened successfully, a PEAR
+     *                error otherwise.
+     */
+    function select($folder)
+    {
+        $folder = $this->_parseFolder($folder);
+        if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) {
+            return PEAR::raiseError(sprintf("IMAP folder %s does not exist!", $folder));
+        }
+        $this->_mbox = &$GLOBALS['KOLAB_TESTING'][$folder];
+        $this->_mboxname = $folder;
+        return true;
+    }
+
+    /**
+     * Does the given folder exist?
+     *
+     * @param string $folder  The folder to check.
+     *
+     * @return mixed True in case the folder exists, false otherwise
+     */
+    function exists($folder)
+    {
+        $folder = $this->_parseFolder($folder);
+        if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) {
+            return false;
+        }
+        return true;
+    }
+
+    /**
+     * Create the specified folder.
+     *
+     * @param string $folder  The folder to create.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function create($folder)
+    {
+        $folder = $this->_parseFolder($folder);
+        if (isset($GLOBALS['KOLAB_TESTING'][$folder])) {
+            return PEAR::raiseError(sprintf("IMAP folder %s does already exist!", $folder));
+        }
+        $GLOBALS['KOLAB_TESTING'][$folder] = array(
+            'status' => array(
+                'uidvalidity' => time(),
+                'uidnext' => 1),
+            'mails' => array(),
+            'permissions' => array(),
+            'annotations' => array(),
+        );
+        return true;
+    }
+
+    /**
+     * Delete the specified folder.
+     *
+     * @param string $folder  The folder to delete.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function delete($folder)
+    {
+        $folder = $this->_parseFolder($folder);
+        if (!isset($GLOBALS['KOLAB_TESTING'][$folder])) {
+            return PEAR::raiseError(sprintf("IMAP folder %s does not exist!", $folder));
+        }
+        unset($GLOBALS['KOLAB_TESTING'][$folder]);
+        return true;
+    }
+
+    /**
+     * Rename the specified folder.
+     *
+     * @param string $old  The folder to rename.
+     * @param string $new  The new name of the folder.
+     *
+     * @return mixed True in case the operation was successfull, a
+     *               PEAR error otherwise.
+     */
+    function rename($old, $new)
+    {
+        $old = $this->_parseFolder($old);
+        $new = $this->_parseFolder($new);
+
+        if (!isset($GLOBALS['KOLAB_TESTING'][$old])) {
+            return PEAR::raiseError(sprintf("IMAP folder %s does not exist!", $old));
+        }
+        if (isset($GLOBALS['KOLAB_TESTING'][$new])) {
+            return PEAR::raiseError(sprintf("IMAP folder %s does already exist!", $new));
+        }
+        $GLOBALS['KOLAB_TESTING'][$new] = $GLOBALS['KOLAB_TESTING'][$old];
+        unset($GLOBALS['KOLAB_TESTING'][$old]);
+        return true;
+    }
+
+    /**
+     * Returns the status of the current folder.
+     *
+     * @return array  An array that contains 'uidvalidity' and 'uidnext'.
+     */
+    function status()
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        return $this->_mbox['status'];
+    }
+
+    /**
+     * Returns the message ids of the messages in this folder.
+     *
+     * @return array  The message ids.
+     */
+    function getUids()
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        $uids = array();
+        foreach ($this->_mbox['mails'] as $uid => $mail) {
+            if (!($mail['flags'] & KOLAB_IMAP_FLAG_DELETED)) {
+                $uids[] = $uid;
+            }
+        }
+        return $uids;
+    }
+
+    /**
+     * Searches the current folder using the given list of search criteria.
+     *
+     * @param string $search_list  A list of search criteria.
+     *
+     * @return mixed  The list of matching message ids or a PEAR error in case
+     *                of an error.
+     */
+    function search($search_list, $uidSearch = true)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        $uids = array();
+        if (substr($search_list, 0, 7) == 'SUBJECT') {
+            $needle = '^Subject: ' . substr($search_list, 8);
+            foreach ($this->_mbox['mails'] as $uid => $mail) {
+                if (preg_match($needle, $mail['header'])) {
+                    $uids[] = $uid;
+                }
+            }
+        } else if (substr($search_list, 0, 6) == 'HEADER') {
+            preg_match('([^ ]*) ([^ ]*)', substr($search_list, 7), $matches);
+            $needle = '^' . $matches[0] . ': ' . $matches[1];
+            foreach ($this->_mbox['mails'] as $uid => $mail) {
+                if (preg_match($needle, $mail['header'])) {
+                    $uids[] = $uid;
+                }
+            }
+
+        }
+        return $uids;
+    }
+
+    /**
+     * Searches the headers of the messages.
+     *
+     * @param string $field  The name of the header field.
+     * @param string $value  The value that field should match.
+     *
+     * @return mixed  The list of matching message ids or a PEAR error in case
+     *                of an error.
+     */
+    function searchHeaders($field, $value)
+    {
+        return $this->search('HEADER "' . $field . '" "' . $value . '"', true);
+    }
+
+    /**
+     * Retrieves the message headers for a given message id.
+     *
+     * @param int $uid                The message id.
+     * @param boolean $peek_for_body  Prefetch the body.
+     *
+     * @return mixed  The message header or a PEAR error in case of an error.
+     */
+    function getMessageHeader($uid, $peek_for_body = true)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        if (!isset($this->_mbox['mails'][$uid])) {
+            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+        }
+        return $this->_mbox['mails'][$uid]['header'];
+    }
+
+    /**
+     * Retrieves the message body for a given message id.
+     *
+     * @param integet $uid  The message id.
+     *
+     * @return mixed  The message body or a PEAR error in case of an error.
+     */
+    function getMessageBody($uid)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        if (!isset($this->_mbox['mails'][$uid])) {
+            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+        }
+        return $this->_mbox['mails'][$uid]['body'];
+    }
+
+    /**
+     * Retrieves the full message text for a given message id.
+     *
+     * @param integer $uid  The message id.
+     *
+     * @return mixed  The message text or a PEAR error in case of an error.
+     */
+    function getMessage($uid)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        if (!isset($this->_mbox['mails'][$uid])) {
+            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+        }
+        return $this->_mbox['mails'][$uid]['header'] . $this->_mbox['mails'][$uid]['body'];
+    }
+
+    /**
+     * Retrieves a list of mailboxes on the server.
+     *
+     * @return mixed  The list of mailboxes or a PEAR error in case of an
+     *                error.
+     */
+    function getMailboxes()
+    {
+        $mboxes = array_keys($GLOBALS['KOLAB_TESTING']);
+        $user = split('@', $this->_user);
+        $pattern = '#^user/' . $user[0] . '#';
+        $result = array();
+        foreach ($mboxes as $mbox) {
+            $result[] = preg_replace($pattern, 'INBOX', $mbox);
+        }
+        return $result;
+    }
+
+    /**
+     * Fetches the annotation on a folder.
+     *
+     * @param string $entries       The entry to fetch.
+     * @param string $value         The specific value to fetch.
+     * @param string $mailbox_name  The name of the folder.
+     *
+     * @return mixed  The annotation value or a PEAR error in case of an error.
+     */
+    function getAnnotation($entries, $value, $mailbox_name)
+    {
+        $mailbox_name = $this->_parseFolder($mailbox_name);
+        $old_mbox = null;
+        if ($mailbox_name != $this->_mboxname) {
+            $old_mbox = $this->_mboxname;
+            $result = $this->select($mailbox_name);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        if (!isset($this->_mbox['annotations'][$entries])
+            || !isset($this->_mbox['annotations'][$entries][$value])) {
+            return false;
+        }
+        $annotation = $this->_mbox['annotations'][$entries][$value];
+        if ($old_mbox) {
+            $this->select($old_mbox);
+        }
+        return $annotation;
+    }
+
+    /**
+     * Sets the annotation on a folder.
+     *
+     * @param string $entries        The entry to set.
+     * @param array  $values         The values to set
+     * @param string $mailbox_name   The name of the folder.
+     *
+     * @return mixed  True if successfull, a PEAR error otherwise.
+     */
+    function setAnnotation($entries, $values, $mailbox_name)
+    {
+        $mailbox_name = $this->_parseFolder($mailbox_name);
+        $old_mbox = null;
+        if ($mailbox_name != $this->_mboxname) {
+            $old_mbox = $this->_mboxname;
+            $result = $this->select($mailbox_name);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        if (!isset($this->_mbox['annotations'][$entries])) {
+            $this->_mbox['annotations'][$entries] = array();
+        }
+        foreach ($values as $key => $value) {
+            $this->_mbox['annotations'][$entries][$key] = $value;
+        }
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Retrieve the access rights from a folder
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     *
+     * @return mixed An array of rights if successfull, a PEAR error
+     * otherwise.
+     */
+    function getACL($folder)
+    {
+        $folder = $this->_parseFolder($folder);
+        $old_mbox = null;
+        if ($folder != $this->_mboxname) {
+            $old_mbox = $this->_mboxname;
+            $result = $this->select($folder);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        $acl = $this->_mbox['permissions'];
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return $acl;
+    }
+
+    /**
+     * Retrieve the access rights on a folder not owned by the current user
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     *
+     * @return mixed An array of rights if successfull, a PEAR error
+     * otherwise.
+     */
+    function getMyRights($folder)
+    {
+        $folder = $this->_parseFolder($folder);
+        $old_mbox = null;
+        if ($folder != $this->_mboxname) {
+            $old_mbox = $this->_mboxname;
+            $result = $this->select($folder);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        $acl = '';
+        if (isset($this->_mbox['permissions'][$this->_user])) {
+            $acl = $this->_mbox['permissions'][$this->_user];
+        }
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return $acl;
+    }
+
+    /**
+     * Set the access rights for a folder
+     *
+     * @param string $folder  The folder to retrieve the ACLs from.
+     * @param string $user    The user to set the ACLs for
+     * @param string $acl     The ACLs
+     *
+     * @return mixed True if successfull, a PEAR error otherwise.
+     */
+    function setACL($folder, $user, $acl)
+    {
+        $folder = $this->_parseFolder($folder);
+        $old_mbox = null;
+        if ($folder != $this->_mboxname) {
+            $old_mbox = $this->_mboxname;
+            $result = $this->select($folder);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        $this->_mbox['permissions'][$user] = $acl;
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Delete the access rights for a user.
+     *
+     * @param string $folder  The folder that should be modified.
+     * @param string $user    The user that should get the ACLs removed
+     *
+     * @return mixed True if successfull, a PEAR error otherwise.
+     */
+    function deleteACL($folder, $user)
+    {
+        $folder = $this->_parseFolder($folder);
+        $old_mbox = null;
+        if ($folder != $this->_mboxname) {
+            $old_mbox = $this->_mboxname;
+            $result = $this->select($folder);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        unset($this->_mbox['permissions'][$user]);
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Appends a message to the current folder.
+     *
+     * @param string $msg  The message to append.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function appendMessage($msg)
+    {
+        $split = strpos($msg, "\r\n\r\n");
+        $mail = array('header' => substr($msg, 0, $split + 2),
+                      'body' => substr($msg, $split + 3));
+        return $this->_appendMessage($mail);
+    }
+
+    /**
+     * Appends a message to the current folder.
+     *
+     * @param array $msg  The message to append.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function _appendMessage($msg)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        $mail = array();
+        $mail['flags'] = 0;
+        $mail['header'] = $msg['header'];
+        $mail['body'] = $msg['body'];
+
+
+        $this->_mbox['mails'][$this->_mbox['status']['uidnext']] = $mail;
+        $this->_mbox['status']['uidnext']++;
+        return true;
+    }
+
+    /**
+     * Copies a message to a new folder.
+     *
+     * @param integer $uid        IMAP message id.
+     * @param string $new_folder  Target folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function copyMessage($uid, $new_folder)
+    {
+        $new_folder = $this->_parseFolder($new_folder);
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        if (!isset($this->_mbox['mails'][$uid])) {
+            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+        }
+        $mail = $this->_mbox['mails'][$uid];
+
+        $old_mbox = null;
+        $result = $this->select($new_folder);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        $this->_appendMessage($mail);
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Moves a message to a new folder.
+     *
+     * @param integer $uid        IMAP message id.
+     * @param string $new_folder  Target folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function moveMessage($uid, $new_folder)
+    {
+        $new_folder = $this->_parseFolder($new_folder);
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+        if (!isset($this->_mbox['mails'][$uid])) {
+            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+        }
+        $mail = $this->_mbox['mails'][$uid];
+        unset($this->_mbox['mails'][$uid]);
+
+        $old_mbox = null;
+        $result = $this->select($new_folder);
+        if (is_a($result, 'PEAR_Error')) {
+            return $result;
+        }
+        $this->_appendMessage($mail);
+        if ($old_mbox) {
+            $result = $this->select($old_mbox);
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+        }
+        return true;
+    }
+
+    /**
+     * Deletes messages from the current folder.
+     *
+     * @param integer $uids  IMAP message ids.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function deleteMessages($uids)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+
+        if (!is_array($uids)) {
+            $uids = array($uids);
+        }
+
+        foreach ($uids as $uid) {
+
+            if (!isset($this->_mbox['mails'][$uid])) {
+                return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+            }
+            $this->_mbox['mails'][$uid]['flags'] |= KOLAB_IMAP_FLAG_DELETED;
+        }
+        return true;
+    }
+
+    /**
+     * Undeletes a message in the current folder.
+     *
+     * @param integer $uid  IMAP message id.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function undeleteMessages($uid)
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+
+        if (!isset($this->_mbox['mails'][$uid])) {
+            return PEAR::raiseError(sprintf("No IMAP message %s!", $uid));
+        }
+        $this->_mbox['mails'][$uid]['flags'] &= ~KOLAB_IMAP_FLAG_DELETED;
+        return true;
+    }
+
+    /**
+     * Expunges messages in the current folder.
+     *
+     * @return mixed  True or a PEAR error in case of an error.
+     */
+    function expunge()
+    {
+        if (!$this->_mbox) {
+            return PEAR::raiseError("No IMAP folder selected!");
+        }
+
+        $remaining = array();
+        foreach ($this->_mbox['mails'] as $uid => $mail) {
+            if (!($mail['flags'] & KOLAB_IMAP_FLAG_DELETED)) {
+                $remaining[$uid] = $mail;
+            }
+        }
+        $this->_mbox['mails'] = $remaining;
+        return true;
+    }
+
+    /**
+     * Return the currently selected mailbox
+     *
+     * @return string  The mailbox currently selected
+     */
+    function current()
+    {
+        return $this->_mboxname;
+    }
+}
diff --git a/framework/Kolab_Session/lib/Horde/Kolab/Session.php b/framework/Kolab_Session/lib/Horde/Kolab/Session.php
new file mode 100644 (file)
index 0000000..7f2c131
--- /dev/null
@@ -0,0 +1,357 @@
+<?php
+/**
+ * The Horde_Kolab_Session class holds additional user details for the current
+ * session.
+ *
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Server
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+
+/** We need the Auth library */
+require_once 'Horde/Auth.php';
+
+/**
+ * The Horde_Kolab_Session class holds additional user details for the current
+ * session.
+ *
+ * The core user credentials (login, pass) are kept within the Auth module and
+ * can be retrieved using <code>Auth::getAuth()</code> respectively
+ * <code>Auth::getCredential('password')</code>. Any additional Kolab user data
+ * relevant for the user session should be accessed via the Horde_Kolab_Session
+ * class.
+ *
+ *
+ * Copyright 2008-2009 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.
+ *
+ * @category Kolab
+ * @package  Kolab_Server
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Server
+ */
+class Horde_Kolab_Session
+{
+
+    /**
+     * User ID.
+     *
+     * @var string
+     */
+    var $user_id;
+
+    /**
+     * User UID.
+     *
+     * @var string
+     */
+    var $user_uid;
+
+    /**
+     * Primary user mail address.
+     *
+     * @var string
+     */
+    var $user_mail;
+
+    /**
+     * Full name.
+     *
+     * @var string
+     */
+    var $user_name = '';
+
+    /**
+     * True if the Kolab_Server login was successfull.
+     *
+     * @var boolean|PEAR_Error
+     */
+    var $auth;
+
+    /**
+     * The connection parameters for the IMAP server.
+     *
+     * @var array|PEAR_Error
+     */
+    var $_imap_params;
+
+    /**
+     * Our IMAP connection.
+     *
+     * @var Horde_Kolab_IMAP
+     */
+    var $_imap;
+
+    /**
+     * The free/busy server for the current user.
+     *
+     * @var array|PEAR_Error
+     */
+    var $freebusy_server;
+
+    /**
+     * Constructor.
+     *
+     * @param string $user        The session will be setup for the user with
+     *                            this ID.
+     * @param array  $credentials An array of login credentials. For Kolab,
+     *                            this must contain a "password" entry.
+     */
+    function Horde_Kolab_Session($user = null, $credentials = null)
+    {
+        global $conf;
+
+        if (empty($user)) {
+            $user = Auth::getAuth();
+            if (empty($user)) {
+                $user = 'anonymous';
+            } else if (!strpos($user, '@')) {
+                $user = $user . '@' . (!empty($_SERVER['SERVER_NAME']) ?
+                                       $_SERVER['SERVER_NAME'] : 'localhost');
+            }
+        }
+
+        $this->user_id      = $user;
+        $this->_imap_params = array();
+
+        $user_object = null;
+
+        if ($user != 'anonymous') {
+            $server = $this->getServer($user, $credentials);
+            $this->user_uid = $server->uid;
+            $user_object    = $server->fetch();
+
+            if (empty($conf['kolab']['imap']['allow_special_users'])
+                && !is_a($user_object, 'Horde_Kolab_Server_Object_user')) {
+                throw new Horde_Kolab_Server_Exception(_('Access to special Kolab users is denied.'));
+            }
+            if (isset($conf['kolab']['server']['deny_group'])) {
+                $dn = $server->gidForMail($conf['kolab']['server']['deny_group']);
+                if (empty($dn)) {
+                    Horde::logMessage('The Kolab configuratin setting $conf[\'kolab\'][\'server\'][\'deny_group\'] holds a non-existing group!',
+                                      __FILE__, __LINE__, PEAR_LOG_WARNING);
+                } else if (in_array($dn, $user_object->getGroups())) {
+                    throw new Horde_Kolab_Server_Exception(_('You are member of a group that may not login on this server.'));
+                }
+            }
+            if (isset($conf['kolab']['server']['allow_group'])) {
+                $dn = $server->gidForMail($conf['kolab']['server']['allow_group']);
+                if (empty($dn)) {
+                    Horde::logMessage('The Kolab configuratin setting $conf[\'kolab\'][\'server\'][\'allow_group\'] holds a non-existing group!',
+                                      __FILE__, __LINE__, PEAR_LOG_WARNING);
+                } else if (!in_array($dn, $user_object->getGroups())) {
+                    throw new Horde_Kolab_Server_Exception(_('You are no member of a group that may login on this server.'));
+                }
+            }
+                
+            $result = $user_object->get(KOLAB_ATTR_MAIL);
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->user_mail = $result;
+            }
+
+            $result = $user_object->get(KOLAB_ATTR_SID);
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->user_id = $result;
+            }
+
+            $result = $user_object->get(KOLAB_ATTR_FNLN);
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->user_name = $result;
+            }
+
+            $result = $user_object->getServer('imap');
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $server = explode(':', $result, 2);
+                if (!empty($server[0])) {
+                    $this->_imap_params['hostspec'] = $server[0];
+                }
+                if (!empty($server[1])) {
+                    $this->_imap_params['port'] = $server[1];
+                }
+            }
+
+            $result = $user_object->getServer('freebusy');
+            if (!empty($result) && !is_a($result, 'PEAR_Error')) {
+                $this->freebusy_server = $result;
+            }
+        }
+
+        if (empty($this->user_mail)) {
+            $this->user_mail = $user;
+        }
+
+        if (!isset($this->_imap_params['hostspec'])) {
+            if (isset($conf['kolab']['imap']['server'])) {
+                $this->_imap_params['hostspec'] = $conf['kolab']['imap']['server'];
+            } else {
+                $this->_imap_params['hostspec'] = 'localhost';
+            }
+        }
+
+        if (!isset($this->_imap_params['port'])) {
+            if (isset($conf['kolab']['imap']['port'])) {
+                $this->_imap_params['port'] = $conf['kolab']['imap']['port'];
+            } else {
+                $this->_imap_params['port'] = 143;
+            }
+        }
+
+        $this->_imap_params['protocol'] = 'imap/notls/novalidate-cert';
+    }
+
+    /**
+     * Returns the properties that need to be serialized.
+     *
+     * @return array  List of serializable properties.
+     */
+    function __sleep()
+    {
+        $properties = get_object_vars($this);
+        unset($properties['_imap']);
+        $properties = array_keys($properties);
+        return $properties;
+    }
+
+    /**
+     * Get the Kolab Server connection.
+     *
+     * @param string $user        The session will be setup for the user with
+     *                            this ID.
+     * @param array  $credentials An array of login credentials. For Kolab,
+     *                            this must contain a "password" entry.
+     *
+     * @return Horde_Kolab_Server|PEAR_Error The Kolab Server connection.
+     */
+    function &getServer($user = null, $credentials = null)
+    {
+        /** We need the Kolab Server access. */
+        require_once 'Horde/Kolab/Server.php';
+
+        $params = array();
+        if ($this->user_uid) {
+            $params['uid']  = $this->user_uid;
+            $params['pass'] = Auth::getCredential('password');
+        } else if (isset($user)) {
+            $params['user'] = $user;
+            if (isset($credentials['password'])) {
+                $params['pass'] = $credentials['password'];
+            } else {
+                $params['pass'] = Auth::getCredential('password');
+            }
+        }
+        return Horde_Kolab_Server::singleton($params);
+    }
+
+    /**
+     * Get the IMAP connection parameters.
+     *
+     * @return array|PEAR_Error The IMAP connection parameters.
+     */
+    function &getImapParams()
+    {
+        return $this->_imap_params;
+    }
+
+    /**
+     * Create an IMAP connection.
+     *
+     * @return Horde_Kolab_IMAP|PEAR_Error The IMAP connection.
+     */
+    function &getImap()
+    {
+        if (!isset($this->_imap)) {
+
+            $params = $this->getImapParams();
+            if (is_a($params, 'PEAR_Error')) {
+                return $params;
+            }
+
+            /** We need the Kolab IMAP library now. */
+            require_once 'Horde/Kolab/IMAP.php';
+
+            $imap = &Horde_Kolab_IMAP::singleton($params['hostspec'],
+                                                 $params['port'], true, false);
+            if (is_a($imap, 'PEAR_Error')) {
+                return $imap;
+            }
+
+            $result = $imap->connect(Auth::getAuth(),
+                                     Auth::getCredential('password'));
+            if (is_a($result, 'PEAR_Error')) {
+                return $result;
+            }
+            $this->_imap = &$imap;
+        }
+        return $this->_imap;
+    }
+
+    /**
+     * Attempts to return a reference to a concrete Horde_Kolab_Session instance.
+     *
+     * It will only create a new instance if no Horde_Kolab_Session instance
+     * currently exists or if a user ID has been specified that does not match the
+     * user ID/user mail of the current session.
+     *
+     * This method must be invoked as:
+     *   <code>$var = &Horde_Kolab_Session::singleton();</code>
+     *
+     * @param string $user        The session will be setup for the user with
+     *                            this ID.
+     * @param array  $credentials An array of login credentials. For Kolab,
+     *                            this must contain a "password" entry.
+     *
+     * @static
+     *
+     * @return Horde_Kolab_Session  The concrete Session reference.
+     */
+    function &singleton($user = null, $credentials = null, $destruct = false)
+    {
+        static $session;
+
+        if (!isset($session)) {
+            /**
+             * Horde_Kolab_Server currently has no caching so we mainly
+             * cache some user information here as reading this data
+             * may be expensive when running in a multi-host
+             * environment.
+             */
+            require_once 'Horde/SessionObjects.php';
+            $hs      = &Horde_SessionObjects::singleton();
+            $session = $hs->query('kolab_session');
+        }
+
+        if (empty($user)) {
+            $user = Auth::getAuth();
+        }
+
+        if ($destruct || empty($session)
+            || ($user != $session->user_mail && $user != $session->user_id)) {
+            $session = new Horde_Kolab_Session($user, $credentials);
+        }
+
+        register_shutdown_function(array(&$session, 'shutdown'));
+
+        return $session;
+    }
+
+    /**
+     * Stores the object in the session cache.
+     *
+     * @return NULL
+     */
+    function shutdown()
+    {
+        require_once 'Horde/SessionObjects.php';
+        $session = &Horde_SessionObjects::singleton();
+        $session->overwrite('kolab_session', $this, false);
+    }
+
+}
diff --git a/framework/Kolab_Session/package.xml b/framework/Kolab_Session/package.xml
new file mode 100644 (file)
index 0000000..16e7c46
--- /dev/null
@@ -0,0 +1,114 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<package packagerversion="1.4.9" version="2.0" xmlns="http://pear.php.net/dtd/package-2.0" xmlns:tasks="http://pear.php.net/dtd/tasks-1.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://pear.php.net/dtd/tasks-1.0
+http://pear.php.net/dtd/tasks-1.0.xsd
+http://pear.php.net/dtd/package-2.0
+http://pear.php.net/dtd/package-2.0.xsd">
+ <name>Kolab_Session</name>
+ <channel>pear.horde.org</channel>
+ <summary>A package managing an active Kolab session.</summary>
+ <description>This package handles a Kolab session. It allows to
+ authenticate against LDAP and provides the users storage locations.
+ </description>
+ <lead>
+  <name>Gunnar Wrobel</name>
+  <user>wrobel</user>
+  <email>p@rdus.de</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Chuck Hagenbuch</name>
+  <user>chuck</user>
+  <email>chuck@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <lead>
+  <name>Jan Schneider</name>
+  <user>jan</user>
+  <email>jan@horde.org</email>
+  <active>yes</active>
+ </lead>
+ <date>2009-03-02</date>
+ <version>
+  <release>0.1.0</release>
+  <api>0.1.0</api>
+ </version>
+ <stability>
+  <release>alpha</release>
+  <api>alpha</api>
+ </stability>
+ <license uri="http://www.gnu.org/copyleft/lesser.html">LGPL</license>
+ <notes>
+  * Split package from Kolab_Server
+ </notes>
+ <contents>
+  <dir name="/">
+   <dir name="lib">
+    <dir name="Horde">
+     <dir name="Kolab">
+      <file name="IMAP.php" role="php" />
+      <dir name="IMAP">
+       <file name="cclient.php" role="php" />
+       <file name="pear.php" role="php" />
+       <file name="test.php" role="php" />
+      </dir> <!-- /lib/Horde/Kolab/IMAP -->
+      <file name="Session.php" role="php" />
+     </dir> <!-- /lib/Horde/Kolab -->
+    </dir> <!-- /lib/Horde -->
+   </dir> <!-- /lib -->
+   <dir name="test">
+    <dir name="Horde">
+     <dir name="Kolab">
+      <dir name="Session">
+       <file name="AllTests.php" role="test" />
+       <file name="SessionTest.php" role="test" />
+      </dir> <!-- /test/Horde/Kolab/Session -->
+     </dir> <!-- /test/Horde/Kolab -->
+    </dir> <!-- /test/Horde -->
+   </dir> <!-- /test -->
+  </dir> <!-- / -->
+ </contents>
+ <dependencies>
+  <required>
+   <php>
+    <min>4.3.0</min>
+   </php>
+   <pearinstaller>
+    <min>1.4.0b1</min>
+   </pearinstaller>
+   <package>
+    <name>Auth</name>
+    <channel>pear.horde.org</channel>
+   </package>
+  </required>
+  <optional>
+   <package>
+    <name>Kolab_Server</name>
+    <channel>pear.horde.org</channel>
+   </package>
+   <package>
+    <name>Horde_SessionObjects</name>
+    <channel>pear.horde.org</channel>
+   </package>
+   <package>
+    <name>PHPUnit</name>
+    <channel>pear.phpunit.de</channel>
+   </package>
+   <extension>
+    <name>ldap</name>
+   </extension>
+  </optional>
+ </dependencies>
+ <phprelease>
+  <filelist>
+   <install name="lib/Horde/Kolab/IMAP.php" as="Horde/Kolab/IMAP.php" />
+   <install name="lib/Horde/Kolab/IMAP/cclient.php" as="Horde/Kolab/IMAP/cclient.php" />
+   <install name="lib/Horde/Kolab/IMAP/pear.php" as="Horde/Kolab/IMAP/pear.php" />
+   <install name="lib/Horde/Kolab/IMAP/pear/test.php" as="Horde/Kolab/IMAP/test.php" />
+   <install name="lib/Horde/Kolab/Session.php" as="Horde/Kolab/Session.php" />
+   <install name="test/Horde/Kolab/Session/AllTests.php" as="Horde/Kolab/Session/AllTests.php" />
+   <install name="test/Horde/Kolab/Session/SessionTest.php" as="Horde/Kolab/Session/SessionTest.php" />
+  </filelist>
+ </phprelease>
+ <changelog>
+ </changelog>
+</package>
diff --git a/framework/Kolab_Session/test/Horde/Kolab/Session/AllTests.php b/framework/Kolab_Session/test/Horde/Kolab/Session/AllTests.php
new file mode 100644 (file)
index 0000000..7eebe26
--- /dev/null
@@ -0,0 +1,85 @@
+<?php
+/**
+ * All tests for the Horde_Kolab_Session:: package.
+ *
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Session
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Session
+ */
+
+/**
+ * Define the main method
+ */
+if (!defined('PHPUnit_MAIN_METHOD')) {
+    define('PHPUnit_MAIN_METHOD', 'Horde_Kolab_Session_AllTests::main');
+}
+
+/**
+ * The Autoloader allows us to omit "require/include" statements.
+ */
+require_once 'Horde/Autoloader.php';
+
+/**
+ * Combine the tests for this package.
+ *
+ *
+ * Copyright 2007-2009 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.
+ *
+ * @category Kolab
+ * @package  Kolab_Session
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Session
+ */
+class Horde_Kolab_Session_AllTests
+{
+
+    /**
+     * Main entry point for running the suite.
+     *
+     * @return NULL
+     */
+    public static function main()
+    {
+        PHPUnit_TextUI_TestRunner::run(self::suite());
+    }
+
+    /**
+     * Collect the unit tests of this directory into a new suite.
+     *
+     * @return PHPUnit_Framework_TestSuite The test suite.
+     */
+    public static function suite()
+    {
+        $suite = new PHPUnit_Framework_TestSuite('Horde Framework - Kolab_Session');
+
+        $basedir    = dirname(__FILE__);
+        $baseregexp = preg_quote($basedir . DIRECTORY_SEPARATOR, '/');
+
+        foreach (new RecursiveIteratorIterator(new RecursiveDirectoryIterator($basedir)) as $file) {
+            if ($file->isFile() && preg_match('/Test.php$/', $file->getFilename())) {
+                $pathname = $file->getPathname();
+                require $pathname;
+
+                $class = str_replace(DIRECTORY_SEPARATOR, '_',
+                                     preg_replace("/^$baseregexp(.*)\.php/", '\\1', $pathname));
+                $suite->addTestSuite('Horde_Kolab_Session_' . $class);
+            }
+        }
+
+        return $suite;
+    }
+
+}
+
+if (PHPUnit_MAIN_METHOD == 'Horde_Kolab_Session_AllTests::main') {
+    Horde_Kolab_Session_AllTests::main();
+}
diff --git a/framework/Kolab_Session/test/Horde/Kolab/Session/SessionTest.php b/framework/Kolab_Session/test/Horde/Kolab/Session/SessionTest.php
new file mode 100644 (file)
index 0000000..eecc197
--- /dev/null
@@ -0,0 +1,208 @@
+<?php
+/**
+ * Test the Kolab session handler.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package  Kolab_Session
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Session
+ */
+
+/**
+ * The Autoloader allows us to omit "require/include" statements.
+ */
+require_once 'Horde/Autoloader.php';
+
+/**
+ * Test the Kolab session handler.
+ *
+ * Copyright 2008-2009 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.
+ *
+ * @category Kolab
+ * @package  Kolab_Session
+ * @author   Gunnar Wrobel <wrobel@pardus.de>
+ * @license  http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link     http://pear.horde.org/index.php?package=Kolab_Session
+ */
+class Horde_Kolab_Session_SessionTest extends Horde_Kolab_Test_Session
+{
+    /**
+     * Test class construction.
+     *
+     * @return NULL
+     */
+    public function testConstructEmpty()
+    {
+        global $conf;
+        $conf['kolab']['imap']['allow_special_users'] = true;
+
+        $session = &Horde_Kolab_Session::singleton();
+
+        $this->assertEquals('anonymous', $session->user_mail);
+
+        $params = $session->getImapParams();
+        $this->assertNoError($params);
+        $this->assertEquals('localhost', $params['hostspec']);
+        $this->assertEquals(143, $params['port']);
+    }
+
+    /**
+     * Test old style class construction.
+     *
+     * @return NULL
+     */
+    public function testConstructSimple()
+    {
+        global $conf;
+        $conf['kolab']['imap']['server']     = 'example.com';
+        $conf['kolab']['imap']['port']       = 200;
+        $conf['kolab']['freebusy']['server'] = 'fb.example.com';
+
+        $session = &new Horde_Kolab_Session();
+        $params  = $session->getImapParams();
+        if (is_a($params, 'PEAR_Error')) {
+            $this->assertEquals('', $params->getMessage());
+        }
+        $this->assertEquals('example.com', $params['hostspec']);
+        $this->assertEquals(200, $params['port']);
+    }
+
+    /**
+     * Test IMAP server retrieval.
+     *
+     * @return NULL
+     */
+    public function testGetSession()
+    {
+        $server = &$this->prepareEmptyKolabSession();
+        $result = $server->add($this->provideBasicUserTwo());
+        $this->assertNoError($result);
+        $this->assertEquals(1, count($GLOBALS['KOLAB_SERVER_TEST_DATA']));
+
+        $session = &Horde_Kolab_Session::singleton('test',
+                                                   array('password' => 'test'));
+
+        $this->assertNoError($session->auth);
+        $this->assertEquals('test@example.org', $session->user_mail);
+
+        $params = $session->getImapParams();
+        $this->assertNoError($params);
+        $this->assertEquals('home.example.org', $params['hostspec']);
+        $this->assertEquals(143, $params['port']);
+        $this->assertEquals('test@example.org', $session->user_mail);
+
+        $session->shutdown();
+
+        $hs = &Horde_SessionObjects::singleton();
+
+        $recovered_session = &$hs->query('kolab_session');
+        $params            = $recovered_session->getImapParams();
+        $this->assertNoError($params);
+        $this->assertEquals('home.example.org', $params['hostspec']);
+        $this->assertEquals(143, $params['port']);
+        $this->assertEquals('test@example.org', $session->user_mail);
+
+        $this->assertEquals('https://fb.example.org/freebusy', $session->freebusy_server);
+    }
+
+    /**
+     * Test retrieving the FreeBusy server for the unauthenticated state.
+     *
+     * @return NULL
+     */
+    public function testGetFreeBusySession()
+    {
+        $server = &$this->prepareEmptyKolabSession();
+        $result = $server->add($this->provideBasicUserTwo());
+        $this->assertNoError($result);
+        $session = &Horde_Kolab_Session::singleton();
+        $this->assertEquals('', $session->freebusy_server);
+    }
+
+    /**
+     * Test group based login allow implemention.
+     *
+     * @return NULL
+     */
+    public function testLoginAllow()
+    {
+        global $conf;
+        $conf['kolab']['server']['allow_group'] = 'group2@example.org';
+        $conf['kolab']['server']['deny_group'] = null;
+
+        $server = &$this->prepareEmptyKolabSession();
+        $result = $server->add($this->provideBasicUserOne());
+        $this->assertNoError($result);
+        $result = $server->add($this->provideBasicUserTwo());
+        $this->assertNoError($result);
+        $groups = $this->validGroups();
+        foreach ($groups as $group) {
+            $result = $server->add($group[0]);
+            $this->assertNoError($result);
+        }
+
+        $session = &Horde_Kolab_Session::singleton('wrobel',
+                                                   array('password' => 'none'),
+                                                   true);
+
+        $this->assertNoError($session->auth);
+        $this->assertEquals('wrobel@example.org', $session->user_mail);
+
+        try {
+            $session = &Horde_Kolab_Session::singleton('test',
+                                                       array('password' => 'test'),
+                                                       true);
+        } catch (Horde_Kolab_Session_Exception $e) {
+            $this->assertError($e, 'You are no member of a group that may login on this server.');
+        }
+        // FIXME: Ensure that the session gets overwritten
+        //$this->assertTrue(empty($session->user_mail));
+    }
+
+    /**
+     * Test group based login deny implemention.
+     *
+     * @return NULL
+     */
+    public function testLoginDeny()
+    {
+        global $conf;
+        $conf['kolab']['server']['deny_group'] = 'group2@example.org';
+        unset($conf['kolab']['server']['allow_group']);
+
+        $server = &$this->prepareEmptyKolabSession();
+        $result = $server->add($this->provideBasicUserOne());
+        $this->assertNoError($result);
+        $result = $server->add($this->provideBasicUserTwo());
+        $this->assertNoError($result);
+        $groups = $this->validGroups();
+        foreach ($groups as $group) {
+            $result = $server->add($group[0]);
+            $this->assertNoError($result);
+        }
+
+        $session = &Horde_Kolab_Session::singleton('test',
+                                                   array('password' => 'test'),
+                                                   true);
+
+        $this->assertNoError($session->auth);
+        $this->assertEquals('test@example.org', $session->user_mail);
+
+        try {
+            $session = &Horde_Kolab_Session::singleton('wrobel',
+                                                       array('password' => 'none'),
+                                                       true);
+        } catch (Horde_Kolab_Session_Exception $e) {
+            $this->assertError($e, 'You are member of a group that may not login on this server.');
+        }
+        // FIXME: Ensure that the session gets overwritten
+        //$this->assertTrue(empty($session->user_mail));
+    }
+
+}