aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files/lib
diff options
context:
space:
mode:
Diffstat (limited to 'apps/files/lib')
-rw-r--r--apps/files/lib/AppInfo/Application.php8
-rw-r--r--apps/files/lib/Command/Copy.php7
-rw-r--r--apps/files/lib/Command/Move.php7
-rw-r--r--apps/files/lib/Command/TransferOwnership.php46
-rw-r--r--apps/files/lib/Service/OwnershipTransferService.php79
-rw-r--r--apps/files/lib/Service/UserConfig.php6
6 files changed, 120 insertions, 33 deletions
diff --git a/apps/files/lib/AppInfo/Application.php b/apps/files/lib/AppInfo/Application.php
index 4b3948d43b5..32c072ef0f4 100644
--- a/apps/files/lib/AppInfo/Application.php
+++ b/apps/files/lib/AppInfo/Application.php
@@ -132,7 +132,6 @@ class Application extends App implements IBootstrap {
public function boot(IBootContext $context): void {
$context->injectFn(Closure::fromCallable([$this, 'registerCollaboration']));
$context->injectFn([Listener::class, 'register']);
- $this->registerTemplates();
$this->registerHooks();
}
@@ -140,13 +139,6 @@ class Application extends App implements IBootstrap {
$providerManager->registerResourceProvider(ResourceProvider::class);
}
- private function registerTemplates(): void {
- $templateManager = \OC_Helper::getFileTemplateManager();
- $templateManager->registerTemplate('application/vnd.oasis.opendocument.presentation', 'core/templates/filetemplates/template.odp');
- $templateManager->registerTemplate('application/vnd.oasis.opendocument.text', 'core/templates/filetemplates/template.odt');
- $templateManager->registerTemplate('application/vnd.oasis.opendocument.spreadsheet', 'core/templates/filetemplates/template.ods');
- }
-
private function registerHooks(): void {
Util::connectHook('\OCP\Config', 'js', '\OCA\Files\App', 'extendJsConfig');
}
diff --git a/apps/files/lib/Command/Copy.php b/apps/files/lib/Command/Copy.php
index e51a1689907..ad0dfa90de1 100644
--- a/apps/files/lib/Command/Copy.php
+++ b/apps/files/lib/Command/Copy.php
@@ -19,10 +19,9 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
class Copy extends Command {
- private FileUtils $fileUtils;
-
- public function __construct(FileUtils $fileUtils) {
- $this->fileUtils = $fileUtils;
+ public function __construct(
+ private FileUtils $fileUtils,
+ ) {
parent::__construct();
}
diff --git a/apps/files/lib/Command/Move.php b/apps/files/lib/Command/Move.php
index cd9e56f8e29..29dd8860b2a 100644
--- a/apps/files/lib/Command/Move.php
+++ b/apps/files/lib/Command/Move.php
@@ -20,10 +20,9 @@ use Symfony\Component\Console\Output\OutputInterface;
use Symfony\Component\Console\Question\ConfirmationQuestion;
class Move extends Command {
- private FileUtils $fileUtils;
-
- public function __construct(FileUtils $fileUtils) {
- $this->fileUtils = $fileUtils;
+ public function __construct(
+ private FileUtils $fileUtils,
+ ) {
parent::__construct();
}
diff --git a/apps/files/lib/Command/TransferOwnership.php b/apps/files/lib/Command/TransferOwnership.php
index edc73e62c38..104a8fb4985 100644
--- a/apps/files/lib/Command/TransferOwnership.php
+++ b/apps/files/lib/Command/TransferOwnership.php
@@ -11,20 +11,26 @@ 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 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 {
public function __construct(
private IUserManager $userManager,
private OwnershipTransferService $transferService,
private IConfig $config,
+ private IMountManager $mountManager,
) {
parent::__construct();
}
@@ -60,6 +66,16 @@ class TransferOwnership extends Command {
InputOption::VALUE_OPTIONAL,
'transfer incoming user file shares to destination user. Usage: --transfer-incoming-shares=1 (value required)',
'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',
);
}
@@ -87,6 +103,31 @@ class TransferOwnership extends Command {
return self::FAILURE;
}
+ $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;
+ }
+ }
+ }
+ }
+
try {
$includeIncomingArgument = $input->getOption('transfer-incoming-shares');
@@ -112,11 +153,12 @@ class TransferOwnership extends Command {
$this->transferService->transfer(
$sourceUserObject,
$destinationUserObject,
- ltrim($input->getOption('path'), '/'),
+ $path,
$output,
$input->getOption('move') === true,
false,
- $includeIncoming
+ $includeIncoming,
+ $includeExternalStorage,
);
} catch (TransferOwnershipException $e) {
$output->writeln('<error>' . $e->getMessage() . '</error>');
diff --git a/apps/files/lib/Service/OwnershipTransferService.php b/apps/files/lib/Service/OwnershipTransferService.php
index 7f6681a9b89..b3a36ee13e5 100644
--- a/apps/files/lib/Service/OwnershipTransferService.php
+++ b/apps/files/lib/Service/OwnershipTransferService.php
@@ -15,10 +15,11 @@ use OC\Files\View;
use OC\User\NoUserException;
use OCA\Encryption\Util;
use OCA\Files\Exception\TransferOwnershipException;
+use OCA\Files_External\Config\ConfigAdapter;
use OCP\Encryption\IManager as IEncryptionManager;
+use OCP\Files\Config\IHomeMountProvider;
use OCP\Files\Config\IUserMountCache;
use OCP\Files\FileInfo;
-use OCP\Files\IHomeStorage;
use OCP\Files\InvalidPathException;
use OCP\Files\IRootFolder;
use OCP\Files\Mount\IMountManager;
@@ -70,6 +71,7 @@ class OwnershipTransferService {
bool $move = false,
bool $firstLogin = false,
bool $transferIncomingShares = false,
+ bool $includeExternalStorage = false,
): void {
$output = $output ?? new NullOutput();
$sourceUid = $sourceUser->getUID();
@@ -149,7 +151,8 @@ class OwnershipTransferService {
$sourcePath,
$finalTarget,
$view,
- $output
+ $output,
+ $includeExternalStorage,
);
$sizeDifference = $sourceSize - $view->getFileInfo($finalTarget)->getSize();
@@ -215,11 +218,14 @@ class OwnershipTransferService {
*
* @throws TransferOwnershipException
*/
- protected function analyse(string $sourceUid,
+ protected function analyse(
+ string $sourceUid,
string $destinationUid,
string $sourcePath,
View $view,
- OutputInterface $output): void {
+ OutputInterface $output,
+ bool $includeExternalStorage = false,
+ ): void {
$output->writeln('Validating quota');
$sourceFileInfo = $view->getFileInfo($sourcePath, false);
if ($sourceFileInfo === false) {
@@ -247,17 +253,22 @@ class OwnershipTransferService {
$encryptedFiles[] = $sourceFileInfo;
} else {
$this->walkFiles($view, $sourcePath,
- function (FileInfo $fileInfo) use ($progress, $masterKeyEnabled, &$encryptedFiles) {
+ function (FileInfo $fileInfo) use ($progress, $masterKeyEnabled, &$encryptedFiles, $includeExternalStorage) {
if ($fileInfo->getType() === FileInfo::TYPE_FOLDER) {
+ $mount = $fileInfo->getMountPoint();
// only analyze into folders from main storage,
- if (!$fileInfo->getStorage()->instanceOfStorage(IHomeStorage::class)) {
+ if (
+ $mount->getMountProvider() instanceof IHomeMountProvider ||
+ ($includeExternalStorage && $mount->getMountProvider() instanceof ConfigAdapter)
+ ) {
+ if ($fileInfo->isEncrypted()) {
+ /* Encrypted folder means e2ee encrypted, we cannot transfer it */
+ $encryptedFiles[] = $fileInfo;
+ }
+ return true;
+ } else {
return false;
}
- if ($fileInfo->isEncrypted()) {
- /* Encrypted folder means e2ee encrypted, we cannot transfer it */
- $encryptedFiles[] = $fileInfo;
- }
- return true;
}
$progress->advance();
if ($fileInfo->isEncrypted() && !$masterKeyEnabled) {
@@ -399,11 +410,14 @@ class OwnershipTransferService {
/**
* @throws TransferOwnershipException
*/
- protected function transferFiles(string $sourceUid,
+ protected function transferFiles(
+ string $sourceUid,
string $sourcePath,
string $finalTarget,
View $view,
- OutputInterface $output): void {
+ OutputInterface $output,
+ bool $includeExternalStorage,
+ ): void {
$output->writeln("Transferring files to $finalTarget ...");
// This change will help user to transfer the folder specified using --path option.
@@ -412,15 +426,50 @@ class OwnershipTransferService {
$view->mkdir($finalTarget);
$finalTarget = $finalTarget . '/' . basename($sourcePath);
}
- if ($view->rename($sourcePath, $finalTarget, ['checkSubMounts' => false]) === false) {
- throw new TransferOwnershipException('Could not transfer files.', 1);
+ $sourceInfo = $view->getFileInfo($sourcePath);
+
+ /// handle the external storages mounted at the root, or the admin specifying an external storage with --path
+ if ($sourceInfo->getInternalPath() === '' && $includeExternalStorage) {
+ $this->moveMountContents($view, $sourcePath, $finalTarget);
+ } else {
+ if ($view->rename($sourcePath, $finalTarget, ['checkSubMounts' => false]) === false) {
+ throw new TransferOwnershipException('Could not transfer files.', 1);
+ }
+ }
+
+ if ($includeExternalStorage) {
+ $nestedMounts = $this->mountManager->findIn($sourcePath);
+ foreach ($nestedMounts as $mount) {
+ if ($mount->getMountProvider() === ConfigAdapter::class) {
+ $relativePath = substr(trim($mount->getMountPoint(), '/'), strlen($sourcePath));
+ $this->moveMountContents($view, $mount->getMountPoint(), $finalTarget . $relativePath);
+ }
+ }
}
+
if (!is_dir("$sourceUid/files")) {
// because the files folder is moved away we need to recreate it
$view->mkdir("$sourceUid/files");
}
}
+ private function moveMountContents(View $rootView, string $source, string $target) {
+ if ($rootView->copy($source, $target)) {
+ // just doing `rmdir` on the mountpoint would cause it to try and unmount the storage
+ // we need to empty the contents instead
+ $content = $rootView->getDirectoryContent($source);
+ foreach ($content as $item) {
+ if ($item->getType() === FileInfo::TYPE_FOLDER) {
+ $rootView->rmdir($item->getPath());
+ } else {
+ $rootView->unlink($item->getPath());
+ }
+ }
+ } else {
+ throw new TransferOwnershipException("Could not transfer $source to $target");
+ }
+ }
+
/**
* @param string $targetLocation New location of the transfered node
* @param array<array{share: IShare, suffix: string}> $shares previously collected share information
diff --git a/apps/files/lib/Service/UserConfig.php b/apps/files/lib/Service/UserConfig.php
index b01caf9f960..a2f2f1c1d14 100644
--- a/apps/files/lib/Service/UserConfig.php
+++ b/apps/files/lib/Service/UserConfig.php
@@ -54,6 +54,12 @@ class UserConfig {
'default' => true,
'allowed' => [true, false],
],
+ [
+ // Whether to show the mime column or not
+ 'key' => 'show_mime_column',
+ 'default' => false,
+ 'allowed' => [true, false],
+ ]
];
protected ?IUser $user = null;