@@ -72,3 +72,7 @@ Options -Indexes | |||
<IfModule pagespeed_module> | |||
ModPagespeed Off | |||
</IfModule> | |||
#### DO NOT CHANGE ANYTHING ABOVE THIS LINE #### | |||
ErrorDocument 403 /core/templates/403.php | |||
ErrorDocument 404 /core/templates/404.php |
@@ -489,7 +489,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
*/ | |||
function getCalendarObjects($calendarId) { | |||
$query = $this->db->getQueryBuilder(); | |||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype']) | |||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'componenttype', 'classification']) | |||
->from('calendarobjects') | |||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId))); | |||
$stmt = $query->execute(); | |||
@@ -504,6 +504,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
'calendarid' => $row['calendarid'], | |||
'size' => (int)$row['size'], | |||
'component' => strtolower($row['componenttype']), | |||
'classification'=> $row['classification'] | |||
]; | |||
} | |||
@@ -529,7 +530,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
function getCalendarObject($calendarId, $objectUri) { | |||
$query = $this->db->getQueryBuilder(); | |||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype']) | |||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification']) | |||
->from('calendarobjects') | |||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId))) | |||
->andWhere($query->expr()->eq('uri', $query->createNamedParameter($objectUri))); | |||
@@ -547,6 +548,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
'size' => (int)$row['size'], | |||
'calendardata' => $this->readBlob($row['calendardata']), | |||
'component' => strtolower($row['componenttype']), | |||
'classification'=> $row['classification'] | |||
]; | |||
} | |||
@@ -564,7 +566,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
*/ | |||
function getMultipleCalendarObjects($calendarId, array $uris) { | |||
$query = $this->db->getQueryBuilder(); | |||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype']) | |||
$query->select(['id', 'uri', 'lastmodified', 'etag', 'calendarid', 'size', 'calendardata', 'componenttype', 'classification']) | |||
->from('calendarobjects') | |||
->where($query->expr()->eq('calendarid', $query->createNamedParameter($calendarId))) | |||
->andWhere($query->expr()->in('uri', $query->createParameter('uri'))) | |||
@@ -584,6 +586,7 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
'size' => (int)$row['size'], | |||
'calendardata' => $this->readBlob($row['calendardata']), | |||
'component' => strtolower($row['componenttype']), | |||
'classification' => $row['classification'] | |||
]; | |||
} | |||
@@ -679,6 +682,11 @@ class CalDavBackend extends AbstractBackend implements SyncSupport, Subscription | |||
* @param int $classification | |||
*/ | |||
public function setClassification($calendarObjectId, $classification) { | |||
if (!in_array($classification, [ | |||
self::CLASSIFICATION_PUBLIC, self::CLASSIFICATION_PRIVATE, self::CLASSIFICATION_CONFIDENTIAL | |||
])) { | |||
throw new \InvalidArgumentException(); | |||
} | |||
$query = $this->db->getQueryBuilder(); | |||
$query->update('calendarobjects') | |||
->set('classification', $query->createNamedParameter($classification)) |
@@ -55,7 +55,7 @@ class Classification implements IRepairStep { | |||
foreach ($calendars as $calendar) { | |||
$objects = $this->calDavBackend->getCalendarObjects($calendar['id']); | |||
foreach ($objects as $object) { | |||
$calObject = $this->calDavBackend->getCalendarObject($calendar['id'], $object['id']); | |||
$calObject = $this->calDavBackend->getCalendarObject($calendar['id'], $object['uri']); | |||
$classification = $this->extractClassification($calObject['calendardata']); | |||
$this->calDavBackend->setClassification($object['id'], $classification); | |||
} |
@@ -0,0 +1,163 @@ | |||
<?php | |||
/** | |||
* @author Joas Schilling <nickvergessen@owncloud.com> | |||
* @author Thomas Müller <thomas.mueller@tmit.eu> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OCA\DAV\Tests\unit\CalDAV; | |||
use DateTime; | |||
use DateTimeZone; | |||
use OCA\DAV\CalDAV\CalDavBackend; | |||
use OCA\DAV\CalDAV\Calendar; | |||
use OCA\DAV\Connector\Sabre\Principal; | |||
use OCP\IL10N; | |||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; | |||
use Sabre\DAV\PropPatch; | |||
use Sabre\DAV\Xml\Property\Href; | |||
use Sabre\DAVACL\IACL; | |||
use Test\TestCase; | |||
/** | |||
* Class CalDavBackendTest | |||
* | |||
* @group DB | |||
* | |||
* @package OCA\DAV\Tests\unit\CalDAV | |||
*/ | |||
abstract class AbstractCalDavBackendTest extends TestCase { | |||
/** @var CalDavBackend */ | |||
protected $backend; | |||
/** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ | |||
protected $principal; | |||
const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; | |||
const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; | |||
const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group'; | |||
public function setUp() { | |||
parent::setUp(); | |||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') | |||
->disableOriginalConstructor() | |||
->setMethods(['getPrincipalByPath', 'getGroupMembership']) | |||
->getMock(); | |||
$this->principal->expects($this->any())->method('getPrincipalByPath') | |||
->willReturn([ | |||
'uri' => 'principals/best-friend' | |||
]); | |||
$this->principal->expects($this->any())->method('getGroupMembership') | |||
->withAnyParameters() | |||
->willReturn([self::UNIT_TEST_GROUP]); | |||
$db = \OC::$server->getDatabaseConnection(); | |||
$this->backend = new CalDavBackend($db, $this->principal); | |||
$this->tearDown(); | |||
} | |||
public function tearDown() { | |||
parent::tearDown(); | |||
if (is_null($this->backend)) { | |||
return; | |||
} | |||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); | |||
foreach ($books as $book) { | |||
$this->backend->deleteCalendar($book['id']); | |||
} | |||
$subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER); | |||
foreach ($subscriptions as $subscription) { | |||
$this->backend->deleteSubscription($subscription['id']); | |||
} | |||
} | |||
protected function createTestCalendar() { | |||
$this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [ | |||
'{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF' | |||
]); | |||
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); | |||
$this->assertEquals(1, count($calendars)); | |||
$this->assertEquals(self::UNIT_TEST_USER, $calendars[0]['principaluri']); | |||
/** @var SupportedCalendarComponentSet $components */ | |||
$components = $calendars[0]['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']; | |||
$this->assertEquals(['VEVENT','VTODO'], $components->getValue()); | |||
$color = $calendars[0]['{http://apple.com/ns/ical/}calendar-color']; | |||
$this->assertEquals('#1C4587FF', $color); | |||
$this->assertEquals('Example', $calendars[0]['uri']); | |||
$this->assertEquals('Example', $calendars[0]['{DAV:}displayname']); | |||
$calendarId = $calendars[0]['id']; | |||
return $calendarId; | |||
} | |||
protected function createEvent($calendarId, $start = '20130912T130000Z', $end = '20130912T140000Z') { | |||
$calData = <<<EOD | |||
BEGIN:VCALENDAR | |||
VERSION:2.0 | |||
PRODID:ownCloud Calendar | |||
BEGIN:VEVENT | |||
CREATED;VALUE=DATE-TIME:20130910T125139Z | |||
UID:47d15e3ec8 | |||
LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z | |||
DTSTAMP;VALUE=DATE-TIME:20130910T125139Z | |||
SUMMARY:Test Event | |||
DTSTART;VALUE=DATE-TIME:$start | |||
DTEND;VALUE=DATE-TIME:$end | |||
CLASS:PUBLIC | |||
END:VEVENT | |||
END:VCALENDAR | |||
EOD; | |||
$uri0 = $this->getUniqueID('event'); | |||
$this->backend->createCalendarObject($calendarId, $uri0, $calData); | |||
return $uri0; | |||
} | |||
protected function assertAcl($principal, $privilege, $acl) { | |||
foreach($acl as $a) { | |||
if ($a['principal'] === $principal && $a['privilege'] === $privilege) { | |||
$this->assertTrue(true); | |||
return; | |||
} | |||
} | |||
$this->fail("ACL does not contain $principal / $privilege"); | |||
} | |||
protected function assertNotAcl($principal, $privilege, $acl) { | |||
foreach($acl as $a) { | |||
if ($a['principal'] === $principal && $a['privilege'] === $privilege) { | |||
$this->fail("ACL contains $principal / $privilege"); | |||
return; | |||
} | |||
} | |||
$this->assertTrue(true); | |||
} | |||
protected function assertAccess($shouldHaveAcl, $principal, $privilege, $acl) { | |||
if ($shouldHaveAcl) { | |||
$this->assertAcl($principal, $privilege, $acl); | |||
} else { | |||
$this->assertNotAcl($principal, $privilege, $acl); | |||
} | |||
} | |||
} |
@@ -26,13 +26,10 @@ use DateTime; | |||
use DateTimeZone; | |||
use OCA\DAV\CalDAV\CalDavBackend; | |||
use OCA\DAV\CalDAV\Calendar; | |||
use OCA\DAV\Connector\Sabre\Principal; | |||
use OCP\IL10N; | |||
use Sabre\CalDAV\Xml\Property\SupportedCalendarComponentSet; | |||
use Sabre\DAV\PropPatch; | |||
use Sabre\DAV\Xml\Property\Href; | |||
use Sabre\DAVACL\IACL; | |||
use Test\TestCase; | |||
/** | |||
* Class CalDavBackendTest | |||
@@ -41,54 +38,7 @@ use Test\TestCase; | |||
* | |||
* @package OCA\DAV\Tests\unit\CalDAV | |||
*/ | |||
class CalDavBackendTest extends TestCase { | |||
/** @var CalDavBackend */ | |||
private $backend; | |||
/** @var Principal | \PHPUnit_Framework_MockObject_MockObject */ | |||
private $principal; | |||
const UNIT_TEST_USER = 'principals/users/caldav-unit-test'; | |||
const UNIT_TEST_USER1 = 'principals/users/caldav-unit-test1'; | |||
const UNIT_TEST_GROUP = 'principals/groups/caldav-unit-test-group'; | |||
public function setUp() { | |||
parent::setUp(); | |||
$this->principal = $this->getMockBuilder('OCA\DAV\Connector\Sabre\Principal') | |||
->disableOriginalConstructor() | |||
->setMethods(['getPrincipalByPath', 'getGroupMembership']) | |||
->getMock(); | |||
$this->principal->expects($this->any())->method('getPrincipalByPath') | |||
->willReturn([ | |||
'uri' => 'principals/best-friend' | |||
]); | |||
$this->principal->expects($this->any())->method('getGroupMembership') | |||
->withAnyParameters() | |||
->willReturn([self::UNIT_TEST_GROUP]); | |||
$db = \OC::$server->getDatabaseConnection(); | |||
$this->backend = new CalDavBackend($db, $this->principal); | |||
$this->tearDown(); | |||
} | |||
public function tearDown() { | |||
parent::tearDown(); | |||
if (is_null($this->backend)) { | |||
return; | |||
} | |||
$books = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); | |||
foreach ($books as $book) { | |||
$this->backend->deleteCalendar($book['id']); | |||
} | |||
$subscriptions = $this->backend->getSubscriptionsForUser(self::UNIT_TEST_USER); | |||
foreach ($subscriptions as $subscription) { | |||
$this->backend->deleteSubscription($subscription['id']); | |||
} | |||
} | |||
class CalDavBackendTest extends AbstractCalDavBackendTest { | |||
public function testCalendarOperations() { | |||
@@ -232,6 +182,7 @@ EOD; | |||
$calendarObjects = $this->backend->getCalendarObjects($calendarId); | |||
$this->assertEquals(1, count($calendarObjects)); | |||
$this->assertEquals($calendarId, $calendarObjects[0]['calendarid']); | |||
$this->assertArrayHasKey('classification', $calendarObjects[0]); | |||
// get the cards | |||
$calendarObject = $this->backend->getCalendarObject($calendarId, $uri); | |||
@@ -241,6 +192,7 @@ EOD; | |||
$this->assertArrayHasKey('lastmodified', $calendarObject); | |||
$this->assertArrayHasKey('etag', $calendarObject); | |||
$this->assertArrayHasKey('size', $calendarObject); | |||
$this->assertArrayHasKey('classification', $calendarObject); | |||
$this->assertEquals($calData, $calendarObject['calendardata']); | |||
// update the card | |||
@@ -310,6 +262,7 @@ EOD; | |||
$this->assertArrayHasKey('lastmodified', $card); | |||
$this->assertArrayHasKey('etag', $card); | |||
$this->assertArrayHasKey('size', $card); | |||
$this->assertArrayHasKey('classification', $card); | |||
$this->assertEquals($calData, $card['calendardata']); | |||
} | |||
@@ -363,49 +316,6 @@ EOD; | |||
]; | |||
} | |||
private function createTestCalendar() { | |||
$this->backend->createCalendar(self::UNIT_TEST_USER, 'Example', [ | |||
'{http://apple.com/ns/ical/}calendar-color' => '#1C4587FF' | |||
]); | |||
$calendars = $this->backend->getCalendarsForUser(self::UNIT_TEST_USER); | |||
$this->assertEquals(1, count($calendars)); | |||
$this->assertEquals(self::UNIT_TEST_USER, $calendars[0]['principaluri']); | |||
/** @var SupportedCalendarComponentSet $components */ | |||
$components = $calendars[0]['{urn:ietf:params:xml:ns:caldav}supported-calendar-component-set']; | |||
$this->assertEquals(['VEVENT','VTODO'], $components->getValue()); | |||
$color = $calendars[0]['{http://apple.com/ns/ical/}calendar-color']; | |||
$this->assertEquals('#1C4587FF', $color); | |||
$this->assertEquals('Example', $calendars[0]['uri']); | |||
$this->assertEquals('Example', $calendars[0]['{DAV:}displayname']); | |||
$calendarId = $calendars[0]['id']; | |||
return $calendarId; | |||
} | |||
private function createEvent($calendarId, $start = '20130912T130000Z', $end = '20130912T140000Z') { | |||
$calData = <<<EOD | |||
BEGIN:VCALENDAR | |||
VERSION:2.0 | |||
PRODID:ownCloud Calendar | |||
BEGIN:VEVENT | |||
CREATED;VALUE=DATE-TIME:20130910T125139Z | |||
UID:47d15e3ec8 | |||
LAST-MODIFIED;VALUE=DATE-TIME:20130910T125139Z | |||
DTSTAMP;VALUE=DATE-TIME:20130910T125139Z | |||
SUMMARY:Test Event | |||
DTSTART;VALUE=DATE-TIME:$start | |||
DTEND;VALUE=DATE-TIME:$end | |||
CLASS:PUBLIC | |||
END:VEVENT | |||
END:VCALENDAR | |||
EOD; | |||
$uri0 = $this->getUniqueID('event'); | |||
$this->backend->createCalendarObject($calendarId, $uri0, $calData); | |||
return $uri0; | |||
} | |||
public function testSyncSupport() { | |||
$calendarId = $this->createTestCalendar(); | |||
@@ -480,32 +390,4 @@ EOD; | |||
'unknown class -> private' => [CalDavBackend::CLASSIFICATION_PRIVATE, 'classification', "BEGIN:VCALENDAR\r\nVERSION:2.0\r\nPRODID:-//dmfs.org//mimedir.icalendar//EN\r\nBEGIN:VTIMEZONE\r\nTZID:Europe/Berlin\r\nX-LIC-LOCATION:Europe/Berlin\r\nBEGIN:DAYLIGHT\r\nTZOFFSETFROM:+0100\r\nTZOFFSETTO:+0200\r\nTZNAME:CEST\r\nDTSTART:19700329T020000\r\nRRULE:FREQ=YEARLY;BYMONTH=3;BYDAY=-1SU\r\nEND:DAYLIGHT\r\nBEGIN:STANDARD\r\nTZOFFSETFROM:+0200\r\nTZOFFSETTO:+0100\r\nTZNAME:CET\r\nDTSTART:19701025T030000\r\nRRULE:FREQ=YEARLY;BYMONTH=10;BYDAY=-1SU\r\nEND:STANDARD\r\nEND:VTIMEZONE\r\nBEGIN:VEVENT\r\nDTSTART;TZID=Europe/Berlin:20160419T130000\r\nSUMMARY:Test\r\nCLASS:VERTRAULICH\r\nTRANSP:OPAQUE\r\nSTATUS:CONFIRMED\r\nDTEND;TZID=Europe/Berlin:20160419T140000\r\nLAST-MODIFIED:20160419T074202Z\r\nDTSTAMP:20160419T074202Z\r\nCREATED:20160419T074202Z\r\nUID:2e468c48-7860-492e-bc52-92fa0daeeccf.1461051722310\r\nEND:VEVENT\r\nEND:VCALENDAR"], | |||
]; | |||
} | |||
private function assertAcl($principal, $privilege, $acl) { | |||
foreach($acl as $a) { | |||
if ($a['principal'] === $principal && $a['privilege'] === $privilege) { | |||
$this->assertTrue(true); | |||
return; | |||
} | |||
} | |||
$this->fail("ACL does not contain $principal / $privilege"); | |||
} | |||
private function assertNotAcl($principal, $privilege, $acl) { | |||
foreach($acl as $a) { | |||
if ($a['principal'] === $principal && $a['privilege'] === $privilege) { | |||
$this->fail("ACL contains $principal / $privilege"); | |||
return; | |||
} | |||
} | |||
$this->assertTrue(true); | |||
} | |||
private function assertAccess($shouldHaveAcl, $principal, $privilege, $acl) { | |||
if ($shouldHaveAcl) { | |||
$this->assertAcl($principal, $privilege, $acl); | |||
} else { | |||
$this->assertNotAcl($principal, $privilege, $acl); | |||
} | |||
} | |||
} |
@@ -0,0 +1,75 @@ | |||
<?php | |||
/** | |||
* @author Thomas Müller <thomas.mueller@tmit.eu> | |||
* | |||
* @copyright Copyright (c) 2016, ownCloud, Inc. | |||
* @license AGPL-3.0 | |||
* | |||
* This code is free software: you can redistribute it and/or modify | |||
* it under the terms of the GNU Affero General Public License, version 3, | |||
* as published by the Free Software Foundation. | |||
* | |||
* 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, version 3, | |||
* along with this program. If not, see <http://www.gnu.org/licenses/> | |||
* | |||
*/ | |||
namespace OCA\DAV\Tests\unit\DAV\Migration; | |||
use OCA\DAV\CalDAV\CalDavBackend; | |||
use OCA\DAV\Migration\Classification; | |||
use OCA\DAV\Tests\unit\CalDAV\AbstractCalDavBackendTest; | |||
use OCP\IUser; | |||
/** | |||
* Class ClassificationTest | |||
* | |||
* @group DB | |||
* | |||
* @package OCA\DAV\Tests\unit\DAV | |||
*/ | |||
class ClassificationTest extends AbstractCalDavBackendTest { | |||
/** @var \PHPUnit_Framework_MockObject_MockObject | \OCP\IUserManager */ | |||
private $userManager; | |||
public function setUp() { | |||
parent::setUp(); | |||
$this->userManager = $this->getMockBuilder('OCP\IUserManager') | |||
->disableOriginalConstructor()->getMock(); | |||
} | |||
public function test() { | |||
// setup data | |||
$calendarId = $this->createTestCalendar(); | |||
$eventUri = $this->createEvent($calendarId, '20130912T130000Z', '20130912T140000Z'); | |||
$object = $this->backend->getCalendarObject($calendarId, $eventUri); | |||
// assert proper classification | |||
$this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']); | |||
$this->backend->setClassification($object['id'], CalDavBackend::CLASSIFICATION_CONFIDENTIAL); | |||
$object = $this->backend->getCalendarObject($calendarId, $eventUri); | |||
$this->assertEquals(CalDavBackend::CLASSIFICATION_CONFIDENTIAL, $object['classification']); | |||
// run migration | |||
$c = new Classification($this->backend, $this->userManager); | |||
/** @var IUser | \PHPUnit_Framework_MockObject_MockObject $user */ | |||
$user = $this->getMockBuilder('OCP\IUser') | |||
->disableOriginalConstructor() | |||
->getMock(); | |||
$user->expects($this->once())->method('getUID')->willReturn('caldav-unit-test'); | |||
$c->runForUser($user); | |||
// assert classification after migration | |||
$object = $this->backend->getCalendarObject($calendarId, $eventUri); | |||
$this->assertEquals(CalDavBackend::CLASSIFICATION_PUBLIC, $object['classification']); | |||
} | |||
} |