gunnar: server/kolab-freebusy/freebusy config.php, 1.4, 1.5 freebusy.php, 1.4, 1.5 pfb.php, 1.7, 1.8

cvs at kolab.org cvs at kolab.org
Thu Nov 22 17:58:35 CET 2007


Author: gunnar

Update of /kolabrepository/server/kolab-freebusy/freebusy
In directory doto:/tmp/cvs-serv2449/freebusy

Modified Files:
	config.php freebusy.php pfb.php 
Log Message:
Fully restructured the kolab-freebusy package. Implements the newest free/busy concepts.

Index: config.php
===================================================================
RCS file: /kolabrepository/server/kolab-freebusy/freebusy/config.php,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- config.php	14 Oct 2007 12:31:58 -0000	1.4
+++ config.php	22 Nov 2007 16:58:33 -0000	1.5
@@ -34,112 +34,73 @@
  *
  */
 
-// Kolab prefix
-$params['kolab_prefix'] = '/kolab';
-
-// What is the address of the Cyrus server where the calendar data is stored?
-// This is also used as the LDAP server address where user objects reside
-$params['server'] = 'localhost';
-
-// What is the address of the LDAP server address where user objects reside
-$params['ldap_uri'] = "ldap://127.0.0.1:389";
-
-// What is the Base DN of our LDAP database?
-$params['base_dn'] = 'dc=example,dc=com';
-
-// What DN should we use to bind to the LDAP server?
-$params['bind_dn'] = 'cn=nobody,cn=internal,' . $params['base_dn'];
-
-// What password should we use with the above DN when binding?
-$params['bind_pw'] = 'php password from kolab.conf';
-
-// Are we using a multi-location setup? If this is true, we check the users'
-// LDAP object for the next attribute - if it is different than $params['server']
-// we get the free/busy information from the script running on the other box
-$params['multi_location'] = true;
-
-// What LDAP attribute is used to store the users' home server address?
-$params['home_server'] = 'kolabhomeserver';
-
-// What is our default mail domain? This is used if any users do not have
-// '@domain' specified after their username as part of their email address.
-$params['email_domain'] = 'example.com';
-
-// Are we using virtual domains with Cyrus?
-$params['virtual_domains'] = true;
-
-// Should we append domains to mailbox URIs? This only applies when
-// virtual_domains is true, and when using manager accounts.
-$params['append_domains'] = false;
-
-// What account should we use to read in calendar data in the case the user
-// does not supply credentials? This account should
-// have access to the calendar mailbox of all the users for which free/busy
-// information is to be retrieved.
-//$params['calendar_user'] = '@ @@cyrus-admins@@@';
-
-// What password should we use with the above account?
-//$params['calendar_pass'] = '@ @@bind_pw@@@';
-
-// What is the name of the users' calendar mailbox?
-$params['calendar_store'] = 'Calendar';
-
-// How many days of free/busy data should we generate?
-$params['freebusy_days'] = 56;
+$conf = array();
 
-// Should we generate extended free/busy information? This can be overridden by
-// the URL parameter "x" (= 0 or 1).
-$params['extended'] = false;
+/* Horde::Log configuration */
+$conf['log']['enabled']          = true;
+$conf['log']['priority']         = PEAR_LOG_DEBUG; // Leave this on DEBUG for now. We just restructured the package...
+$conf['log']['type']             = 'file';
+$conf['log']['name']             = '/kolab/var/kolab-freebusy/log/freebusy.log';
+$conf['log']['ident']            = 'Kolab Free/Busy';
+$conf['log']['params']['append'] = true;
 
-// Should we use the caching mechanism, which avoids having to always re-read
-// all the events? This can be overridden by the URL parameter "c" (= 0 or 1).
-$params['cache'] = true;
+/* PHP error logging */
+ini_set('error_log', '/kolab/var/kolab-freebusy/log/php-error.log');
 
-// Should we redirect using a Location header, if the user is not local? If this
-// is false we silently download the file ourselves and output it so that it
-// looks as though the free/busy information is coming from us.
-$params['redirect'] = false;
+/* Horde::Kolab::LDAP configuration */
+$conf['kolab']['ldap']['server'] = 'example.com';
+$conf['kolab']['ldap']['basedn'] = 'dc=example,dc=com';
+$conf['kolab']['ldap']['phpdn']  = 'cn=nobody,cn=internal,dc=example,dc=com';
+$conf['kolab']['ldap']['phppw']  = '';
 
-// Should we send a Content-Type header, indicating what the mime type of the
-// resulting VFB file is?
-$params['send_content_type'] = false;
+/* Horde::Kolab::IMAP configuration */
+$conf['kolab']['imap']['server']   = 'example.com';
+$conf['kolab']['imap']['port']     = 143;
+$conf['kolab']['imap']['protocol'] = 'notls/readonly';
 
-// Should we send a Content-Length header, indicating how large the resulting
-// VFB file is?
-$params['send_content_length'] = false;
+/* Horde::Auth configuration */
+$conf['auth']['params']['login_block'] = 0;
+$conf['auth']['checkbrowser']          = false;
+$conf['auth']['checkip']               = false;
 
-// Should we send a Content-Disposition header, indicating what the name of the
-// resulting VFB file should be?
-$params['send_content_disposition'] = false;
+/* Kolab::Freebusy configuration */
 
-// Where are we logging to?
-$params['log'] = 'file:/kolab/var/apache/log/freebusy/freebusy.log';                // File...
-// $params['log'] = 'syslog:cons, pid';            // Or syslog...
+/* Should we redirect using a Location header, if the user is not local? If this
+ * is false we silently download the file ourselves and output it so that it
+ * looks as though the free/busy information is coming from us.
+ */
+$conf['fb']['redirect']     = false;
 
-// What level of output should we log? Higher levels give more verbose output.
-// One of: 0 (RM_LOG_SILENT); 1 (RM_LOG_ERROR); 2 (RM_LOG_WARN); 3 (RM_LOG_INFO) or 4 (RM_LOG_DEBUG).
-$params['log_level'] = 4;
+/* What is the address of the current server where the calendar data is stored?
+ * This is also used as the LDAP server address where user objects reside.
+ */
+$conf['fb']['server']       = 'example.com';
 
-// What db type to use for freebusy caches
-$params['dbtype'] = 'db4';
+/* What is our default mail domain? This is used if any users do not have
+ * '@domain' specified after their username as part of their email address.
+ */
+$conf['fb']['email_domain'] = 'example.com';
 
-// IMAP options passed to imap_open
-//$params['imap_options'] = "/notls/secure/readonly";
-$params['imap_options'] = "/notls/readonly";
+/* Location of the cache files */
+$conf['fb']['cache_dir']    = '/kolab/var/kolab-freebusy/cache';
 
-$params['pfb_dbformat'] = 'db4';
+/* What db type to use for the freebusy caches */
+$conf['fb']['dbformat']     = 'db4';
 
-// Location of the cache files
-$params['cache_dir'] = '/kolab/var/kolab/www/freebusy/cache';
+/* Should we send a Content-Type header, indicating what the mime type of the
+ * resulting VFB file is?
+ */
+$conf['fb']['send_content_type'] = false;
 
-// don't change this if you don't have to
-//$params['ldap_classname_suffix'] = "_dummy";
+/* Should we send a Content-Length header, indicating how large the resulting
+ * VFB file is?
+ */
+$conf['fb']['send_content_length'] = false;
 
-// Activate if you wish to use the new horde framework
-// (horde-framework-kolab) package instead of the old code in
-// kolab-horde-framework. This is still untested and considered
-// UNSAFE!
-$params['use_new_horde'] = false;
+/* Should we send a Content-Disposition header, indicating what the name of the
+ * resulting VFB file should be?
+ */
+$conf['fb']['send_content_disposition'] = false;
 
 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
 //
@@ -152,3 +113,15 @@
 // diff -Nau kolab-freebusy/freebusy/config.php kolabd/kolabd/templates/freebusy.conf.template.in
 //
 //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
+
+// DEBUGGING
+// =========
+//
+// Activate this to see the log messages on the screen
+// $conf['log']['type'] = 'display';
+//
+// Activate this to see the php messages on the screen
+// ini_set('display_errors', 1);
+//
+// Both setting will disrupt header delivery (which should not cause a
+// problem).
\ No newline at end of file

Index: freebusy.php
===================================================================
RCS file: /kolabrepository/server/kolab-freebusy/freebusy/freebusy.php,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- freebusy.php	13 Aug 2007 08:53:33 -0000	1.4
+++ freebusy.php	22 Nov 2007 16:58:33 -0000	1.5
@@ -32,178 +32,66 @@
  *
  */
 
-require_once('config.php');
-require_once('Kolab/Freebusy/freebusycache.class.php');
-require_once('Kolab/Freebusy/freebusycollector.class.php');
-
-if (empty($params['ldap_classname_suffix'])) {
-    $params['ldap_classname_suffix'] = '';
- }
-
-require_once('Kolab/Freebusy/freebusyldap' 
-             . $params['ldap_classname_suffix'] 
-             . '.class.php');
-
-require_once('Kolab/Freebusy/misc.php');
-
-logInit( 'freebusy' );
-
-$imapuser     = isset($_SERVER['PHP_AUTH_USER'])?$_SERVER['PHP_AUTH_USER']:false;
-$imappw       = isset($_SERVER['PHP_AUTH_PW'])?$_SERVER['PHP_AUTH_PW']:false;
-
-// This part allows you to use the PHP scripts with CGI rather than as
-// an apache module. This will of course slow down things but on the
-// other hand it allows you to reduce the memory footprint of the 
-// apache server. The default is to use PHP as a module and the CGI 
-// version requires specific Apache configuration.
-//
-// The line you need to add to your configuration of the /freebusy 
-// location of your server looks like this:
-//
-//    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
-//
-// The complete section will probably look like this then:
-//
-//  <IfModule mod_rewrite.c>
-//    RewriteEngine On
-//    # FreeBusy list handling
-//    RewriteBase /freebusy
-//    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
-//    RewriteRule ^([^/]+)\.ifb       freebusy.php?uid=$1		    [L]
-//    RewriteRule ^([^/]+)\.vfb       freebusy.php?uid=$1		    [L]
-//    RewriteRule ^([^/]+)\.xfb       freebusy.php?uid=$1&extended=1        [L]
-//    RewriteRule ^trigger/(.+)\.pfb  pfb.php?folder=$1&cache=0             [L]
-//    RewriteRule ^(.+)\.pfb          pfb.php?folder=$1&cache=1             [L]
-//    RewriteRule ^trigger/(.+)\.xpfb pfb.php?folder=$1&cache=0&extended=1  [L]
-//    RewriteRule ^(.+)\.xpfb         pfb.php?folder=$1&cache=1&extended=1  [L]
-//  </IfModule>
-if( empty($imapuser) && isset($_ENV['REDIRECT_REDIRECT_REMOTE_USER']) ) {
-  $a = base64_decode( substr($_ENV['REDIRECT_REDIRECT_REMOTE_USER'], 6)) ;
-
-  if ( (strlen($a) == 0) || ( strcasecmp($a, ":" )  == 0 ))
-    {
-      $imapuser = false;
-      $imappw   = false;
-    }
-  else
-    {
-      list($name, $password) = explode(':', $a, 2);
-      $imapuser = $name;
-      $imappw   =  $password;
-    }
- }
-
-$user = trim($_REQUEST['uid']);
-
-$req_cache    = false;
-$req_extended = false;
-if (!empty($_REQUEST['cache'])) {
-    $req_cache    = (bool)$_REQUEST['cache'];
- }
-
-if (!empty($_REQUEST['extended'])) {
-    $req_extended = (bool)$_REQUEST['extended'];
- }
-
-myLog("---FreeBusy Script starting (" . $_SERVER['REQUEST_URI'] . ")---", RM_LOG_DEBUG );
-myLog("user=$user, imapuser=$imapuser, req_cache=$req_cache, req_extended=$req_extended", RM_LOG_DEBUG );
+/* Load the required free/busy libraries - this also loads Horde:: and
+ Util:: as well as the PEAR constants*/ 
+require_once 'Kolab/Freebusy/Page.php';
 
-$ldap =& new FreeBusyLDAP( $params['ldap_uri'], $params['base_dn'] );
-if( !$ldap->bind( $params['bind_dn'], $params['bind_pw'] ) ) {
-    notFound( "Bind failed: ".$ldap->error() );
-    exit;
- }
+/* Load the configuration */ 
+require_once 'config.php';
 
-$imapuser = $ldap->mailForUid( $imapuser );
-$user = $ldap->mailForUidOrAlias( $user );
-$homeserver = $ldap->homeServer( $user );
+/* Profiling */
+$timer = &new Timer();
 
-if( $homeserver === false ) {
-    notFound("Resource " .$_SERVER['REQUEST_URI'] . " (user=$user, req_extended=$req_extended, req_cache=$req_cache) not found");
- }
+/* Get the user requsted */
+$req_owner = Util::getFormData('uid');
 
-if( $homeserver != $params['server'] ) {
-    $redirect = 'https://' . $homeserver . $_SERVER['REQUEST_URI'];
-    if ($params['redirect']) {
-        header("Location: $redirect");
-    } else {
-        header("X-Redirect-To: $redirect");
-        $redirect = 'https://' . urlencode($_SERVER['PHP_AUTH_USER']) . ':'
-            . urlencode($_SERVER['PHP_AUTH_PW']) . '@' . $homeserver
-            . $_SERVER['REQUEST_URI'];
-        if (!@readfile($redirect)) {
-            unauthorized("Unable to read free/busy information from " . removePassword($redirect));
-        }
-    }
-    shutdown();
-    exit;
- }
+Horde::logMessage(sprintf(_("Starting generation of free/busy data for user %s"), 
+                          $req_owner), __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
-$user = strtolower($user);
+/* Validate folder access */
+$access = &new FolderAccess();
+$result = $access->parseOwner($req_owner);
+if (is_a($result, 'PEAR_Error')) {
+    Kolab_Freebusy_Error::notFound($result);
+}
 
-$cache =& new FreeBusyCache( $params['cache_dir'], $params['pfb_dbformat'], $params, $req_extended );
+Horde::logMessage(sprintf(_("Free/busy data of owner %s on server %s requested by user %s."),
+                          $access->owner, $access->homeserver, $access->user), 
+                  __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
-$collector =& new FreeBusyCollector( $user );
+/* Try to fetch the data if it is stored on a remote server */
+$result = $access->fetchRemote();
+if (is_a($result, 'PEAR_Error')) {
+    Kolab_Freebusy_Error::unauthorized($result);
+}
 
-$groups = $ldap->distlists( $ldap->dn( $user ) );
-for( $i = 0; $i < count($groups); $i++ ) {
-    $groups[$i] = $groups[$i].'@'.$params['email_domain'];
- }
-$pfbs = $cache->findAll( $user, $groups );
-$ts = 0;
-if( $pfbs === false ) {
-    notFound($pfb->error);
- }
+/* Load the cache class now */
+require_once('Kolab/Freebusy/Cache.php');
 
-//myLog("Found pfbs: ".join(",",$pfbs)." for $user",RM_LOG_DEBUG);
+/* Where is the cache data stored? */
+if (!empty($conf['fb']['cache_dir'])) {
+    $cache_dir = $conf['fb']['cache_dir'];
+} else {
+    /* This default is not recommended so make sure you set a 
+     * cache dir outside of the apache document root.
+     */
+    $cache_dir = dirname(__FILE__) . '/cache';
+}
+$cache = &new FreeBusyCache($cache_dir);
 
-if( $req_extended ) {
-    // Get accessing users groups
-    $imapgroups = $ldap->distlists( $ldap->dn( $imapuser ) );
- }
+/* Get the cache request variables */
+$req_extended = Util::getFormData('extended', false);
 
-foreach( $pfbs as $pfb ) {
-    $fb = $cache->load( $pfb, $ts2, $acl );
-    if( $fb ) {
-        myLog("Found fb for $pfb", RM_LOG_DEBUG);
-    } else {
-        myLog("No fb found for $pfb", RM_LOG_DEBUG);
-    }
-    if( $acl && $req_extended ) {
-        $r = $cache->getRights( $acl, $imapuser, $imapgroups );
-        if( !$fb || !array_key_exists( 'r', $r ) ) {
-            $cache->extended = false; // HACK!
-            $fb = $cache->load( $pfb, $ts2, $acl );    
-            $cache->extended = true;
-            myLog("Falling back to non-extended fb", RM_LOG_DEBUG );
-        }
-    }
-    $ts = max( $ts, $ts2 );
-    if( $fb ) {
-        if( $collector->addFreebusy( $fb ) == FB_TOO_OLD ) {
-            $cache->delete( $pfb );
-        }
-    }
+$result = $cache->load($access, $req_extended);
+if (is_a($result, 'PEAR_Error')) {
+    Kolab_Freebusy_Error::notFound($result);
 }
-$vfb = $collector->exportvCalendar();
 
-// And finally send it out, ensuring it doesn't get cached along the way
-header('Cache-Control: no-store, no-cache, must-revalidate');
-header('Cache-Control: post-check=0, pre-check=0', false);
-header('Pragma: no-cache');
-header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
-header('Last-Modified: ' . gmdate("D, d M Y H:i:s",$ts) . ' GMT');
-header('Pragma: public');
-header('Content-Transfer-Encoding: none');
-if ($params['send_content_type']) {
-    header('Content-Type: text/calendar');
-}
-if ($params['send_content_length']) {
-    header('Content-Length: ' . strlen($vfb));
-}
-if ($params['send_content_disposition']) {
-    header('Content-Disposition: attachment; filename="' . $user . '.ifb"');
-}
+/* And finally send it out */
+$view = &new FreeBusyView($result);
+$view->render($access->owner . '.vfb');
 
-echo $vfb;
+/* Finish up */
+Horde::logMessage(sprintf(_("Free/busy generation complete, execution time was %s seconds."), 
+                          $timer->stop()), __FILE__, __LINE__, PEAR_LOG_DEBUG);
 ?>

Index: pfb.php
===================================================================
RCS file: /kolabrepository/server/kolab-freebusy/freebusy/pfb.php,v
retrieving revision 1.7
retrieving revision 1.8
diff -u -d -r1.7 -r1.8
--- pfb.php	8 Oct 2007 15:57:49 -0000	1.7
+++ pfb.php	22 Nov 2007 16:58:33 -0000	1.8
@@ -35,250 +35,95 @@
  *
  */
 
-  // Profiling
-function microtime_float() 
-{
-    list($usec, $sec) = explode(" ", microtime());
-    return ((float)$usec + (float)$sec);
-}
-$start_time = microtime_float();
-
-
-error_reporting(E_ALL);
-$max_execution_time = ini_get('max_execution_time');
-if( $max_execution_time < 200 ) {
-    ini_set('max_execution_time', '200');
- }
-
-require_once('Kolab/Freebusy/misc.php');
-require_once('config.php');
-
-if ( empty($params['ldap_classname_suffix'])) $params['ldap_classname_suffix'] = '';
-require_once('Kolab/Freebusy/freebusyldap'
-             . $params['ldap_classname_suffix']
-             . '.class.php');
-
-require_once('Kolab/Freebusy/freebusycache.class.php');
-
-logInit('pfb');
-
-$imapuser     = isset($_SERVER['PHP_AUTH_USER'])?$_SERVER['PHP_AUTH_USER']:false;
-$imappw       = isset($_SERVER['PHP_AUTH_PW'])?$_SERVER['PHP_AUTH_PW']:false;
-
-// This part allows you to use the PHP scripts with CGI rather than as
-// an apache module. This will of course slow down things but on the
-// other hand it allows you to reduce the memory footprint of the 
-// apache server. The default is to use PHP as a module and the CGI 
-// version requires specific Apache configuration.
-//
-// The line you need to add to your configuration of the /freebusy 
-// location of your server looks like this:
-//
-//    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
-//
-// The complete section will probably look like this then:
-//
-//  <IfModule mod_rewrite.c>
-//    RewriteEngine On
-//    # FreeBusy list handling
-//    RewriteBase /freebusy
-//    RewriteRule .* - [E=REMOTE_USER:%{HTTP:Authorization}]
-//    RewriteRule ^([^/]+)\.ifb       freebusy.php?uid=$1		    [L]
-//    RewriteRule ^([^/]+)\.vfb       freebusy.php?uid=$1		    [L]
-//    RewriteRule ^([^/]+)\.xfb       freebusy.php?uid=$1&extended=1        [L]
-//    RewriteRule ^trigger/(.+)\.pfb  pfb.php?folder=$1&cache=0             [L]
-//    RewriteRule ^(.+)\.pfb          pfb.php?folder=$1&cache=1             [L]
-//    RewriteRule ^trigger/(.+)\.xpfb pfb.php?folder=$1&cache=0&extended=1  [L]
-//    RewriteRule ^(.+)\.xpfb         pfb.php?folder=$1&cache=1&extended=1  [L]
-//  </IfModule>
-if( empty($imapuser) && isset($_ENV['REDIRECT_REDIRECT_REMOTE_USER']) ) {
-  $a = base64_decode( substr($_ENV['REDIRECT_REDIRECT_REMOTE_USER'], 6)) ;
+/* Load the required free/busy libraries - this also loads Horde:: and
+ Util:: as well as the PEAR constants*/ 
+require_once 'Kolab/Freebusy/Page.php';
 
-  if ( (strlen($a) == 0) || ( strcasecmp($a, ":" )  == 0 ))
-    {
-      $imapuser = false;
-      $imappw   = false;
-    }
-  else
-    {
-      list($name, $password) = explode(':', $a, 2);
-      $imapuser = $name;
-      $imappw   =  $password;
-    }
- }
+/* Load the configuration */ 
+require_once 'config.php';
 
-$req_cache    = isset($_REQUEST['cache'])?(bool)$_REQUEST['cache']:false;
-$req_folder   = isset($_REQUEST['folder'])?$_REQUEST['folder']:false;
-$req_extended = isset($_REQUEST['extended'])?(bool)$_REQUEST['extended']:false;
+/* Profiling */
+$timer = &new Timer();
 
-// convert character encoding (stores utf7 folder names also on disc)
-require_once "Horde/Util.php";
-require_once "Horde/String.php";
-$req_folder = String::convertCharset($req_folder, "UTF-8", "UTF7-IMAP");
+/* Get the folder name */
+$req_folder = Util::getFormData('folder', '');
 
-myLog("pfb.php starting up: user=$imapuser, folder=$req_folder, extended=$req_extended", 
-      RM_LOG_DEBUG);
+Horde::logMessage(sprintf(_("Starting generation of partial free/busy data for folder %s"), 
+                          $req_folder), __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
-$ldap =& new FreeBusyLDAP( $params['ldap_uri'], $params['base_dn'] );
-if( !$ldap->bind( $params['bind_dn'], $params['bind_pw'] ) ) {
-    notFound( "Bind failed: ".$ldap->error() );
-    exit;
+/* Validate folder access */
+$access = &new FolderAccess();
+$result = $access->parseFolder($req_folder);
+if (is_a($result, 'PEAR_Error')) {
+    Kolab_Freebusy_Error::notFound($result);
 }
 
-$userinfo = $ldap->userInfo( $imapuser );
-if( $userinfo ) {
-    if( $userinfo['MAIL'] ) $imapuser = $userinfo['MAIL'];
-    //$homeserver = $userinfo['HOMESERVER'];  
- }
-
-$folder = explode('/', $req_folder);
+Horde::logMessage(sprintf(_("Partial free/busy data of owner %s on server %s requested by user %s."),
+                          $access->owner, $access->homeserver, $access->user), 
+                  __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
-if( count($folder) < 1 ) {
-    // error
-    notFound( _('No such folder ') . htmlentities($req_folder) );
+/* Try to fetch the data if it is stored on a remote server */
+$result = $access->fetchRemote();
+if (is_a($result, 'PEAR_Error')) {
+    Kolab_Freebusy_Error::unauthorized($result);
 }
 
-// Make sure email address is in lowercase
-$folder[0] = strtolower($folder[0]);
-$req_folder = implode('/', $folder);
+/* Load the cache class now */
+require_once('Kolab/Freebusy/Cache.php');
 
-$uinfo = $ldap->userInfo($folder[0]);
-$owner = $uinfo['MAIL'];
-$homeserver = $uinfo['HOMESERVER'];  
-if( empty($owner) || false===strpos($owner,'@')) {
-    // try guessing the domain
-    $idx = strpos( $imapuser, '@' );
-    if( $idx !== false ) {
-        $domain = substr( $imapuser, $idx+1 );
-        myLog("Trying to append $domain to ".$folder[0], RM_LOG_DEBUG);
-        $uinfo = $ldap->userInfo($folder[0].'@'.$domain);
-        $owner = $uinfo['MAIL'];
-    }
+/* Where is the cache data stored? */
+if (!empty($conf['fb']['cache_dir'])) {
+    $cache_dir = $conf['fb']['cache_dir'];
+} else {
+    /* This default is not recommended so make sure you set a 
+     * cache dir outside of the apache document root.
+     */
+    $cache_dir = dirname(__FILE__) . '/cache';
 }
 
-if( $homeserver && $homeserver != $params['server'] ) {
-    $redirect = 'https://'.$homeserver . $_SERVER['REQUEST_URI'];
-    myLog("Found remote user, redirecting to $homeserver", RM_LOG_DEBUG);
-    if ($params['redirect']) {
-        header("Location: $redirect");
-    } else {
-        header("X-Redirect-To: $redirect");
-        $redirect = 'https://' . urlencode($_SERVER['PHP_AUTH_USER']) . ':'
-            . urlencode($_SERVER['PHP_AUTH_PW']) . '@' . $homeserver
-            . $_SERVER['REQUEST_URI'];
-        if (!@readfile($redirect)) {
-            unauthorized("Unable to read free/busy information from ".removePassword($redirect));
-        }
-    }
-    shutdown();
-    exit;
- }
+/* Get the cache request variables */
+$req_cache    = Util::getFormData('cache', false);
+$req_extended = Util::getFormData('extended', false);
 
-$cache =& new FreeBusyCache( $params['cache_dir'], $params['pfb_dbformat'], $params, false );
-$xcache =& new FreeBusyCache( $params['cache_dir'], $params['pfb_dbformat'], $params, true );
+$cache = &new FreeBusyCache($cache_dir);
 
-if( $req_cache ) {
-    $acl = false;
-    if( $req_extended ) {
-        $vfb = $xcache->load( $req_folder, $ts, $acl );
-    } else {
-        $vfb = $cache->load( $req_folder, $ts, $acl );
-    }
-    if( $acl && $req_extended ) {
-        // Check access
-        $distlists = $ldap->distlists( $userinfo['DN'] );
-        if( $distlists === false ) {
-            unauthorized( $req_folder.($req_extended?'.xpfb':'.pfb' ) );
-        }
-        for( $i = 0; $i < count($distlists); $i++ ) {
-            $distlists[$i] = $distlists[$i].'@'.$params['email_domain'];
-        }
-        $rights = $xcache->getRights( $acl, $imapuser, $distlists );
-        if( !$req_extended || $rights['r'] ) {
-            // All OK
-        } else {
-            // Nope
-            unauthorized( $req_folder.($req_extended?'.xpfb':'.pfb' ) );
-        }
-    }
-    if( !$vfb ) {
-        notFound( $req_folder.($req_extended?'.xpfb':'.pfb').' not found in cache');
-    }
- } else {
-    if( empty($imapuser) ) {
-        // Here we really need an authenticated user!
-        unauthorized("Please authenticate");
-    }
-    require_once('Kolab/Freebusy/freebusy.class.php');
-    
-    if( empty($owner) ) {
-        notFound( _('No such account ').htmlentities($folder[0]));
-        return false;
-    }
-    unset($folder[0]);
-    $folder = join('/', $folder);
-    $fbpast = $ldap->freeBusyPast();
-    $fb =& new FreeBusy( $owner, $imapuser, $imappw, $params, $uinfo['FBFUTURE'], $fbpast );
+if (!$req_cache) {
+    /* User wants to regenerate the cache */
 
-    $fb->default_domain = $params['email_domain'];
-    $rc = $fb->imapConnect();
-    if( $rc === false ) {
-        unauthorized(imap_last_error());
-        return false;
-    }
-    $rc = $fb->imapOpenMailbox(FreeBusy::imapFolderName( $imapuser, $owner, 
-                                                         $folder, $params['email_domain']));
-    if( $rc === false ) {
-        notfound( "Folder: ".$fb->foldername.', '.imap_last_error());
-        return false;
-    }
-    $relevance = $fb->getRelevance();
-    list($vfb,$xvfb) = $fb->generateFreeBusy();
-    $ts = mktime();
-    if( PEAR::isError( $vfb ) ) {
-        unauthorized($vfb->toString());
-        return false;
+    /* Here we really need an authenticated IMAP user */
+    $result = $access->authenticate();
+    if (is_a($result, 'PEAR_Error')) {
+        Kolab_Freebusy_Error::unauthorized($result);
     }
 
-    if(ereg('(.*)@(.*)',$owner,$regs)) {
-        $owner = $regs[2].'/'.$regs[1];
+    if (empty($access->owner)) {
+        $message = sprintf(_("No such account %s!"), 
+                           htmlentities($access->req_owner));
+        Kolab_Freebusy_Error::notFound(PEAR::raiseError($message));
     }
 
-    $acl = $fb->getACL();
-    if( !$cache->store( $owner.'/'.$folder, $vfb, $acl, $relevance ) ) {
-        trigger_error('Could not store pfb in cache file '.$owner.'/'.$folder
-                      .'.pfb: '.$cache->error, E_USER_WARNING);
-    }
-    if( !$xcache->store( $owner.'/'.$folder, $xvfb, $acl, $relevance ) ) {
-        trigger_error('Could not store xpfb in cache file '.$owner.'/'.$folder
-                      .'.xpfb: '.$cache->error, E_USER_WARNING);
+    /* Update the cache */
+    $result = $cache->store($access);
+    if (is_a($result, 'PEAR_Error')) {
+        Kolab_Freebusy_Error::notFound($result);
     }
+}
 
-    if( $req_extended ) $vfb = $xvfb;
-    unset($xvfb);
- }
+/* Load the cache data */
+$vfb = $cache->loadPartial($access, $req_extended);
+if (is_a($vfb, 'PEAR_Error')) {
+    Kolab_Freebusy_Error::notFound($vfb);
+}
 
-// And finally send it out, ensuring it doesn't get cached along the way
-header('Cache-Control: no-store, no-cache, must-revalidate');
-header('Cache-Control: post-check=0, pre-check=0', false);
-header('Pragma: no-cache');
-header('Expires: Mon, 26 Jul 1997 05:00:00 GMT');
-header('Last-Modified: ' . gmdate("D, d M Y H:i:s",$ts) . ' GMT');
-header('Pragma: public');
-header('Content-Transfer-Encoding: none');
-if ($params['send_content_type']) {
-    header('Content-Type: text/calendar');
- }
-if ($params['send_content_length']) {
-    header('Content-Length: ' . strlen($vfb));
- }
-if ($params['send_content_disposition']) {
-    header('Content-Disposition: attachment; filename="' . $user . '.vfb"');
- }
+Horde::logMessage(sprintf(_("Delivering partial free/busy data (extended=%s)."),
+                          $req_extended), 
+                  __FILE__, __LINE__, PEAR_LOG_DEBUG);
 
-echo $vfb;
+/* And finally send it out */
+$view = &new FreeBusyView($vfb);
+$view->render($access->owner . '.ifb');
 
-// Finish up
-myLog("pfb.php complete, execution time was ".(microtime_float()-$start_time)." secs.", RM_LOG_DEBUG);
-shutdown();
+/* Finish up */
+Horde::logMessage(sprintf(_("Partial free/busy generation complete, execution time was %s seconds."), 
+                          $timer->stop()), __FILE__, __LINE__, PEAR_LOG_DEBUG);
 ?>





More information about the commits mailing list