diff options
Diffstat (limited to 'apps/files/lib/Command')
-rw-r--r-- | apps/files/lib/Command/SanitizeFilenames.php | 50 | ||||
-rw-r--r-- | apps/files/lib/Command/TransferOwnership.php | 46 |
2 files changed, 60 insertions, 36 deletions
diff --git a/apps/files/lib/Command/SanitizeFilenames.php b/apps/files/lib/Command/SanitizeFilenames.php index ea01afd20d6..a404f0b3fd9 100644 --- a/apps/files/lib/Command/SanitizeFilenames.php +++ b/apps/files/lib/Command/SanitizeFilenames.php @@ -27,7 +27,7 @@ use Symfony\Component\Console\Output\OutputInterface; class SanitizeFilenames extends Base { private OutputInterface $output; - private string $charReplacement; + private ?string $charReplacement; private bool $dryRun; public function __construct( @@ -43,10 +43,6 @@ class SanitizeFilenames extends Base { protected function configure(): void { parent::configure(); - $forbiddenCharacter = $this->filenameValidator->getForbiddenCharacters(); - $charReplacement = array_diff([' ', '_', '-'], $forbiddenCharacter); - $charReplacement = reset($charReplacement) ?: ''; - $this ->setName('files:sanitize-filenames') ->setDescription('Renames files to match naming constraints') @@ -65,16 +61,25 @@ class SanitizeFilenames extends Base { 'c', mode: InputOption::VALUE_REQUIRED, description: 'Replacement for invalid character (by default space, underscore or dash is used)', - default: $charReplacement, ); } protected function execute(InputInterface $input, OutputInterface $output): int { $this->charReplacement = $input->getOption('char-replacement'); - if ($this->charReplacement === '' || mb_strlen($this->charReplacement) > 1) { - $output->writeln('<error>No character replacement given</error>'); - return 1; + // check if replacement is needed + $c = $this->filenameValidator->getForbiddenCharacters(); + if (count($c) > 0) { + try { + $this->filenameValidator->sanitizeFilename($c[0], $this->charReplacement); + } catch (\InvalidArgumentException) { + if ($this->charReplacement === null) { + $output->writeln('<error>Character replacement required</error>'); + } else { + $output->writeln('<error>Invalid character replacement given</error>'); + } + return 1; + } } $this->dryRun = $input->getOption('dry-run'); @@ -115,8 +120,8 @@ class SanitizeFilenames extends Base { try { $oldName = $node->getName(); - if (!$this->filenameValidator->isFilenameValid($oldName)) { - $newName = $this->sanitizeName($oldName); + $newName = $this->filenameValidator->sanitizeFilename($oldName, $this->charReplacement); + if ($oldName !== $newName) { $newName = $folder->getNonExistingName($newName); $path = rtrim(dirname($node->getPath()), '/'); @@ -142,27 +147,4 @@ class SanitizeFilenames extends Base { } } - private function sanitizeName(string $name): string { - $l10n = $this->l10nFactory->get('files'); - - foreach ($this->filenameValidator->getForbiddenExtensions() as $extension) { - if (str_ends_with($name, $extension)) { - $name = substr($name, 0, strlen($name) - strlen($extension)); - } - } - - $basename = substr($name, 0, strpos($name, '.', 1) ?: null); - if (in_array($basename, $this->filenameValidator->getForbiddenBasenames())) { - $name = str_replace($basename, $l10n->t('%1$s (renamed)', [$basename]), $name); - } - - if ($name === '') { - $name = $l10n->t('renamed file'); - } - - $forbiddenCharacter = $this->filenameValidator->getForbiddenCharacters(); - $name = str_replace($forbiddenCharacter, $this->charReplacement, $name); - - return $name; - } } 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>'); |