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 cad1b1b46cb..2675a7dd1bb 100644 --- a/apps/files/lib/Command/TransferOwnership.php +++ b/apps/files/lib/Command/TransferOwnership.php @@ -77,7 +77,12 @@ class TransferOwnership extends Command { 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 @@ class TransferOwnership extends Command { $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 8530edd17b1..8af894a0167 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -71,12 +71,16 @@ class OwnershipTransferService { * @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 @@ class OwnershipTransferService { 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 @@ class OwnershipTransferService { 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 8af894a0167..3dc55615c95 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -87,7 +87,7 @@ class OwnershipTransferService { $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 3dc55615c95..b130910e25b 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -286,7 +286,7 @@ class OwnershipTransferService { } } 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 b130910e25b..f316216814f 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -80,7 +80,8 @@ class OwnershipTransferService { 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 @@ class OwnershipTransferService { 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); }