Merge branch 'master' into share_api
Conflicts: apps/calendar/js/loader.js apps/contacts/index.php apps/contacts/js/loader.js apps/files/js/files.js apps/files_sharing/sharedstorage.php lib/filesystemview.php
|
@ -294,6 +294,7 @@ class Sabre_CalDAV_CalendarQueryValidator {
|
|||
// in the VALARM component code, so this is a hack, and an
|
||||
// expensive one too.
|
||||
if ($component->parent->name === 'VEVENT' && $component->parent->RRULE) {
|
||||
|
||||
// Fire up the iterator!
|
||||
$it = new Sabre_VObject_RecurrenceIterator($component->parent->parent, (string)$component->parent->UID);
|
||||
while($it->valid()) {
|
||||
|
@ -304,14 +305,35 @@ class Sabre_CalDAV_CalendarQueryValidator {
|
|||
// determine if we can 'give up' expanding events.
|
||||
$firstAlarm = null;
|
||||
foreach($expandedEvent->VALARM as $expandedAlarm) {
|
||||
|
||||
$effectiveTrigger = $expandedAlarm->getEffectiveTriggerTime();
|
||||
if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
|
||||
$firstAlarm = $effectiveTrigger;
|
||||
}
|
||||
if ($expandedAlarm->isInTimeRange($start, $end)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if ((string)$expandedAlarm->TRIGGER['VALUE'] === 'DATE-TIME') {
|
||||
// This is an alarm with a non-relative trigger
|
||||
// time, likely created by a buggy client. The
|
||||
// implication is that every alarm in this
|
||||
// recurring event trigger at the exact same
|
||||
// time. It doesn't make sense to traverse
|
||||
// further.
|
||||
} else {
|
||||
// We store the first alarm as a means to
|
||||
// figure out when we can stop traversing.
|
||||
if (!$firstAlarm || $effectiveTrigger < $firstAlarm) {
|
||||
$firstAlarm = $effectiveTrigger;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
if (is_null($firstAlarm)) {
|
||||
// No alarm was found.
|
||||
//
|
||||
// Or technically: No alarm that will change for
|
||||
// every instance of the recurrence was found,
|
||||
// which means we can assume there was no match.
|
||||
return false;
|
||||
}
|
||||
if ($firstAlarm > $end) {
|
||||
return false;
|
||||
|
|
|
@ -672,6 +672,42 @@ class Sabre_CalDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
|
||||
}
|
||||
|
||||
if ($vobj->name !== 'VCALENDAR') {
|
||||
throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support iCalendar objects.');
|
||||
}
|
||||
|
||||
$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 (!isset($component->UID)) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' component must have an UID');
|
||||
}
|
||||
$foundUID = (string)$component->UID;
|
||||
} else {
|
||||
if ($foundType !== $component->name) {
|
||||
throw new Sabre_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 Sabre_DAV_Exception_BadRequest('Every ' . $component->name . ' in this object must have identical UIDs');
|
||||
}
|
||||
}
|
||||
break;
|
||||
default :
|
||||
throw new Sabre_DAV_Exception_BadRequest('You are not allowed to create components of type: ' . $component->name . ' here');
|
||||
|
||||
}
|
||||
}
|
||||
if (!$foundType)
|
||||
throw new Sabre_DAV_Exception_BadRequest('iCalendar object must contain at least 1 of VEVENT, VTODO or VJOURNAL');
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
0
3rdparty/Sabre/CalDAV/Property/SupportedCalendarComponentSet.php
vendored
Normal file → Executable file
|
@ -14,7 +14,7 @@ class Sabre_CalDAV_Version {
|
|||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.2';
|
||||
const VERSION = '1.6.3';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
|
|
|
@ -108,7 +108,9 @@ class Sabre_CardDAV_AddressBook extends Sabre_DAV_Collection implements Sabre_Ca
|
|||
*/
|
||||
public function createFile($name,$vcardData = null) {
|
||||
|
||||
$vcardData = stream_get_contents($vcardData);
|
||||
if (is_resource($vcardData)) {
|
||||
$vcardData = stream_get_contents($vcardData);
|
||||
}
|
||||
// Converting to UTF-8, if needed
|
||||
$vcardData = Sabre_DAV_StringUtil::ensureUTF8($vcardData);
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
* @package Sabre
|
||||
* @subpackage CardDAV
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_CardDAV_AddressBookQueryParser {
|
||||
|
@ -88,12 +88,22 @@ class Sabre_CardDAV_AddressBookQueryParser {
|
|||
if (is_nan($limit)) $limit = null;
|
||||
|
||||
$filter = $this->xpath->query('/card:addressbook-query/card:filter');
|
||||
if ($filter->length !== 1) {
|
||||
|
||||
// According to the CardDAV spec there needs to be exactly 1 filter
|
||||
// element. However, KDE 4.8.2 contains a bug that will encode 0 filter
|
||||
// elements, so this is a workaround for that.
|
||||
//
|
||||
// See: https://bugs.kde.org/show_bug.cgi?id=300047
|
||||
if ($filter->length === 0) {
|
||||
$test = null;
|
||||
$filter = null;
|
||||
} elseif ($filter->length === 1) {
|
||||
$filter = $filter->item(0);
|
||||
$test = $this->xpath->evaluate('string(@test)', $filter);
|
||||
} else {
|
||||
throw new Sabre_DAV_Exception_BadRequest('Only one filter element is allowed');
|
||||
}
|
||||
|
||||
$filter = $filter->item(0);
|
||||
$test = $this->xpath->evaluate('string(@test)', $filter);
|
||||
if (!$test) $test = self::TEST_ANYOF;
|
||||
if ($test !== self::TEST_ANYOF && $test !== self::TEST_ALLOF) {
|
||||
throw new Sabre_DAV_Exception_BadRequest('The test attribute must either hold "anyof" or "allof"');
|
||||
|
|
|
@ -52,6 +52,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
$server->subscribeEvent('report', array($this,'report'));
|
||||
$server->subscribeEvent('onHTMLActionsPanel', array($this,'htmlActionsPanel'));
|
||||
$server->subscribeEvent('onBrowserPostAction', array($this,'browserPostAction'));
|
||||
$server->subscribeEvent('beforeWriteContent', array($this, 'beforeWriteContent'));
|
||||
$server->subscribeEvent('beforeCreateFile', array($this, 'beforeCreateFile'));
|
||||
|
||||
/* Namespaces */
|
||||
$server->xmlNamespaces[self::NS_CARDDAV] = 'card';
|
||||
|
@ -283,6 +285,81 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is triggered before a file gets updated with new content.
|
||||
*
|
||||
* This plugin uses this method to ensure that Card nodes receive valid
|
||||
* vcard data.
|
||||
*
|
||||
* @param string $path
|
||||
* @param Sabre_DAV_IFile $node
|
||||
* @param resource $data
|
||||
* @return void
|
||||
*/
|
||||
public function beforeWriteContent($path, Sabre_DAV_IFile $node, &$data) {
|
||||
|
||||
if (!$node instanceof Sabre_CardDAV_ICard)
|
||||
return;
|
||||
|
||||
$this->validateVCard($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* This method is triggered before a new file is created.
|
||||
*
|
||||
* This plugin uses this method to ensure that Card nodes receive valid
|
||||
* vcard data.
|
||||
*
|
||||
* @param string $path
|
||||
* @param resource $data
|
||||
* @param Sabre_DAV_ICollection $parentNode
|
||||
* @return void
|
||||
*/
|
||||
public function beforeCreateFile($path, &$data, Sabre_DAV_ICollection $parentNode) {
|
||||
|
||||
if (!$parentNode instanceof Sabre_CardDAV_IAddressBook)
|
||||
return;
|
||||
|
||||
$this->validateVCard($data);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the submitted iCalendar data is in fact, valid.
|
||||
*
|
||||
* An exception is thrown if it's not.
|
||||
*
|
||||
* @param resource|string $data
|
||||
* @return void
|
||||
*/
|
||||
protected function validateVCard(&$data) {
|
||||
|
||||
// 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 = Sabre_DAV_StringUtil::ensureUTF8($data);
|
||||
|
||||
try {
|
||||
|
||||
$vobj = Sabre_VObject_Reader::read($data);
|
||||
|
||||
} catch (Sabre_VObject_ParseException $e) {
|
||||
|
||||
throw new Sabre_DAV_Exception_UnsupportedMediaType('This resource only supports valid vcard data. Parse error: ' . $e->getMessage());
|
||||
|
||||
}
|
||||
|
||||
if ($vobj->name !== 'VCARD') {
|
||||
throw new Sabre_DAV_Exception_UnsupportedMediaType('This collection can only support vcard objects.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This function handles the addressbook-query REPORT
|
||||
*
|
||||
|
@ -362,6 +439,8 @@ class Sabre_CardDAV_Plugin extends Sabre_DAV_ServerPlugin {
|
|||
|
||||
$vcard = Sabre_VObject_Reader::read($vcardData);
|
||||
|
||||
if (!$filters) return true;
|
||||
|
||||
foreach($filters as $filter) {
|
||||
|
||||
$isDefined = isset($vcard->{$filter['name']});
|
||||
|
|
|
@ -16,7 +16,7 @@ class Sabre_CardDAV_Version {
|
|||
/**
|
||||
* Full version number
|
||||
*/
|
||||
const VERSION = '1.6.1';
|
||||
const VERSION = '1.6.3';
|
||||
|
||||
/**
|
||||
* Stability : alpha, beta, stable
|
||||
|
|
Before Width: | Height: | Size: 4.2 KiB After Width: | Height: | Size: 4.2 KiB |
Before Width: | Height: | Size: 7.1 KiB After Width: | Height: | Size: 7.1 KiB |
Before Width: | Height: | Size: 4.3 KiB After Width: | Height: | Size: 4.3 KiB |
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.4 KiB After Width: | Height: | Size: 3.4 KiB |
Before Width: | Height: | Size: 5.4 KiB After Width: | Height: | Size: 5.4 KiB |
|
@ -11,7 +11,7 @@
|
|||
* @package Sabre
|
||||
* @subpackage DAVClient
|
||||
* @copyright Copyright (C) 2007-2012 Rooftop Solutions. All rights reserved.
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @author Evert Pot (http://www.rooftopsolutions.nl/)
|
||||
* @license http://code.google.com/p/sabredav/wiki/License Modified BSD License
|
||||
*/
|
||||
class Sabre_DAV_Client {
|
||||
|
@ -23,6 +23,28 @@ class Sabre_DAV_Client {
|
|||
protected $password;
|
||||
protected $proxy;
|
||||
|
||||
/**
|
||||
* Basic authentication
|
||||
*/
|
||||
const AUTH_BASIC = 1;
|
||||
|
||||
/**
|
||||
* Digest authentication
|
||||
*/
|
||||
const AUTH_DIGEST = 2;
|
||||
|
||||
/**
|
||||
* The authentication type we're using.
|
||||
*
|
||||
* This is a bitmask of AUTH_BASIC and AUTH_DIGEST.
|
||||
*
|
||||
* If DIGEST is used, the client makes 1 extra request per request, to get
|
||||
* the authentication tokens.
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $authType;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
|
@ -46,16 +68,21 @@ class Sabre_DAV_Client {
|
|||
'baseUri',
|
||||
'userName',
|
||||
'password',
|
||||
'proxy'
|
||||
'proxy',
|
||||
);
|
||||
|
||||
|
||||
foreach($validSettings as $validSetting) {
|
||||
if (isset($settings[$validSetting])) {
|
||||
$this->$validSetting = $settings[$validSetting];
|
||||
}
|
||||
}
|
||||
|
||||
if (isset($settings['authType'])) {
|
||||
$this->authType = $settings['authType'];
|
||||
} else {
|
||||
$this->authType = self::AUTH_BASIC | self::AUTH_DIGEST;
|
||||
}
|
||||
|
||||
$this->propertyMap['{DAV:}resourcetype'] = 'Sabre_DAV_Property_ResourceType';
|
||||
|
||||
}
|
||||
|
@ -250,14 +277,9 @@ class Sabre_DAV_Client {
|
|||
// Automatically follow redirects
|
||||
CURLOPT_FOLLOWLOCATION => true,
|
||||
CURLOPT_MAXREDIRS => 5,
|
||||
CURLOPT_SSL_VERIFYPEER => true,
|
||||
//CURLOPT_SSL_VERIFYPEER => false,
|
||||
);
|
||||
|
||||
switch ($method) {
|
||||
case 'PUT':
|
||||
$curlSettings[CURLOPT_PUT] = true;
|
||||
break;
|
||||
case 'HEAD' :
|
||||
|
||||
// do not read body with HEAD requests (this is neccessary because cURL does not ignore the body with HEAD
|
||||
|
@ -288,8 +310,15 @@ class Sabre_DAV_Client {
|
|||
$curlSettings[CURLOPT_PROXY] = $this->proxy;
|
||||
}
|
||||
|
||||
if ($this->userName) {
|
||||
$curlSettings[CURLOPT_HTTPAUTH] = CURLAUTH_BASIC | CURLAUTH_DIGEST;
|
||||
if ($this->userName && $this->authType) {
|
||||
$curlType = 0;
|
||||
if ($this->authType & self::AUTH_BASIC) {
|
||||
$curlType |= CURLAUTH_BASIC;
|
||||
}
|
||||
if ($this->authType & self::AUTH_DIGEST) {
|
||||
$curlType |= CURLAUTH_DIGEST;
|
||||
}
|
||||
$curlSettings[CURLOPT_HTTPAUTH] = $curlType;
|
||||
$curlSettings[CURLOPT_USERPWD] = $this->userName . ':' . $this->password;
|
||||
}
|
||||
|
||||
|
|