Merge pull request #3589 from nextcloud/remove-unneeded-repair-step
Remove unneeded repair steps
This commit is contained in:
commit
ee52313e76
|
@ -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,18 +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\\UpdateCertificateStore' => $baseDir . '/lib/private/Repair/UpdateCertificateStore.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',
|
||||
|
|
|
@ -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,18 +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\\UpdateCertificateStore' => __DIR__ . '/../../..' . '/lib/private/Repair/UpdateCertificateStore.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',
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Adam Williamson <awilliam@redhat.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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.');
|
||||
}
|
||||
}
|
||||
|
|
@ -1,88 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Arthur Schiwon <blizzz@arthur-schiwon.de>
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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],
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -1,111 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Florian Preinstorfer <nblock@archlinux.us>
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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'
|
||||
];
|
||||
}
|
||||
}
|
|
@ -1,57 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Joas Schilling <coding@schilljs.com>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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.");
|
||||
}
|
||||
}
|
||||
|
|
@ -1,70 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Robin Appelman <robin@icewind.nl>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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;
|
||||
}
|
||||
}
|
||||
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Georg Ehrke <georg@owncloud.com>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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.');
|
||||
}
|
||||
}
|
|
@ -1,104 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Roeland Jago Douma <roeland@famdouma.nl>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace 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();
|
||||
}
|
||||
}
|
||||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -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');
|
||||
}
|
||||
|
|
|
@ -1,357 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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();
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,80 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Jörn Friedrich Dreyer <jfd@butonic.de>
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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');
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Robin Appelman <robin@icewind.nl>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Lukas Reschke <lukas@statuscode.ch>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace OC\Repair;
|
||||
|
||||
use OC\Files\View;
|
||||
use OC\Server;
|
||||
use OCP\IConfig;
|
||||
use OCP\Migration\IOutput;
|
||||
use OCP\Migration\IRepairStep;
|
||||
|
||||
/**
|
||||
* Class UpdateCertificateStore rewrites the user specific certificate store after
|
||||
* an update has been performed. This is done because a new root certificate file
|
||||
* might have been added.
|
||||
*
|
||||
* @package OC\Repair
|
||||
*/
|
||||
class UpdateCertificateStore implements IRepairStep {
|
||||
/**
|
||||
* FIXME: The certificate manager does only allow specifying the user
|
||||
* within the constructor. This makes DI impossible.
|
||||
* @var Server
|
||||
*/
|
||||
protected $server;
|
||||
/** @var IConfig */
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* @param Server $server
|
||||
* @param IConfig $config
|
||||
*/
|
||||
public function __construct(Server $server,
|
||||
IConfig $config) {
|
||||
$this->server = $server;
|
||||
$this->config = $config;
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public function getName() {
|
||||
return 'Update user certificate stores with new root certificates';
|
||||
}
|
||||
|
||||
/** {@inheritDoc} */
|
||||
public function run(IOutput $out) {
|
||||
$rootView = new View();
|
||||
$dataDirectory = $this->config->getSystemValue('datadirectory', null);
|
||||
if(is_null($dataDirectory)) {
|
||||
throw new \Exception('No data directory specified');
|
||||
}
|
||||
|
||||
$pathToRootCerts = '/files_external/rootcerts.crt';
|
||||
|
||||
foreach($rootView->getDirectoryContent('', 'httpd/unix-directory') as $fileInfo) {
|
||||
$uid = trim($fileInfo->getPath(), '/');
|
||||
if($rootView->file_exists($uid . $pathToRootCerts)) {
|
||||
// Delete the existing root certificate
|
||||
$rootView->unlink($uid . $pathToRootCerts);
|
||||
|
||||
/**
|
||||
* FIXME: The certificate manager does only allow specifying the user
|
||||
* within the constructor. This makes DI impossible.
|
||||
*/
|
||||
// Regenerate the certificates
|
||||
$certificateManager = $this->server->getCertificateManager($uid);
|
||||
$certificateManager->createCertificateBundle();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,106 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
*
|
||||
* @author Lukas Reschke <lukas@statuscode.ch>
|
||||
* @author Thomas Müller <thomas.mueller@tmit.eu>
|
||||
*
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,48 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Arthur Schiwon <blizzz@owncloud.com>
|
||||
* 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');
|
||||
}
|
||||
}
|
|
@ -1,46 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2015 Joas Schilling <nickvergessen@owncloud.com>
|
||||
* 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');
|
||||
}
|
||||
}
|
|
@ -1,90 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Morris Jobke <hey@morrisjobke.de>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
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]);
|
||||
}
|
||||
|
||||
}
|
|
@ -1,160 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Roeland Jago Douma <rullzer@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
namespace 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']);
|
||||
}
|
||||
}
|
|
@ -1,78 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2014 Thomas Müller <deepdiver@owncloud.com>
|
||||
* 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;
|
||||
}
|
||||
}
|
|
@ -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
|
||||
*/
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -1,58 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* Copyright (c) 2016 Robin Appelman <icewind@owncloud.com>
|
||||
* 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);
|
||||
}
|
||||
}
|
|
@ -1,575 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Vincent Petry <pvince81@owncloud.com>
|
||||
*
|
||||
* @copyright Copyright (c) 2016, ownCloud, Inc.
|
||||
* @license AGPL-3.0
|
||||
*
|
||||
* This code is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License, version 3,
|
||||
* as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License, version 3,
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
namespace 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]));
|
||||
}
|
||||
}
|
||||
|
|
@ -1,80 +0,0 @@
|
|||
<?php
|
||||
/**
|
||||
* @author Lukas Reschke <l8kas@owncloud.com>
|
||||
*
|
||||
* @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 <http://www.gnu.org/licenses/>
|
||||
*
|
||||
*/
|
||||
|
||||
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'));
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
<?xml version="1.0" encoding="utf-8" ?>
|
||||
<database>
|
||||
|
||||
<name>*dbname*</name>
|
||||
<create>true</create>
|
||||
<overwrite>false</overwrite>
|
||||
|
||||
<charset>utf8</charset>
|
||||
|
||||
<table>
|
||||
|
||||
<name>*dbprefix*permissions</name>
|
||||
|
||||
<declaration>
|
||||
<field>
|
||||
<name>textfield</name>
|
||||
<type>text</type>
|
||||
<default>foo</default>
|
||||
<notnull>true</notnull>
|
||||
<length>32</length>
|
||||
</field>
|
||||
</declaration>
|
||||
</table>
|
||||
</database>
|
Loading…
Reference in New Issue