Skip to content

Commit 5bc50e9

Browse files
committed
fix: preserve link shares on ownership transfer
Signed-off-by: Salvatore Martire <4652631+salmart-dev@users.noreply.github.com>
1 parent 254f721 commit 5bc50e9

1 file changed

Lines changed: 31 additions & 0 deletions

File tree

apps/files/lib/Service/OwnershipTransferService.php

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
use OCA\Files\Exception\TransferOwnershipException;
1919
use OCA\Files_External\Config\ConfigAdapter;
2020
use OCA\GroupFolders\Mount\GroupMountPoint;
21+
use OCP\DB\QueryBuilder\IQueryBuilder;
2122
use OCP\Encryption\IManager as IEncryptionManager;
2223
use OCP\Files\Config\IHomeMountProvider;
2324
use OCP\Files\Config\IUserMountCache;
@@ -27,6 +28,7 @@
2728
use OCP\Files\IRootFolder;
2829
use OCP\Files\Mount\IMountManager;
2930
use OCP\Files\NotFoundException;
31+
use OCP\IDBConnection;
3032
use OCP\IUser;
3133
use OCP\IUserManager;
3234
use OCP\L10N\IFactory;
@@ -53,6 +55,7 @@ public function __construct(
5355
private IUserManager $userManager,
5456
private IFactory $l10nFactory,
5557
private IRootFolder $rootFolder,
58+
private IDBConnection $connection,
5659
) {
5760
}
5861

@@ -388,6 +391,9 @@ private function collectUsersShares(
388391
}, $shares)));
389392
}
390393

394+
/**
395+
* @return array<int, IShare> shares keyed by node ID
396+
*/
391397
private function collectIncomingShares(
392398
string $sourceUid,
393399
OutputInterface $output,
@@ -517,6 +523,8 @@ private function restoreShares(
517523
if ($shareMountPoint) {
518524
$this->mountManager->removeMount($shareMountPoint->getMountPoint());
519525
}
526+
527+
$this->promoteLinkShares($share);
520528
$this->shareManager->deleteShare($share);
521529
} else {
522530
if ($share->getShareOwner() === $sourceUid) {
@@ -565,6 +573,10 @@ private function restoreShares(
565573
$output->writeln('');
566574
}
567575

576+
/**
577+
* @param array<int, IShare> $sourceShares shares of the source user, keyed by node ID
578+
* @param array<int, IShare> $destinationShares shares of the destination user, keyed by node ID
579+
*/
568580
private function transferIncomingShares(string $sourceUid,
569581
string $destinationUid,
570582
array $sourceShares,
@@ -594,11 +606,13 @@ private function transferIncomingShares(string $sourceUid,
594606
$shareTarget = $finalShareTarget . $shareTarget;
595607
if ($share->getShareType() === IShare::TYPE_USER
596608
&& $share->getSharedBy() === $destinationUid) {
609+
$this->promoteLinkShares($share);
597610
$this->shareManager->deleteShare($share);
598611
} elseif (isset($destinationShares[$share->getNodeId()])) {
599612
$destinationShare = $destinationShares[$share->getNodeId()];
600613
// Keep the share which has the most permissions and discard the other one.
601614
if ($destinationShare->getPermissions() < $share->getPermissions()) {
615+
$this->promoteLinkShares($destinationShare, $share->getId());
602616
$this->shareManager->deleteShare($destinationShare);
603617
$share->setSharedWith($destinationUid);
604618
// trigger refetching of the node so that the new owner and mountpoint are taken into account
@@ -615,8 +629,10 @@ private function transferIncomingShares(string $sourceUid,
615629
$this->shareManager->moveShare($share, $destinationUid);
616630
continue;
617631
}
632+
$this->promoteLinkShares($share, $destinationShare->getId());
618633
$this->shareManager->deleteShare($share);
619634
} elseif ($share->getShareOwner() === $destinationUid) {
635+
$this->promoteLinkShares($share);
620636
$this->shareManager->deleteShare($share);
621637
} else {
622638
$share->setSharedWith($destinationUid);
@@ -644,4 +660,19 @@ private function transferIncomingShares(string $sourceUid,
644660
$progress->finish();
645661
$output->writeln('');
646662
}
663+
664+
/**
665+
* Sets the parent column of the link/email shares with $share as parent to
666+
* `null` or, if provided, to $newParentId.
667+
*/
668+
private function promoteLinkShares(IShare $share, ?string $newParentId = null): void {
669+
$qb = $this->connection->getQueryBuilder();
670+
$parentParam = $newParentId === null ? $qb->createNamedParameter(null, IQueryBuilder::PARAM_NULL) : $qb->createNamedParameter($newParentId, IQueryBuilder::PARAM_STR);
671+
672+
$qb->update('share')
673+
->set('parent', $parentParam)
674+
->where($qb->expr()->eq('parent', $qb->createNamedParameter($share->getId())))
675+
->andWhere($qb->expr()->in('share_type', $qb->createNamedParameter([IShare::TYPE_LINK, IShare::TYPE_EMAIL], IQueryBuilder::PARAM_INT_ARRAY)))
676+
->executeStatement();
677+
}
647678
}

0 commit comments

Comments
 (0)