Page MenuHomePhorge

No OneTemporary

Size
33 KB
Referenced Files
None
Subscribers
None
diff --git a/composer.json b/composer.json
index 053ce31..25546d2 100644
--- a/composer.json
+++ b/composer.json
@@ -1,29 +1,28 @@
{
"name": "kolab/irony",
"description": "iRony - The Kolab WebDAV/CalDAV/CardDAV Server",
"license": "AGPL-3.0",
"version": "0.4-dev",
"repositories": [
{
"type": "pear",
"url": "http://pear.php.net/"
},
{
"type": "vcs",
"url": "git://git.kolab.org/git/pear/Net_LDAP3"
}
],
"require": {
"php": ">=5.4.1",
"sabre/dav" : "~2.1.0"
},
"require-dev": {
"pear/mail_mime": ">=1.8.9",
"pear/mail_mime-decode": ">=1.5.5",
- "pear/http_request2": ">=2.1.1",
"pear-pear.php.net/net_idna2": ">=0.1.1",
"pear-pear.php.net/net_ldap2": ">=2.0.12",
"kolab/Net_LDAP3": "dev-master"
},
"minimum-stability": "dev"
}
diff --git a/lib/Kolab/CalDAV/Plugin.php b/lib/Kolab/CalDAV/Plugin.php
index 815f37b..3f71070 100644
--- a/lib/Kolab/CalDAV/Plugin.php
+++ b/lib/Kolab/CalDAV/Plugin.php
@@ -1,239 +1,171 @@
<?php
/**
* Extended CalDAV plugin for the Kolab DAV server
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\CalDAV;
use Sabre\DAV;
use Sabre\CalDAV;
use Sabre\VObject;
use Kolab\DAV\Auth\HTTPBasic;
/**
* Extended CalDAV plugin to tweak data validation
*/
class Plugin extends CalDAV\Plugin
{
// make already parsed text/calednar blocks available for later use
public static $parsed_vcalendar;
public static $parsed_vevent;
// allow the backend to force a redirect Location
public static $redirect_basename;
/**
* Initializes the plugin
*
* @param DAV\Server $server
* @return void
*/
public function initialize(DAV\Server $server)
{
parent::initialize($server);
$server->on('afterCreateFile', array($this, 'afterWriteContent'));
$server->on('afterWriteContent', array($this, 'afterWriteContent'));
}
/**
* Inject some additional HTTP response headers
*/
public function afterWriteContent($uri, $node)
{
// send Location: header to corrected URI
if (self::$redirect_basename) {
$path = explode('/', $uri);
array_pop($path);
array_push($path, self::$redirect_basename);
$this->server->httpResponse->setHeader('Location', $this->server->getBaseUri() . join('/', array_map('urlencode', $path)));
self::$redirect_basename = null;
}
}
/**
* Checks if the submitted iCalendar data is in fact, valid.
*
* An exception is thrown if it's not.
*
* @param resource|string $data
* @param string $path
* @return void
*/
protected function validateICalendar(&$data, $path)
{
// If it's a stream, we convert it to a string first.
if (is_resource($data)) {
$data = stream_get_contents($data);
}
// Converting the data to unicode, if needed.
$data = DAV\StringUtil::ensureUTF8($data);
try {
// modification: Set options to be more tolerant when parsing extended or invalid properties
$vobj = VObject\Reader::read($data, VObject\Reader::OPTION_FORGIVING | VObject\Reader::OPTION_IGNORE_INVALID_LINES);
// keep the parsed object in memory for later processing
if ($vobj->name == 'VCALENDAR') {
self::$parsed_vcalendar = $vobj;
foreach ($vobj->getBaseComponents() as $vevent) {
if ($vevent->name == 'VEVENT' || $vevent->name == 'VTODO') {
self::$parsed_vevent = $vevent;
break;
}
}
}
}
catch (VObject\ParseException $e) {
throw new DAV\Exception\UnsupportedMediaType('This resource requires valid iCalendar 2.0 data. Parse error: ' . $e->getMessage());
}
if ($vobj->name !== 'VCALENDAR') {
throw new DAV\Exception\UnsupportedMediaType('This collection can only support iCalendar objects.');
}
// Get the Supported Components for the target calendar
list($parentPath,$object) = DAV\URLUtil::splitPath($path);
$calendarProperties = $this->server->getProperties($parentPath,array('{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set'));
$supportedComponents = $calendarProperties['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']->getValue();
$foundType = null;
$foundUID = null;
foreach($vobj->getComponents() as $component) {
switch($component->name) {
case 'VTIMEZONE':
continue 2;
case 'VEVENT':
case 'VTODO':
case 'VJOURNAL':
if (is_null($foundType)) {
$foundType = $component->name;
if (!in_array($foundType, $supportedComponents)) {
throw new CalDAV\Exception\InvalidComponentType('This calendar only supports ' . implode(', ', $supportedComponents) . '. We found a ' . $foundType);
}
if (!isset($component->UID)) {
throw new DAV\Exception\BadRequest('Every ' . $component->name . ' component must have an UID');
}
$foundUID = (string)$component->UID;
} else {
if ($foundType !== $component->name) {
throw new DAV\Exception\BadRequest('A calendar object must only contain 1 component. We found a ' . $component->name . ' as well as a ' . $foundType);
}
if ($foundUID !== (string)$component->UID) {
throw new DAV\Exception\BadRequest('Every ' . $component->name . ' in this object must have identical UIDs');
}
}
break;
default:
throw new DAV\Exception\BadRequest('You are not allowed to create components of type: ' . $component->name . ' here');
}
}
if (!$foundType)
throw new DAV\Exception\BadRequest('iCalendar object must contain at least 1 of VEVENT, VTODO or VJOURNAL');
}
/**
* Returns a list of features for the DAV: HTTP header.
* Including 'calendar-schedule' to enable scheduling support in Thunderbird Lightning.
*
* @return array
*/
public function getFeatures()
{
$features = parent::getFeatures();
$features[] = 'calendar-schedule';
return $features;
}
- /**
- * Returns free-busy information for a specific address. The returned
- * data is an array containing the following properties:
- *
- * calendar-data : A VFREEBUSY VObject
- * request-status : an iTip status code.
- * href: The principal's email address, as requested
- *
- * @param string $email address
- * @param \DateTime $start
- * @param \DateTime $end
- * @param VObject\Component $request
- * @return array
- */
- protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, VObject\Component $request)
- {
- console(__METHOD__, $email, $start, $end);
-
- $email = preg_replace('/^mailto:/', '', $email);
-
- // pass-through the pre-generatd free/busy feed from Kolab's free/busy service
- if ($fburl = \kolab_storage::get_freebusy_url($email)) {
- // use PEAR::HTTP_Request2 for data fetching
- // @include_once('HTTP/Request2.php');
-
- try {
- $rcube = \rcube::get_instance();
- $request = new \HTTP_Request2($fburl);
- $request->setConfig(array(
- 'store_body' => true,
- 'follow_redirects' => true,
- 'ssl_verify_peer' => $rcube->config->get('kolab_ssl_verify_peer', true),
- ));
-
- $response = $request->send();
-
- // authentication required
- if ($response->getStatus() == 401) {
- $request->setAuth(HTTPBasic::$current_user, HTTPBasic::$current_pass);
- $response = $request->send();
- }
-
- // success!
- if ($response->getStatus() == 200) {
- $vcalendar = VObject\Reader::read($response->getBody(), VObject\Reader::OPTION_FORGIVING | VObject\Reader::OPTION_IGNORE_INVALID_LINES);
- return array(
- 'calendar-data' => $vcalendar,
- 'request-status' => '2.0;Success',
- 'href' => 'mailto:' . $email,
- );
- }
- }
- catch (\Exception $e) {
- // log failures
- \rcube::raise_error($e, true, false);
- }
- }
- else {
- // generate free/busy data from this user's calendars
- return parent::getFreeBusyForEmail($email, $start, $end, $request);
- }
-
- // return "not found"
- return array(
- 'request-status' => '3.7;Could not find principal',
- 'href' => 'mailto:' . $email,
- );
- }
}
\ No newline at end of file
diff --git a/lib/Kolab/CalDAV/SchedulePlugin.php b/lib/Kolab/CalDAV/SchedulePlugin.php
new file mode 100644
index 0000000..6ae5151
--- /dev/null
+++ b/lib/Kolab/CalDAV/SchedulePlugin.php
@@ -0,0 +1,100 @@
+<?php
+
+/**
+ * Extended CalDAV Schedule plugin for the Kolab DAV server
+ *
+ * @author Thomas Bruederli <bruederli@kolabsys.com>
+ *
+ * Copyright (C) 2014, Kolab Systems AG <contact@kolabsys.com>
+ *
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as
+ * published by the Free Software Foundation, either version 3 of the
+ * License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+ *
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+namespace Kolab\CalDAV;
+
+use Sabre\DAV;
+use Sabre\CalDAV;
+use Sabre\VObject;
+use Sabre\HTTP;
+
+/**
+ * Extended CalDAV Schedule plugin
+ */
+class SchedulePlugin extends CalDAV\Schedule\Plugin
+{
+ /**
+ * Returns free-busy information for a specific address. The returned
+ * data is an array containing the following properties:
+ *
+ * calendar-data : A VFREEBUSY VObject
+ * request-status : an iTip status code.
+ * href: The principal's email address, as requested
+ *
+ * @param string $email address
+ * @param \DateTime $start
+ * @param \DateTime $end
+ * @param VObject\Component $request
+ * @return array
+ */
+ protected function getFreeBusyForEmail($email, \DateTime $start, \DateTime $end, VObject\Component $request)
+ {
+ console(__METHOD__, $email, $start, $end);
+
+ $email = preg_replace('!^mailto:!', '', $email);
+
+ // pass-through the pre-generatd free/busy feed from Kolab's free/busy service
+ if ($fburl = \kolab_storage::get_freebusy_url($email)) {
+ try {
+ $rcube = \rcube::get_instance();
+ $client = new HTTP\Client();
+ $client->addCurlSetting(CURLOPT_SSL_VERIFYPEER, $rcube->config->get('kolab_ssl_verify_peer', true));
+
+ // authentication required
+ $client->on('error:401', function($request, $response, &$retry, $retryCount) {
+ if ($retryCount <= 1) {
+ // We're only going to retry exactly once.
+ $request->setHeader('Authorization', 'Basic ' . base64_encode(HTTPBasic::$current_user . ':' . HTTPBasic::$current_pass));
+ $retry = true;
+ }
+ });
+
+ $response = $client->send(new HTTP\Request('GET', $fburl));
+
+ // success!
+ if ($response->getStatus() == 200) {
+ $vcalendar = VObject\Reader::read($response->getBodyAsString(), VObject\Reader::OPTION_FORGIVING | VObject\Reader::OPTION_IGNORE_INVALID_LINES);
+ return array(
+ 'calendar-data' => $vcalendar,
+ 'request-status' => '2.0;Success',
+ 'href' => 'mailto:' . $email,
+ );
+ }
+ }
+ catch (\Exception $e) {
+ // log failures
+ \rcube::raise_error($e, true, false);
+ }
+ }
+ else {
+ // generate free/busy data from this user's calendars
+ return parent::getFreeBusyForEmail($email, $start, $end, $request);
+ }
+
+ // return "not found"
+ return array(
+ 'request-status' => '3.7;Could not find principal',
+ 'href' => 'mailto:' . $email,
+ );
+ }
+}
\ No newline at end of file
diff --git a/lib/Kolab/CalDAV/UserCalendars.php b/lib/Kolab/CalDAV/UserCalendars.php
index dcd2aff..3573baa 100644
--- a/lib/Kolab/CalDAV/UserCalendars.php
+++ b/lib/Kolab/CalDAV/UserCalendars.php
@@ -1,166 +1,167 @@
<?php
/**
* SabreDAV UserCalendars derived class for the Kolab.
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\CalDAV;
use Sabre\DAV;
use Sabre\DAVACL;
use Sabre\CalDAV\Backend;
use Sabre\CalDAV\Schedule;
use Kolab\CalDAV\Calendar;
/**
* The UserCalenders class contains all calendars associated to one user
*
*/
class UserCalendars extends \Sabre\CalDAV\UserCalendars implements DAV\IExtendedCollection, DAVACL\IACL
{
private $outbox;
/**
* Returns a list of calendars
*
* @return array
*/
public function getChildren()
{
$calendars = $this->caldavBackend->getCalendarsForUser($this->principalInfo['uri']);
$objs = array();
foreach ($calendars as $calendar) {
// TODO: (later) add sharing support by implenting this all
if ($this->caldavBackend instanceof Backend\SharingSupport) {
if (isset($calendar['{http://calendarserver.org/ns/}shared-url'])) {
$objs[] = new SharedCalendar($this->caldavBackend, $calendar);
}
else {
$objs[] = new ShareableCalendar($this->caldavBackend, $calendar);
}
}
else {
$objs[] = new Calendar($this->caldavBackend, $calendar);
}
}
// add support for scheduling AKA free/busy
+ // TODO: remove when CalendarBackend implements SchedulingSupport
$objs[] = new Schedule\Outbox($this->principalInfo['uri']);
// TODO: add notification support (check with clients first, if anybody supports it)
if ($this->caldavBackend instanceof Backend\NotificationSupport) {
$objs[] = new Notifications\Collection($this->caldavBackend, $this->principalInfo['uri']);
}
return $objs;
}
/**
* Returns a single calendar, by name
*
* @param string $name
* @return Calendar
*/
public function getChild($name)
{
if ($name == 'outbox') {
return new Schedule\Outbox($this->principalInfo['uri']);
}
if ($calendar = $this->caldavBackend->getCalendarByName($name)) {
$calendar['principaluri'] = $this->principalInfo['uri'];
return new Calendar($this->caldavBackend, $calendar);
}
throw new DAV\Exception\NotFound('Calendar with name \'' . $name . '\' could not be found');
}
/**
* Checks if a calendar exists.
*
* @param string $name
* @return bool
*/
public function childExists($name)
{
if ($this->caldavBackend->getCalendarByName($name)) {
return true;
}
return false;
}
/**
* Returns a list of ACE's for this node.
*
* Each ACE has the following properties:
* - 'privilege', a string such as {DAV:}read or {DAV:}write. These are currently the only supported privileges
* - 'principal', a url to the principal who owns the node
* - 'protected' (optional), indicating that this ACE is not allowed to be updated.
*
* @return array
*/
public function getACL()
{
// define rights for the user's calendar root (which is in fact INBOX)
return array(
array(
'privilege' => '{DAV:}read',
'principal' => $this->principalInfo['uri'],
'protected' => true,
),
array(
'privilege' => '{DAV:}write',
'principal' => $this->principalInfo['uri'],
'protected' => true,
),
/* TODO: implement sharing support
array(
'privilege' => '{DAV:}read',
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write',
'protected' => true,
),
array(
'privilege' => '{DAV:}write',
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-write',
'protected' => true,
),
array(
'privilege' => '{DAV:}read',
'principal' => $this->principalInfo['uri'] . '/calendar-proxy-read',
'protected' => true,
),
*/
);
}
/**
* Updates the ACL
*
* This method will receive a list of new ACE's.
*
* @param array $acl
* @return void
*/
public function setACL(array $acl)
{
// TODO: implement this
throw new DAV\Exception\MethodNotAllowed('Changing ACL is not yet supported');
}
}
diff --git a/lib/Kolab/Utils/DAVLogger.php b/lib/Kolab/Utils/DAVLogger.php
index 94a39ba..6e2f608 100644
--- a/lib/Kolab/Utils/DAVLogger.php
+++ b/lib/Kolab/Utils/DAVLogger.php
@@ -1,195 +1,194 @@
<?php
/**
* Utility class logging DAV requests
*
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
namespace Kolab\Utils;
use \rcube;
use Sabre\DAV;
use Kolab\DAV\Auth\HTTPBasic;
/**
* Utility class to log debug information about processed DAV requests
*/
class DAVLogger extends DAV\ServerPlugin
{
const CONSOLE = 1;
const HTTP_REQUEST = 2;
const HTTP_RESPONSE = 4;
private $rcube;
private $server;
private $method;
private $loglevel;
/**
* Default constructor
*/
public function __construct($level = 1)
{
$this->rcube = rcube::get_instance();
$this->loglevel = $level;
}
/**
* This initializes the plugin.
* This method should set up the required event subscriptions.
*
* @param Server $server
*/
public function initialize(DAV\Server $server)
{
$this->server = $server;
$server->on('beforeMethod', array($this, '_beforeMethod'), 15);
$server->on('exception', array($this, '_exception'));
$server->on('exit', array($this, '_exit'));
// replace $server->httpResponse with a derived class that can do logging
$server->httpResponse = new HTTPResponse();
}
/**
* Handler for 'beforeMethod' events
*/
- public function _beforeMethod($method, $uri)
+ public function _beforeMethod($request, $response)
{
- $this->method = $method;
+ $this->method = $request->getMethod();
// turn on per-user http logging if the destination file exists
if ($this->loglevel < 2 && $this->rcube->config->get('kolabdav_user_debug', false)
&& ($log_dir = $this->user_log_dir()) && file_exists($log_dir . '/httpraw')) {
$this->loglevel |= (self::HTTP_REQUEST | self::HTTP_RESPONSE);
}
// log full HTTP request data
if ($this->loglevel & self::HTTP_REQUEST) {
- $request = $this->server->httpRequest;
- $content_type = $request->getHeader('CONTENT_TYPE');
+ $content_type = $request->getHeader('Content-Type');
if (strpos($content_type, 'text/') === 0 || strpos($content_type, 'application/xml') === 0) {
- $http_body = $request->getBody(true);
+ $http_body = $request->getBodyAsString();
// Hack for reading php:://input because that stream can only be read once.
// This is why we re-populate the request body with the existing data.
$request->setBody($http_body);
}
else if (!empty($content_type)) {
$http_body = '[binary data]';
}
// catch all headers
$http_headers = array();
foreach (apache_request_headers() as $hdr => $value) {
if (strtolower($hdr) == 'authorization') {
$method = preg_match('/^((basic|digest)\s+)/i', $value, $m) ? $m[1] : '';
$value = $method . str_repeat('*', strlen($value) - strlen($method));
}
$http_headers[$hdr] = "$hdr: $value";
}
$this->write_log('httpraw', $request->getMethod() . ' ' . $request->getUrl() . ' ' . $_SERVER['SERVER_PROTOCOL'] . "\n" .
join("\n", $http_headers) . "\n\n" . $http_body);
}
// log to console
if ($this->loglevel & self::CONSOLE) {
- $this->write_log('console', $method . ' ' . $uri);
+ $this->write_log('console', $this->method . ' ' . $request->getUrl());
}
}
/**
* Handler for 'exception' events
*/
public function _exception($e)
{
// log to console
$this->console(get_class($e) . ' (EXCEPTION)', $e->getMessage() /*, $e->getTraceAsString()*/);
}
/**
* Handler for 'exit' events
*/
public function _exit()
{
if ($this->loglevel & self::CONSOLE) {
$time = microtime(true) - KOLAB_DAV_START;
if (function_exists('memory_get_usage'))
$mem = round(memory_get_usage() / 1024 / 1024, 1) . 'MB';
if (function_exists('memory_get_peak_usage'))
$mem .= '/' . round(memory_get_peak_usage() / 1024 / 1024, 1) . 'MB';
$this->write_log('console', sprintf("/%s: %0.4f sec; %s", $this->method, $time, $mem));
}
// log full HTTP reponse
if ($this->loglevel & self::HTTP_RESPONSE) {
$this->write_log('httpraw', "RESPONSE: " . $this->server->httpResponse->dump());
}
}
/**
* Wrapper for rcube::cosole() to write per-user logs
*/
public function console(/* ... */)
{
if ($this->loglevel & self::CONSOLE) {
$msg = array();
foreach (func_get_args() as $arg) {
$msg[] = !is_string($arg) ? var_export($arg, true) : $arg;
}
$this->write_log('console', join(";\n", $msg));
}
}
/**
* Wrapper for rcube::write_log() that can write per-user logs
*/
public function write_log($filename, $msg)
{
// dump data per user
if ($this->rcube->config->get('kolabdav_user_debug', false)) {
if ($this->user_log_dir()) {
$filename = HTTPBasic::$current_user . '/' . $filename;
}
else {
return; // don't log
}
}
rcube::write_log($filename, $msg);
}
/**
* Get the per-user log directory
*/
private function user_log_dir()
{
$log_dir = $this->rcube->config->get('log_dir', RCUBE_INSTALL_PATH . 'logs');
$user_log_dir = $log_dir . '/' . HTTPBasic::$current_user;
return HTTPBasic::$current_user && is_writable($user_log_dir) ? $user_log_dir : false;
}
}
\ No newline at end of file
diff --git a/public_html/index.php b/public_html/index.php
index 9b9c201..348c52c 100644
--- a/public_html/index.php
+++ b/public_html/index.php
@@ -1,197 +1,199 @@
<?php
/**
* iRony, the Kolab WebDAV/CalDAV/CardDAV Server
*
* This is the public API to provide *DAV-based access to the Kolab Groupware backend
*
* @version 0.4-dev
* @author Thomas Bruederli <bruederli@kolabsys.com>
*
* Copyright (C) 2013-2014, Kolab Systems AG <contact@kolabsys.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// define some environment variables used throughout the app and libraries
define('KOLAB_DAV_ROOT', realpath('../'));
define('KOLAB_DAV_VERSION', '0.4-dev');
define('KOLAB_DAV_START', microtime(true));
define('RCUBE_INSTALL_PATH', KOLAB_DAV_ROOT . '/');
define('RCUBE_CONFIG_DIR', KOLAB_DAV_ROOT . '/config/');
define('RCUBE_PLUGINS_DIR', KOLAB_DAV_ROOT . '/lib/plugins/');
// suppress error notices
ini_set('error_reporting', E_ALL &~ E_NOTICE &~ E_STRICT);
/**
* Mapping PHP errors to exceptions.
*
* While this is not strictly needed, it makes a lot of sense to do so. If an
* E_NOTICE or anything appears in your code, this allows SabreDAV to intercept
* the issue and send a proper response back to the client (HTTP/1.1 500).
*/
function exception_error_handler($errno, $errstr, $errfile, $errline ) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
}
//set_error_handler("exception_error_handler");
// use composer's autoloader for dependencies
$loader = require_once(KOLAB_DAV_ROOT . '/vendor/autoload.php');
$loader->set('Kolab', array(KOLAB_DAV_ROOT . '/lib')); // register iRony namespace(s)
$loader->setUseIncludePath(true); // enable include_path to load PEAR classes from their default location
// load the Roundcube framework with its autoloader
require_once KOLAB_DAV_ROOT . '/lib/Roundcube/bootstrap.php';
// Roundcube framework initialization
$rcube = rcube::get_instance(rcube::INIT_WITH_DB | rcube::INIT_WITH_PLUGINS);
$rcube->config->load_from_file(RCUBE_CONFIG_DIR . 'dav.inc.php');
// Load plugins
$plugins = (array)$rcube->config->get('kolabdav_plugins', array('kolab_auth'));
$required = array('libkolab', 'libcalendaring');
$rcube->plugins->init($rcube);
$rcube->plugins->load_plugins($plugins, $required);
// enable logger
if ($rcube->config->get('kolabdav_console') || $rcube->config->get('kolabdav_user_debug')) {
$logger = new \Kolab\Utils\DAVLogger((\Kolab\Utils\DAVLogger::CONSOLE | $rcube->config->get('kolabdav_http_log', 0)));
}
// convenience function, you know it well :-)
function console()
{
global $logger;
if ($logger) {
call_user_func_array(array($logger, 'console'), func_get_args());
}
}
// Make sure this setting is turned on and reflects the root url of the *DAV server.
$base_uri = $rcube->config->get('base_uri', slashify(substr(dirname($_SERVER['SCRIPT_FILENAME']), strlen($_SERVER['DOCUMENT_ROOT']))));
// add filename to base URI when called without mod_rewrite (e.g. /dav/index.php/calendar)
if (strpos($_SERVER['REQUEST_URI'], 'index.php'))
$base_uri .= 'index.php/';
// create the various backend instances
$auth_backend = new \Kolab\DAV\Auth\HTTPBasic();
$principal_backend = new \Kolab\DAVACL\PrincipalBackend();
$services = array();
foreach (array('CALDAV','CARDDAV','WEBDAV') as $skey) {
if (getenv($skey))
$services[$skey] = 1;
}
// no config means *all* services
if (empty($services))
$services = array('CALDAV' => 1, 'CARDDAV' => 1, 'WEBDAV' => 1);
// add chwala directories to include path for autoloading
if ($services['WEBDAV']) {
$include_path = ini_get('include_path') . PATH_SEPARATOR;
$include_path .= KOLAB_DAV_ROOT . '/lib/FileAPI' . PATH_SEPARATOR;
$include_path .= KOLAB_DAV_ROOT . '/lib/FileAPI/kolab' . PATH_SEPARATOR;
$include_path .= KOLAB_DAV_ROOT . '/lib/FileAPI/ext';
set_include_path($include_path);
}
// Build the directory tree
// This is an array which contains the 'top-level' directories in the WebDAV server.
if ($services['CALDAV'] || $services['CARDDAV']) {
$nodes = array(
new \Kolab\CalDAV\Principal\Collection($principal_backend),
);
if ($services['CALDAV']) {
$caldav_backend = new \Kolab\CalDAV\CalendarBackend();
$caldav_backend->setUserAgent($_SERVER['HTTP_USER_AGENT']);
$nodes[] = new \Kolab\CalDAV\CalendarRootNode($principal_backend, $caldav_backend);
}
if ($services['CARDDAV']) {
$carddav_backend = new \Kolab\CardDAV\ContactsBackend();
$carddav_backend->setUserAgent($_SERVER['HTTP_USER_AGENT']);
$nodes[] = new \Kolab\CardDAV\AddressBookRoot($principal_backend, $carddav_backend);
}
if ($services['WEBDAV']) {
$nodes[] = new \Kolab\DAV\Collection(\Kolab\DAV\Collection::ROOT_DIRECTORY);
}
}
// register WebDAV service as root
else if ($services['WEBDAV']) {
$nodes = new \Kolab\DAV\Collection('');
}
// the object tree needs in turn to be passed to the server class
$server = new \Sabre\DAV\Server($nodes);
$server->setBaseUri($base_uri);
// connect logger
if (is_object($logger)) {
$server->addPlugin($logger);
}
// register some plugins
$server->addPlugin(new \Sabre\DAV\Auth\Plugin($auth_backend, 'KolabDAV'));
$server->addPlugin(new \Sabre\DAVACL\Plugin());
if ($services['CALDAV']) {
$caldav_plugin = new \Kolab\CalDAV\Plugin();
- #$caldav_plugin->setIMipHandler(new \Kolab\CalDAV\IMip());
$server->addPlugin($caldav_plugin);
+
+ $server->addPlugin(new \Kolab\CalDAV\SchedulePlugin());
+ #$server->addPlugin(new \Kolab\CalDAV\IMipPlugin());
}
if ($services['CARDDAV']) {
$server->addPlugin(new \Kolab\CardDAV\Plugin());
}
if ($services['WEBDAV']) {
// the lock manager is responsible for making sure users don't overwrite each others changes.
$locks_backend = new \Kolab\DAV\Locks\Chwala(\Kolab\DAV\Collection::ROOT_DIRECTORY);
$server->addPlugin(new \Sabre\DAV\Locks\Plugin($locks_backend));
// intercept some of the garbage files operation systems tend to generate when mounting a WebDAV share
$server->addPlugin(new \Kolab\DAV\TempFilesPlugin(KOLAB_DAV_ROOT . '/temp'));
}
// HTML UI for browser-based access (recommended only for development)
if (getenv('DAVBROWSER')) {
$server->addPlugin(new \Sabre\DAV\Browser\Plugin());
}
// log exceptions in iRony error log
$server->on('exception', function($e){
if (!($e instanceof \Sabre\DAV\Exception) || $e->getHTTPCode() == 500) {
rcube::raise_error(array(
'code' => 500,
'type' => 'php',
'file' => $e->getFile(),
'line' => $e->getLine(),
'message' => $e->getMessage() . " (error 500)\n" . $e->getTraceAsString(),
), true, false);
}
});
// finally, process the request
$server->exec();
// trigger log
$server->emit('exit', array());

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jan 31, 11:15 AM (1 d, 46 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
426270
Default Alt Text
(33 KB)

Event Timeline