diff options
Diffstat (limited to 'apps/files/lib/Command/TransferOwnership.php')
-rw-r--r-- | apps/files/lib/Command/TransferOwnership.php | 139 |
1 files changed, 61 insertions, 78 deletions
diff --git a/apps/files/lib/Command/TransferOwnership.php b/apps/files/lib/Command/TransferOwnership.php index 50aa0b21a5f..f7663e26f28 100644 --- a/apps/files/lib/Command/TransferOwnership.php +++ b/apps/files/lib/Command/TransferOwnership.php @@ -1,71 +1,41 @@ <?php declare(strict_types=1); - /** - * @copyright Copyright (c) 2016, ownCloud, Inc. - * - * @author Carla Schroder <carla@owncloud.com> - * @author Christoph Wurst <christoph@winzerhof-wurst.at> - * @author Joas Schilling <coding@schilljs.com> - * @author Morris Jobke <hey@morrisjobke.de> - * @author Roeland Jago Douma <roeland@famdouma.nl> - * @author Sujith Haridasan <sujith.h@gmail.com> - * @author Sujith H <sharidasan@owncloud.com> - * @author Thomas Müller <thomas.mueller@tmit.eu> - * @author Tobia De Koninck <LEDfan@users.noreply.github.com> - * @author Vincent Petry <vincent@nextcloud.com> - * - * @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/> - * + * SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-FileCopyrightText: 2016 ownCloud, Inc. + * SPDX-License-Identifier: AGPL-3.0-only */ namespace OCA\Files\Command; use OCA\Files\Exception\TransferOwnershipException; use OCA\Files\Service\OwnershipTransferService; +use OCA\Files_External\Config\ConfigAdapter; +use OCP\Files\Mount\IMountManager; +use OCP\Files\Mount\IMountPoint; +use OCP\IConfig; use OCP\IUser; use OCP\IUserManager; -use OCP\IConfig; use Symfony\Component\Console\Command\Command; +use Symfony\Component\Console\Helper\QuestionHelper; use Symfony\Component\Console\Input\InputArgument; use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; +use Symfony\Component\Console\Question\ConfirmationQuestion; class TransferOwnership extends Command { - - /** @var IUserManager */ - private $userManager; - - /** @var OwnershipTransferService */ - private $transferService; - - /** @var IConfig */ - private $config; - - public function __construct(IUserManager $userManager, - OwnershipTransferService $transferService, - IConfig $config) { + public function __construct( + private IUserManager $userManager, + private OwnershipTransferService $transferService, + private IConfig $config, + private IMountManager $mountManager, + ) { parent::__construct(); - $this->userManager = $userManager; - $this->transferService = $transferService; - $this->config = $config; } - protected function configure() { + protected function configure(): void { $this ->setName('files:transfer-ownership') ->setDescription('All files and folders are moved to another user - outgoing shares and incoming user file shares (optionally) are moved as well.') @@ -94,9 +64,19 @@ class TransferOwnership extends Command { 'transfer-incoming-shares', null, InputOption::VALUE_OPTIONAL, - 'transfer incoming user file shares to destination user. Usage: --transfer-incoming-shares=1 (value required)', + 'Incoming shares are always transferred now, so this option does not affect the ownership transfer anymore', '2' - ); + )->addOption( + 'include-external-storage', + null, + InputOption::VALUE_NONE, + 'include files on external storages, this will _not_ setup an external storage for the target user, but instead moves all the files from the external storages into the target users home directory', + )->addOption( + 'force-include-external-storage', + null, + InputOption::VALUE_NONE, + 'don\'t ask for confirmation for transferring external storages', + ); } protected function execute(InputInterface $input, OutputInterface $output): int { @@ -107,59 +87,62 @@ class TransferOwnership extends Command { if ($input->getArgument(('source-user')) === $input->getArgument('destination-user')) { $output->writeln("<error>Ownership can't be transferred when Source and Destination users are the same user. Please check your input.</error>"); - return 1; + return self::FAILURE; } $sourceUserObject = $this->userManager->get($input->getArgument('source-user')); $destinationUserObject = $this->userManager->get($input->getArgument('destination-user')); if (!$sourceUserObject instanceof IUser) { - $output->writeln("<error>Unknown source user " . $input->getArgument('source-user') . "</error>"); - return 1; + $output->writeln('<error>Unknown source user ' . $input->getArgument('source-user') . '</error>'); + return self::FAILURE; } if (!$destinationUserObject instanceof IUser) { - $output->writeln("<error>Unknown destination user " . $input->getArgument('destination-user') . "</error>"); - return 1; + $output->writeln('<error>Unknown destination user ' . $input->getArgument('destination-user') . '</error>'); + return self::FAILURE; } - try { - $includeIncomingArgument = $input->getOption('transfer-incoming-shares'); - - switch ($includeIncomingArgument) { - case '0': - $includeIncoming = false; - break; - case '1': - $includeIncoming = true; - break; - case '2': - $includeIncoming = $this->config->getSystemValue('transferIncomingShares', false); - if (gettype($includeIncoming) !== 'boolean') { - $output->writeln("<error> config.php: 'transfer-incoming-shares': wrong usage. Transfer aborted.</error>"); - return 1; + $path = ltrim($input->getOption('path'), '/'); + $includeExternalStorage = $input->getOption('include-external-storage'); + if ($includeExternalStorage) { + $mounts = $this->mountManager->findIn('/' . rtrim($sourceUserObject->getUID() . '/files/' . $path, '/')); + /** @var IMountPoint[] $mounts */ + $mounts = array_filter($mounts, fn ($mount) => $mount->getMountProvider() === ConfigAdapter::class); + if (count($mounts) > 0) { + $output->writeln(count($mounts) . ' external storages will be transferred:'); + foreach ($mounts as $mount) { + $output->writeln(' - <info>' . $mount->getMountPoint() . '</info>'); + } + $output->writeln(''); + $output->writeln('<comment>Any other users with access to these external storages will lose access to the files.</comment>'); + $output->writeln(''); + if (!$input->getOption('force-include-external-storage')) { + /** @var QuestionHelper $helper */ + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Are you sure you want to transfer external storages? (y/N) ', false); + if (!$helper->ask($input, $output, $question)) { + return self::FAILURE; } - break; - default: - $output->writeln("<error>Option --transfer-incoming-shares: wrong usage. Transfer aborted.</error>"); - return 1; - break; + } } + } + try { $this->transferService->transfer( $sourceUserObject, $destinationUserObject, - ltrim($input->getOption('path'), '/'), + $path, $output, $input->getOption('move') === true, false, - $includeIncoming + $includeExternalStorage, ); } catch (TransferOwnershipException $e) { - $output->writeln("<error>" . $e->getMessage() . "</error>"); - return $e->getCode() !== 0 ? $e->getCode() : 1; + $output->writeln('<error>' . $e->getMessage() . '</error>'); + return $e->getCode() !== 0 ? $e->getCode() : self::FAILURE; } - return 0; + return self::SUCCESS; } } |