steffen: server/kolab-resource-handlers/kolab-resource-handlers/freebusy freebusy.class.php, 1.1, 1.2 freebusy.php, 1.27, 1.28 freebusycache.class.php, 1.1, 1.2 freebusyldap.class.php, 1.1, 1.2 pfb.php, 1.1, 1.2
cvs at intevation.de
cvs at intevation.de
Mon Oct 4 11:31:20 CEST 2004
- Previous message: bernhard: doc/architecture client_client.sgml, 1.5, 1.6 client_server.sgml, 1.12, 1.13 concept.sgml, 1.13, 1.14 server.sgml, 1.26, 1.27 windows.sgml, 1.6, 1.7
- Next message: steffen: server/kolab-resource-handlers kolab-resource-handlers.spec, 1.39, 1.40
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
Author: steffen
Update of /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy
In directory doto:/tmp/cvs-serv24788/kolab-resource-handlers/freebusy
Modified Files:
freebusy.class.php freebusy.php freebusycache.class.php
freebusyldap.class.php pfb.php
Log Message:
fb stuff
Index: freebusy.class.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusy.class.php,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- freebusy.class.php 28 Sep 2004 13:12:26 -0000 1.1
+++ freebusy.class.php 4 Oct 2004 09:31:18 -0000 1.2
@@ -29,6 +29,10 @@
return $this->imap->selectMailbox( $foldername );
}
+ function getACL() {
+ return $this->imap->getACL();
+ }
+
function &generateFreeBusy($extended = false, $startstamp = NULL, $endstamp = NULL ) {
require_once 'PEAR.php';
Index: freebusy.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusy.php,v
retrieving revision 1.27
retrieving revision 1.28
diff -u -d -r1.27 -r1.28
--- freebusy.php 28 Sep 2004 13:12:26 -0000 1.27
+++ freebusy.php 4 Oct 2004 09:31:18 -0000 1.28
@@ -1,21 +1,68 @@
<?php
require_once('freebusy/freebusycache.class.php');
require_once('freebusy/freebusycollector.class.php');
+require_once('freebusy/freebusyldap.class.php');
require_once('freebusy/misc.php');
require_once('@l_prefix@/etc/resmgr/freebusy.conf');
$user = trim($_REQUEST['uid']);
-$cache =& new FreeBusyCache( $params['kolab_prefix'].'/var/kolab/www/pfb/cache' );
+$imapuser = $_SERVER['PHP_AUTH_USER'];
+$imappw = $_SERVER['PHP_AUTH_PW'];
+$req_cache = (bool)$_REQUEST['cache'];
+//$req_folder = $_REQUEST['folder'];
+$req_extended = (defined( $_REQUEST['extended'] ) && $_REQUEST['extended']);
+
+$ldap =& new FreeBusyLDAP( $params['ldap_uri'], $params['base_dn'] );
+if( !$ldap->bind( $params['bind_dn'], $params['bind_pw'] ) ) {
+ notFound( "Bind failed: ".$ldap->error() );
+ exit;
+}
+
+$imapuser = $ldap->mailForUid( $imapuser );
+$homeserver = $ldap->homeServer( $user );
+
+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 $redirect");
+ }
+ }
+ shutdown();
+ exit;
+}
+
+
+$cache =& new FreeBusyCache( $params['kolab_prefix'].'/var/kolab/www/freebusy/cache', $req_extended );
$collector =& new FreeBusyCollector( $user );
-$pfbs = $cache->findAll( $user );
+$groups = $ldap->distlists( $ldap->dn( $user ) );
+$pfbs = $cache->findAll( $user, $groups );
$ts = 0;
if( $pfbs === false ) {
notFound($pfb->error);
}
+
+if( $req_extended ) {
+ // Get accessing users groups
+ $imapgroups = $ldap->distlists( $ldap->dn( $imapuser ) );
+}
+
foreach( $pfbs as $pfb ) {
- $ts = max( $ts, filectime( $pfb ) );
- $collector->addFreebusy( file_get_contents( $pfb ) );
+ $fb = $cache->load( $pfb, $ts2, $acl );
+ if( $req_extended && !$cache->checkAcl( $acl, $imapuser, $imappw ) ) {
+ $fb->extended = false; // HACK!
+ $fb = $cache->load( $pfb, $ts2, $acl );
+ $fb->extended = true;
+ }
+ $ts = max( $ts, $ts2 );
+ if( $fb ) $collector->addFreebusy( $fb );
}
$vfb = $collector->exportvCalendar();
Index: freebusycache.class.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusycache.class.php,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- freebusycache.class.php 28 Sep 2004 13:12:26 -0000 1.1
+++ freebusycache.class.php 4 Oct 2004 09:31:18 -0000 1.2
@@ -1,20 +1,21 @@
<?php
+/*! To load/store partial freebusy lists
+ and their ACLs */
class FreeBusyCache {
- function FreeBusyCache( $basedir ) {
+ function FreeBusyCache( $basedir, $extended = false ) {
$this->basedir = $basedir;
+ $this->extended = $extended;
}
- function store( $fbfilename, $fbdata ) {
- $tmpn = tempnam($this->basedir, 'fb');
- $tmpf = fopen($tmpn, 'w');
- if( !$tmpf ) return false;
- fwrite($tmpf, $fbdata);
- if( ereg( '\.\.', $fbfilename ) ) {
- $this->error = $fbfilename._(' is not absolute');
+ function store( $filename, $fbdata, $acl ) {
+ if( ereg( '\.\.', $filename ) ) {
+ $this->error = $filename._(' is not absolute');
return false;
}
- $fbfilename = $this->basedir.'/'.$fbfilename;
+
+ // Create directories if missing
+ $fbfilename = $this->mkfbfilename($filename);
$fbdirname = dirname( $fbfilename );
if (!is_dir($fbdirname)) {
if( !$this->mkdirhier($fbdirname) ) {
@@ -22,31 +23,76 @@
return false;
}
}
+
+ // Store the fb list
+ $tmpn = tempnam($this->basedir, 'fb');
+ $tmpf = fopen($tmpn, 'w');
+ if( !$tmpf ) return false;
+ fwrite($tmpf, $fbdata);
if( !rename($tmpn, $fbfilename) ) {
$this->error = _("Error renaming $tmpn to $fbfilename");
return false;
}
fclose($tmpf);
+
+ // Store the ACL
+ $oldacl = $this->loadACL( $filename );
+ if( !$this->storeACL( $filename, $acl ) ) return false;
+
+ // Update overview db
+ $db = dba_open( $this->basedir.'/pfbcache.db', 'cd', 'gdbm' );
+ if( $db === false ) return false;
+ foreach( $acl as $ac ) {
+ if( strpos( $ac['RIGHTS'], 'r' ) !== false ) {
+ if( dba_exists( $ac['USER'], $db ) ) {
+ $lst = dba_fetch( $ac['USER'], $db );
+ $lst = $this->decodeList( $lst );
+ $lst[] = $filename;
+ dba_replace( $ac['USER'], $this->encodeList(array_unique($lst)), $db );
+ } else {
+ dba_insert( $ac['USER'], $filename, $db );
+ }
+ }
+ }
+ $deleteduids = $this->aclDiff( $oldacl, $acl );
+ foreach( $deleteduids as $uid ) {
+ if( dba_exists( $uid, $db ) ) {
+ $lst = dba_fetch( $uid, $db );
+ $lst = $this->decodeList( $lst );
+ $lst = array_diff( $lst, array($fbfilename));
+ dba_replace( $uid, $this->encodeList($lst), $db );
+ }
+ }
+ dba_close($db);
return true;
}
- function load( $fbfilename, &$ts ) {
- $fbfilename = $this->basedir.'/'.$fbfilename;
+ function load( $filename, &$ts, &$acl ) {
+ $fbfilename = $this->mkfbfilename($filename);
if( $fbfilename != realpath( $fbfilename )) return false;
if( file_exists($fbfilename) ) {
if( !is_null($ts)) $ts = filectime($fbfilename);
+ $acl = $this->loadACL($filename);
return file_get_contents($fbfilename);
}
return false;
}
- function findAll( $user ) {
- $fbdir = $this->basedir.'/'.$user;
- if( $fbdir != realpath($fbdir) ) {
- $this->error = $fbdir._(' is not absolute');
- return false;
+ function findAll( $uid, $groups ) {
+ $lst = false;
+ $db = dba_open( $this->basedir.'/pfbcache.db', 'rd', 'gdbm' );
+ if( $db === false ) return false;
+ $uids = $groups;
+ $uids[] = $uid;
+ foreach( $uids as $uid ) {
+ if( dba_exists( $uid, $db ) ) {
+ $lst = dba_fetch( $uid, $db );
+ $lst = array_merge( $lst, $this->decodeList( $lst ) );
+ }
+ dba_close($db);
}
- return FreeBusyCache::recursivedir( $fbdir );
+ if( is_array( $lst ) ) return array_unique($lst);
+ else return false;
}
/*************** Private API below this line *************/
@@ -59,6 +105,105 @@
return true;
}
+ function mkfbfilename( $fbfilename ) {
+ return $this->basedir.'/'.$fbfilename.($this->extended?'.xpfb':'.pfb');
+ }
+
+ function mkaclfilename( $fbfilename ) {
+ return $this->basedir.'/'.$fbfilename.($this->extended?'.xpfb':'.pfb').'.acl';
+ }
+
+ function aclToString( $acl ) {
+ $aclstr = '';
+ foreach( $acl as $ac ) {
+ $aclstr .= $ac['USER'].' '.$ac['RIGHTS']."\n";
+ }
+ return $aclstr;
+ }
+
+ function aclFromString( $aclstr ) {
+ $acl = array();
+ foreach( split("\n", $aclstr ) as $ac ) {
+ if( ereg("(.*) (.*)", $ac, $regs ) ) {
+ $acl[] = array('USER' => $regs[1], 'RIGHTS' => $regs[2] );
+ }
+ }
+ return $acl;
+ }
+
+ function loadACL( $filename ) {
+ return $this->aclFromString( file_get_contents($this->mkaclfilename($filename)) );
+ }
+
+ function storeACL( $filename, $acl ) {
+ $tmpn = tempnam($this->basedir, 'acl');
+ $tmpf = fopen($tmpn, 'w');
+ if( !$tmpf ) return false;
+ fwrite($tmpf, $this->aclToString($acl) );
+
+ $aclfilename = $this->mkaclfilename($filename);
+ if( !rename($tmpn, $aclfilename) ) {
+ $this->error = _("Error renaming $tmpn to $fbfilename");
+ return false;
+ }
+ fclose($tmpf);
+ return true;
+ }
+
+ function aclDiff( $oldacl, $newacl ) {
+ $newuids = array();
+ foreach( $newacl as $ac ) {
+ if( strpos( $ac['RIGHTS'], 'r' ) !== false ) {
+ $newuids[$ac['USER']] = true;
+ }
+ }
+ $deleteduids = array();
+ foreach( $oldacl as $ac ) {
+ if( !$newuids[$ac['USER']] ) $deleteduids[] = $ac['USER'];
+ }
+ return $deleteduids;
+ }
+
+ function getRights( $acl, $uid, $groups ) {
+ $uids = array_merge( array($uid), $groups );
+ $rights = array();
+ $negacl = array();
+
+ // Calc positive rights
+ foreach( $acl as $ac ) {
+ $r = $ac['RIGHTS'];
+ $u = $ac['USER'];
+ if( $r{0} == '-' ) {
+ $negacl[] = array( 'USER' => $u, 'RIGHTS' => $r );
+ continue;
+ }
+ if( in_array( $u, $uids ) ) {
+ for( $i = 0; $i < strlen($r); ++$i ) {
+ $rights[$r{$i}] = true;
+ }
+ }
+ }
+
+ // Remove negative rights
+ foreach( $negacl as $ac ) {
+ $r = $ac['RIGHTS'];
+ $u = $ac['USER'];
+ if( in_array( $u, $uids ) ) {
+ for( $i = 1; $i < strlen($r); ++$i ) {
+ unset($rights[$r{$i}]);
+ }
+ }
+ }
+ return $rights;
+ }
+
+ function decodeList( $str ) {
+ return split( ',', $str );
+ }
+ function encodeList( $lst ) {
+ return join(',',$lst);
+ }
+
function recursivedir( $dir ) {
$dh = opendir( $dir );
if( $dh === false ) return false;
@@ -66,7 +211,8 @@
while (($file = readdir($dh)) !== false) {
if( is_dir($dir.'/'.$file) ) {
if($file=='.' || $file=='..') continue;
- $tmp = FreeBusyCache::recursivedir( $dir.'/'.$file );
+ if( !ereg( ($this->extended?'/.*\.xpfb$/':'/.*\.pfb$/'), $file ) ) continue;
+ $tmp = $this->recursivedir( $dir.'/'.$file );
if( $tmp !== false ) $dirs = array_merge( $dirs, $tmp );
} else if( is_file($dir.'/'.$file) ) {
$dirs[] = $dir.'/'.$file;
Index: freebusyldap.class.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/freebusyldap.class.php,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- freebusyldap.class.php 28 Sep 2004 13:12:26 -0000 1.1
+++ freebusyldap.class.php 4 Oct 2004 09:31:18 -0000 1.2
@@ -45,6 +45,32 @@
return false;
}
+ function dn( $uid ) {
+ $result = ldap_search( $this->connection, $this->base,
+ '(&(objectClass=kolabInetOrgPerson)(|(uid='.$uid.')(mail='.$uid.')))',
+ array( 'dn' ) );
+ if( $result ) {
+ $entries = ldap_get_entries( $this->connection, $result );
+ if( $entries['count'] > 0 ) {
+ return $entries[0]['dn'];
+ }
+ }
+ return false;
+ }
+ function distlists( $dn ) {
+ $result = ldap_search( $this->connection, $this->base,
+ '(&(objectClass=kolabGroupOfNames)(member=$dn))',
+ array( 'cn' ) );
+ if( $result ) {
+ $entries = ldap_get_entries( $this->connection, $result );
+ $lst = array();
+ for( $i = 0; i < $entries['count']; ++$i ) {
+ $lst[] = $entries[$i]['cn'][0];
+ }
+ return $lst;
+ }
+ return false;
+ }
var $connection;
var $is_bound;
Index: pfb.php
===================================================================
RCS file: /kolabrepository/server/kolab-resource-handlers/kolab-resource-handlers/freebusy/pfb.php,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -d -r1.1 -r1.2
--- pfb.php 28 Sep 2004 13:12:26 -0000 1.1
+++ pfb.php 4 Oct 2004 09:31:18 -0000 1.2
@@ -8,9 +8,9 @@
$imapuser = $_SERVER['PHP_AUTH_USER'];
$imappw = $_SERVER['PHP_AUTH_PW'];
-$req_cache = $_REQUEST['cache'];
+$req_cache = (bool)$_REQUEST['cache'];
$req_folder = $_REQUEST['folder'];
-$req_extended = $_REQUEST['extended'];
+$req_extended = (bool)$_REQUEST['extended'];
$ldap =& new FreeBusyLDAP( $params['ldap_uri'], $params['base_dn'] );
if( !$ldap->bind( $params['bind_dn'], $params['bind_pw'] ) ) {
@@ -38,28 +38,36 @@
exit;
}
-$cache =& new FreeBusyCache( $params['kolab_prefix'].'/var/kolab/www/pfb/cache' );
+$cache =& new FreeBusyCache( $params['kolab_prefix'].'/var/kolab/www/freebusy/cache',
+ $req_extended );
if( $req_cache ) {
- $vfb = $cache->load( $req_folder.'.pfb', $ts );
- if( !$vfb ) notFound( $req_folder.'.pfb not found in cache');
+ $acl = false;
+ $vfb = $cache->load( $req_folder, $ts, $acl );
+ if( $acl && $req_extended ) {
+ // Check access
+ $distlists = $ldap->distlists( $ldap->dn($imapuser));
+ if( $distlists === false ) unauthorized( $req_folder.($req_extended?'.xpfb':'.pfb' ) );
+ $rights = $cache->getRights( $acl, $imapuser, $distlists );
+ if( $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 {
require_once('freebusy/freebusy.class.php');
$folder = split('/', $req_folder );
- if( count($folder) < 2 ) {
+ if( count($folder) < 1 ) {
// error
notFound( 'No such folder ').htmlentities($req_folder);
}
$owner = $folder[0];
- $mbox = $folder[1];
unset($folder[0]);
- unset($folder[1]);
$folder = join('/', $folder);
- if( strtolower( $owner ) != strtolower( $imapuser ) ) {
- unauthorized(_("User $imapuser is not allowed to create freebusy data for $owner"));
- return false;
- }
$fb =& new FreeBusy( $imapuser, $imappw, 'localhost' );
$fb->freebusy_days = $params['freebusy_days'];
$fb->default_domain = $params['email_domain'];
@@ -73,21 +81,23 @@
unauthorized("Access denied for user $imapuser: ".$rc->toString());
return false;
}
- $rc = $fb->imapOpenMailbox(FreeBusy::imapFolderName( $imapuser, $mbox,
+ $rc = $fb->imapOpenMailbox(FreeBusy::imapFolderName( $imapuser, $owner,
$folder, $params['email_domain']));
if( PEAR::isError( $rc ) ) {
notfound( "Folder: ".$fb->foldername.', '.$rc->toString());
return false;
}
- $vfb = $fb->generateFreeBusy();
+ $vfb = $fb->generateFreeBusy($req_extended);
$ts = mktime();
if( PEAR::isError( $vfb ) ) {
unauthorized($rc->toString());
return false;
}
- if( !$cache->store( $owner.'/'.$mbox.'/'.$folder.'.pfb', $vfb ) ) {
- trigger_error('Could not store vfb in cache file '.$owner.'/'.$mbox.'/'.$folder.'.pfb: '
- .$cache->error, E_USER_WARNING);
+
+ $acl = $fb->getACL();
+ if( !$cache->store( $owner.'/'.$folder, $vfb, $acl ) ) {
+ trigger_error('Could not store vfb in cache file '.$owner.'/'.$folder
+ .($req_extended?'.xpfb':'.pfb').$cache->error, E_USER_WARNING);
}
}
@@ -109,7 +119,9 @@
header('Content-Disposition: attachment; filename="' . $user . '.vfb"');
}
+#print "folder=$req_folder, cache=$req_cache, extended=$req_extended";
echo $vfb;
+#print_r($acl);
// Finish up
shutdown();
- Previous message: bernhard: doc/architecture client_client.sgml, 1.5, 1.6 client_server.sgml, 1.12, 1.13 concept.sgml, 1.13, 1.14 server.sgml, 1.26, 1.27 windows.sgml, 1.6, 1.7
- Next message: steffen: server/kolab-resource-handlers kolab-resource-handlers.spec, 1.39, 1.40
- Messages sorted by:
[ date ]
[ thread ]
[ subject ]
[ author ]
More information about the commits
mailing list