*/
class Horde_Kolab_Filter
{
+ /**
+ * The injector providing the dependencies for this application.
+ *
+ * @var Horde_Injector
+ */
+ private $_injector;
+
public function __construct(Horde_Injector $injector = null)
{
if ($injector === null) {
- $this->injector = new Horde_Injector(new Horde_Injector_TopLevel());
+ $this->_injector = new Horde_Injector(new Horde_Injector_TopLevel());
- $this->injector->bindFactory(
+ $this->_injector->bindFactory(
'Horde_Log_Logger', 'Horde_Kolab_Filter_Factory', 'getLogger'
);
- $this->injector->bindImplementation(
+ $this->_injector->bindFactory(
+ 'Horde_Kolab_Server_Composite', 'Horde_Kolab_Filter_Factory', 'getUserDb'
+ );
+ $this->_injector->bindImplementation(
'Horde_Kolab_Filter_Temporary', 'Horde_Kolab_Filter_Temporary_File'
);
+ $this->_injector->setInstance(
+ 'Horde_Kolab_Filter', $this
+ );
} else {
- $this->injector = $injector;
+ $this->_injector = $injector;
}
}
public function main($type, $inh = STDIN, $transport = null)
{
/** Setup all configuration information */
- /* $configuration = $this->injector->getInstance('Horde_Kolab_Filter_Configuration'); */
+ /* $configuration = $this->_injector->getInstance('Horde_Kolab_Filter_Configuration'); */
/* $configuration->init(); */
/** Now run the filter */
- $filter = $this->injector->getInstance('Horde_Kolab_Filter_' . $type);
+ $filter = $this->_injector->getInstance('Horde_Kolab_Filter_' . $type);
$filter->init();
$filter->parse($inh, $transport);
}
+
+ /**
+ * Return the connection to the user database.
+ *
+ * @return Horde_Kolab_Server_Composite The user DB handle.
+ */
+ public function getUserDb()
+ {
+ return $this->_injector->getInstance('Horde_Kolab_Server_Composite');
+ }
}
\ No newline at end of file
<?php
/**
- * @package Kolab_Filter
+ * A basic definition for a PHP based postfix filter.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Filter
*/
/**
* A basic definition for a PHP based postfix filter.
*
- * Copyright 2004-2008 Klarälvdalens Datakonsult AB
+ * Copyright 2004-2010 Klarälvdalens Datakonsult AB
*
* See the enclosed file COPYING for license information (LGPL). If you
* did not receive this file, see http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
*
- * @author Steffen Hansen <steffen@klaralvdalens-datakonsult.se>
- * @author Gunnar Wrobel <wrobel@pardus.de>
- * @package Kolab_Filter
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Filter
*/
class Horde_Kolab_Filter_Base
{
* Configuration.
*
* @param Horde_Kolab_Filter_Configuration
+ *
+ * @todo Make private
*/
- private $_config;
+ protected $_config;
/**
* The log backend that needs to implement the debug(), info() and err()
* methods.
*
* @param Horde_Kolab_Filter_Logger
+ *
+ * @todo Make private/decorator
*/
protected $_logger;
}
/* This is used as the default domain for unqualified adresses */
- if (!array_key_exists('SERVER_NAME', $_SERVER)) {
- $_SERVER['SERVER_NAME'] = $conf['kolab']['imap']['server'];
- }
-
- if (!array_key_exists('REMOTE_ADDR', $_SERVER)) {
- $_SERVER['REMOTE_ADDR'] = $conf['kolab']['imap']['server'];
- }
-
- if (!array_key_exists('REMOTE_HOST', $_SERVER)) {
- $_SERVER['REMOTE_HOST'] = $conf['kolab']['imap']['server'];
+ /* @todo: What do we need this for? Which libraries grab these infos from global scope? MIME? */
+ if (isset($conf['kolab']['imap']['server'])) {
+ if (!array_key_exists('SERVER_NAME', $_SERVER)) {
+ $_SERVER['SERVER_NAME'] = $conf['kolab']['imap']['server'];
+ }
+
+ if (!array_key_exists('REMOTE_ADDR', $_SERVER)) {
+ $_SERVER['REMOTE_ADDR'] = $conf['kolab']['imap']['server'];
+ }
+
+ if (!array_key_exists('REMOTE_HOST', $_SERVER)) {
+ $_SERVER['REMOTE_HOST'] = $conf['kolab']['imap']['server'];
+ }
}
/* Always display all possible problems */
--- /dev/null
+<?php
+/**
+ * This class provides an error thrown when a potentially temporary failure
+ * occured.
+ *
+ * PHP version 5
+ *
+ * @category Kolab
+ * @package Kolab_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Filter
+ */
+
+/**
+ * This class provides an error thrown when a potentially temporary failure
+ * occured.
+ *
+ * Copyright 2010 Klarälvdalens Datakonsult AB
+ *
+ * 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_Filter
+ * @author Gunnar Wrobel <wrobel@pardus.de>
+ * @license http://www.fsf.org/copyleft/lgpl.html LGPL
+ * @link http://pear.horde.org/index.php?package=Kolab_Filter
+ */
+class Horde_Kolab_Filter_Exception_Temporary
+extends Horde_Kolab_Filter_Exception
+{
+ /**
+ * Construct the exception
+ *
+ * @param string $msg
+ * @param Exception $previous
+ */
+ public function __construct($msg = '', Exception $previous = null)
+ {
+ parent::__construct(
+ $msg,
+ Horde_Kolab_Filter_Exception::OUT_STDOUT |
+ Horde_Kolab_Filter_Exception::EX_TEMPFAIL,
+ $previous
+ );
+ }
+}
$handler->addFilter(constant('Horde_Log::' . $conf['log']['priority']));
return new Horde_Log_Logger($handler);
}
+
+ /**
+ * Creates the connection to the user database.
+ *
+ * @param Horde_Injector $injector The injector provides the required
+ * configuration.
+ *
+ * @return Horde_Kolab_Server_Composite The connection to the user DB.
+ */
+ public function getUserDb(Horde_Injector $injector)
+ {
+ $configuration = $injector->getInstance('Horde_Kolab_Filter_Configuration');
+
+ $conf = $configuration->getConf();
+
+ $factory = new Horde_Kolab_Server_Factory();
+
+ return new Horde_Kolab_Server_Composite(
+ $factory->getServer($conf['server']),
+ new Horde_Kolab_Server_Objects_Base(),
+ new Horde_Kolab_Server_Structure_Kolab(),
+ new Horde_Kolab_Server_Search_Base(),
+ new Horde_Kolab_Server_Schema_Base()
+ );
+ }
}
\ No newline at end of file
class Horde_Kolab_Filter_Incoming extends Horde_Kolab_Filter_Base
{
/**
+ * The application.
+ *
+ * @param Horde_Kolab_Filter
+ */
+ private $_application;
+
+ /**
* A temporary storage place for incoming messages.
*
* @param Horde_Kolab_Filter_Temporary
/**
* Constructor.
*
- * @param Horde_Kolab_Filter_Configuration $config The configuration.
- * @param Horde_Kolab_Filter_Temporary $temporaray Temporary storage
- * location.
- * @param Horde_Kolab_Filter_Logger $logger The logging backend.
+ * @param Horde_Kolab_Filter_Configuration $config The configuration.
+ * @param Horde_Kolab_Filter_Temporary $temporary Temporary storage
+ * location.
+ * @param Horde_Kolab_Filter_Logger $logger The logging backend.
+ * @param Horde_Kolab_Filter $application Main application.
*/
public function __construct(
Horde_Kolab_Filter_Configuration $config,
Horde_Kolab_Filter_Temporary $temporary,
- Horde_Log_Logger $logger
+ Horde_Log_Logger $logger,
+ Horde_Kolab_Filter $application
) {
parent::__construct($config, $logger);
$this->_temporary = $temporary;
+ $this->_application = $application;
}
/**
OUT_LOG | EX_IOERR);
}
+ $recipients = $this->_config->getRecipients();
+
if ($ical) {
require_once 'Horde/Kolab/Resource.php';
$newrecips = array();
- foreach ($this->_recipients as $recip) {
+ foreach ($recipients as $recip) {
if (strpos($recip, '+')) {
list($local, $rest) = explode('+', $recip, 2);
list($rest, $domain) = explode('@', $recip, 2);
$newrecips[] = $resource;
}
}
- $this->_recipients = $newrecips;
+ $recipients = $newrecips;
$this->_add_headers[] = 'X-Kolab-Scheduling-Message: TRUE';
} else {
$this->_add_headers[] = 'X-Kolab-Scheduling-Message: FALSE';
}
/* Check if we still have recipients */
- if (empty($this->_recipients)) {
- $this->_logger->debug("No recipients left.", 'DEBUG');
+ if (empty($recipients)) {
+ $this->_logger->debug('No recipients left.');
return;
} else {
- $result = $this->_deliver($transport);
+ $result = $this->_deliver($transport, $recipients);
if (is_a($result, 'PEAR_Error')) {
return $result;
}
}
- $this->_logger->debug("Filter_Incoming successfully completed.", 'DEBUG');
+ $this->_logger->debug('Filter_Incoming successfully completed.');
}
private function _transportItipReply(Horde_Kolab_Resource_Reply $reply)
*
* @return mixed A PEAR_Error in case of an error, nothing otherwise.
*/
- function _deliver($transport)
+ function _deliver($transport, $recipients)
{
global $conf;
$port = 2003;
}
- /* Load the LDAP library */
- require_once 'Horde/Kolab/Server.php';
-
- $server = &Horde_Kolab_Server::singleton();
- if (is_a($server, 'PEAR_Error')) {
- $server->code = OUT_LOG | EX_TEMPFAIL;
- return $server;
- }
+ // @todo: extract as separate (optional) class
+ $userDb = $this->_application->getUserDb();
$hosts = array();
- foreach ($this->_recipients as $recipient) {
+ foreach ($recipients as $recipient) {
if (strpos($recipient, '+')) {
list($local, $rest) = explode('+', $recipient, 2);
list($rest, $domain) = explode('@', $recipient, 2);
} else {
$real_recipient = $recipient;
}
- $dn = $server->uidForIdOrMail($real_recipient);
- if (is_a($dn, 'PEAR_Error')) {
- return $dn;
- }
- if (!$dn) {
- Horde::logMessage(sprintf('User %s does not exist!', $real_recipient), 'DEBUG');
- }
try {
- $user = $server->fetch($dn, 'Horde_Kolab_Server_Object_Kolab_User');
+ //@todo: fix anonymous binding in Kolab_Server. The method name should be explicit.
+ $userDb->server->connectGuid();
+ $guid = $userDb->search->searchGuidForUidOrMail($real_recipient);
+ if (empty($guid)) {
+ throw new Horde_Kolab_Filter_Exception_Temporary(
+ sprintf('User %s does not exist!', $real_recipient)
+ );
+ }
+ $imapserver = $userDb->objects->fetch(
+ $guid, 'Horde_Kolab_Server_Object_Kolab_User'
+ )->getSingle('kolabHomeServer');
} catch (Horde_Kolab_Server_Exception $e) {
- Horde::logMessage(sprintf('Failed fetching user object %s. Error was:',
- $dn, $e->getMessage()), 'DEBUG');
- $user->code = OUT_LOG | EX_TEMPFAIL;
- return $user;
- }
- $imapserver = $user->get(Horde_Kolab_Server_Object_Kolab_User::ATTRIBUTE_IMAPHOST);
- if (is_a($imapserver, 'PEAR_Error')) {
- $imapserver->code = OUT_LOG | EX_TEMPFAIL;
- return $imapserver;
+ //@todo: If a message made it till here than we shouldn't fail
+ // because the LDAP lookup fails. The safer alternative is to try the local
+ // delivery. LMTP should deny anyway in case the user is unknown
+ // (despite the initial postfix checks).
+ throw new Horde_Kolab_Filter_Exception_Temporary(
+ sprintf(
+ 'Failed identifying IMAP host of user %s. Error was: %s',
+ $real_recipient, $e->getMessage()
+ ),
+ $e
+ );
}
if (!empty($imapserver)) {
$uhost = $imapserver;
OUT_LOG | EX_IOERR);
}
- $result = $transport->start($this->_sender, $hosts[$imap_host]);
+ $result = $transport->start($this->_config->getSender(), $hosts[$imap_host]);
if (is_a($result, 'PEAR_Error')) {
return $result;
}
<file name="Exception.php" role="php" />
<dir name="Exception">
<file name="IoError.php" role="php" />
+ <file name="Temporary.php" role="php" />
<file name="Usage.php" role="php" />
</dir> <!-- /lib/Horde/Kolab/Filter/Exception -->
<file name="Factory.php" role="php" />
<install name="lib/Horde/Kolab/Filter/Content.php" as="Horde/Kolab/Filter/Content.php" />
<install name="lib/Horde/Kolab/Filter/Base.php" as="Horde/Kolab/Filter/Base.php" />
<install name="lib/Horde/Kolab/Filter/Exception.php" as="Horde/Kolab/Filter/Exception.php" />
+ <install name="lib/Horde/Kolab/Filter/Exception/IoError.php" as="Horde/Kolab/Filter/Exception/IoError.php" />
+ <install name="lib/Horde/Kolab/Filter/Exception/Temporary.php" as="Horde/Kolab/Filter/Exception/Temporary.php" />
<install name="lib/Horde/Kolab/Filter/Exception/Usage.php" as="Horde/Kolab/Filter/Exception/Usage.php" />
<install name="lib/Horde/Kolab/Filter/Factory.php" as="Horde/Kolab/Filter/Factory.php" />
<install name="lib/Horde/Kolab/Filter/Incoming.php" as="Horde/Kolab/Filter/Incoming.php" />
{
switch($action) {
case 'handling the message':
+ global $conf;
+ $conf['server']['mock'] = true;
+ //@todo: Fix guid => dn here
+ $conf['server']['data'] = array('dn=example' => array('dn' => 'dn=example', 'data' => array('mail' => array('me@example.org'), 'kolabHomeServer' => array('localhost'), 'objectClass' => array('kolabInetOrgPerson'), 'guid' => 'dn=example')));
$_SERVER['argv'] = $this->_prepareArguments($world);
$filter = new Horde_Kolab_Filter();
ob_start();
--- /dev/null
+<?php
+/**
+ * A Horde_Kolab_Server:: factory.
+ *
+ * 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
+ */
+
+/**
+ * A based Horde_Kolab_Server:: factory.
+ *
+ * Copyright 2008-2010 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_Factory
+{
+ /**
+ * Return the suggested interface bindings for the Kolab Server components.
+ *
+ * @return array The bindings.
+ */
+ public function getBindings()
+ {
+ return array(
+ array(
+ 'Horde_Kolab_Server_Objects_Interface',
+ 'Horde_Kolab_Server_Objects_Base'
+ ),
+ array(
+ 'Horde_Kolab_Server_Search_Interface',
+ 'Horde_Kolab_Server_Search_Base'
+ ),
+ array(
+ 'Horde_Kolab_Server_Schema_Interface',
+ 'Horde_Kolab_Server_Schema_Base'
+ ),
+ );
+ }
+
+ /**
+ * Setup the machinery to create a Horde_Kolab_Server_Structure handler.
+ *
+ * @param array $configuration The configuration parameters for the
+ * connection. (@todo: describe parameters)
+ *
+ * @return Horde_Kolab_Server_Structure_Interface
+ */
+ private function getStructure(array $configuration)
+ {
+ if (!isset($configuration['driver'])) {
+ $driver = 'Horde_Kolab_Server_Structure_Kolab';
+ } else {
+ $driver = $configuration['driver'];
+ }
+ return new $driver();
+ }
+
+ /**
+ * Return the server connection that should be used.
+ *
+ * @param array $configuration The configuration parameters for the
+ * connection. (@todo: describe parameters)
+ *
+ * @return Horde_Kolab_Server_Connection The connection to the server.
+ */
+ public function getConnection(array $configuration)
+ {
+ if (empty($configuration['mock'])) {
+ if (!isset($configuration['basedn'])) {
+ throw new Horde_Exception('The parameter \'basedn\' is missing in the Kolab server configuration!');
+ }
+
+ $ldap_read = new Horde_Ldap($configuration);
+ if (isset($configuration['host_master'])) {
+ $configuration['host'] = $configuration['host_master'];
+ $ldap_write = new Horde_Ldap($configuration);
+ $connection = new Horde_Kolab_Server_Connection_Splittedldap(
+ $ldap_read, $ldap_write
+ );
+ } else {
+ $connection = new Horde_Kolab_Server_Connection_Simpleldap(
+ $ldap_read
+ );
+ }
+ return $connection;
+ } else {
+ if (isset($configuration['data'])) {
+ $data = $configuration['data'];
+ } else {
+ $data = array();
+ }
+ $connection = new Horde_Kolab_Server_Connection_Mock(
+ new Horde_Kolab_Server_Connection_Mock_Ldap(
+ $configuration, $data
+ )
+ );
+ return $connection;
+ }
+ }
+
+ /**
+ * Return the server connection that should be used.
+ *
+ * @param array $configuration The configuration parameters for the
+ * server. (@todo: describe parameters)
+ * @param mixed $logger The logger (@todo: which methods need to be provided?)
+ *
+ * @return Horde_Kolab_Server_Interface The Horde_Kolab_Server connection.
+ */
+ public function getServer(array $configuration, $logger)
+ {
+ $connection = $this->getConnection($configuration);
+
+ if (!isset($configuration['filter'])) {
+ $server = new Horde_Kolab_Server_Ldap_Standard(
+ $connection,
+ $configuration['basedn']
+ );
+ } else {
+ $server = new Horde_Kolab_Server_Ldap_Filtered(
+ $connection,
+ $configuration['basedn'],
+ $configuration['filter']
+ );
+ }
+
+ if (isset($configuration['map'])) {
+ $server = new Horde_Kolab_Server_Decorator_Map(
+ $server, $configuration['map']
+ );
+ }
+
+ if (isset($configuration['debug']) || isset($configuration['log'])) {
+ $server = new Horde_Kolab_Server_Decorator_Log(
+ $server, $logger
+ );
+ }
+
+ if (isset($configuration['debug']) || isset($configuration['count'])) {
+ $server = new Horde_Kolab_Server_Decorator_Count(
+ $server, $logger
+ );
+ }
+
+ if (!empty($configuration['cleanup'])) {
+ $server = new Horde_Kolab_Server_Decorator_Clean(
+ $server
+ );
+ }
+ return $server;
+ }
+}
\ No newline at end of file