From 2bbf3b18d90301e4c1afc8deb5ef0cf9b91a6ff9 Mon Sep 17 00:00:00 2001 From: Morris Jobke Date: Wed, 22 Feb 2017 22:20:56 -0600 Subject: [PATCH] cleanup old and not needed repair steps to speed up the update Signed-off-by: Morris Jobke --- lib/composer/composer/autoload_classmap.php | 12 - lib/composer/composer/autoload_static.php | 12 - lib/private/Repair.php | 35 -- lib/private/Repair/AssetCache.php | 43 -- lib/private/Repair/DropOldJobs.php | 88 --- lib/private/Repair/DropOldTables.php | 111 ---- lib/private/Repair/FillETags.php | 57 -- lib/private/Repair/InnoDB.php | 70 --- lib/private/Repair/Preview.php | 48 -- lib/private/Repair/RemoveGetETagEntries.php | 58 -- lib/private/Repair/RemoveOldShares.php | 104 ---- lib/private/Repair/RepairInvalidShares.php | 45 -- lib/private/Repair/RepairMimeTypes.php | 258 -------- lib/private/Repair/RepairUnmergedShares.php | 357 ----------- lib/private/Repair/SearchLuceneTables.php | 80 --- lib/private/Repair/SharePropagation.php | 56 -- lib/private/Repair/UpdateOutdatedOcsIds.php | 106 ---- tests/lib/Repair/DropOldJobsTest.php | 48 -- tests/lib/Repair/DropOldTablesTest.php | 46 -- tests/lib/Repair/RemoveGetETagEntriesTest.php | 90 --- tests/lib/Repair/RemoveOldSharesTest.php | 160 ----- tests/lib/Repair/RepairInnoDBTest.php | 78 --- tests/lib/Repair/RepairInvalidSharesTest.php | 153 +---- tests/lib/Repair/RepairMimeTypesTest.php | 359 +---------- .../lib/Repair/RepairSharePropagationTest.php | 58 -- tests/lib/Repair/RepairUnmergedSharesTest.php | 575 ------------------ tests/lib/Repair/UpdateOutdatedOcsIdsTest.php | 80 --- tests/lib/Repair/fixtures/dropoldtables.xml | 24 - 28 files changed, 19 insertions(+), 3192 deletions(-) delete mode 100644 lib/private/Repair/AssetCache.php delete mode 100644 lib/private/Repair/DropOldJobs.php delete mode 100644 lib/private/Repair/DropOldTables.php delete mode 100644 lib/private/Repair/FillETags.php delete mode 100644 lib/private/Repair/InnoDB.php delete mode 100644 lib/private/Repair/Preview.php delete mode 100644 lib/private/Repair/RemoveGetETagEntries.php delete mode 100644 lib/private/Repair/RemoveOldShares.php delete mode 100644 lib/private/Repair/RepairUnmergedShares.php delete mode 100644 lib/private/Repair/SearchLuceneTables.php delete mode 100644 lib/private/Repair/SharePropagation.php delete mode 100644 lib/private/Repair/UpdateOutdatedOcsIds.php delete mode 100644 tests/lib/Repair/DropOldJobsTest.php delete mode 100644 tests/lib/Repair/DropOldTablesTest.php delete mode 100644 tests/lib/Repair/RemoveGetETagEntriesTest.php delete mode 100644 tests/lib/Repair/RemoveOldSharesTest.php delete mode 100644 tests/lib/Repair/RepairInnoDBTest.php delete mode 100644 tests/lib/Repair/RepairSharePropagationTest.php delete mode 100644 tests/lib/Repair/RepairUnmergedSharesTest.php delete mode 100644 tests/lib/Repair/UpdateOutdatedOcsIdsTest.php delete mode 100644 tests/lib/Repair/fixtures/dropoldtables.xml diff --git a/lib/composer/composer/autoload_classmap.php b/lib/composer/composer/autoload_classmap.php index eec6d23dce..19eb4ca7df 100644 --- a/lib/composer/composer/autoload_classmap.php +++ b/lib/composer/composer/autoload_classmap.php @@ -679,13 +679,8 @@ return array( 'OC\\RedisFactory' => $baseDir . '/lib/private/RedisFactory.php', 'OC\\Repair' => $baseDir . '/lib/private/Repair.php', 'OC\\RepairException' => $baseDir . '/lib/private/RepairException.php', - 'OC\\Repair\\AssetCache' => $baseDir . '/lib/private/Repair/AssetCache.php', 'OC\\Repair\\CleanTags' => $baseDir . '/lib/private/Repair/CleanTags.php', 'OC\\Repair\\Collation' => $baseDir . '/lib/private/Repair/Collation.php', - 'OC\\Repair\\DropOldJobs' => $baseDir . '/lib/private/Repair/DropOldJobs.php', - 'OC\\Repair\\DropOldTables' => $baseDir . '/lib/private/Repair/DropOldTables.php', - 'OC\\Repair\\FillETags' => $baseDir . '/lib/private/Repair/FillETags.php', - 'OC\\Repair\\InnoDB' => $baseDir . '/lib/private/Repair/InnoDB.php', 'OC\\Repair\\MoveUpdaterStepFile' => $baseDir . '/lib/private/Repair/MoveUpdaterStepFile.php', 'OC\\Repair\\NC11\\CleanPreviews' => $baseDir . '/lib/private/Repair/NC11/CleanPreviews.php', 'OC\\Repair\\NC11\\CleanPreviewsBackgroundJob' => $baseDir . '/lib/private/Repair/NC11/CleanPreviewsBackgroundJob.php', @@ -693,17 +688,10 @@ return array( 'OC\\Repair\\NC11\\MoveAvatars' => $baseDir . '/lib/private/Repair/NC11/MoveAvatars.php', 'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => $baseDir . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php', 'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php', - 'OC\\Repair\\Preview' => $baseDir . '/lib/private/Repair/Preview.php', - 'OC\\Repair\\RemoveGetETagEntries' => $baseDir . '/lib/private/Repair/RemoveGetETagEntries.php', - 'OC\\Repair\\RemoveOldShares' => $baseDir . '/lib/private/Repair/RemoveOldShares.php', 'OC\\Repair\\RemoveRootShares' => $baseDir . '/lib/private/Repair/RemoveRootShares.php', 'OC\\Repair\\RepairInvalidShares' => $baseDir . '/lib/private/Repair/RepairInvalidShares.php', 'OC\\Repair\\RepairMimeTypes' => $baseDir . '/lib/private/Repair/RepairMimeTypes.php', - 'OC\\Repair\\RepairUnmergedShares' => $baseDir . '/lib/private/Repair/RepairUnmergedShares.php', - 'OC\\Repair\\SearchLuceneTables' => $baseDir . '/lib/private/Repair/SearchLuceneTables.php', - 'OC\\Repair\\SharePropagation' => $baseDir . '/lib/private/Repair/SharePropagation.php', 'OC\\Repair\\SqliteAutoincrement' => $baseDir . '/lib/private/Repair/SqliteAutoincrement.php', - 'OC\\Repair\\UpdateOutdatedOcsIds' => $baseDir . '/lib/private/Repair/UpdateOutdatedOcsIds.php', 'OC\\RichObjectStrings\\Validator' => $baseDir . '/lib/private/RichObjectStrings/Validator.php', 'OC\\Route\\CachingRouter' => $baseDir . '/lib/private/Route/CachingRouter.php', 'OC\\Route\\Route' => $baseDir . '/lib/private/Route/Route.php', diff --git a/lib/composer/composer/autoload_static.php b/lib/composer/composer/autoload_static.php index 9967b709c3..e1b5e025d0 100644 --- a/lib/composer/composer/autoload_static.php +++ b/lib/composer/composer/autoload_static.php @@ -709,13 +709,8 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\RedisFactory' => __DIR__ . '/../../..' . '/lib/private/RedisFactory.php', 'OC\\Repair' => __DIR__ . '/../../..' . '/lib/private/Repair.php', 'OC\\RepairException' => __DIR__ . '/../../..' . '/lib/private/RepairException.php', - 'OC\\Repair\\AssetCache' => __DIR__ . '/../../..' . '/lib/private/Repair/AssetCache.php', 'OC\\Repair\\CleanTags' => __DIR__ . '/../../..' . '/lib/private/Repair/CleanTags.php', 'OC\\Repair\\Collation' => __DIR__ . '/../../..' . '/lib/private/Repair/Collation.php', - 'OC\\Repair\\DropOldJobs' => __DIR__ . '/../../..' . '/lib/private/Repair/DropOldJobs.php', - 'OC\\Repair\\DropOldTables' => __DIR__ . '/../../..' . '/lib/private/Repair/DropOldTables.php', - 'OC\\Repair\\FillETags' => __DIR__ . '/../../..' . '/lib/private/Repair/FillETags.php', - 'OC\\Repair\\InnoDB' => __DIR__ . '/../../..' . '/lib/private/Repair/InnoDB.php', 'OC\\Repair\\MoveUpdaterStepFile' => __DIR__ . '/../../..' . '/lib/private/Repair/MoveUpdaterStepFile.php', 'OC\\Repair\\NC11\\CleanPreviews' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/CleanPreviews.php', 'OC\\Repair\\NC11\\CleanPreviewsBackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/CleanPreviewsBackgroundJob.php', @@ -723,17 +718,10 @@ class ComposerStaticInit53792487c5a8370acc0b06b1a864ff4c 'OC\\Repair\\NC11\\MoveAvatars' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatars.php', 'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php', 'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php', - 'OC\\Repair\\Preview' => __DIR__ . '/../../..' . '/lib/private/Repair/Preview.php', - 'OC\\Repair\\RemoveGetETagEntries' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveGetETagEntries.php', - 'OC\\Repair\\RemoveOldShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveOldShares.php', 'OC\\Repair\\RemoveRootShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveRootShares.php', 'OC\\Repair\\RepairInvalidShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairInvalidShares.php', 'OC\\Repair\\RepairMimeTypes' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairMimeTypes.php', - 'OC\\Repair\\RepairUnmergedShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairUnmergedShares.php', - 'OC\\Repair\\SearchLuceneTables' => __DIR__ . '/../../..' . '/lib/private/Repair/SearchLuceneTables.php', - 'OC\\Repair\\SharePropagation' => __DIR__ . '/../../..' . '/lib/private/Repair/SharePropagation.php', 'OC\\Repair\\SqliteAutoincrement' => __DIR__ . '/../../..' . '/lib/private/Repair/SqliteAutoincrement.php', - 'OC\\Repair\\UpdateOutdatedOcsIds' => __DIR__ . '/../../..' . '/lib/private/Repair/UpdateOutdatedOcsIds.php', 'OC\\RichObjectStrings\\Validator' => __DIR__ . '/../../..' . '/lib/private/RichObjectStrings/Validator.php', 'OC\\Route\\CachingRouter' => __DIR__ . '/../../..' . '/lib/private/Route/CachingRouter.php', 'OC\\Route\\Route' => __DIR__ . '/../../..' . '/lib/private/Route/Route.php', diff --git a/lib/private/Repair.php b/lib/private/Repair.php index e8d466cd84..6344db64e8 100644 --- a/lib/private/Repair.php +++ b/lib/private/Repair.php @@ -30,28 +30,17 @@ namespace OC; -use OC\Repair\AssetCache; use OC\Repair\CleanTags; use OC\Repair\Collation; -use OC\Repair\DropOldJobs; use OC\Repair\MoveUpdaterStepFile; use OC\Repair\NC11\CleanPreviews; use OC\Repair\NC11\FixMountStorages; use OC\Repair\NC11\MoveAvatars; use OC\Repair\OldGroupMembershipShares; -use OC\Repair\RemoveGetETagEntries; -use OC\Repair\RemoveOldShares; use OC\Repair\RemoveRootShares; -use OC\Repair\SharePropagation; use OC\Repair\SqliteAutoincrement; -use OC\Repair\DropOldTables; -use OC\Repair\FillETags; -use OC\Repair\InnoDB; use OC\Repair\RepairMimeTypes; -use OC\Repair\SearchLuceneTables; -use OC\Repair\UpdateOutdatedOcsIds; use OC\Repair\RepairInvalidShares; -use OC\Repair\RepairUnmergedShares; use OCP\AppFramework\QueryException; use OCP\Migration\IOutput; use OCP\Migration\IRepairStep; @@ -131,23 +120,9 @@ class Repair implements IOutput{ return [ new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), \OC::$server->getDatabaseConnection(), false), new RepairMimeTypes(\OC::$server->getConfig()), - new AssetCache(), - new FillETags(\OC::$server->getDatabaseConnection()), new CleanTags(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager()), - new DropOldTables(\OC::$server->getDatabaseConnection()), - new DropOldJobs(\OC::$server->getJobList()), - new RemoveGetETagEntries(\OC::$server->getDatabaseConnection()), - new UpdateOutdatedOcsIds(\OC::$server->getConfig()), new RepairInvalidShares(\OC::$server->getConfig(), \OC::$server->getDatabaseConnection()), - new SharePropagation(\OC::$server->getConfig()), - new RemoveOldShares(\OC::$server->getDatabaseConnection()), new RemoveRootShares(\OC::$server->getDatabaseConnection(), \OC::$server->getUserManager(), \OC::$server->getLazyRootFolder()), - new RepairUnmergedShares( - \OC::$server->getConfig(), - \OC::$server->getDatabaseConnection(), - \OC::$server->getUserManager(), - \OC::$server->getGroupManager() - ), new MoveUpdaterStepFile(\OC::$server->getConfig()), new MoveAvatars( \OC::$server->getJobList(), @@ -183,20 +158,10 @@ class Repair implements IOutput{ public static function getBeforeUpgradeRepairSteps() { $connection = \OC::$server->getDatabaseConnection(); $steps = [ - new InnoDB(), new Collation(\OC::$server->getConfig(), \OC::$server->getLogger(), $connection, true), new SqliteAutoincrement($connection), - new SearchLuceneTables(), ]; - //There is no need to delete all previews on every single update - //only 7.0.0 through 7.0.2 generated broken previews - $currentVersion = \OC::$server->getConfig()->getSystemValue('version'); - if (version_compare($currentVersion, '7.0.0.0', '>=') && - version_compare($currentVersion, '7.0.3.4', '<=')) { - $steps[] = new \OC\Repair\Preview(); - } - return $steps; } diff --git a/lib/private/Repair/AssetCache.php b/lib/private/Repair/AssetCache.php deleted file mode 100644 index 74eb9c5198..0000000000 --- a/lib/private/Repair/AssetCache.php +++ /dev/null @@ -1,43 +0,0 @@ - - * @author Morris Jobke - * @author Roeland Jago Douma - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class AssetCache implements IRepairStep { - - public function getName() { - return 'Remove asset cache'; - } - - public function run(IOutput $output) { - $assetDir = \OC::$server->getConfig()->getSystemValue('assetdirectory', \OC::$SERVERROOT) . '/assets'; - \OC_Helper::rmdirr($assetDir, false); - $output->info('Asset cache cleared.'); - } -} - diff --git a/lib/private/Repair/DropOldJobs.php b/lib/private/Repair/DropOldJobs.php deleted file mode 100644 index 126df9e940..0000000000 --- a/lib/private/Repair/DropOldJobs.php +++ /dev/null @@ -1,88 +0,0 @@ - - * @author Joas Schilling - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\BackgroundJob\IJobList; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class DropOldJobs implements IRepairStep { - - /** @var IJobList */ - protected $jobList; - - /** - * @param IJobList $jobList - */ - public function __construct(IJobList $jobList) { - $this->jobList = $jobList; - } - - /** - * Returns the step's name - * - * @return string - */ - public function getName() { - return 'Drop old background jobs'; - } - - /** - * Run repair step. - * Must throw exception on error. - * - * @throws \Exception in case of failure - */ - public function run(IOutput $output) { - $oldJobs = $this->oldJobs(); - foreach($oldJobs as $job) { - if($this->jobList->has($job['class'], $job['arguments'])) { - $this->jobList->remove($job['class'], $job['arguments']); - } - } - } - - /** - * returns a list of old jobs as an associative array with keys 'class' and - * 'arguments'. - * - * @return array - */ - public function oldJobs() { - return [ - ['class' => 'OC_Cache_FileGlobalGC', 'arguments' => null], - ['class' => 'OC\Cache\FileGlobalGC', 'arguments' => null], - ['class' => 'OCA\Files\BackgroundJob\DeleteOrphanedTagsJob', 'arguments' => null], - - ['class' => 'OCA\Files_sharing\Lib\DeleteOrphanedSharesJob', 'arguments' => null], - ['class' => 'OCA\Files_sharing\ExpireSharesJob', 'arguments' => null], - - ['class' => 'OCA\user_ldap\lib\Jobs', 'arguments' => null], - ['class' => '\OCA\User_LDAP\Jobs\CleanUp', 'arguments' => null], - ]; - } - - -} diff --git a/lib/private/Repair/DropOldTables.php b/lib/private/Repair/DropOldTables.php deleted file mode 100644 index dfc3f757ea..0000000000 --- a/lib/private/Repair/DropOldTables.php +++ /dev/null @@ -1,111 +0,0 @@ - - * @author Joas Schilling - * @author Morris Jobke - * @author Thomas Müller - * - * @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 OC\Repair; - - -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class DropOldTables implements IRepairStep { - - /** @var IDBConnection */ - protected $connection; - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - /** - * Returns the step's name - * - * @return string - */ - public function getName() { - return 'Drop old database tables'; - } - - /** - * Run repair step. - * Must throw exception on error. - * - * @throws \Exception in case of failure - */ - public function run(IOutput $output) { - $tables = $this->oldDatabaseTables(); - $output->startProgress(count($tables)); - foreach ($this->oldDatabaseTables() as $tableName) { - if ($this->connection->tableExists($tableName)){ - $this->connection->dropTable($tableName); - } - $output->advance(1, "Drop old database table: $tableName"); - } - $output->finishProgress(); - } - - /** - * Returns a list of outdated tables which are not used anymore - * @return array - */ - protected function oldDatabaseTables() { - return [ - 'calendar_calendars', - 'calendar_objects', - 'calendar_share_calendar', - 'calendar_share_event', - 'file_map', - 'foldersize', - 'fscache', - 'gallery_sharing', - 'locks', - 'log', - 'media_albums', - 'media_artists', - 'media_sessions', - 'media_songs', - 'media_users', - 'permissions', - 'pictures_images_cache', - 'principalgroups', - 'principals', - 'queuedtasks', - 'sharing', - 'clndr_calendars', - 'clndr_objects', - 'clndr_share_event', - 'clndr_share_calendar', - 'clndr_repeat', - 'contacts_addressbooks', - 'contacts_cards', - 'contacts_cards_properties', - 'gallery_albums', - 'gallery_photos' - ]; - } -} diff --git a/lib/private/Repair/FillETags.php b/lib/private/Repair/FillETags.php deleted file mode 100644 index 2954c0eaa6..0000000000 --- a/lib/private/Repair/FillETags.php +++ /dev/null @@ -1,57 +0,0 @@ - - * @author Morris Jobke - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class FillETags implements IRepairStep { - - /** @var \OCP\IDBConnection */ - protected $connection; - - /** - * @param \OCP\IDBConnection $connection - */ - public function __construct($connection) { - $this->connection = $connection; - } - - public function getName() { - return 'Generate ETags for file where no ETag is present.'; - } - - public function run(IOutput $output) { - $qb = $this->connection->getQueryBuilder(); - $qb->update('filecache') - ->set('etag', $qb->expr()->literal('xxx')) - ->where($qb->expr()->eq('etag', $qb->expr()->literal(''))) - ->orWhere($qb->expr()->isNull('etag')); - - $result = $qb->execute(); - $output->info("ETags have been fixed for $result files/folders."); - } -} - diff --git a/lib/private/Repair/InnoDB.php b/lib/private/Repair/InnoDB.php deleted file mode 100644 index 174cc33448..0000000000 --- a/lib/private/Repair/InnoDB.php +++ /dev/null @@ -1,70 +0,0 @@ - - * @author Robin Appelman - * @author Thomas Müller - * - * @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 OC\Repair; - -use Doctrine\DBAL\Platforms\MySqlPlatform; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class InnoDB implements IRepairStep { - - public function getName() { - return 'Repair MySQL database engine'; - } - - /** - * Fix mime types - */ - public function run(IOutput $output) { - $connection = \OC::$server->getDatabaseConnection(); - if (!$connection->getDatabasePlatform() instanceof MySqlPlatform) { - $output->info('Not a mysql database -> nothing to do'); - return; - } - - $tables = $this->getAllMyIsamTables($connection); - if (is_array($tables)) { - foreach ($tables as $table) { - $connection->exec("ALTER TABLE $table ENGINE=InnoDB;"); - $output->info("Fixed $table"); - } - } - } - - /** - * @param \Doctrine\DBAL\Connection $connection - * @return string[] - */ - private function getAllMyIsamTables($connection) { - $dbName = \OC::$server->getConfig()->getSystemValue("dbname"); - $result = $connection->fetchArray( - "SELECT table_name FROM information_schema.tables WHERE table_schema = ? AND engine = 'MyISAM' AND TABLE_NAME LIKE \"*PREFIX*%\"", - array($dbName) - ); - - return $result; - } -} - diff --git a/lib/private/Repair/Preview.php b/lib/private/Repair/Preview.php deleted file mode 100644 index 8391c3bf72..0000000000 --- a/lib/private/Repair/Preview.php +++ /dev/null @@ -1,48 +0,0 @@ - - * @author Thomas Müller - * - * @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 OC\Repair; - -use OC\Files\View; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class Preview implements IRepairStep { - - public function getName() { - return 'Cleaning-up broken previews'; - } - - public function run(IOutput $out) { - $view = new View('/'); - $children = $view->getDirectoryContent('/'); - - foreach ($children as $child) { - if ($view->is_dir($child->getPath())) { - $thumbnailsFolder = $child->getPath() . '/thumbnails'; - if ($view->is_dir($thumbnailsFolder)) { - $view->rmdir($thumbnailsFolder); - } - } - } - } -} diff --git a/lib/private/Repair/RemoveGetETagEntries.php b/lib/private/Repair/RemoveGetETagEntries.php deleted file mode 100644 index d701a8f26d..0000000000 --- a/lib/private/Repair/RemoveGetETagEntries.php +++ /dev/null @@ -1,58 +0,0 @@ - - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class RemoveGetETagEntries implements IRepairStep { - - /** - * @var IDBConnection - */ - protected $connection; - - /** - * @param IDBConnection $connection - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - public function getName() { - return 'Remove getetag entries in properties table'; - } - - /** - * Removes all entries with the key "{DAV:}getetag" from the table properties - */ - public function run(IOutput $out) { - $sql = 'DELETE FROM `*PREFIX*properties`' - . ' WHERE `propertyname` = ?'; - $deletedRows = $this->connection->executeUpdate($sql, ['{DAV:}getetag']); - - $out->info('Removed ' . $deletedRows . ' unneeded "{DAV:}getetag" entries from properties table.'); - } -} diff --git a/lib/private/Repair/RemoveOldShares.php b/lib/private/Repair/RemoveOldShares.php deleted file mode 100644 index 32a17189fb..0000000000 --- a/lib/private/Repair/RemoveOldShares.php +++ /dev/null @@ -1,104 +0,0 @@ - - * - * @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 OC\Repair; - -use OCP\IDBConnection; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -/** - * Class RemoveOldShares - * - * @package OC\Repair - */ -class RemoveOldShares implements IRepairStep { - - /** @var IDBConnection */ - protected $connection; - - /** - * RemoveOldCalendarShares constructor. - * - * @param IDBConnection $db - */ - public function __construct(IDBConnection $connection) { - $this->connection = $connection; - } - - /** - * @return string - */ - public function getName() { - return 'Remove old (< 9.0) calendar/contact shares'; - } - - /** - * @param IOutput $output - */ - public function run(IOutput $output) { - $output->startProgress(4); - - $this->removeCalendarShares($output); - $this->removeContactShares($output); - - $output->finishProgress(); - } - - /** - * @param IOutput $output - */ - private function removeCalendarShares(IOutput $output) { - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share') - ->where($qb->expr()->eq('item_type', $qb->createNamedParameter('calendar'))); - $qb->execute(); - - $output->advance(); - - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share') - ->where($qb->expr()->eq('item_type', $qb->createNamedParameter('event'))); - $qb->execute(); - - $output->advance(); - } - - /** - * @param IOutput $output - */ - private function removeContactShares(IOutput $output) { - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share') - ->where($qb->expr()->eq('item_type', $qb->createNamedParameter('contact'))); - $qb->execute(); - - $output->advance(); - - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share') - ->where($qb->expr()->eq('item_type', $qb->createNamedParameter('addressbook'))); - $qb->execute(); - - $output->advance(); - } -} - diff --git a/lib/private/Repair/RepairInvalidShares.php b/lib/private/Repair/RepairInvalidShares.php index 04624c910d..eba66e295c 100644 --- a/lib/private/Repair/RepairInvalidShares.php +++ b/lib/private/Repair/RepairInvalidShares.php @@ -55,43 +55,6 @@ class RepairInvalidShares implements IRepairStep { return 'Repair invalid shares'; } - /** - * Past bugs would make it possible to set an expiration date on user shares even - * though it is not supported. This functions removes the expiration date from such entries. - */ - private function removeExpirationDateFromNonLinkShares(IOutput $out) { - $builder = $this->connection->getQueryBuilder(); - $builder - ->update('share') - ->set('expiration', 'null') - ->where($builder->expr()->isNotNull('expiration')) - ->andWhere($builder->expr()->neq('share_type', $builder->expr()->literal(\OC\Share\Constants::SHARE_TYPE_LINK))); - - $updatedEntries = $builder->execute(); - if ($updatedEntries > 0) { - $out->info('Removed invalid expiration date from ' . $updatedEntries . ' shares'); - } - } - - /** - * In the past link shares with public upload enabled were missing the delete permission. - */ - private function addShareLinkDeletePermission(IOutput $out) { - $oldPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE; - $newPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE; - $builder = $this->connection->getQueryBuilder(); - $builder - ->update('share') - ->set('permissions', $builder->expr()->literal($newPerms)) - ->where($builder->expr()->eq('share_type', $builder->expr()->literal(\OC\Share\Constants::SHARE_TYPE_LINK))) - ->andWhere($builder->expr()->eq('permissions', $builder->expr()->literal($oldPerms))); - - $updatedEntries = $builder->execute(); - if ($updatedEntries > 0) { - $out->info('Fixed link share permissions for ' . $updatedEntries . ' shares'); - } - } - /** * Adjust file share permissions */ @@ -150,14 +113,6 @@ class RepairInvalidShares implements IRepairStep { public function run(IOutput $out) { $ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); - if (version_compare($ocVersionFromBeforeUpdate, '8.2.0.7', '<')) { - // this situation was only possible before 8.2 - $this->removeExpirationDateFromNonLinkShares($out); - } - if (version_compare($ocVersionFromBeforeUpdate, '9.1.0.9', '<')) { - // this situation was only possible before 9.1 - $this->addShareLinkDeletePermission($out); - } if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.11', '<')) { $this->adjustFileSharePermissions($out); } diff --git a/lib/private/Repair/RepairMimeTypes.php b/lib/private/Repair/RepairMimeTypes.php index fbf446a681..534b5ce2c2 100644 --- a/lib/private/Repair/RepairMimeTypes.php +++ b/lib/private/Repair/RepairMimeTypes.php @@ -78,24 +78,6 @@ class RepairMimeTypes implements IRepairStep { '); } - private static function updateWrongStmt() { - return \OC_DB::prepare(' - UPDATE `*PREFIX*filecache` - SET `mimetype` = ( - SELECT `id` - FROM `*PREFIX*mimetypes` - WHERE `mimetype` = ? - ) WHERE `mimetype` = ? - '); - } - - private static function deleteStmt() { - return \OC_DB::prepare(' - DELETE FROM `*PREFIX*mimetypes` - WHERE `id` = ? - '); - } - private static function updateByNameStmt() { return \OC_DB::prepare(' UPDATE `*PREFIX*filecache` @@ -104,34 +86,6 @@ class RepairMimeTypes implements IRepairStep { '); } - private function repairMimetypes($wrongMimetypes) { - foreach ($wrongMimetypes as $wrong => $correct) { - // do we need to remove a wrong mimetype? - $result = \OC_DB::executeAudited(self::getIdStmt(), array($wrong)); - $wrongId = $result->fetchOne(); - - if ($wrongId !== false) { - // do we need to insert the correct mimetype? - $result = \OC_DB::executeAudited(self::existsStmt(), array($correct)); - $exists = $result->fetchOne(); - - if (!is_null($correct)) { - if (!$exists) { - // insert mimetype - \OC_DB::executeAudited(self::insertStmt(), array($correct)); - } - - // change wrong mimetype to correct mimetype in filecache - \OC_DB::executeAudited(self::updateWrongStmt(), array($correct, $wrongId)); - } - - // delete wrong mimetype - \OC_DB::executeAudited(self::deleteStmt(), array($wrongId)); - - } - } - } - private function updateMimetypes($updatedMimetypes) { if (empty($this->folderMimeTypeId)) { $result = \OC_DB::executeAudited(self::getIdStmt(), array('httpd/unix-directory')); @@ -156,158 +110,6 @@ class RepairMimeTypes implements IRepairStep { } } - private function fixOfficeMimeTypes() { - // update wrong mimetypes - $wrongMimetypes = array( - 'application/mspowerpoint' => 'application/vnd.ms-powerpoint', - 'application/msexcel' => 'application/vnd.ms-excel', - ); - - self::repairMimetypes($wrongMimetypes); - - $updatedMimetypes = array( - 'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document', - 'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', - 'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation', - ); - - - // separate doc from docx etc - self::updateMimetypes($updatedMimetypes); - - } - - private function fixApkMimeType() { - $updatedMimetypes = array( - 'apk' => 'application/vnd.android.package-archive', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function fixFontsMimeTypes() { - // update wrong mimetypes - $wrongMimetypes = array( - 'font' => null, - 'font/opentype' => 'application/font-sfnt', - 'application/x-font-ttf' => 'application/font-sfnt', - ); - - self::repairMimetypes($wrongMimetypes); - - $updatedMimetypes = array( - 'ttf' => 'application/font-sfnt', - 'otf' => 'application/font-sfnt', - 'pfb' => 'application/x-font', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function fixPostscriptMimeType() { - $updatedMimetypes = array( - 'eps' => 'application/postscript', - 'ps' => 'application/postscript', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceRawMimeType() { - $updatedMimetypes = array( - 'arw' => 'image/x-dcraw', - 'cr2' => 'image/x-dcraw', - 'dcr' => 'image/x-dcraw', - 'dng' => 'image/x-dcraw', - 'erf' => 'image/x-dcraw', - 'iiq' => 'image/x-dcraw', - 'k25' => 'image/x-dcraw', - 'kdc' => 'image/x-dcraw', - 'mef' => 'image/x-dcraw', - 'nef' => 'image/x-dcraw', - 'orf' => 'image/x-dcraw', - 'pef' => 'image/x-dcraw', - 'raf' => 'image/x-dcraw', - 'rw2' => 'image/x-dcraw', - 'srf' => 'image/x-dcraw', - 'sr2' => 'image/x-dcraw', - 'xrf' => 'image/x-dcraw', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduce3dImagesMimeType() { - $updatedMimetypes = array( - 'jps' => 'image/jpeg', - 'mpo' => 'image/jpeg', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceConfMimeType() { - $updatedMimetypes = array( - 'conf' => 'text/plain', - 'cnf' => 'text/plain', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceYamlMimeType() { - $updatedMimetypes = array( - 'yaml' => 'application/yaml', - 'yml' => 'application/yaml', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceJavaMimeType() { - $updatedMimetypes = array( - 'class' => 'application/java', - 'java' => 'text/x-java-source', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceHppMimeType() { - $updatedMimetypes = array( - 'hpp' => 'text/x-h', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceRssMimeType() { - $updatedMimetypes = array( - 'rss' => 'application/rss+xml', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceRtfMimeType() { - $updatedMimetypes = array( - 'rtf' => 'text/rtf', - ); - - self::updateMimetypes($updatedMimetypes); - } - - private function introduceRichDocumentsMimeTypes() { - $updatedMimetypes = array( - 'lwp' => 'application/vnd.lotus-wordpro', - 'one' => 'application/msonenote', - 'vsd' => 'application/vnd.visio', - 'wpd' => 'application/vnd.wordperfect', - ); - - self::updateMimetypes($updatedMimetypes); - } - private function introduceWindowsProgramTypes() { $updatedMimetypes = array( 'htaccess' => 'text/plain', @@ -328,66 +130,6 @@ class RepairMimeTypes implements IRepairStep { // NOTE TO DEVELOPERS: when adding new mime types, please make sure to // add a version comparison to avoid doing it every time - // only update mime types if necessary as it can be expensive - if (version_compare($ocVersionFromBeforeUpdate, '8.2.0', '<')) { - if ($this->fixOfficeMimeTypes()) { - $out->info('Fixed office mime types'); - } - - if ($this->fixApkMimeType()) { - $out->info('Fixed APK mime type'); - } - - if ($this->fixFontsMimeTypes()) { - $out->info('Fixed fonts mime types'); - } - - if ($this->fixPostscriptMimeType()) { - $out->info('Fixed Postscript mime types'); - } - - if ($this->introduceRawMimeType()) { - $out->info('Fixed Raw mime types'); - } - - if ($this->introduce3dImagesMimeType()) { - $out->info('Fixed 3D images mime types'); - } - - if ($this->introduceConfMimeType()) { - $out->info('Fixed Conf/cnf mime types'); - } - - if ($this->introduceYamlMimeType()) { - $out->info('Fixed Yaml/Yml mime types'); - } - } - - // Mimetype updates from #19272 - if (version_compare($ocVersionFromBeforeUpdate, '8.2.0.8', '<')) { - if ($this->introduceJavaMimeType()) { - $out->info('Fixed java/class mime types'); - } - - if ($this->introduceHppMimeType()) { - $out->info('Fixed hpp mime type'); - } - - if ($this->introduceRssMimeType()) { - $out->info('Fixed rss mime type'); - } - - if ($this->introduceRtfMimeType()) { - $out->info('Fixed rtf mime type'); - } - } - - if (version_compare($ocVersionFromBeforeUpdate, '9.0.0.10', '<')) { - if ($this->introduceRichDocumentsMimeTypes()) { - $out->info('Fixed richdocuments additional office mime types'); - } - } - if (version_compare($ocVersionFromBeforeUpdate, '12.0.0.13', '<') && $this->introduceWindowsProgramTypes()) { $out->info('Fixed windows program mime types'); } diff --git a/lib/private/Repair/RepairUnmergedShares.php b/lib/private/Repair/RepairUnmergedShares.php deleted file mode 100644 index 56d935c74f..0000000000 --- a/lib/private/Repair/RepairUnmergedShares.php +++ /dev/null @@ -1,357 +0,0 @@ - - * - * @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 - * - */ - -namespace OC\Repair; - -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; -use OC\Share\Constants; -use OCP\DB\QueryBuilder\IQueryBuilder; -use OCP\IConfig; -use OCP\IDBConnection; -use OCP\IUserManager; -use OCP\IUser; -use OCP\IGroupManager; -use OC\Share20\DefaultShareProvider; - -/** - * Repairs shares for which the received folder was not properly deduplicated. - * - * An unmerged share can for example happen when sharing a folder with the same - * user through multiple ways, like several groups and also directly, additionally - * to group shares. Since 9.0.0 these would create duplicate entries "folder (2)", - * one for every share. This repair step rearranges them so they only appear as a single - * folder. - */ -class RepairUnmergedShares implements IRepairStep { - - /** @var \OCP\IConfig */ - protected $config; - - /** @var \OCP\IDBConnection */ - protected $connection; - - /** @var IUserManager */ - protected $userManager; - - /** @var IGroupManager */ - protected $groupManager; - - /** @var IQueryBuilder */ - private $queryGetSharesWithUsers; - - /** @var IQueryBuilder */ - private $queryUpdateSharePermissionsAndTarget; - - /** @var IQueryBuilder */ - private $queryUpdateShareInBatch; - - /** - * @param \OCP\IConfig $config - * @param \OCP\IDBConnection $connection - */ - public function __construct( - IConfig $config, - IDBConnection $connection, - IUserManager $userManager, - IGroupManager $groupManager - ) { - $this->connection = $connection; - $this->config = $config; - $this->userManager = $userManager; - $this->groupManager = $groupManager; - } - - public function getName() { - return 'Repair unmerged shares'; - } - - /** - * Builds prepared queries for reuse - */ - private function buildPreparedQueries() { - /** - * Retrieve shares for a given user/group and share type - */ - $query = $this->connection->getQueryBuilder(); - $query - ->select('item_source', 'id', 'file_target', 'permissions', 'parent', 'share_type', 'stime') - ->from('share') - ->where($query->expr()->eq('share_type', $query->createParameter('shareType'))) - ->andWhere($query->expr()->in('share_with', $query->createParameter('shareWiths'))) - ->andWhere($query->expr()->in('item_type', $query->createParameter('itemTypes'))) - ->orderBy('item_source', 'ASC') - ->addOrderBy('stime', 'ASC'); - - $this->queryGetSharesWithUsers = $query; - - /** - * Updates the file_target to the given value for all given share ids. - * - * This updates several shares in bulk which is faster than individually. - */ - $query = $this->connection->getQueryBuilder(); - $query->update('share') - ->set('file_target', $query->createParameter('file_target')) - ->where($query->expr()->in('id', $query->createParameter('ids'))); - - $this->queryUpdateShareInBatch = $query; - - /** - * Updates the share permissions and target path of a single share. - */ - $query = $this->connection->getQueryBuilder(); - $query->update('share') - ->set('permissions', $query->createParameter('permissions')) - ->set('file_target', $query->createParameter('file_target')) - ->where($query->expr()->eq('id', $query->createParameter('shareid'))); - - $this->queryUpdateSharePermissionsAndTarget = $query; - - } - - private function getSharesWithUser($shareType, $shareWiths) { - $groupedShares = []; - - $query = $this->queryGetSharesWithUsers; - $query->setParameter('shareWiths', $shareWiths, IQueryBuilder::PARAM_STR_ARRAY); - $query->setParameter('shareType', $shareType); - $query->setParameter('itemTypes', ['file', 'folder'], IQueryBuilder::PARAM_STR_ARRAY); - - $shares = $query->execute()->fetchAll(); - - // group by item_source - foreach ($shares as $share) { - if (!isset($groupedShares[$share['item_source']])) { - $groupedShares[$share['item_source']] = []; - } - $groupedShares[$share['item_source']][] = $share; - } - return $groupedShares; - } - - private function isPotentialDuplicateName($name) { - return (preg_match('/\(\d+\)(\.[^\.]+)?$/', $name) === 1); - } - - /** - * Decide on the best target name based on all group shares and subshares, - * goal is to increase the likeliness that the chosen name matches what - * the user is expecting. - * - * For this, we discard the entries with parenthesis "(2)". - * In case the user also renamed the duplicates to a legitimate name, this logic - * will still pick the most recent one as it's the one the user is most likely to - * remember renaming. - * - * If no suitable subshare is found, use the least recent group share instead. - * - * @param array $groupShares group share entries - * @param array $subShares sub share entries - * - * @return string chosen target name - */ - private function findBestTargetName($groupShares, $subShares) { - $pickedShare = null; - // sort by stime, this also properly sorts the direct user share if any - @usort($subShares, function($a, $b) { - return ((int)$a['stime'] - (int)$b['stime']); - }); - - foreach ($subShares as $subShare) { - // skip entries that have parenthesis with numbers - if ($this->isPotentialDuplicateName($subShare['file_target'])) { - continue; - } - // pick any share found that would match, the last being the most recent - $pickedShare = $subShare; - } - - // no suitable subshare found - if ($pickedShare === null) { - // use least recent group share target instead - $pickedShare = $groupShares[0]; - } - - return $pickedShare['file_target']; - } - - /** - * Fix the given received share represented by the set of group shares - * and matching sub shares - * - * @param array $groupShares group share entries - * @param array $subShares sub share entries - * - * @return boolean false if the share was not repaired, true if it was - */ - private function fixThisShare($groupShares, $subShares) { - if (empty($subShares)) { - return false; - } - - $groupSharesById = []; - foreach ($groupShares as $groupShare) { - $groupSharesById[$groupShare['id']] = $groupShare; - } - - if ($this->isThisShareValid($groupSharesById, $subShares)) { - return false; - } - - $targetPath = $this->findBestTargetName($groupShares, $subShares); - - // check whether the user opted out completely of all subshares - $optedOut = true; - foreach ($subShares as $subShare) { - if ((int)$subShare['permissions'] !== 0) { - $optedOut = false; - break; - } - } - - $shareIds = []; - foreach ($subShares as $subShare) { - // only if the user deleted some subshares but not all, adjust the permissions of that subshare - if (!$optedOut && (int)$subShare['permissions'] === 0 && (int)$subShare['share_type'] === DefaultShareProvider::SHARE_TYPE_USERGROUP) { - // set permissions from parent group share - $permissions = $groupSharesById[$subShare['parent']]['permissions']; - - // fix permissions and target directly - $query = $this->queryUpdateSharePermissionsAndTarget; - $query->setParameter('shareid', $subShare['id']); - $query->setParameter('file_target', $targetPath); - $query->setParameter('permissions', $permissions); - $query->execute(); - } else { - // gather share ids for bulk target update - if ($subShare['file_target'] !== $targetPath) { - $shareIds[] = (int)$subShare['id']; - } - } - } - - if (!empty($shareIds)) { - $query = $this->queryUpdateShareInBatch; - $query->setParameter('ids', $shareIds, IQueryBuilder::PARAM_INT_ARRAY); - $query->setParameter('file_target', $targetPath); - $query->execute(); - } - - return true; - } - - /** - * Checks whether the number of group shares is balanced with the child subshares. - * If all group shares have exactly one subshare, and the target of every subshare - * is the same, then the share is valid. - * If however there is a group share entry that has no matching subshare, it means - * we're in the bogus situation and the whole share must be repaired - * - * @param array $groupSharesById - * @param array $subShares - * - * @return true if the share is valid, false if it needs repair - */ - private function isThisShareValid($groupSharesById, $subShares) { - $foundTargets = []; - - // every group share needs to have exactly one matching subshare - foreach ($subShares as $subShare) { - $foundTargets[$subShare['file_target']] = true; - if (count($foundTargets) > 1) { - // not all the same target path value => invalid - return false; - } - if (isset($groupSharesById[$subShare['parent']])) { - // remove it from the list as we found it - unset($groupSharesById[$subShare['parent']]); - } - } - - // if we found one subshare per group entry, the set will be empty. - // If not empty, it means that one of the group shares did not have - // a matching subshare entry. - return empty($groupSharesById); - } - - /** - * Detect unmerged received shares and merge them properly - */ - private function fixUnmergedShares(IOutput $out, IUser $user) { - $groups = $this->groupManager->getUserGroupIds($user); - if (empty($groups)) { - // user is in no groups, so can't have received group shares - return; - } - - // get all subshares grouped by item source - $subSharesByItemSource = $this->getSharesWithUser(DefaultShareProvider::SHARE_TYPE_USERGROUP, [$user->getUID()]); - - // because sometimes one wants to give the user more permissions than the group share - $userSharesByItemSource = $this->getSharesWithUser(Constants::SHARE_TYPE_USER, [$user->getUID()]); - - if (empty($subSharesByItemSource) && empty($userSharesByItemSource)) { - // nothing to repair for this user, no need to do extra queries - return; - } - - $groupSharesByItemSource = $this->getSharesWithUser(Constants::SHARE_TYPE_GROUP, $groups); - if (empty($groupSharesByItemSource) && empty($userSharesByItemSource)) { - // nothing to repair for this user - return; - } - - foreach ($groupSharesByItemSource as $itemSource => $groupShares) { - $subShares = []; - if (isset($subSharesByItemSource[$itemSource])) { - $subShares = $subSharesByItemSource[$itemSource]; - } - - if (isset($userSharesByItemSource[$itemSource])) { - // add it to the subshares to get a similar treatment - $subShares = array_merge($subShares, $userSharesByItemSource[$itemSource]); - } - - $this->fixThisShare($groupShares, $subShares); - } - } - - public function run(IOutput $output) { - $ocVersionFromBeforeUpdate = $this->config->getSystemValue('version', '0.0.0'); - if (version_compare($ocVersionFromBeforeUpdate, '9.1.0.16', '<')) { - // this situation was only possible between 9.0.0 and 9.0.3 included - - $function = function(IUser $user) use ($output) { - $this->fixUnmergedShares($output, $user); - $output->advance(); - }; - - $this->buildPreparedQueries(); - - $output->startProgress($this->userManager->countUsers()); - - $this->userManager->callForAllUsers($function); - - $output->finishProgress(); - } - } -} diff --git a/lib/private/Repair/SearchLuceneTables.php b/lib/private/Repair/SearchLuceneTables.php deleted file mode 100644 index 0a06371ce9..0000000000 --- a/lib/private/Repair/SearchLuceneTables.php +++ /dev/null @@ -1,80 +0,0 @@ - - * @author Morris Jobke - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class SearchLuceneTables implements IRepairStep { - - public function getName() { - return 'Repair duplicate entries in oc_lucene_status'; - } - - /** - * Fix duplicate entries in oc_lucene_status - * - * search_lucene prior to v0.5.0 did not have a primary key on the lucene_status table. Newer versions do, which - * causes the migration check to fail because it tries to insert duplicate rows into the new schema. - * - * FIXME Currently, apps don't have a way of repairing anything before the migration check: - * @link https://github.com/owncloud/core/issues/10980 - * - * As a result this repair step needs to live in the core repo, although it belongs into search_lucene: - * @link https://github.com/owncloud/core/issues/10205#issuecomment-54957557 - * - * It will completely remove any rows that make a file id have more than one status: - * fileid | status fileid | status - * --------+-------- will become --------+-------- - * 2 | E 3 | E - * 2 | I - * 3 | E - * - * search_lucene will then reindex the fileids without a status when the next indexing job is executed - */ - public function run(IOutput $out) { - $connection = \OC::$server->getDatabaseConnection(); - if ($connection->tableExists('lucene_status')) { - $out->info('removing duplicate entries from lucene_status'); - - $query = $connection->prepare(' - DELETE FROM `*PREFIX*lucene_status` - WHERE `fileid` IN ( - SELECT `fileid` - FROM ( - SELECT `fileid` - FROM `*PREFIX*lucene_status` - GROUP BY `fileid` - HAVING count(`fileid`) > 1 - ) AS `mysqlerr1093hack` - )'); - $query->execute(); - } else { - $out->info('lucene_status table does not exist -> nothing to do'); - } - } - -} - diff --git a/lib/private/Repair/SharePropagation.php b/lib/private/Repair/SharePropagation.php deleted file mode 100644 index c0cca3bd1a..0000000000 --- a/lib/private/Repair/SharePropagation.php +++ /dev/null @@ -1,56 +0,0 @@ - - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\IConfig; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -class SharePropagation implements IRepairStep { - - /** @var IConfig */ - private $config; - - /** - * SharePropagation constructor. - * - * @param IConfig $config - */ - public function __construct(IConfig $config) { - $this->config = $config; - } - - public function getName() { - return 'Remove old share propagation app entries'; - } - - public function run(IOutput $out ) { - $keys = $this->config->getAppKeys('files_sharing'); - - foreach ($keys as $key) { - if (is_numeric($key)) { - $this->config->deleteAppValue('files_sharing', $key); - } - } - } -} diff --git a/lib/private/Repair/UpdateOutdatedOcsIds.php b/lib/private/Repair/UpdateOutdatedOcsIds.php deleted file mode 100644 index 6f4f2447e9..0000000000 --- a/lib/private/Repair/UpdateOutdatedOcsIds.php +++ /dev/null @@ -1,106 +0,0 @@ - - * @author Thomas Müller - * - * @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 OC\Repair; - -use OCP\IConfig; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -/** - * Class UpdateOutdatedOcsIds is used to update invalid outdated OCS IDs, this is - * for example the case when an application has had another OCS ID in the past such - * as for contacts and calendar when apps.owncloud.com migrated to a unified identifier - * for multiple versions. - * - * @package OC\Repair - */ -class UpdateOutdatedOcsIds implements IRepairStep { - /** @var IConfig */ - private $config; - - /** - * @param IConfig $config - */ - public function __construct(IConfig $config) { - $this->config = $config; - } - - /** - * {@inheritdoc} - */ - public function getName() { - return 'Repair outdated OCS IDs'; - } - - /** - * @param string $appName - * @param string $oldId - * @param string $newId - * @return bool True if updated, false otherwise - */ - public function fixOcsId($appName, $oldId, $newId) { - $existingId = $this->config->getAppValue($appName, 'ocsid'); - - if($existingId === $oldId) { - $this->config->setAppValue($appName, 'ocsid', $newId); - return true; - } - - return false; - } - - /** - * {@inheritdoc} - */ - public function run(IOutput $output) { - $appsToUpdate = [ - 'contacts' => [ - 'old' => '166044', - 'new' => '168708', - ], - 'calendar' => [ - 'old' => '166043', - 'new' => '168707', - ], - 'bookmarks' => [ - 'old' => '166042', - 'new' => '168710', - ], - 'search_lucene' => [ - 'old' => '166057', - 'new' => '168709', - ], - 'documents' => [ - 'old' => '166045', - 'new' => '168711', - ] - ]; - - foreach($appsToUpdate as $appName => $ids) { - if ($this->fixOcsId($appName, $ids['old'], $ids['new'])) { - $output->info("Fixed invalid $appName OCS id"); - } - } - } -} diff --git a/tests/lib/Repair/DropOldJobsTest.php b/tests/lib/Repair/DropOldJobsTest.php deleted file mode 100644 index d83ecbe59c..0000000000 --- a/tests/lib/Repair/DropOldJobsTest.php +++ /dev/null @@ -1,48 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace Test\Repair; - -use OCP\BackgroundJob\IJobList; -use OCP\Migration\IOutput; - -/** - * Tests for the dropping old tables - * - * @group DB - * - * @see \OC\Repair\DropOldTables - */ -class DropOldJobsTest extends \Test\TestCase { - /** @var IJobList */ - protected $jobList; - - protected function setUp() { - parent::setUp(); - - $this->jobList = \OC::$server->getJobList(); - $this->jobList->add('OC\Cache\FileGlobalGC'); - $this->jobList->add('OC_Cache_FileGlobalGC'); - } - - public function testRun() { - $this->assertTrue($this->jobList->has('OC\Cache\FileGlobalGC', null), 'Asserting that the job OC\Cache\FileGlobalGC exists before repairing'); - $this->assertTrue($this->jobList->has('OC_Cache_FileGlobalGC', null), 'Asserting that the job OC_Cache_FileGlobalGC exists before repairing'); - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $repair = new \OC\Repair\DropOldJobs($this->jobList); - $repair->run($outputMock); - - $this->assertFalse($this->jobList->has('OC\Cache\FileGlobalGC', null), 'Asserting that the job OC\Cache\FileGlobalGC does not exist after repairing'); - $this->assertFalse($this->jobList->has('OC_Cache_FileGlobalGC', null), 'Asserting that the job OC_Cache_FileGlobalGC does not exist after repairing'); - } -} diff --git a/tests/lib/Repair/DropOldTablesTest.php b/tests/lib/Repair/DropOldTablesTest.php deleted file mode 100644 index 1f5a4c1529..0000000000 --- a/tests/lib/Repair/DropOldTablesTest.php +++ /dev/null @@ -1,46 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace Test\Repair; -use OCP\Migration\IOutput; - -/** - * Tests for the dropping old tables - * - * @group DB - * - * @see \OC\Repair\DropOldTables - */ -class DropOldTablesTest extends \Test\TestCase { - /** @var \OCP\IDBConnection */ - protected $connection; - - protected function setUp() { - parent::setUp(); - - $this->connection = \OC::$server->getDatabaseConnection(); - $manager = new \OC\DB\MDB2SchemaManager($this->connection); - $manager->createDbFromStructure(__DIR__ . '/fixtures/dropoldtables.xml'); - } - - public function testRun() { - $this->assertFalse($this->connection->tableExists('sharing'), 'Asserting that the table oc_sharing does not exist before repairing'); - $this->assertTrue($this->connection->tableExists('permissions'), 'Asserting that the table oc_permissions does exist before repairing'); - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $repair = new \OC\Repair\DropOldTables($this->connection); - $repair->run($outputMock); - - $this->assertFalse($this->connection->tableExists('sharing'), 'Asserting that the table oc_sharing does not exist after repairing'); - $this->assertFalse($this->connection->tableExists('permissions'), 'Asserting that the table oc_permissions does not exist after repairing'); - } -} diff --git a/tests/lib/Repair/RemoveGetETagEntriesTest.php b/tests/lib/Repair/RemoveGetETagEntriesTest.php deleted file mode 100644 index c00923228d..0000000000 --- a/tests/lib/Repair/RemoveGetETagEntriesTest.php +++ /dev/null @@ -1,90 +0,0 @@ - - * - * @copyright Copyright (c) 2015, 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 - * - */ - -namespace Test\Repair; - -use OC\Repair\RemoveGetETagEntries; -use OCP\Migration\IOutput; -use Test\TestCase; - -/** - * Class RemoveGetETagEntriesTest - * - * @group DB - * - * @package Test\Repair - */ -class RemoveGetETagEntriesTest extends TestCase { - /** @var \OCP\IDBConnection */ - protected $connection; - - protected function setUp() { - parent::setUp(); - - $this->connection = \OC::$server->getDatabaseConnection(); - } - - public function testRun() { - - $userName = 'removePropertiesUser'; - $data = [ - [$userName, '/abc.def.txt', '{DAV:}getetag', 'abcdef'], - [$userName, '/abc.def.txt', '{DAV:}anotherRandomProperty', 'ghi'], - ]; - - // insert test data - $sqlToInsertProperties = 'INSERT INTO `*PREFIX*properties` (`userid`, `propertypath`, `propertyname`, `propertyvalue`) VALUES (?, ?, ? ,?)'; - foreach ($data as $entry) { - $this->connection->executeUpdate($sqlToInsertProperties, $entry); - } - - // check if test data is written to DB - $sqlToFetchProperties = 'SELECT `userid`, `propertypath`, `propertyname`, `propertyvalue` FROM `*PREFIX*properties` WHERE `userid` = ?'; - $stmt = $this->connection->executeQuery($sqlToFetchProperties, [$userName]); - $entries = $stmt->fetchAll(\PDO::FETCH_NUM); - - $this->assertCount(2, $entries, 'Asserts that two entries are returned as we have inserted two'); - foreach($entries as $entry) { - $this->assertTrue(in_array($entry, $data), 'Asserts that the entries are the ones from the test data set'); - } - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - // run repair step - $repair = new RemoveGetETagEntries($this->connection); - $repair->run($outputMock); - - // check if test data is correctly modified in DB - $stmt = $this->connection->executeQuery($sqlToFetchProperties, [$userName]); - $entries = $stmt->fetchAll(\PDO::FETCH_NUM); - - $this->assertCount(1, $entries, 'Asserts that only one entry is returned after the repair step - the other one has to be removed'); - $this->assertSame($data[1], $entries[0], 'Asserts that the returned entry is the correct one from the test data set'); - - // remove test data - $sqlToRemoveProperties = 'DELETE FROM `*PREFIX*properties` WHERE `userid` = ?'; - $this->connection->executeUpdate($sqlToRemoveProperties, [$userName]); - } - -} diff --git a/tests/lib/Repair/RemoveOldSharesTest.php b/tests/lib/Repair/RemoveOldSharesTest.php deleted file mode 100644 index ac30585bdc..0000000000 --- a/tests/lib/Repair/RemoveOldSharesTest.php +++ /dev/null @@ -1,160 +0,0 @@ - - * - * @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 - * - */ -namespace Test\Repair; - -use OC\Repair\RemoveOldShares; -use OCP\IDBConnection; -use OCP\Migration\IOutput; - -/** - * Class RemoveOldSharesTest - * - * @package Test\Repair - * @group DB - */ -class RemoveOldSharesTest extends \Test\TestCase { - - /** @var RemoveOldShares */ - protected $repair; - - /** @var IDBConnection */ - protected $connection; - - /** @var IOutput */ - private $outputMock; - - protected function setUp() { - parent::setUp(); - - $this->outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $this->connection = \OC::$server->getDatabaseConnection(); - $this->repair = new RemoveOldShares($this->connection); - } - - protected function tearDown() { - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share'); - $qb->execute(); - - return parent::tearDown(); - } - - public function testRun() { - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->createNamedParameter(0), - 'share_with' => $qb->createNamedParameter('foo'), - 'uid_owner' => $qb->createNamedParameter('owner'), - 'item_type' => $qb->createNamedParameter('file'), - 'item_source' => $qb->createNamedParameter(42), - 'item_target' => $qb->createNamedParameter('/target'), - 'file_source' => $qb->createNamedParameter(42), - 'file_target' => $qb->createNamedParameter('/target'), - 'permissions' => $qb->createNamedParameter(1), - ]); - $qb->execute(); - - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->createNamedParameter(0), - 'share_with' => $qb->createNamedParameter('foo'), - 'uid_owner' => $qb->createNamedParameter('owner'), - 'item_type' => $qb->createNamedParameter('calendar'), - 'item_source' => $qb->createNamedParameter(42), - 'item_target' => $qb->createNamedParameter('/target'), - 'file_source' => $qb->createNamedParameter(42), - 'file_target' => $qb->createNamedParameter('/target'), - 'permissions' => $qb->createNamedParameter(1), - ]); - $qb->execute(); - - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->createNamedParameter(0), - 'share_with' => $qb->createNamedParameter('foo'), - 'uid_owner' => $qb->createNamedParameter('owner'), - 'item_type' => $qb->createNamedParameter('event'), - 'item_source' => $qb->createNamedParameter(42), - 'item_target' => $qb->createNamedParameter('/target'), - 'file_source' => $qb->createNamedParameter(42), - 'file_target' => $qb->createNamedParameter('/target'), - 'permissions' => $qb->createNamedParameter(1), - ]); - $qb->execute(); - - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->createNamedParameter(0), - 'share_with' => $qb->createNamedParameter('foo'), - 'uid_owner' => $qb->createNamedParameter('owner'), - 'item_type' => $qb->createNamedParameter('contact'), - 'item_source' => $qb->createNamedParameter(42), - 'item_target' => $qb->createNamedParameter('/target'), - 'file_source' => $qb->createNamedParameter(42), - 'file_target' => $qb->createNamedParameter('/target'), - 'permissions' => $qb->createNamedParameter(1), - ]); - $qb->execute(); - - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->createNamedParameter(0), - 'share_with' => $qb->createNamedParameter('foo'), - 'uid_owner' => $qb->createNamedParameter('owner'), - 'item_type' => $qb->createNamedParameter('addressbook'), - 'item_source' => $qb->createNamedParameter(42), - 'item_target' => $qb->createNamedParameter('/target'), - 'file_source' => $qb->createNamedParameter(42), - 'file_target' => $qb->createNamedParameter('/target'), - 'permissions' => $qb->createNamedParameter(1), - ]); - $qb->execute(); - - $qb = $this->connection->getQueryBuilder(); - $qb->selectAlias($qb->createFunction('COUNT(*)'), 'count') - ->from('share'); - - $cursor = $qb->execute(); - $data = $cursor->fetchAll(); - $cursor->closeCursor(); - $this->assertEquals(5, $data[0]['count']); - - $this->repair->run($this->outputMock); - - $qb = $this->connection->getQueryBuilder(); - $qb->select('*') - ->from('share'); - - $cursor = $qb->execute(); - $data = $cursor->fetchAll(); - $cursor->closeCursor(); - $this->assertCount(1, $data); - $this->assertEquals('file', $data[0]['item_type']); - } -} diff --git a/tests/lib/Repair/RepairInnoDBTest.php b/tests/lib/Repair/RepairInnoDBTest.php deleted file mode 100644 index 1258dad73f..0000000000 --- a/tests/lib/Repair/RepairInnoDBTest.php +++ /dev/null @@ -1,78 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ -namespace Test\Repair; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; - -/** - * Tests for the converting of MySQL tables to InnoDB engine - * - * @group DB - * - * @see \OC\Repair\RepairMimeTypes - */ -class RepairInnoDBTest extends \Test\TestCase { - - /** @var IRepairStep */ - private $repair; - - /** @var \Doctrine\DBAL\Connection */ - private $connection; - - /** @var string */ - private $tableName; - - protected function setUp() { - parent::setUp(); - - $this->connection = \OC::$server->getDatabaseConnection(); - if (!$this->connection->getDatabasePlatform() instanceof \Doctrine\DBAL\Platforms\MySqlPlatform) { - $this->markTestSkipped("Test only relevant on MySql"); - } - - $dbPrefix = \OC::$server->getConfig()->getSystemValue("dbtableprefix"); - $this->tableName = $this->getUniqueID($dbPrefix . "_innodb_test"); - $this->connection->exec("CREATE TABLE $this->tableName(id INT) ENGINE MyISAM"); - - $this->repair = new \OC\Repair\InnoDB(); - } - - protected function tearDown() { - $this->connection->getSchemaManager()->dropTable($this->tableName); - parent::tearDown(); - } - - public function testInnoDBConvert() { - $result = $this->countMyIsamTables(); - $this->assertEquals(1, $result); - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $this->repair->run($outputMock); - - $result = $this->countMyIsamTables(); - $this->assertEquals(0, $result); - } - - /** - * @param $dbName - * @return mixed - */ - private function countMyIsamTables() { - $dbName = \OC::$server->getConfig()->getSystemValue("dbname"); - - $result = $this->connection->fetchColumn( - "SELECT count(*) FROM information_schema.tables WHERE table_schema = ? and table_name = ? AND engine = 'MyISAM'", - array($dbName, $this->tableName) - ); - return $result; - } -} diff --git a/tests/lib/Repair/RepairInvalidSharesTest.php b/tests/lib/Repair/RepairInvalidSharesTest.php index 83dbed7d20..fa75f58472 100644 --- a/tests/lib/Repair/RepairInvalidSharesTest.php +++ b/tests/lib/Repair/RepairInvalidSharesTest.php @@ -39,7 +39,7 @@ class RepairInvalidSharesTest extends TestCase { $config->expects($this->any()) ->method('getSystemValue') ->with('version') - ->will($this->returnValue('8.0.0.0')); + ->will($this->returnValue('12.0.0.0')); $this->connection = \OC::$server->getDatabaseConnection(); $this->deleteAllShares(); @@ -59,157 +59,6 @@ class RepairInvalidSharesTest extends TestCase { $qb->delete('share')->execute(); } - /** - * Test remove expiration date for non-link shares - */ - public function testRemoveExpirationDateForNonLinkShares() { - // user share with bogus expiration date - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_USER), - 'share_with' => $qb->expr()->literal('recipientuser1'), - 'uid_owner' => $qb->expr()->literal('user1'), - 'item_type' => $qb->expr()->literal('folder'), - 'item_source' => $qb->expr()->literal(123), - 'item_target' => $qb->expr()->literal('/123'), - 'file_source' => $qb->expr()->literal(123), - 'file_target' => $qb->expr()->literal('/test'), - 'permissions' => $qb->expr()->literal(1), - 'stime' => $qb->expr()->literal(time()), - 'expiration' => $qb->expr()->literal('2015-09-25 00:00:00') - ]) - ->execute(); - - $bogusShareId = $this->getLastShareId(); - - // link share with expiration date - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK), - 'uid_owner' => $qb->expr()->literal('user1'), - 'item_type' => $qb->expr()->literal('folder'), - 'item_source' => $qb->expr()->literal(123), - 'item_target' => $qb->expr()->literal('/123'), - 'file_source' => $qb->expr()->literal(123), - 'file_target' => $qb->expr()->literal('/test'), - 'permissions' => $qb->expr()->literal(1), - 'stime' => $qb->expr()->literal(time()), - 'expiration' => $qb->expr()->literal('2015-09-25 00:00:00'), - 'token' => $qb->expr()->literal('abcdefg') - ])->execute(); - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $this->repair->run($outputMock); - - $results = $this->connection->getQueryBuilder() - ->select('*') - ->from('share') - ->orderBy('share_type', 'ASC') - ->execute() - ->fetchAll(); - - $this->assertCount(2, $results); - - $userShare = $results[0]; - $linkShare = $results[1]; - $this->assertEquals($bogusShareId, $userShare['id'], 'sanity check'); - $this->assertNull($userShare['expiration'], 'bogus expiration date was removed'); - $this->assertNotNull($linkShare['expiration'], 'valid link share expiration date still there'); - } - - /** - * Test remove expiration date for non-link shares - */ - public function testAddShareLinkDeletePermission() { - $oldPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE; - $newPerms = \OCP\Constants::PERMISSION_READ | \OCP\Constants::PERMISSION_CREATE | \OCP\Constants::PERMISSION_UPDATE | \OCP\Constants::PERMISSION_DELETE; - - // share with old permissions - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK), - 'uid_owner' => $qb->expr()->literal('user1'), - 'item_type' => $qb->expr()->literal('folder'), - 'item_source' => $qb->expr()->literal(123), - 'item_target' => $qb->expr()->literal('/123'), - 'file_source' => $qb->expr()->literal(123), - 'file_target' => $qb->expr()->literal('/test'), - 'permissions' => $qb->expr()->literal($oldPerms), - 'stime' => $qb->expr()->literal(time()), - ]) - ->execute(); - - $bogusShareId = $this->getLastShareId(); - - // share with read-only permissions - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_LINK), - 'uid_owner' => $qb->expr()->literal('user1'), - 'item_type' => $qb->expr()->literal('folder'), - 'item_source' => $qb->expr()->literal(123), - 'item_target' => $qb->expr()->literal('/123'), - 'file_source' => $qb->expr()->literal(123), - 'file_target' => $qb->expr()->literal('/test'), - 'permissions' => $qb->expr()->literal(\OCP\Constants::PERMISSION_READ), - 'stime' => $qb->expr()->literal(time()), - ]) - ->execute(); - - $keepThisShareId = $this->getLastShareId(); - - // user share to keep - $qb = $this->connection->getQueryBuilder(); - $qb->insert('share') - ->values([ - 'share_type' => $qb->expr()->literal(Constants::SHARE_TYPE_USER), - 'share_with' => $qb->expr()->literal('recipientuser1'), - 'uid_owner' => $qb->expr()->literal('user1'), - 'item_type' => $qb->expr()->literal('folder'), - 'item_source' => $qb->expr()->literal(123), - 'item_target' => $qb->expr()->literal('/123'), - 'file_source' => $qb->expr()->literal(123), - 'file_target' => $qb->expr()->literal('/test'), - 'permissions' => $qb->expr()->literal(3), - 'stime' => $qb->expr()->literal(time()), - ]) - ->execute(); - - $keepThisShareId2 = $this->getLastShareId(); - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $this->repair->run($outputMock); - - $results = $this->connection->getQueryBuilder() - ->select('*') - ->from('share') - ->orderBy('permissions', 'ASC') - ->execute() - ->fetchAll(); - - $this->assertCount(3, $results); - - $untouchedShare = $results[0]; - $untouchedShare2 = $results[1]; - $updatedShare = $results[2]; - $this->assertEquals($keepThisShareId, $untouchedShare['id'], 'sanity check'); - $this->assertEquals($keepThisShareId2, $untouchedShare2['id'], 'sanity check'); - $this->assertEquals($bogusShareId, $updatedShare['id'], 'sanity check'); - $this->assertEquals($newPerms, $updatedShare['permissions'], 'delete permission was added'); - } - /** * Test remove shares where the parent share does not exist anymore */ diff --git a/tests/lib/Repair/RepairMimeTypesTest.php b/tests/lib/Repair/RepairMimeTypesTest.php index 6a42b01693..ef1412b2fd 100644 --- a/tests/lib/Repair/RepairMimeTypesTest.php +++ b/tests/lib/Repair/RepairMimeTypesTest.php @@ -45,7 +45,7 @@ class RepairMimeTypesTest extends \Test\TestCase { $config->expects($this->any()) ->method('getSystemValue') ->with('version') - ->will($this->returnValue('8.0.0.0')); + ->will($this->returnValue('11.0.0.0')); $this->storage = new \OC\Files\Storage\Temporary([]); @@ -90,20 +90,6 @@ class RepairMimeTypesTest extends \Test\TestCase { } } - /** - * Returns the id of a given mime type or null - * if it does not exist. - */ - private function getMimeTypeIdFromDB($mimeType) { - $sql = 'SELECT `id` FROM `*PREFIX*mimetypes` WHERE `mimetype` = ?'; - $results = \OC_DB::executeAudited($sql, [$mimeType]); - $result = $results->fetchOne(); - if ($result) { - return $result['id']; - } - return null; - } - private function renameMimeTypes($currentMimeTypes, $fixedMimeTypes) { $this->addEntries($currentMimeTypes); @@ -120,344 +106,27 @@ class RepairMimeTypesTest extends \Test\TestCase { $this->checkEntries($fixedMimeTypes); } - /** - * Test renaming and splitting old office mime types - */ - public function testRenameOfficeMimeTypes() { - $currentMimeTypes = [ - ['test.doc', 'application/msword'], - ['test.docx', 'application/msword'], - ['test.xls', 'application/msexcel'], - ['test.xlsx', 'application/msexcel'], - ['test.ppt', 'application/mspowerpoint'], - ['test.pptx', 'application/mspowerpoint'], - ]; - - $fixedMimeTypes = [ - ['test.doc', 'application/msword'], - ['test.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], - ['test.xls', 'application/vnd.ms-excel'], - ['test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], - ['test.ppt', 'application/vnd.ms-powerpoint'], - ['test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming old fonts mime types - */ - public function testRenameFontsMimeTypes() { - $currentMimeTypes = [ - ['test.ttf', 'application/x-font-ttf'], - ['test.otf', 'font/opentype'], - ['test.pfb', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.ttf', 'application/font-sfnt'], - ['test.otf', 'application/font-sfnt'], - ['test.pfb', 'application/x-font'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the APK mime type - */ - public function testRenameAPKMimeType() { - $currentMimeTypes = [ - ['test.apk', 'application/octet-stream'], - ['bogus.apk', 'application/vnd.android.package-archive'], - ['bogus2.apk', 'application/wrong'], - ]; - - $fixedMimeTypes = [ - ['test.apk', 'application/vnd.android.package-archive'], - ['bogus.apk', 'application/vnd.android.package-archive'], - ['bogus2.apk', 'application/vnd.android.package-archive'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the postscript mime types - */ - public function testRenamePostscriptMimeType() { - $currentMimeTypes = [ - ['test.eps', 'application/octet-stream'], - ['test.ps', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.eps', 'application/postscript'], - ['test.ps', 'application/postscript'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the Raw mime types - */ - public function testRenameRawMimeType() { - $currentMimeTypes = [ - ['test.arw', 'application/octet-stream'], - ['test.cr2', 'application/octet-stream'], - ['test.dcr', 'application/octet-stream'], - ['test.dng', 'application/octet-stream'], - ['test.erf', 'application/octet-stream'], - ['test.iiq', 'application/octet-stream'], - ['test.k25', 'application/octet-stream'], - ['test.kdc', 'application/octet-stream'], - ['test.mef', 'application/octet-stream'], - ['test.nef', 'application/octet-stream'], - ['test.orf', 'application/octet-stream'], - ['test.pef', 'application/octet-stream'], - ['test.raf', 'application/octet-stream'], - ['test.rw2', 'application/octet-stream'], - ['test.srf', 'application/octet-stream'], - ['test.sr2', 'application/octet-stream'], - ['test.xrf', 'application/octet-stream'], - ['CapitalExtension.DNG', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.arw', 'image/x-dcraw'], - ['test.cr2', 'image/x-dcraw'], - ['test.dcr', 'image/x-dcraw'], - ['test.dng', 'image/x-dcraw'], - ['test.erf', 'image/x-dcraw'], - ['test.iiq', 'image/x-dcraw'], - ['test.k25', 'image/x-dcraw'], - ['test.kdc', 'image/x-dcraw'], - ['test.mef', 'image/x-dcraw'], - ['test.nef', 'image/x-dcraw'], - ['test.orf', 'image/x-dcraw'], - ['test.pef', 'image/x-dcraw'], - ['test.raf', 'image/x-dcraw'], - ['test.rw2', 'image/x-dcraw'], - ['test.srf', 'image/x-dcraw'], - ['test.sr2', 'image/x-dcraw'], - ['test.xrf', 'image/x-dcraw'], - ['CapitalExtension.DNG', 'image/x-dcraw'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the 3D image media type - */ - public function testRename3dImagesMimeType() { - $currentMimeTypes = [ - ['test.jps', 'application/octet-stream'], - ['test.mpo', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.jps', 'image/jpeg'], - ['test.mpo', 'image/jpeg'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the conf/cnf media type - */ - public function testRenameConfMimeType() { - $currentMimeTypes = [ - ['test.conf', 'application/octet-stream'], - ['test.cnf', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.conf', 'text/plain'], - ['test.cnf', 'text/plain'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the yaml media type - */ - public function testRenameYamlMimeType() { - $currentMimeTypes = [ - ['test.yaml', 'application/octet-stream'], - ['test.yml', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.yaml', 'application/yaml'], - ['test.yml', 'application/yaml'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the java mime types - */ - public function testRenameJavaMimeType() { - $currentMimeTypes = [ - ['test.java', 'application/octet-stream'], - ['test.class', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.java', 'text/x-java-source'], - ['test.class', 'application/java'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the hpp mime type - */ - public function testRenameHppMimeType() { - $currentMimeTypes = [ - ['test.hpp', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.hpp', 'text/x-h'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the rss mime type - */ - public function testRenameRssMimeType() { - $currentMimeTypes = [ - ['test.rss', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.rss', 'application/rss+xml'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - - /** - * Test renaming the hpp mime type - */ - public function testRenameRtfMimeType() { - $currentMimeTypes = [ - ['test.rtf', 'application/octet-stream'], - ]; - - $fixedMimeTypes = [ - ['test.rtf', 'text/rtf'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - } - /** * Test renaming the richdocuments additional office mime types */ - public function testRenameRichDocumentsMimeTypes() { + public function testRenameWindowsProgramTypes() { $currentMimeTypes = [ - ['test.lwp', 'application/octet-stream'], - ['test.one', 'application/octet-stream'], - ['test.vsd', 'application/octet-stream'], - ['test.wpd', 'application/octet-stream'], + ['test.htaccess', 'application/octet-stream'], + ['.htaccess', 'application/octet-stream'], + ['test.bat', 'application/octet-stream'], + ['test.cmd', 'application/octet-stream'], ]; $fixedMimeTypes = [ - ['test.lwp', 'application/vnd.lotus-wordpro'], - ['test.one', 'application/msonenote'], - ['test.vsd', 'application/vnd.visio'], - ['test.wpd', 'application/vnd.wordperfect'], + ['test.htaccess', 'text/plain'], + ['.htaccess', 'text/plain'], + ['test.bat', 'application/x-msdos-program'], + ['test.cmd', 'application/cmd'], ]; $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); } - /** - * Test renaming and splitting old office mime types when - * new ones already exist - */ - public function testRenameOfficeMimeTypesWhenExist() { - $currentMimeTypes = [ - ['test.doc', 'application/msword'], - ['test.docx', 'application/msword'], - ['test.xls', 'application/msexcel'], - ['test.xlsx', 'application/msexcel'], - ['test.ppt', 'application/mspowerpoint'], - ['test.pptx', 'application/mspowerpoint'], - // make it so that the new mimetypes already exist - ['bogus.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], - ['bogus.xlsx', 'application/vnd.ms-excel'], - ['bogus.pptx', 'application/vnd.ms-powerpoint'], - ['bogus2.docx', 'application/wrong'], - ['bogus2.xlsx', 'application/wrong'], - ['bogus2.pptx', 'application/wrong'], - ]; - - $fixedMimeTypes = [ - ['test.doc', 'application/msword'], - ['test.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], - ['test.xls', 'application/vnd.ms-excel'], - ['test.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], - ['test.ppt', 'application/vnd.ms-powerpoint'], - ['test.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], - ['bogus.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], - ['bogus.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], - ['bogus.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], - ['bogus2.docx', 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'], - ['bogus2.xlsx', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'], - ['bogus2.pptx', 'application/vnd.openxmlformats-officedocument.presentationml.presentation'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - - // wrong mimetypes are gone - $this->assertNull($this->getMimeTypeIdFromDB('application/msexcel')); - $this->assertNull($this->getMimeTypeIdFromDB('application/mspowerpoint')); - } - - /** - * Test renaming old fonts mime types when - * new ones already exist - */ - public function testRenameFontsMimeTypesWhenExist() { - $currentMimeTypes = [ - ['test.ttf', 'application/x-font-ttf'], - ['test.otf', 'font/opentype'], - // make it so that the new mimetypes already exist - ['bogus.ttf', 'application/font-sfnt'], - ['bogus.otf', 'application/font-sfnt'], - ['bogus2.ttf', 'application/wrong'], - ['bogus2.otf', 'application/wrong'], - ]; - - $fixedMimeTypes = [ - ['test.ttf', 'application/font-sfnt'], - ['test.otf', 'application/font-sfnt'], - ['bogus.ttf', 'application/font-sfnt'], - ['bogus.otf', 'application/font-sfnt'], - ['bogus2.ttf', 'application/font-sfnt'], - ['bogus2.otf', 'application/font-sfnt'], - ]; - - $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); - - // wrong mimetypes are gone - $this->assertNull($this->getMimeTypeIdFromDB('application/x-font-ttf')); - $this->assertNull($this->getMimeTypeIdFromDB('font')); - $this->assertNull($this->getMimeTypeIdFromDB('font/opentype')); - } - /** * Test that nothing happens and no error happens when all mimetypes are * already correct and no old ones exist.. @@ -509,6 +178,10 @@ class RepairMimeTypesTest extends \Test\TestCase { ['test.one', 'application/msonenote'], ['test.vsd', 'application/vnd.visio'], ['test.wpd', 'application/vnd.wordperfect'], + ['test.htaccess', 'text/plain'], + ['.htaccess', 'text/plain'], + ['test.bat', 'application/x-msdos-program'], + ['test.cmd', 'application/cmd'], ]; $fixedMimeTypes = [ @@ -557,6 +230,10 @@ class RepairMimeTypesTest extends \Test\TestCase { ['test.one', 'application/msonenote'], ['test.vsd', 'application/vnd.visio'], ['test.wpd', 'application/vnd.wordperfect'], + ['test.htaccess', 'text/plain'], + ['.htaccess', 'text/plain'], + ['test.bat', 'application/x-msdos-program'], + ['test.cmd', 'application/cmd'], ]; $this->renameMimeTypes($currentMimeTypes, $fixedMimeTypes); diff --git a/tests/lib/Repair/RepairSharePropagationTest.php b/tests/lib/Repair/RepairSharePropagationTest.php deleted file mode 100644 index d6010cf570..0000000000 --- a/tests/lib/Repair/RepairSharePropagationTest.php +++ /dev/null @@ -1,58 +0,0 @@ - - * This file is licensed under the Affero General Public License version 3 or - * later. - * See the COPYING-README file. - */ - -namespace Test\Repair; - -use OC\Repair\SharePropagation; -use OCP\IConfig; -use OCP\Migration\IOutput; - -class RepairSharePropagationTest extends \Test\TestCase { - public function keyProvider() { - return [ - [['1', '2'], ['1', '2']], - [['1', '2', 'foo'], ['1', '2']], - [['foo'], []], - ]; - } - - /** - * @dataProvider keyProvider - * @param array $startKeys - * @param array $expectedRemovedKeys - */ - public function testRemovePropagationEntries(array $startKeys, array $expectedRemovedKeys) { - /** @var \PHPUnit_Framework_MockObject_MockObject|\OCP\IConfig $config */ - $config = $this->createMock(IConfig::class); - $config->expects($this->once()) - ->method('getAppKeys') - ->with('files_sharing') - ->will($this->returnValue($startKeys)); - - $removedKeys = []; - - $config->expects($this->any()) - ->method('deleteAppValue') - ->will($this->returnCallback(function ($app, $key) use (&$removedKeys) { - $removedKeys[] = $key; - })); - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $step = new SharePropagation($config); - $step->run($outputMock); - - sort($expectedRemovedKeys); - sort($removedKeys); - - $this->assertEquals($expectedRemovedKeys, $removedKeys); - } -} diff --git a/tests/lib/Repair/RepairUnmergedSharesTest.php b/tests/lib/Repair/RepairUnmergedSharesTest.php deleted file mode 100644 index 2834cfe94b..0000000000 --- a/tests/lib/Repair/RepairUnmergedSharesTest.php +++ /dev/null @@ -1,575 +0,0 @@ - - * - * @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 - * - */ - -namespace Test\Repair; - - -use OC\Repair\RepairUnmergedShares; -use OC\Share\Constants; -use OCP\IUser; -use OCP\Migration\IOutput; -use OCP\Migration\IRepairStep; -use Test\TestCase; -use OC\Share20\DefaultShareProvider; -use OCP\IUserManager; -use OCP\IGroupManager; - -/** - * Tests for repairing invalid shares - * - * @group DB - * - * @see \OC\Repair\RepairUnmergedShares - */ -class RepairUnmergedSharesTest extends TestCase { - - /** @var IRepairStep */ - private $repair; - - /** @var \OCP\IDBConnection */ - private $connection; - - /** @var int */ - private $lastShareTime; - - /** @var IUserManager */ - private $userManager; - - /** @var IGroupManager */ - private $groupManager; - - protected function setUp() { - parent::setUp(); - - $config = $this->getMockBuilder('OCP\IConfig') - ->disableOriginalConstructor() - ->getMock(); - $config->expects($this->any()) - ->method('getSystemValue') - ->with('version') - ->will($this->returnValue('9.0.3.0')); - - $this->connection = \OC::$server->getDatabaseConnection(); - $this->deleteAllShares(); - - $this->userManager = $this->createMock(IUserManager::class); - $this->groupManager = $this->createMock(IGroupManager::class); - - // used to generate incremental stimes - $this->lastShareTime = time(); - - /** @var \OCP\IConfig $config */ - $this->repair = new RepairUnmergedShares($config, $this->connection, $this->userManager, $this->groupManager); - } - - protected function tearDown() { - $this->deleteAllShares(); - - parent::tearDown(); - } - - protected function deleteAllShares() { - $qb = $this->connection->getQueryBuilder(); - $qb->delete('share')->execute(); - } - - private function createShare($type, $sourceId, $recipient, $targetName, $permissions, $parentId = null) { - $this->lastShareTime += 100; - $qb = $this->connection->getQueryBuilder(); - $values = [ - 'share_type' => $qb->expr()->literal($type), - 'share_with' => $qb->expr()->literal($recipient), - 'uid_owner' => $qb->expr()->literal('user1'), - 'item_type' => $qb->expr()->literal('folder'), - 'item_source' => $qb->expr()->literal($sourceId), - 'item_target' => $qb->expr()->literal('/' . $sourceId), - 'file_source' => $qb->expr()->literal($sourceId), - 'file_target' => $qb->expr()->literal($targetName), - 'permissions' => $qb->expr()->literal($permissions), - 'stime' => $qb->expr()->literal($this->lastShareTime), - ]; - if ($parentId !== null) { - $values['parent'] = $qb->expr()->literal($parentId); - } - $qb->insert('share') - ->values($values) - ->execute(); - - return $this->connection->lastInsertId('*PREFIX*share'); - } - - private function getShareById($id) { - $query = $this->connection->getQueryBuilder(); - $results = $query - ->select('*') - ->from('share') - ->where($query->expr()->eq('id', $query->expr()->literal($id))) - ->execute() - ->fetchAll(); - - if (!empty($results)) { - return $results[0]; - } - return null; - } - - public function sharesDataProvider() { - /** - * For all these test cases we have the following situation: - * - * - "user1" is the share owner - * - "user2" is the recipient, and member of "recipientgroup1" and "recipientgroup2" - * - "user1" is member of "samegroup1", "samegroup2" for same group tests - */ - return [ - [ - // #0 legitimate share: - // - outsider shares with group1, group2 - // - recipient renamed, resulting in subshares - // - one subshare for each group share - // - targets of subshare all match - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test renamed', 31, 0], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test renamed', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 31], - // leave them alone - ['/test renamed', 31], - ['/test renamed', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #1 broken share: - // - outsider shares with group1, group2 - // - only one subshare for two group shares - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // child of the previous one - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 31], - ['/test', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #2 bogus share - // - outsider shares with group1, group2 - // - one subshare for each group share, both with parenthesis - // - but the targets do not match when grouped - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 31, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (3)', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 31], - // reset to original name as the sub-names have parenthesis - ['/test', 31], - ['/test', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #3 bogus share - // - outsider shares with group1, group2 - // - one subshare for each group share, both renamed manually - // - but the targets do not match when grouped - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test_renamed (1 legit paren)', 31, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test_renamed (2 legit paren)', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 31], - // reset to less recent subshare name - ['/test_renamed (2 legit paren)', 31], - ['/test_renamed (2 legit paren)', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #4 bogus share - // - outsider shares with group1, group2 - // - one subshare for each group share, one with parenthesis - // - but the targets do not match when grouped - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 31, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test_renamed', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 31], - // reset to less recent subshare name but without parenthesis - ['/test_renamed', 31], - ['/test_renamed', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #5 bogus share - // - outsider shares with group1, group2 - // - one subshare for each group share - // - first subshare not renamed (as in real world scenario) - // - but the targets do not match when grouped - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test', 31, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 31], - // reset to original name - ['/test', 31], - ['/test', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #6 bogus share: - // - outsider shares with group1, group2 - // - one subshare for each group share - // - non-matching targets - // - recipient deletes one duplicate (unshare from self, permissions 0) - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 15], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 0, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (3)', 15, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 15], - // subshares repaired and permissions restored to the max allowed - ['/test', 31], - ['/test', 15], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #7 bogus share: - // - outsider shares with group1, group2 - // - one subshare for each group share - // - non-matching targets - // - recipient deletes ALL duplicates (unshare from self, permissions 0) - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 15], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 0, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (3)', 0, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - ['/test', 31], - ['/test', 15], - // subshares target repaired but left "deleted" as it was the user's choice - ['/test', 0], - ['/test', 0], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #8 bogus share: - // - outsider shares with group1, group2 and also user2 - // - one subshare for each group share - // - one extra share entry for direct share to user2 - // - non-matching targets - // - user share has more permissions - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 1], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 15], - // child of the previous ones - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (2)', 1, 0], - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/test (3)', 15, 1], - [Constants::SHARE_TYPE_USER, 123, 'user2', '/test (4)', 31], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (5)', 31], - ], - [ - ['/test', 1], - ['/test', 15], - // subshares repaired - ['/test', 1], - ['/test', 15], - ['/test', 31], - // leave unrelated alone - ['/test (5)', 31], - ] - ], - [ - // #9 bogus share: - // - outsider shares with group1 and also user2 - // - no subshare at all - // - one extra share entry for direct share to user2 - // - non-matching targets - // - user share has more permissions - [ - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 1], - [Constants::SHARE_TYPE_USER, 123, 'user2', '/test (2)', 31], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (5)', 31], - ], - [ - ['/test', 1], - // user share repaired - ['/test', 31], - // leave unrelated alone - ['/test (5)', 31], - ] - ], - [ - // #10 legitimate share with own group: - // - insider shares with both groups the user is already in - // - no subshares in this case - [ - [Constants::SHARE_TYPE_GROUP, 123, 'samegroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'samegroup2', '/test', 31], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - // leave all alone - ['/test', 31], - ['/test', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #11 legitimate shares: - // - group share with same group - // - group share with other group - // - user share where recipient renamed - // - user share where recipient did not rename - [ - [Constants::SHARE_TYPE_GROUP, 123, 'samegroup1', '/test', 31], - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - [Constants::SHARE_TYPE_USER, 123, 'user3', '/test legit rename', 31], - [Constants::SHARE_TYPE_USER, 123, 'user4', '/test', 31], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - // leave all alone - ['/test', 31], - ['/test', 31], - ['/test legit rename', 31], - ['/test', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #12 legitimate share: - // - outsider shares with group and user directly with different permissions - // - no subshares - // - same targets - [ - [Constants::SHARE_TYPE_GROUP, 123, 'samegroup1', '/test', 1], - [Constants::SHARE_TYPE_USER, 123, 'user3', '/test', 31], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (4)', 31], - ], - [ - // leave all alone - ['/test', 1], - ['/test', 31], - // leave unrelated alone - ['/test (4)', 31], - ] - ], - [ - // #13 bogus share: - // - outsider shares with group1, user2 and then group2 - // - user renamed share as soon as it arrived before the next share (order) - // - one subshare for each group share - // - one extra share entry for direct share to user2 - // - non-matching targets - [ - // first share with group - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup1', '/test', 31], - // recipient renames - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/first', 31, 0], - // then direct share, user renames too - [Constants::SHARE_TYPE_USER, 123, 'user2', '/second', 31], - // another share with the second group - [Constants::SHARE_TYPE_GROUP, 123, 'recipientgroup2', '/test', 31], - // use renames it - [DefaultShareProvider::SHARE_TYPE_USERGROUP, 123, 'user2', '/third', 31, 1], - // different unrelated share - [Constants::SHARE_TYPE_GROUP, 456, 'recipientgroup1', '/test (5)', 31], - ], - [ - // group share with group1 left alone - ['/test', 31], - // first subshare repaired - ['/third', 31], - // direct user share repaired - ['/third', 31], - // group share with group2 left alone - ['/test', 31], - // second subshare repaired - ['/third', 31], - // leave unrelated alone - ['/test (5)', 31], - ] - ], - ]; - } - - /** - * Test merge shares from group shares - * - * @dataProvider sharesDataProvider - */ - public function testMergeGroupShares($shares, $expectedShares) { - $user1 = $this->createMock(IUser::class); - $user1->expects($this->any()) - ->method('getUID') - ->will($this->returnValue('user1')); - - $user2 = $this->createMock(IUser::class); - $user2->expects($this->any()) - ->method('getUID') - ->will($this->returnValue('user2')); - - $users = [$user1, $user2]; - - $this->groupManager->expects($this->any()) - ->method('getUserGroupIds') - ->will($this->returnValueMap([ - // owner - [$user1, ['samegroup1', 'samegroup2']], - // recipient - [$user2, ['recipientgroup1', 'recipientgroup2']], - ])); - - $this->userManager->expects($this->once()) - ->method('countUsers') - ->will($this->returnValue([2])); - $this->userManager->expects($this->once()) - ->method('callForAllUsers') - ->will($this->returnCallback(function(\Closure $closure) use ($users) { - foreach ($users as $user) { - $closure($user); - } - })); - - $shareIds = []; - - foreach ($shares as $share) { - // if parent - if (isset($share[5])) { - // adjust to real id - $share[5] = $shareIds[$share[5]]; - } else { - $share[5] = null; - } - $shareIds[] = $this->createShare($share[0], $share[1], $share[2], $share[3], $share[4], $share[5]); - } - - /** @var IOutput | \PHPUnit_Framework_MockObject_MockObject $outputMock */ - $outputMock = $this->getMockBuilder('\OCP\Migration\IOutput') - ->disableOriginalConstructor() - ->getMock(); - - $this->repair->run($outputMock); - - foreach ($expectedShares as $index => $expectedShare) { - $share = $this->getShareById($shareIds[$index]); - $this->assertEquals($expectedShare[0], $share['file_target']); - $this->assertEquals($expectedShare[1], $share['permissions']); - } - } - - public function duplicateNamesProvider() { - return [ - // matching - ['filename (1).txt', true], - ['folder (2)', true], - ['filename (1)(2).txt', true], - // non-matching - ['filename ().txt', false], - ['folder ()', false], - ['folder (1x)', false], - ['folder (x1)', false], - ['filename (a)', false], - ['filename (1).', false], - ['filename (1).txt.txt', false], - ['filename (1)..txt', false], - ]; - } - - /** - * @dataProvider duplicateNamesProvider - */ - public function testIsPotentialDuplicateName($name, $expectedResult) { - $this->assertEquals($expectedResult, $this->invokePrivate($this->repair, 'isPotentialDuplicateName', [$name])); - } -} - diff --git a/tests/lib/Repair/UpdateOutdatedOcsIdsTest.php b/tests/lib/Repair/UpdateOutdatedOcsIdsTest.php deleted file mode 100644 index eb80e63a20..0000000000 --- a/tests/lib/Repair/UpdateOutdatedOcsIdsTest.php +++ /dev/null @@ -1,80 +0,0 @@ - - * - * @copyright Copyright (c) 2015, 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 - * - */ - -namespace Test\Repair; - -use OCP\IConfig; -use Test\TestCase; - -/** - * Class UpdateOutdatedOcsIds - * - * @package Test\Repair - */ -class UpdateOutdatedOcsIdsTest extends TestCase { - /** @var IConfig | \PHPUnit_Framework_MockObject_MockObject */ - private $config; - /** @var \OC\Repair\UpdateOutdatedOcsIds */ - private $updateOutdatedOcsIds; - - public function setUp() { - parent::setUp(); - $this->config = $this->getMockBuilder('\\OCP\\IConfig')->getMock(); - $this->updateOutdatedOcsIds = new \OC\Repair\UpdateOutdatedOcsIds($this->config); - } - - public function testGetName() { - $this->assertSame('Repair outdated OCS IDs', $this->updateOutdatedOcsIds->getName()); - } - - public function testFixOcsIdNoOcsId() { - $this->config - ->expects($this->once()) - ->method('getAppValue') - ->with('MyNotInstalledApp', 'ocsid') - ->will($this->returnValue('')); - $this->assertFalse($this->updateOutdatedOcsIds->fixOcsId('MyNotInstalledApp', '1337', '0815')); - } - - public function testFixOcsIdUpdateOcsId() { - $this->config - ->expects($this->at(0)) - ->method('getAppValue') - ->with('MyInstalledApp', 'ocsid') - ->will($this->returnValue('1337')); - $this->config - ->expects($this->at(1)) - ->method('setAppValue') - ->with('MyInstalledApp', 'ocsid', '0815'); - - $this->assertTrue($this->updateOutdatedOcsIds->fixOcsId('MyInstalledApp', '1337', '0815')); - } - - public function testFixOcsIdAlreadyFixed() { - $this->config - ->expects($this->once()) - ->method('getAppValue') - ->with('MyAlreadyFixedAppId', 'ocsid') - ->will($this->returnValue('0815')); - - $this->assertFalse($this->updateOutdatedOcsIds->fixOcsId('MyAlreadyFixedAppId', '1337', '0815')); - } -} diff --git a/tests/lib/Repair/fixtures/dropoldtables.xml b/tests/lib/Repair/fixtures/dropoldtables.xml deleted file mode 100644 index 6c42a8f90a..0000000000 --- a/tests/lib/Repair/fixtures/dropoldtables.xml +++ /dev/null @@ -1,24 +0,0 @@ - - - - *dbname* - true - false - - utf8 - - - - *dbprefix*permissions - - - - textfield - text - foo - true - 32 - - -
-