+++ /dev/null
-<?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;
- }
-}
+++ /dev/null
-<?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;
- }
-}
+++ /dev/null
-<?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();
- }
-}
+++ /dev/null
-<?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;
- }
-}
+++ /dev/null
-<?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);
- }
-
-}
<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" />
<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" />
</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" />
<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" />
+++ /dev/null
-<?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));
- }
-
-}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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();
+ }
+}
--- /dev/null
+<?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;
+ }
+}
--- /dev/null
+<?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);
+ }
+
+}
--- /dev/null
+<?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>
--- /dev/null
+<?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();
+}
--- /dev/null
+<?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));
+ }
+
+}