From 7bac8f0fcadc484e06bcd73e19ae05fe8a64ae60 Mon Sep 17 00:00:00 2001 From: =?utf8?q?C=C3=B4me=20Chilliet?= Date: Tue, 27 Aug 2024 12:53:38 +0200 Subject: [PATCH] feat(transfer-ownership): Correctly react to encrypted files MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit For E2EE encrypted files, we abort the transfer. For SSE encrypted files, we abort only if not using master key. Also fixed the check for when the path to a single file is used. Signed-off-by: Côme Chilliet --- .../lib/Service/OwnershipTransferService.php | 63 +++++++++++++------ 1 file changed, 43 insertions(+), 20 deletions(-) diff --git a/apps/files/lib/Service/OwnershipTransferService.php b/apps/files/lib/Service/OwnershipTransferService.php index a624df4a924..805a81cdc6b 100644 --- a/apps/files/lib/Service/OwnershipTransferService.php +++ b/apps/files/lib/Service/OwnershipTransferService.php @@ -204,7 +204,7 @@ class OwnershipTransferService { /** * @param OutputInterface $output * - * @throws \Exception + * @throws TransferOwnershipException */ protected function analyse(string $sourceUid, string $destinationUid, @@ -212,33 +212,56 @@ class OwnershipTransferService { View $view, OutputInterface $output): void { $output->writeln('Validating quota'); - $size = $view->getFileInfo($sourcePath, false)->getSize(false); + $sourceFileInfo = $view->getFileInfo($sourcePath, false); + if ($sourceFileInfo === false) { + throw new TransferOwnershipException("Unknown path provided: $sourcePath", 1); + } + $size = $sourceFileInfo->getSize(false); $freeSpace = $view->free_space($destinationUid . '/files/'); if ($size > $freeSpace && $freeSpace !== FileInfo::SPACE_UNKNOWN) { - $output->writeln('Target user does not have enough free space available.'); - throw new \Exception('Execution terminated.'); + throw new TransferOwnershipException('Target user does not have enough free space available.', 1); } $output->writeln("Analysing files of $sourceUid ..."); $progress = new ProgressBar($output); $progress->start(); + if ($this->encryptionManager->isEnabled()) { + $masterKeyEnabled = \OCP\Server::get(\OCA\Encryption\Util::class)->isMasterKeyEnabled(); + } else { + $masterKeyEnabled = false; + } $encryptedFiles = []; - $this->walkFiles($view, $sourcePath, - function (FileInfo $fileInfo) use ($progress, &$encryptedFiles) { - if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) { - // only analyze into folders from main storage, - if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) { - return false; - } - return true; - } - $progress->advance(); - if ($fileInfo->isEncrypted()) { - $encryptedFiles[] = $fileInfo; - } - return true; - }); + if ($sourceFileInfo->getType() === FileInfo::TYPE_FOLDER) { + if ($sourceFileInfo->isEncrypted()) { + /* Encrypted folder means e2ee encrypted */ + $encryptedFiles[] = $sourceFileInfo; + } else { + $this->walkFiles($view, $sourcePath, + function (FileInfo $fileInfo) use ($progress, $masterKeyEnabled, &$encryptedFiles) { + if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) { + // only analyze into folders from main storage, + if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) { + return false; + } + if ($fileInfo->isEncrypted()) { + /* Encrypted folder means e2ee encrypted */ + $encryptedFiles[] = $fileInfo; + } + return true; + } + $progress->advance(); + if ($fileInfo->isEncrypted() && !$masterKeyEnabled) { + /* Encrypted file means SSE, we only care if we are using user keys */ + $encryptedFiles[] = $fileInfo; + } + return true; + }); + } + } elseif ($sourceFileInfo->isEncrypted() && !$masterKeyEnabled) { + /* Encrypted file means SSE, we only care if we are using user keys */ + $encryptedFiles[] = $sourceFileInfo; + } $progress->finish(); $output->writeln(''); @@ -249,7 +272,7 @@ class OwnershipTransferService { /** @var FileInfo $encryptedFile */ $output->writeln(" " . $encryptedFile->getPath()); } - throw new \Exception('Execution terminated.'); + throw new TransferOwnershipException('Some files are encrypted - please decrypt them first.', 1); } } -- 2.39.5