aboutsummaryrefslogtreecommitdiffstats
path: root/apps/files_sharing/lib
diff options
context:
space:
mode:
authorLuka Trovic <luka@nextcloud.com>2024-11-07 19:36:36 +0100
committerLuka Trovic <luka@nextcloud.com>2024-11-18 21:24:23 +0100
commit2ca51919db2f1dc425778a4ecf9816c09c8155ed (patch)
tree791769263a20a650f5f71e8f87acc7b22ba74009 /apps/files_sharing/lib
parent8995272f60b7d30c58565aa0eeb01e39f3629644 (diff)
downloadnextcloud-server-2ca51919db2f1dc425778a4ecf9816c09c8155ed.tar.gz
nextcloud-server-2ca51919db2f1dc425778a4ecf9816c09c8155ed.zip
fix(sharing): add command to fix broken shares after ownership transferringbugfix/error-on-reshare-after-transfer-ownership
Signed-off-by: Luka Trovic <luka@nextcloud.com>
Diffstat (limited to 'apps/files_sharing/lib')
-rw-r--r--apps/files_sharing/lib/Command/FixShareOwners.php65
-rw-r--r--apps/files_sharing/lib/OrphanHelper.php24
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();
+ }
}