Skip to content

Commit 164096a

Browse files
authored
Merge pull request #22804 from nextcloud/backport/stable19/22116-22648-22761
[stable19] Fix share transfer of single files and on the transfered node
2 parents ed22e1b + 083d1da commit 164096a

File tree

6 files changed

+371
-5
lines changed

6 files changed

+371
-5
lines changed

apps/files/lib/Service/OwnershipTransferService.php

Lines changed: 37 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,12 +35,14 @@
3535
use OC\Files\View;
3636
use OCA\Files\Exception\TransferOwnershipException;
3737
use OCP\Encryption\IManager as IEncryptionManager;
38+
use OCP\Files\Config\IUserMountCache;
3839
use OCP\Files\FileInfo;
3940
use OCP\Files\IHomeStorage;
4041
use OCP\Files\InvalidPathException;
4142
use OCP\Files\Mount\IMountManager;
4243
use OCP\IUser;
4344
use OCP\Share\IManager as IShareManager;
45+
use OCP\Share\IShare;
4446
use Symfony\Component\Console\Helper\ProgressBar;
4547
use Symfony\Component\Console\Output\NullOutput;
4648
use Symfony\Component\Console\Output\OutputInterface;
@@ -62,12 +64,17 @@ class OwnershipTransferService {
6264
/** @var IMountManager */
6365
private $mountManager;
6466

67+
/** @var IUserMountCache */
68+
private $userMountCache;
69+
6570
public function __construct(IEncryptionManager $manager,
6671
IShareManager $shareManager,
67-
IMountManager $mountManager) {
72+
IMountManager $mountManager,
73+
IUserMountCache $userMountCache) {
6874
$this->encryptionManager = $manager;
6975
$this->shareManager = $shareManager;
7076
$this->mountManager = $mountManager;
77+
$this->userMountCache = $userMountCache;
7178
}
7279

7380
/**
@@ -148,7 +155,9 @@ public function transfer(IUser $sourceUser,
148155
// collect all the shares
149156
$shares = $this->collectUsersShares(
150157
$sourceUid,
151-
$output
158+
$output,
159+
$view,
160+
$sourcePath
152161
);
153162

154163
// transfer the files
@@ -233,7 +242,9 @@ function (FileInfo $fileInfo) use ($progress) {
233242
}
234243

235244
private function collectUsersShares(string $sourceUid,
236-
OutputInterface $output): array {
245+
OutputInterface $output,
246+
View $view,
247+
string $path): array {
237248
$output->writeln("Collecting all share information for files and folders of $sourceUid ...");
238249

239250
$shares = [];
@@ -246,6 +257,23 @@ private function collectUsersShares(string $sourceUid,
246257
if (empty($sharePage)) {
247258
break;
248259
}
260+
if ($path !== "$sourceUid/files") {
261+
$sharePage = array_filter($sharePage, function (IShare $share) use ($view, $path) {
262+
try {
263+
$relativePath = $view->getPath($share->getNodeId());
264+
$singleFileTranfer = $view->is_file($path);
265+
if ($singleFileTranfer) {
266+
return Filesystem::normalizePath($relativePath) === Filesystem::normalizePath($path);
267+
}
268+
269+
return mb_strpos(
270+
Filesystem::normalizePath($relativePath . '/', false),
271+
Filesystem::normalizePath($path . '/', false)) === 0;
272+
} catch (\Exception $e) {
273+
return false;
274+
}
275+
});
276+
}
249277
$shares = array_merge($shares, $sharePage);
250278
$offset += 50;
251279
}
@@ -306,6 +334,12 @@ private function restoreShares(string $sourceUid,
306334
$share->setSharedBy($destinationUid);
307335
}
308336

337+
338+
// trigger refetching of the node so that the new owner and mountpoint are taken into account
339+
// otherwise the checks on the share update will fail due to the original node not being available in the new user scope
340+
$this->userMountCache->clear();
341+
$share->setNodeId($share->getNode()->getId());
342+
309343
$this->shareManager->updateShare($share);
310344
}
311345
} catch (\OCP\Files\NotFoundException $e) {

build/integration/features/bootstrap/CommandLineContext.php

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
require __DIR__ . '/../../vendor/autoload.php';
2727

2828
use Behat\Behat\Hook\Scope\BeforeScenarioScope;
29+
use PHPUnit\Framework\Assert;
2930

3031
class CommandLineContext implements \Behat\Behat\Context\Context {
3132
use CommandLine;
@@ -128,4 +129,11 @@ public function usingTransferFolderAsDavPath($user) {
128129
$davPath = rtrim($davPath, '/') . $this->lastTransferPath;
129130
$this->featureContext->usingDavPath($davPath);
130131
}
132+
133+
/**
134+
* @Then /^transfer folder name contains "([^"]+)"$/
135+
*/
136+
public function transferFolderNameContains($text) {
137+
Assert::assertContains($text, $this->lastTransferPath);
138+
}
131139
}

build/integration/features/bootstrap/Provisioning.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public function assureUserExists($user) {
7070
}
7171

7272
/**
73-
* @Given /^user "([^"]*)" with displayname "([^"]*)" exists$/
73+
* @Given /^user "([^"]*)" with displayname "((?:[^"]|\\")*)" exists$/
7474
* @param string $user
7575
*/
7676
public function assureUserWithDisplaynameExists($user, $displayname) {

0 commit comments

Comments
 (0)