Page MenuHomePhorge

No OneTemporary

Size
12 KB
Referenced Files
None
Subscribers
None
diff --git a/lib/Kolab/CalDAV/Plugin.php b/lib/Kolab/CalDAV/Plugin.php
index 70c0f0f..87ccacf 100644
--- a/lib/Kolab/CalDAV/Plugin.php
+++ b/lib/Kolab/CalDAV/Plugin.php
@@ -1,157 +1,189 @@
<?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;
/**
* 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('VEVENT') as $vevent) {
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 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)
{
- return parent::getFreeBusyForEmail($email, $start, $end, $request);
+ $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();
+ }
- // TODO: pass-through the pre-generatd free/busy feed from Kolab's free/busy service
+ // success!
+ if ($response->getStatus() == 200) {
+ return array(
+ 'calendar-data' => $response->getBody(),
+ 'request-status' => '2.0;Success',
+ 'href' => 'mailto:' . $email,
+ );
+ }
+ }
+ catch (\Exception $e) {
+ // ignore failures
+ }
+ }
+ else {
+ // generate free/busy data from this user's calendars
+ return parent::getFreeBusyForEmail($email, $start, $end, $request);
+ }
- // not found:
+ // return "not found"
return array(
'request-status' => '3.7;Could not find principal',
'href' => 'mailto:' . $email,
);
-
- // success_
- return array(
- 'calendar-data' => $fbdata,
- 'request-status' => '2.0;Success',
- 'href' => 'mailto:' . $email,
- );
}
}
\ No newline at end of file
diff --git a/lib/Kolab/DAV/Auth/HTTPBasic.php b/lib/Kolab/DAV/Auth/HTTPBasic.php
index 036d54f..3b551ab 100644
--- a/lib/Kolab/DAV/Auth/HTTPBasic.php
+++ b/lib/Kolab/DAV/Auth/HTTPBasic.php
@@ -1,113 +1,116 @@
<?php
/**
* SabreDAV Auth Backend implementation for 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\DAV\Auth;
use \rcube;
use \rcube_user;
use \rcube_utils;
use Kolab\Utils\CacheAPC;
/**
*
*/
class HTTPBasic extends \Sabre\DAV\Auth\Backend\AbstractBasic
{
- // Make the current user name availabel to all classes
+ // Make the current user name available to all classes
public static $current_user = null;
+ public static $current_pass = null;
/**
* Validates a username and password
*
* This method should return true or false depending on if login
* succeeded.
*
* @param string $username
* @param string $password
* @return bool
*/
protected function validateUserPass($username, $password)
{
$rcube = rcube::get_instance();
$cache = CacheAPC::get_instance('kolabdav:auth');
// Here we need IDNA ASCII
$host = rcube_utils::idn_to_ascii($rcube->config->get('default_host', 'localhost'));
$user = rcube_utils::idn_to_ascii($username);
$port = $rcube->config->get('default_port', 143);
$_host = parse_url($host);
if ($_host['host']) {
$host = $_host['host'];
$ssl = (isset($_host['scheme']) && in_array($_host['scheme'], array('ssl','imaps','tls'))) ? $_host['scheme'] : null;
if (!empty($_host['port']))
$port = $_host['port'];
else if ($ssl && $ssl != 'tls' && (!$port || $port == 143))
$port = 993;
}
// check if we already canonified this username
if ($auth_user = $cache->get($user)) {
$user = $auth_user;
}
else { // load kolab_auth plugin to resolve the canonical username
$rcube->plugins->load_plugin('kolab_auth');
}
// let plugins do their work
$auth = $rcube->plugins->exec_hook('authenticate', array(
'host' => $host,
'user' => $user,
'pass' => $password,
));
// authenticate user against the IMAP server
$imap = $rcube->get_storage();
$success = $imap->connect($auth['host'], $auth['user'], $auth['pass'], $port, $ssl);
if ($success) {
self::$current_user = $auth['user'];
+ self::$current_pass = $password;
if (!$auth_user) {
$cache->set($user, $auth['user']);
}
// register a rcube_user object for global access
$rcube->user = new rcube_user(null, array('username' => $auth['user'], 'mail_host' => $auth['host']));
+ $_SESSION['imap_host'] = $auth['host'];
}
return $success;
}
/**
* Returns information about the currently logged in username.
*
* If nobody is currently logged in, this method should return null.
*
* @return string|null
*/
public function getCurrentUser()
{
// return the canonic user name
return self::$current_user;
}
}

File Metadata

Mime Type
text/x-diff
Expires
Sat, Jan 10, 10:57 AM (16 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
421920
Default Alt Text
(12 KB)

Event Timeline