diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index d31851fe17..5e0847ff5d 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -5,7 +5,7 @@
WebDAV
WebDAV endpoint
WebDAV endpoint
- 1.5.2
+ 1.5.3
agpl
owncloud.org
DAV
@@ -28,6 +28,7 @@
OCA\DAV\Migration\FixBirthdayCalendarComponent
OCA\DAV\Migration\CalDAVRemoveEmptyValue
OCA\DAV\Migration\BuildCalendarSearchIndex
+ OCA\DAV\Repair\RemoveInvalidShares
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 50689568eb..d4ef0a5337 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -142,6 +142,7 @@ return array(
'OCA\\DAV\\Migration\\Version1004Date20170924124212' => $baseDir . '/../lib/Migration/Version1004Date20170924124212.php',
'OCA\\DAV\\Migration\\Version1004Date20170926103422' => $baseDir . '/../lib/Migration/Version1004Date20170926103422.php',
'OCA\\DAV\\Migration\\Version1005Date20180413093149' => $baseDir . '/../lib/Migration/Version1005Date20180413093149.php',
+ 'OCA\\DAV\\Repair\\RemoveInvalidShares' => $baseDir . '/../lib/Repair/RemoveInvalidShares.php',
'OCA\\DAV\\RootCollection' => $baseDir . '/../lib/RootCollection.php',
'OCA\\DAV\\Server' => $baseDir . '/../lib/Server.php',
'OCA\\DAV\\Settings\\CalDAVSettings' => $baseDir . '/../lib/Settings/CalDAVSettings.php',
diff --git a/apps/dav/composer/composer/autoload_static.php b/apps/dav/composer/composer/autoload_static.php
index 760ca3426f..afaecd28e8 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -157,6 +157,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1004Date20170924124212' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170924124212.php',
'OCA\\DAV\\Migration\\Version1004Date20170926103422' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170926103422.php',
'OCA\\DAV\\Migration\\Version1005Date20180413093149' => __DIR__ . '/..' . '/../lib/Migration/Version1005Date20180413093149.php',
+ 'OCA\\DAV\\Repair\\RemoveInvalidShares' => __DIR__ . '/..' . '/../lib/Repair/RemoveInvalidShares.php',
'OCA\\DAV\\RootCollection' => __DIR__ . '/..' . '/../lib/RootCollection.php',
'OCA\\DAV\\Server' => __DIR__ . '/..' . '/../lib/Server.php',
'OCA\\DAV\\Settings\\CalDAVSettings' => __DIR__ . '/..' . '/../lib/Settings/CalDAVSettings.php',
diff --git a/apps/dav/lib/Repair/RemoveInvalidShares.php b/apps/dav/lib/Repair/RemoveInvalidShares.php
new file mode 100644
index 0000000000..b69f918a57
--- /dev/null
+++ b/apps/dav/lib/Repair/RemoveInvalidShares.php
@@ -0,0 +1,100 @@
+
+ *
+ * @copyright Copyright (c) 2018, ownCloud GmbH
+ * @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
+ *
+ */
+
+namespace OCA\DAV\Repair;
+
+use OCA\DAV\Connector\Sabre\Principal;
+use OCP\IDBConnection;
+use OCP\ILogger;
+use OCP\Migration\IOutput;
+use OCP\Migration\IRepairStep;
+
+/**
+ * Class RemoveInvalidShares - removes shared calendars and addressbook which
+ * have no matching principal. Happened because of a bug in the calendar app.
+ *
+ * @package OCA\DAV\Repair
+ */
+class RemoveInvalidShares implements IRepairStep {
+
+ /** @var IDBConnection */
+ private $connection;
+ /** @var Principal */
+ private $principalBackend;
+
+ /**
+ * RemoveInvalidShares constructor.
+ *
+ * @param IDBConnection $connection
+ * @param Principal $principalBackend
+ */
+ public function __construct(IDBConnection $connection,
+ Principal $principalBackend) {
+ $this->connection = $connection;
+ $this->principalBackend = $principalBackend;
+ }
+
+ /**
+ * Returns the step's name
+ *
+ * @return string
+ * @since 9.1.0
+ */
+ public function getName() {
+ return 'Remove invalid calendar and addressbook shares';
+ }
+
+ /**
+ * Run repair step.
+ * Must throw exception on error.
+ *
+ * @param IOutput $output
+ * @throws \Exception in case of failure
+ * @since 9.1.0
+ */
+ public function run(IOutput $output) {
+ $query = $this->connection->getQueryBuilder();
+ $result = $query->selectDistinct('principaluri')
+ ->from('dav_shares')
+ ->execute();
+
+ while($row = $result->fetch()) {
+ $principaluri = $row['principaluri'];
+ $p = $this->principalBackend->getPrincipalByPath($principaluri);
+ if ($p === null) {
+ $output->info(" ... for principal '$principaluri'");
+ $this->deleteSharesForPrincipal($principaluri);
+ }
+ }
+
+ $result->closeCursor();
+ }
+
+ /**
+ * @param string $principaluri
+ */
+ private function deleteSharesForPrincipal($principaluri) {
+ $delete = $this->connection->getQueryBuilder();
+ $delete->delete('dav_shares')
+ ->where($delete->expr()->eq('principaluri', $delete->createNamedParameter($principaluri)));
+ $delete->execute();
+ }
+}
diff --git a/apps/dav/tests/unit/Repair/RemoveInvalidSharesTest.php b/apps/dav/tests/unit/Repair/RemoveInvalidSharesTest.php
new file mode 100644
index 0000000000..14553740f3
--- /dev/null
+++ b/apps/dav/tests/unit/Repair/RemoveInvalidSharesTest.php
@@ -0,0 +1,70 @@
+
+ *
+ * @copyright Copyright (c) 2018, ownCloud GmbH
+ * @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
+ *
+ */
+
+
+namespace OCA\DAV\Tests\Unit\Repair;
+
+
+use OCA\DAV\Connector\Sabre\Principal;
+use OCA\DAV\Repair\RemoveInvalidShares;
+use OCP\Migration\IOutput;
+use Test\TestCase;
+
+/**
+ * Class RemoveInvalidSharesTest
+ *
+ * @package OCA\DAV\Tests\Unit\Repair
+ * @group DB
+ */
+class RemoveInvalidSharesTest extends TestCase {
+
+ public function setUp() {
+ parent::setUp();
+ $db = \OC::$server->getDatabaseConnection();
+
+ $db->insertIfNotExist('*PREFIX*dav_shares', [
+ 'principaluri' => 'principal:unknown',
+ 'type' => 'calendar',
+ 'access' => 2,
+ 'resourceid' => 666,
+ ]);
+ }
+
+ public function test() {
+ $db = \OC::$server->getDatabaseConnection();
+ /** @var Principal | \PHPUnit_Framework_MockObject_MockObject $principal */
+ $principal = $this->createMock(Principal::class);
+
+ /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $output */
+ $output = $this->createMock(IOutput::class);
+
+ $repair = new RemoveInvalidShares($db, $principal);
+ $this->assertEquals("Remove invalid calendar and addressbook shares", $repair->getName());
+ $repair->run($output);
+
+ $query = $db->getQueryBuilder();
+ $result = $query->select('*')->from('dav_shares')
+ ->where($query->expr()->eq('principaluri', $query->createNamedParameter('principal:unknown')))->execute();
+ $data = $result->fetchAll();
+ $result->closeCursor();
+ $this->assertEquals(0, count($data));
+ }
+}