Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
feat(transfer-ownership): Correctly react to encrypted files
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 <[email protected]>
  • Loading branch information
come-nc authored and backportbot[bot] committed Sep 5, 2024
commit 9b057e472dcb9b5cc2e8c21edc7b1b823ac55dd6
63 changes: 43 additions & 20 deletions apps/files/lib/Service/OwnershipTransferService.php
Original file line number Diff line number Diff line change
Expand Up @@ -223,41 +223,64 @@ private function walkFiles(View $view, $path, Closure $callBack) {
/**
* @param OutputInterface $output
*
* @throws \Exception
* @throws TransferOwnershipException
*/
protected function analyse(string $sourceUid,
string $destinationUid,
string $sourcePath,
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('<error>Target user does not have enough free space available.</error>');
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('');

Expand All @@ -268,7 +291,7 @@ function (FileInfo $fileInfo) use ($progress, &$encryptedFiles) {
/** @var FileInfo $encryptedFile */
$output->writeln(" " . $encryptedFile->getPath());
}
throw new \Exception('Execution terminated.');
throw new TransferOwnershipException('Some files are encrypted - please decrypt them first.', 1);
}
}

Expand Down