remove reminders from read-only shared calendars

Signed-off-by: Georg Ehrke <developer@georgehrke.com>
This commit is contained in:
Georg Ehrke 2017-10-22 12:53:21 +02:00
parent 2b31b82891
commit 1855204ad9
No known key found for this signature in database
GPG Key ID: 9D98FD9380A1CB43
2 changed files with 221 additions and 11 deletions

View File

@ -37,10 +37,24 @@ class CalendarObject extends \Sabre\CalDAV\CalendarObject {
*/
function get() {
$data = parent::get();
if ($this->isShared() && $this->objectData['classification'] === CalDavBackend::CLASSIFICATION_CONFIDENTIAL) {
return $this->createConfidentialObject($data);
if (!$this->isShared()) {
return $data;
}
return $data;
$vObject = Reader::read($data);
// remove VAlarms if calendar is shared read-only
if (!$this->canWrite()) {
$this->removeVAlarms($vObject);
}
// shows as busy if event is declared confidential
if ($this->objectData['classification'] === CalDavBackend::CLASSIFICATION_CONFIDENTIAL) {
$this->createConfidentialObject($vObject);
}
return $vObject->serialize();
}
protected function isShared() {
@ -52,13 +66,10 @@ class CalendarObject extends \Sabre\CalDAV\CalendarObject {
}
/**
* @param string $calData
* @return string
* @param Component\VCalendar $vObject
* @return void
*/
private static function createConfidentialObject($calData) {
$vObject = Reader::read($calData);
private static function createConfidentialObject(Component\VCalendar $vObject) {
/** @var Component $vElement */
$vElement = null;
if(isset($vObject->VEVENT)) {
@ -92,8 +103,27 @@ class CalendarObject extends \Sabre\CalDAV\CalendarObject {
}
}
}
return $vObject->serialize();
}
/**
* @param Component\VCalendar $vObject
* @return void
*/
private function removeVAlarms(Component\VCalendar $vObject) {
$subcomponents = $vObject->getComponents();
foreach($subcomponents as $subcomponent) {
unset($subcomponent->VALARM);
}
}
/**
* @return bool
*/
private function canWrite() {
if (isset($this->calendarInfo['{http://owncloud.org/ns}read-only'])) {
return !$this->calendarInfo['{http://owncloud.org/ns}read-only'];
}
return true;
}
}

View File

@ -381,4 +381,184 @@ EOD;
[2, true]
];
}
public function testRemoveVAlarms() {
$publicObjectData = <<<EOD
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud calendar v1.5.6
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20171022T125130
DTSTAMP:20171022T125130
LAST-MODIFIED:20171022T125130
UID:PPL24TH8UGOWE94XET87ER
SUMMARY:Foo bar blub
CLASS:PUBLIC
STATUS:CONFIRMED
DTSTART;VALUE=DATE:20171024
DTEND;VALUE=DATE:20171025
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR
EOD;
$confidentialObjectData = <<<EOD
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud calendar v1.5.6
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20171022T125130
DTSTAMP:20171022T125130
LAST-MODIFIED:20171022T125130
UID:PPL24TH8UGOWE94XET87ER
SUMMARY:Foo bar blub
CLASS:CONFIDENTIAL
STATUS:CONFIRMED
DTSTART;VALUE=DATE:20171024
DTEND;VALUE=DATE:20171025
BEGIN:VALARM
ACTION:AUDIO
TRIGGER:-PT15M
END:VALARM
END:VEVENT
END:VCALENDAR
EOD;
$publicObjectDataWithoutVAlarm = <<<EOD
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud calendar v1.5.6
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20171022T125130
DTSTAMP:20171022T125130
LAST-MODIFIED:20171022T125130
UID:PPL24TH8UGOWE94XET87ER
SUMMARY:Foo bar blub
CLASS:PUBLIC
STATUS:CONFIRMED
DTSTART;VALUE=DATE:20171024
DTEND;VALUE=DATE:20171025
END:VEVENT
END:VCALENDAR
EOD;
$confidentialObjectCleaned = <<<EOD
BEGIN:VCALENDAR
VERSION:2.0
PRODID:-//Nextcloud calendar v1.5.6
CALSCALE:GREGORIAN
BEGIN:VEVENT
CREATED:20171022T125130
UID:PPL24TH8UGOWE94XET87ER
SUMMARY:Busy
CLASS:CONFIDENTIAL
DTSTART;VALUE=DATE:20171024
DTEND;VALUE=DATE:20171025
END:VEVENT
END:VCALENDAR
EOD;
$publicObject = ['uri' => 'event-0',
'classification' => CalDavBackend::CLASSIFICATION_PUBLIC,
'calendardata' => $publicObjectData];
$confidentialObject = ['uri' => 'event-1',
'classification' => CalDavBackend::CLASSIFICATION_CONFIDENTIAL,
'calendardata' => $confidentialObjectData];
/** @var \PHPUnit_Framework_MockObject_MockObject | CalDavBackend $backend */
$backend = $this->createMock(CalDavBackend::class);
$backend->expects($this->any())
->method('getCalendarObjects')
->willReturn([$publicObject, $confidentialObject]);
$backend->expects($this->any())
->method('getMultipleCalendarObjects')
->with(666, ['event-0', 'event-1'])
->willReturn([$publicObject, $confidentialObject]);
$backend->expects($this->any())
->method('getCalendarObject')
->will($this->returnCallback(function($cId, $uri) use($publicObject, $confidentialObject) {
switch($uri) {
case 'event-0':
return $publicObject;
case 'event-1':
return $confidentialObject;
default:
throw new \Exception('unexpected uri');
}
}));
$backend->expects($this->any())
->method('applyShareAcl')
->willReturnArgument(1);
$calendarInfoOwner = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'principaluri' => 'user1',
'id' => 666,
'uri' => 'cal',
];
$calendarInfoSharedRW = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'principaluri' => 'user2',
'id' => 666,
'uri' => 'cal',
];
$calendarInfoSharedRO = [
'{http://owncloud.org/ns}owner-principal' => 'user1',
'{http://owncloud.org/ns}read-only' => true,
'principaluri' => 'user2',
'id' => 666,
'uri' => 'cal',
];
$ownerCalendar = new Calendar($backend, $calendarInfoOwner, $this->l10n);
$rwCalendar = new Calendar($backend, $calendarInfoSharedRW, $this->l10n);
$roCalendar = new Calendar($backend, $calendarInfoSharedRO, $this->l10n);
$this->assertEquals(count($ownerCalendar->getChildren()), 2);
$this->assertEquals(count($rwCalendar->getChildren()), 2);
$this->assertEquals(count($roCalendar->getChildren()), 2);
// calendar data shall not be altered for the owner
$this->assertEquals($ownerCalendar->getChild('event-0')->get(), $publicObjectData);
$this->assertEquals($ownerCalendar->getChild('event-1')->get(), $confidentialObjectData);
// valarms shall not be removed for read-write shares
$this->assertEquals(
$this->fixLinebreak($rwCalendar->getChild('event-0')->get()),
$this->fixLinebreak($publicObjectData));
$this->assertEquals(
$this->fixLinebreak($rwCalendar->getChild('event-1')->get()),
$this->fixLinebreak($confidentialObjectCleaned));
// valarms shall be removed for read-only shares
$this->assertEquals(
$this->fixLinebreak($roCalendar->getChild('event-0')->get()),
$this->fixLinebreak($publicObjectDataWithoutVAlarm));
$this->assertEquals(
$this->fixLinebreak($roCalendar->getChild('event-1')->get()),
$this->fixLinebreak($confidentialObjectCleaned));
}
private function fixLinebreak($str) {
return preg_replace('~(*BSR_ANYCRLF)\R~', "\r\n", $str);
}
}