summaryrefslogtreecommitdiffstats
path: root/apps
diff options
context:
space:
mode:
authorRoeland Jago Douma <roeland@famdouma.nl>2018-04-23 14:02:53 +0200
committerJohn Molakvoæ (skjnldsv) <skjnldsv@protonmail.com>2018-05-30 13:27:51 +0200
commit1ea356cd6a56d1e6b25045b6308da6aff0e7bd1d (patch)
tree7415efed97f7850ce60631d8ab9534f6e1d78e4e /apps
parent0f88f3f00eb9347393490ea75d1fc75a8c2e1003 (diff)
downloadnextcloud-server-1ea356cd6a56d1e6b25045b6308da6aff0e7bd1d.tar.gz
nextcloud-server-1ea356cd6a56d1e6b25045b6308da6aff0e7bd1d.zip
Adding repair step which cleans shares of invalid principals
https://github.com/owncloud/core/pull/30149/commits/edacf22fbce4deefc181c53dd84c5fb278a9a28d Signed-off-by: Roeland Jago Douma <roeland@famdouma.nl>
Diffstat (limited to 'apps')
-rw-r--r--apps/dav/appinfo/info.xml3
-rw-r--r--apps/dav/composer/composer/ClassLoader.php15
-rw-r--r--apps/dav/composer/composer/autoload_classmap.php1
-rw-r--r--apps/dav/composer/composer/autoload_static.php10
-rw-r--r--apps/dav/lib/Repair/RemoveInvalidShares.php100
-rw-r--r--apps/dav/tests/unit/Repair/RemoveInvalidSharesTest.php70
6 files changed, 188 insertions, 11 deletions
diff --git a/apps/dav/appinfo/info.xml b/apps/dav/appinfo/info.xml
index 25a0d542e85..a861a6ba0c0 100644
--- a/apps/dav/appinfo/info.xml
+++ b/apps/dav/appinfo/info.xml
@@ -4,8 +4,8 @@
<name>WebDAV</name>
<description>WebDAV endpoint</description>
<licence>AGPL</licence>
+ <version>1.4.7</version>
<author>owncloud.org</author>
- <version>1.4.6</version>
<default_enable/>
<types>
<filesystem/>
@@ -22,6 +22,7 @@
<step>OCA\DAV\Migration\FixBirthdayCalendarComponent</step>
<step>OCA\DAV\Migration\CalDAVRemoveEmptyValue</step>
<step>OCA\DAV\Migration\BuildCalendarSearchIndex</step>
+ <step>OCA\DAV\Repair\RemoveInvalidShares</step>
</post-migration>
</repair-steps>
<commands>
diff --git a/apps/dav/composer/composer/ClassLoader.php b/apps/dav/composer/composer/ClassLoader.php
index c6f6d2322bb..dc02dfb114f 100644
--- a/apps/dav/composer/composer/ClassLoader.php
+++ b/apps/dav/composer/composer/ClassLoader.php
@@ -43,8 +43,7 @@ namespace Composer\Autoload;
class ClassLoader
{
// PSR-4
- private $firstCharsPsr4 = array();
- private $prefixLengthsPsr4 = array(); // For BC with legacy static maps
+ private $prefixLengthsPsr4 = array();
private $prefixDirsPsr4 = array();
private $fallbackDirsPsr4 = array();
@@ -171,10 +170,11 @@ class ClassLoader
}
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
// Register directories for a new namespace.
- if ('\\' !== substr($prefix, -1)) {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
- $this->firstCharsPsr4[$prefix[0]] = true;
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
} elseif ($prepend) {
// Prepend directories for an already registered namespace.
@@ -221,10 +221,11 @@ class ClassLoader
if (!$prefix) {
$this->fallbackDirsPsr4 = (array) $paths;
} else {
- if ('\\' !== substr($prefix, -1)) {
+ $length = strlen($prefix);
+ if ('\\' !== $prefix[$length - 1]) {
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
}
- $this->firstCharsPsr4[$prefix[0]] = true;
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
$this->prefixDirsPsr4[$prefix] = (array) $paths;
}
}
@@ -372,7 +373,7 @@ class ClassLoader
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
$first = $class[0];
- if (isset($this->firstCharsPsr4[$first]) || isset($this->prefixLengthsPsr4[$first])) {
+ if (isset($this->prefixLengthsPsr4[$first])) {
$subPath = $class;
while (false !== $lastPos = strrpos($subPath, '\\')) {
$subPath = substr($subPath, 0, $lastPos);
diff --git a/apps/dav/composer/composer/autoload_classmap.php b/apps/dav/composer/composer/autoload_classmap.php
index 0bf6b25751e..7419c5d709c 100644
--- a/apps/dav/composer/composer/autoload_classmap.php
+++ b/apps/dav/composer/composer/autoload_classmap.php
@@ -133,6 +133,7 @@ return array(
'OCA\\DAV\\Migration\\Version1004Date20170919104507' => $baseDir . '/../lib/Migration/Version1004Date20170919104507.php',
'OCA\\DAV\\Migration\\Version1004Date20170924124212' => $baseDir . '/../lib/Migration/Version1004Date20170924124212.php',
'OCA\\DAV\\Migration\\Version1004Date20170926103422' => $baseDir . '/../lib/Migration/Version1004Date20170926103422.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 41fea367ee5..9bb554eff01 100644
--- a/apps/dav/composer/composer/autoload_static.php
+++ b/apps/dav/composer/composer/autoload_static.php
@@ -6,8 +6,11 @@ namespace Composer\Autoload;
class ComposerStaticInitDAV
{
- public static $firstCharsPsr4 = array (
- 'O' => true,
+ public static $prefixLengthsPsr4 = array (
+ 'O' =>
+ array (
+ 'OCA\\DAV\\' => 8,
+ ),
);
public static $prefixDirsPsr4 = array (
@@ -145,6 +148,7 @@ class ComposerStaticInitDAV
'OCA\\DAV\\Migration\\Version1004Date20170919104507' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170919104507.php',
'OCA\\DAV\\Migration\\Version1004Date20170924124212' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170924124212.php',
'OCA\\DAV\\Migration\\Version1004Date20170926103422' => __DIR__ . '/..' . '/../lib/Migration/Version1004Date20170926103422.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',
@@ -166,7 +170,7 @@ class ComposerStaticInitDAV
public static function getInitializer(ClassLoader $loader)
{
return \Closure::bind(function () use ($loader) {
- $loader->firstCharsPsr4 = ComposerStaticInitDAV::$firstCharsPsr4;
+ $loader->prefixLengthsPsr4 = ComposerStaticInitDAV::$prefixLengthsPsr4;
$loader->prefixDirsPsr4 = ComposerStaticInitDAV::$prefixDirsPsr4;
$loader->classMap = ComposerStaticInitDAV::$classMap;
diff --git a/apps/dav/lib/Repair/RemoveInvalidShares.php b/apps/dav/lib/Repair/RemoveInvalidShares.php
new file mode 100644
index 00000000000..b69f918a576
--- /dev/null
+++ b/apps/dav/lib/Repair/RemoveInvalidShares.php
@@ -0,0 +1,100 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+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 00000000000..14553740f38
--- /dev/null
+++ b/apps/dav/tests/unit/Repair/RemoveInvalidSharesTest.php
@@ -0,0 +1,70 @@
+<?php
+/**
+ * @author Thomas Müller <thomas.mueller@tmit.eu>
+ *
+ * @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 <http://www.gnu.org/licenses/>
+ *
+ */
+
+
+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));
+ }
+}