diff options
author | Côme Chilliet <91878298+come-nc@users.noreply.github.com> | 2024-11-25 18:20:29 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-25 18:20:29 +0100 |
commit | ae7f9cb3c10ac093b901345ccbaa9835edb4e0ea (patch) | |
tree | ce1b4eb7f753cf727ce46299abf5f25ba214d24d /apps/files_sharing/lib | |
parent | d948fcb575768f13d7ddfb4a581539283fc38c38 (diff) | |
parent | 2ca51919db2f1dc425778a4ecf9816c09c8155ed (diff) | |
download | nextcloud-server-ae7f9cb3c10ac093b901345ccbaa9835edb4e0ea.tar.gz nextcloud-server-ae7f9cb3c10ac093b901345ccbaa9835edb4e0ea.zip |
Merge pull request #43025 from nextcloud/bugfix/error-on-reshare-after-transfer-ownership
fix: update re-share if shared-by user has been revoked
Diffstat (limited to 'apps/files_sharing/lib')
-rw-r--r-- | apps/files_sharing/lib/Command/FixShareOwners.php | 65 | ||||
-rw-r--r-- | apps/files_sharing/lib/OrphanHelper.php | 24 |
2 files changed, 89 insertions, 0 deletions
diff --git a/apps/files_sharing/lib/Command/FixShareOwners.php b/apps/files_sharing/lib/Command/FixShareOwners.php new file mode 100644 index 00000000000..1cf5f82f5a8 --- /dev/null +++ b/apps/files_sharing/lib/Command/FixShareOwners.php @@ -0,0 +1,65 @@ +<?php + +declare(strict_types=1); +/** + * SPDX-FileCopyrightText: 2024 Nextcloud GmbH and Nextcloud contributors + * SPDX-License-Identifier: AGPL-3.0-or-later + */ + +namespace OCA\Files_Sharing\Command; + +use OC\Core\Command\Base; +use OCA\Files_Sharing\OrphanHelper; +use Symfony\Component\Console\Input\InputInterface; +use Symfony\Component\Console\Input\InputOption; +use Symfony\Component\Console\Output\OutputInterface; + +class FixShareOwners extends Base { + public function __construct( + private readonly OrphanHelper $orphanHelper, + ) { + parent::__construct(); + } + + protected function configure(): void { + $this + ->setName('sharing:fix-share-owners') + ->setDescription('Fix owner of broken shares after transfer ownership on old versions') + ->addOption( + 'dry-run', + null, + InputOption::VALUE_NONE, + 'only show which shares would be updated' + ); + } + + public function execute(InputInterface $input, OutputInterface $output): int { + $shares = $this->orphanHelper->getAllShares(); + $dryRun = $input->getOption('dry-run'); + $count = 0; + + foreach ($shares as $share) { + if ($this->orphanHelper->isShareValid($share['owner'], $share['fileid']) || !$this->orphanHelper->fileExists($share['fileid'])) { + continue; + } + + $owner = $this->orphanHelper->findOwner($share['fileid']); + + if ($owner !== null) { + if ($dryRun) { + $output->writeln("Share with id <info>{$share['id']}</info> (target: <info>{$share['target']}</info>) can be updated to owner <info>$owner</info>"); + } else { + $this->orphanHelper->updateShareOwner($share['id'], $owner); + $output->writeln("Share with id <info>{$share['id']}</info> (target: <info>{$share['target']}</info>) updated to owner <info>$owner</info>"); + } + $count++; + } + } + + if ($count === 0) { + $output->writeln('No broken shares detected'); + } + + return static::SUCCESS; + } +} diff --git a/apps/files_sharing/lib/OrphanHelper.php b/apps/files_sharing/lib/OrphanHelper.php index 220de619c87..4a52af0406c 100644 --- a/apps/files_sharing/lib/OrphanHelper.php +++ b/apps/files_sharing/lib/OrphanHelper.php @@ -10,6 +10,7 @@ namespace OCA\Files_Sharing; use OC\User\NoUserException; use OCP\DB\QueryBuilder\IQueryBuilder; +use OCP\Files\Config\IUserMountCache; use OCP\Files\IRootFolder; use OCP\IDBConnection; @@ -17,6 +18,7 @@ class OrphanHelper { public function __construct( private IDBConnection $connection, private IRootFolder $rootFolder, + private IUserMountCache $userMountCache, ) { } @@ -68,4 +70,26 @@ class OrphanHelper { ]; } } + + public function findOwner(int $fileId): ?string { + $mounts = $this->userMountCache->getMountsForFileId($fileId); + if (!$mounts) { + return null; + } + foreach ($mounts as $mount) { + $userHomeMountPoint = '/' . $mount->getUser()->getUID() . '/'; + if ($mount->getMountPoint() === $userHomeMountPoint) { + return $mount->getUser()->getUID(); + } + } + return null; + } + + public function updateShareOwner(int $shareId, string $owner): void { + $query = $this->connection->getQueryBuilder(); + $query->update('share') + ->set('uid_owner', $query->createNamedParameter($owner)) + ->where($query->expr()->eq('id', $query->createNamedParameter($shareId, IQueryBuilder::PARAM_INT))); + $query->executeStatement(); + } } |