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)); + } +}