[cvs] [Wiki] changed: ImapSelect

Jan Schneider jan at horde.org
Tue Aug 30 08:46:32 PDT 2005


jan  Tue, 30 Aug 2005 08:46:32 -0700

Modified page: http://wiki.horde.org/ImapSelect
New Revision:  3.0
Change log:  Better example

@@ -1,75 +1,57 @@
-+++ Introduction
++ Dynamically selecting an IMAP server for authentication
+
+++ Introduction
 
 During a migration from one IMAP server to another, the need arose to run both the old and the new IMAP servers in paralell. By default,
 Horde only allows a single primary server to be enabled in servers.php. Of course, we could have allowed our users to simply select
 their server by enabling IMAP server selection, but there is a better way. What follows are instructions on using a !MySQL backend to 
 select an IMAP server for authentication, given a username:
 
-+++ The SQL table
-
-
+++ The SQL table
 
 There are many ways to do this of course. In this example, we'll just be using a table with two rows:
 
 <code>
 ---------------------------------------------------------
-|   username        |     server.domain.com             |
+|   username        |     cyrus                         |
 ---------------------------------------------------------
 </code>
 
-Your table can be constructed however you like. It can even be a part of your existing Horde DB. The important point is that you need the
-table to be constructed in such a way as to be able to query a username and have the lookup return a servername. Our example
-uses a table called 'host'. 
-
-+++ Writing a hook
-
+Your table can be constructed however you like. It can even be a part of your existing Horde DB. The important point is that you need the table to be constructed in such a way as to be able to query a username and have the lookup return a server name from {{imp/config/servers.php}}.
 
+++ Writing a hook
 
 Here's some sample code for a hook placed inside horde/config/hooks.php:
 
 <code type="php">
-if (!function_exists('_imp_hook_imap')) {
-        function _imp_hook_imap($userName)
-        {
-                global $conf;
-                include_once 'DB.php';
-                $_db = &DB::connect($conf['sql'], true);
-                $query = sprintf('SELECT server FROM host WHERE user=%s', $_db->quote($userName));
-                $result = $_db->getOne($query);
-                if (!is_a($result, 'PEAR_Error')) {
-                        return $result;
-                } else {
-                        return false;
-                }
+if (!function_exists('_horde_hook_preauthenticate')) {
+    function _horde_hook_preauthenticate($userID, $credential, $realm)
+    {
+        require dirname(__FILE__) . '/../imp/config/servers.php';
+
+        // Strip domain part from user.
+        $userID = substr($userID, 0, strpos($userID, '@'));
+        // Connect to database server.
+        $db = mysql_connect('hostname', 'dbuser', 'dbpasswd') or die('Can not connect to database.');
+        // Select database.
+        mysql_select_db('dbname') or die('Can not select database.');
+        // Execute the query
+        $sth = mysql_query('SELECT server_name FROM users WHERE user=\'' . mysql_real_escape_string($userID) . '\'') or die ('Can not query database.');
+        // Fetch the server name.
+        $server = mysql_fetch_row($sth);
+        if ($server === false) {
+            die('Can not read user from database.');
         }
-} 
 
-</code>
+        // Set IMAP server values.
+        foreach (array('server', 'folders', 'namespace') as $key) {
+            $_SESSION['imp'][$key] = $servers[$server[0]][$key];
+        }
 
-+++ Placing the hook into the session
-
-
-
-The above hook returns a single line containing a server name. The results are injected into /horde/imp/lib/Session.php as follows:
-
-<code type="php">
-
-        if (!empty($GLOBALS['conf']['hooks']['imap'])) {
-                require_once HORDE_BASE . '/config/hooks.php';
-                if (function_exists('_imp_hook_imap')) {
-                        $_SESSION['imp']['server'] = call_user_func('_imp_hook_imap',  $_SESSION['imp']['user']);
-                        }
-        }
+        return true;
+    }
+}
 
 </code>
 
-On our setup, this is done right before authentication is attempted (right around line 223). As best I can tell, you're fine so long
-as you don't have $_SESSION['imp']['server']  overwritten by anything else before you get to the call to &Auth::singleton(array('imp', 'imp'));
-
-+++ Disclaimer 
-
-
-
-This code works on our setup thus far. It could be wrong, uneccesary, foolish, or otherwise idiotic. In short, YMMV. 
-
-Questions? Send them to mp at xmission.com
+All that's left to do, is to activate the preauthenticate hook in Horde's configuration.


More information about the cvs mailing list