Skip to content

Commit

Permalink
Merge pull request #6903 from nextcloud/feature/679/remove_valarms_fr…
Browse files Browse the repository at this point in the history
…om_read_only_shared_calendars

remove reminders from read-only shared calendars
  • Loading branch information
nickvergessen authored Oct 31, 2017
2 parents 299ef9a + 1855204 commit 8ce5adc
Show file tree
Hide file tree
Showing 2 changed files with 221 additions and 11 deletions.
52 changes: 41 additions & 11 deletions apps/dav/lib/CalDAV/CalendarObject.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}

$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 $data;

return $vObject->serialize();
}

protected function isShared() {
Expand All @@ -52,13 +66,10 @@ protected function isShared() {
}

/**
* @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)) {
Expand Down Expand Up @@ -92,8 +103,27 @@ private static function createConfidentialObject($calData) {
}
}
}

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;
}
}
180 changes: 180 additions & 0 deletions apps/dav/tests/unit/CalDAV/CalendarTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -381,4 +381,184 @@ public function providesConfidentialClassificationData() {
[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);
}
}

0 comments on commit 8ce5adc

Please sign in to comment.