From 7c56144f4927ed56d02c197710833c2b10c2f65d Mon Sep 17 00:00:00 2001 From: Tobia De Koninck Date: Fri, 3 Jan 2020 08:43:39 +0100 Subject: [PATCH 1/4] Add option to transfer-ownership to move data This will move the home folder of own user to another user. Only allowed if that other user's home folder is empty. Can be used as workaround to rename users. Signed-off-by: Tobia De Koninck --- apps/files/lib/Command/TransferOwnership.php | 10 ++++++++-- .../lib/Service/OwnershipTransferService.php | 19 ++++++++++++++++--- 2 files changed, 24 insertions(+), 5 deletions(-) diff --git a/apps/files/lib/Command/TransferOwnership.php b/apps/files/lib/Command/TransferOwnership.php index cad1b1b46cbe9..2675a7dd1bb8b 100644 --- a/apps/files/lib/Command/TransferOwnership.php +++ b/apps/files/lib/Command/TransferOwnership.php @@ -77,7 +77,12 @@ protected function configure() { InputOption::VALUE_REQUIRED, 'selectively provide the path to transfer. For example --path="folder_name"', '' - ); + )->addOption( + 'move', + null, + InputOption::VALUE_NONE, + 'move data from source user to root directory of destination user, which must be empty' + ); } protected function execute(InputInterface $input, OutputInterface $output) { @@ -99,7 +104,8 @@ protected function execute(InputInterface $input, OutputInterface $output) { $sourceUserObject, $destinationUserObject, ltrim($input->getOption('path'), '/'), - $output + $output, + $input->getOption('move') === true ); } catch (TransferOwnershipException $e) { $output->writeln("" . $e->getMessage() . ""); diff --git a/apps/files/lib/Service/OwnershipTransferService.php b/apps/files/lib/Service/OwnershipTransferService.php index 8530edd17b17f..8af894a01673a 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -71,12 +71,16 @@ public function __construct(IEncryptionManager $manager, * @param IUser $destinationUser * @param string $path * + * @param OutputInterface|null $output + * @param bool $move * @throws TransferOwnershipException + * @throws \OC\User\NoUserException */ public function transfer(IUser $sourceUser, IUser $destinationUser, string $path, - ?OutputInterface $output = null): void { + ?OutputInterface $output = null, + bool $move = false): void { $output = $output ?? new NullOutput(); $sourceUid = $sourceUser->getUID(); $destinationUid = $destinationUser->getUID(); @@ -87,8 +91,12 @@ public function transfer(IUser $sourceUser, throw new TransferOwnershipException("The target user is not ready to accept files. The user has at least to have logged in once.", 2); } - $date = date('Y-m-d H-i-s'); - $finalTarget = "$destinationUid/files/transferred from $sourceUid on $date"; + if ($move) { + $finalTarget = "$destinationUid/files/"; + } else { + $date = date('Y-m-d H-i-s'); + $finalTarget = "$destinationUid/files/transferred from $sourceUid on $date"; + } // setup filesystem Filesystem::initMountPoints($sourceUid); @@ -99,6 +107,11 @@ public function transfer(IUser $sourceUser, throw new TransferOwnershipException("Unknown path provided: $path", 1); } + if ($move && (!$view->is_dir($finalTarget) || count($view->getDirectoryContent($finalTarget)) > 0)) { + throw new TransferOwnershipException("Destination path does not exists or is not empty", 1); + } + + // analyse source folder $this->analyse( $sourceUid, From 97508f69ec5046c3876912b80530c7a164ce49f9 Mon Sep 17 00:00:00 2001 From: Tobia De Koninck Date: Fri, 3 Jan 2020 08:48:17 +0100 Subject: [PATCH 2/4] Prevent transferring data to user which never loggedin Signed-off-by: Tobia De Koninck --- apps/files/lib/Service/OwnershipTransferService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/lib/Service/OwnershipTransferService.php b/apps/files/lib/Service/OwnershipTransferService.php index 8af894a01673a..3dc55615c9525 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -87,7 +87,7 @@ public function transfer(IUser $sourceUser, $sourcePath = rtrim($sourceUid . '/files/' . $path, '/'); // target user has to be ready - if (!$this->encryptionManager->isReadyForUser($destinationUid)) { + if ($destinationUser->getLastLogin() === 0 || !$this->encryptionManager->isReadyForUser($destinationUid)) { throw new TransferOwnershipException("The target user is not ready to accept files. The user has at least to have logged in once.", 2); } From 055ae9b2cd9f37f854d3c8c4f7e2051cd116fa53 Mon Sep 17 00:00:00 2001 From: Tobia De Koninck Date: Fri, 3 Jan 2020 08:50:37 +0100 Subject: [PATCH 3/4] Catch \Error in Transfer::restoreShares This makes the command more fault tolerant. An \Error can happen when e.g. the owner of a share is null. If we don't catch this, the restore process will stop in an unknown state. Signed-off-by: Tobia De Koninck --- apps/files/lib/Service/OwnershipTransferService.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apps/files/lib/Service/OwnershipTransferService.php b/apps/files/lib/Service/OwnershipTransferService.php index 3dc55615c9525..b130910e25b31 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -286,7 +286,7 @@ private function restoreShares(string $sourceUid, } } catch (\OCP\Files\NotFoundException $e) { $output->writeln('Share with id ' . $share->getId() . ' points at deleted file, skipping'); - } catch (\Exception $e) { + } catch (\Throwable $e) { $output->writeln('Could not restore share with id ' . $share->getId() . ':' . $e->getTraceAsString() . ''); } $progress->advance(); From 5bc0951267466e2bd6cbe169fd87e79ede04bba6 Mon Sep 17 00:00:00 2001 From: Roeland Jago Douma Date: Fri, 31 Jan 2020 11:04:43 +0100 Subject: [PATCH 4/4] Allow specifying this is the first login On firstlogin we allow non empty target folders. So that for guest transfers the user sees the same UI. Signed-off-by: Roeland Jago Douma --- apps/files/lib/Service/OwnershipTransferService.php | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/apps/files/lib/Service/OwnershipTransferService.php b/apps/files/lib/Service/OwnershipTransferService.php index b130910e25b31..f316216814fda 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -80,7 +80,8 @@ public function transfer(IUser $sourceUser, IUser $destinationUser, string $path, ?OutputInterface $output = null, - bool $move = false): void { + bool $move = false, + bool $firstLogin = false): void { $output = $output ?? new NullOutput(); $sourceUid = $sourceUser->getUID(); $destinationUid = $destinationUser->getUID(); @@ -107,7 +108,13 @@ public function transfer(IUser $sourceUser, throw new TransferOwnershipException("Unknown path provided: $path", 1); } - if ($move && (!$view->is_dir($finalTarget) || count($view->getDirectoryContent($finalTarget)) > 0)) { + if ($move && ( + !$view->is_dir($finalTarget) || ( + !$firstLogin && + count($view->getDirectoryContent($finalTarget)) > 0 + ) + ) + ) { throw new TransferOwnershipException("Destination path does not exists or is not empty", 1); }