'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',
'OC\\Repair\\NC11\\MoveAvatars' => $baseDir . '/lib/private/Repair/NC11/MoveAvatars.php',
'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => $baseDir . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php',
'OC\\Repair\\OldGroupMembershipShares' => $baseDir . '/lib/private/Repair/OldGroupMembershipShares.php',
- 'OC\\Repair\\Preview' => $baseDir . '/lib/private/Repair/Preview.php',
- 'OC\\Repair\\RemoveGetETagEntries' => $baseDir . '/lib/private/Repair/RemoveGetETagEntries.php',
- 'OC\\Repair\\RemoveOldShares' => $baseDir . '/lib/private/Repair/RemoveOldShares.php',
'OC\\Repair\\RemoveRootShares' => $baseDir . '/lib/private/Repair/RemoveRootShares.php',
'OC\\Repair\\RepairInvalidShares' => $baseDir . '/lib/private/Repair/RepairInvalidShares.php',
'OC\\Repair\\RepairMimeTypes' => $baseDir . '/lib/private/Repair/RepairMimeTypes.php',
- 'OC\\Repair\\RepairUnmergedShares' => $baseDir . '/lib/private/Repair/RepairUnmergedShares.php',
- 'OC\\Repair\\SearchLuceneTables' => $baseDir . '/lib/private/Repair/SearchLuceneTables.php',
- 'OC\\Repair\\SharePropagation' => $baseDir . '/lib/private/Repair/SharePropagation.php',
'OC\\Repair\\SqliteAutoincrement' => $baseDir . '/lib/private/Repair/SqliteAutoincrement.php',
- 'OC\\Repair\\UpdateOutdatedOcsIds' => $baseDir . '/lib/private/Repair/UpdateOutdatedOcsIds.php',
'OC\\RichObjectStrings\\Validator' => $baseDir . '/lib/private/RichObjectStrings/Validator.php',
'OC\\Route\\CachingRouter' => $baseDir . '/lib/private/Route/CachingRouter.php',
'OC\\Route\\Route' => $baseDir . '/lib/private/Route/Route.php',
'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',
'OC\\Repair\\NC11\\MoveAvatars' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatars.php',
'OC\\Repair\\NC11\\MoveAvatarsBackgroundJob' => __DIR__ . '/../../..' . '/lib/private/Repair/NC11/MoveAvatarsBackgroundJob.php',
'OC\\Repair\\OldGroupMembershipShares' => __DIR__ . '/../../..' . '/lib/private/Repair/OldGroupMembershipShares.php',
- 'OC\\Repair\\Preview' => __DIR__ . '/../../..' . '/lib/private/Repair/Preview.php',
- 'OC\\Repair\\RemoveGetETagEntries' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveGetETagEntries.php',
- 'OC\\Repair\\RemoveOldShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveOldShares.php',
'OC\\Repair\\RemoveRootShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RemoveRootShares.php',
'OC\\Repair\\RepairInvalidShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairInvalidShares.php',
'OC\\Repair\\RepairMimeTypes' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairMimeTypes.php',
- 'OC\\Repair\\RepairUnmergedShares' => __DIR__ . '/../../..' . '/lib/private/Repair/RepairUnmergedShares.php',
- 'OC\\Repair\\SearchLuceneTables' => __DIR__ . '/../../..' . '/lib/private/Repair/SearchLuceneTables.php',
- 'OC\\Repair\\SharePropagation' => __DIR__ . '/../../..' . '/lib/private/Repair/SharePropagation.php',
'OC\\Repair\\SqliteAutoincrement' => __DIR__ . '/../../..' . '/lib/private/Repair/SqliteAutoincrement.php',
- 'OC\\Repair\\UpdateOutdatedOcsIds' => __DIR__ . '/../../..' . '/lib/private/Repair/UpdateOutdatedOcsIds.php',
'OC\\RichObjectStrings\\Validator' => __DIR__ . '/../../..' . '/lib/private/RichObjectStrings/Validator.php',
'OC\\Route\\CachingRouter' => __DIR__ . '/../../..' . '/lib/private/Route/CachingRouter.php',
'OC\\Route\\Route' => __DIR__ . '/../../..' . '/lib/private/Route/Route.php',
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;
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(),
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;
}
+++ /dev/null
-<?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.');
- }
-}
-
+++ /dev/null
-<?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],
- ];
- }
-
-
-}
+++ /dev/null
-<?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'
- ];
- }
-}
+++ /dev/null
-<?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.");
- }
-}
-
+++ /dev/null
-<?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;
- }
-}
-
+++ /dev/null
-<?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);
- }
- }
- }
- }
-}
+++ /dev/null
-<?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.');
- }
-}
+++ /dev/null
-<?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();
- }
-}
-
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
*/
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);
}
');
}
- 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`
');
}
- 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'));
}
}
- 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',
// 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');
}
+++ /dev/null
-<?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();
- }
- }
-}
+++ /dev/null
-<?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');
- }
- }
-
-}
-
+++ /dev/null
-<?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);
- }
- }
- }
-}
+++ /dev/null
-<?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");
- }
- }
- }
-}
+++ /dev/null
-<?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');
- }
-}
+++ /dev/null
-<?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');
- }
-}
+++ /dev/null
-<?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]);
- }
-
-}
+++ /dev/null
-<?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']);
- }
-}
+++ /dev/null
-<?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;
- }
-}
$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();
$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
*/
$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([]);
}
}
- /**
- * 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);
$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..
['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 = [
['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);
+++ /dev/null
-<?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);
- }
-}
+++ /dev/null
-<?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]));
- }
-}
-
+++ /dev/null
-<?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'));
- }
-}
+++ /dev/null
-<?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>