Skip to content

Commit c378e74

Browse files
committed
feat(Share20\Manager): Return all shares on IShareOwnerlessMount
Signed-off-by: provokateurin <[email protected]>
1 parent a978e0a commit c378e74

File tree

2 files changed

+99
-11
lines changed

2 files changed

+99
-11
lines changed

lib/private/Share20/Manager.php

Lines changed: 30 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
use OCP\Files\Folder;
1818
use OCP\Files\IRootFolder;
1919
use OCP\Files\Mount\IMountManager;
20+
use OCP\Files\Mount\IShareOwnerlessMount;
2021
use OCP\Files\Node;
2122
use OCP\Files\NotFoundException;
2223
use OCP\HintException;
@@ -1215,17 +1216,26 @@ public function getSharesInFolder($userId, Folder $node, $reshares = false, $sha
12151216
throw new \Exception('non-shallow getSharesInFolder is no longer supported');
12161217
}
12171218

1218-
return array_reduce($providers, function ($shares, IShareProvider $provider) use ($userId, $node, $reshares) {
1219-
$newShares = $provider->getSharesInFolder($userId, $node, $reshares);
1220-
foreach ($newShares as $fid => $data) {
1221-
if (!isset($shares[$fid])) {
1222-
$shares[$fid] = [];
1223-
}
1219+
$isOwnerless = $node->getMountPoint() instanceof IShareOwnerlessMount;
12241220

1225-
$shares[$fid] = array_merge($shares[$fid], $data);
1221+
$shares = [];
1222+
foreach ($providers as $provider) {
1223+
if ($isOwnerless) {
1224+
foreach ($node->getDirectoryListing() as $childNode) {
1225+
$data = $provider->getSharesByPath($childNode);
1226+
$fid = $childNode->getId();
1227+
$shares[$fid] ??= [];
1228+
$shares[$fid] = array_merge($shares[$fid], $data);
1229+
}
1230+
} else {
1231+
foreach ($provider->getSharesInFolder($userId, $node, $reshares) as $fid => $data) {
1232+
$shares[$fid] ??= [];
1233+
$shares[$fid] = array_merge($shares[$fid], $data);
1234+
}
12261235
}
1227-
return $shares;
1228-
}, []);
1236+
}
1237+
1238+
return $shares;
12291239
}
12301240

12311241
/**
@@ -1244,7 +1254,11 @@ public function getSharesBy($userId, $shareType, $path = null, $reshares = false
12441254
return [];
12451255
}
12461256

1247-
$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1257+
if ($path?->getMountPoint() instanceof IShareOwnerlessMount) {
1258+
$shares = array_filter($provider->getSharesByPath($path), static fn (IShare $share) => $share->getShareType() === $shareType);
1259+
} else {
1260+
$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1261+
}
12481262

12491263
/*
12501264
* Work around so we don't return expired shares but still follow
@@ -1288,7 +1302,12 @@ public function getSharesBy($userId, $shareType, $path = null, $reshares = false
12881302
$offset += $added;
12891303

12901304
// Fetch again $limit shares
1291-
$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1305+
if ($path?->getMountPoint() instanceof IShareOwnerlessMount) {
1306+
// We already fetched all shares, so end here
1307+
$shares = [];
1308+
} else {
1309+
$shares = $provider->getSharesBy($userId, $shareType, $path, $reshares, $limit, $offset);
1310+
}
12921311

12931312
// No more shares means we are done
12941313
if (empty($shares)) {

tests/lib/Share20/ManagerTest.php

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,7 @@
2323
use OCP\Files\IRootFolder;
2424
use OCP\Files\Mount\IMountManager;
2525
use OCP\Files\Mount\IMountPoint;
26+
use OCP\Files\Mount\IShareOwnerlessMount;
2627
use OCP\Files\Node;
2728
use OCP\Files\Storage\IStorage;
2829
use OCP\HintException;
@@ -2895,6 +2896,31 @@ public function testGetSharesBy(): void {
28952896
$this->assertSame($share, $shares[0]);
28962897
}
28972898

2899+
public function testGetSharesByOwnerless(): void {
2900+
$mount = $this->createMock(IShareOwnerlessMount::class);
2901+
2902+
$node = $this->createMock(Folder::class);
2903+
$node
2904+
->expects($this->once())
2905+
->method('getMountPoint')
2906+
->willReturn($mount);
2907+
2908+
$share = $this->manager->newShare();
2909+
$share->setNode($node);
2910+
$share->setShareType(IShare::TYPE_USER);
2911+
2912+
$this->defaultProvider
2913+
->expects($this->once())
2914+
->method('getSharesByPath')
2915+
->with($this->equalTo($node))
2916+
->willReturn([$share]);
2917+
2918+
$shares = $this->manager->getSharesBy('user', IShare::TYPE_USER, $node, true, 1, 1);
2919+
2920+
$this->assertCount(1, $shares);
2921+
$this->assertSame($share, $shares[0]);
2922+
}
2923+
28982924
/**
28992925
* Test to ensure we correctly remove expired link shares
29002926
*
@@ -4493,6 +4519,49 @@ public function testGetSharesInFolder(): void {
44934519
$this->assertSame($expects, $result);
44944520
}
44954521

4522+
public function testGetSharesInFolderOwnerless(): void {
4523+
$factory = new DummyFactory2($this->createMock(IServerContainer::class));
4524+
4525+
$manager = $this->createManager($factory);
4526+
4527+
$factory->setProvider($this->defaultProvider);
4528+
$extraProvider = $this->createMock(IShareProvider::class);
4529+
$factory->setSecondProvider($extraProvider);
4530+
4531+
$share1 = $this->createMock(IShare::class);
4532+
$share2 = $this->createMock(IShare::class);
4533+
4534+
$mount = $this->createMock(IShareOwnerlessMount::class);
4535+
4536+
$file = $this->createMock(File::class);
4537+
$file
4538+
->method('getId')
4539+
->willReturn(1);
4540+
4541+
$folder = $this->createMock(Folder::class);
4542+
$folder
4543+
->method('getMountPoint')
4544+
->willReturn($mount);
4545+
$folder
4546+
->method('getDirectoryListing')
4547+
->willReturn([$file]);
4548+
4549+
$this->defaultProvider
4550+
->method('getSharesByPath')
4551+
->with($file)
4552+
->willReturn([$share1]);
4553+
4554+
$extraProvider
4555+
->method('getSharesByPath')
4556+
->with($file)
4557+
->willReturn([$share2]);
4558+
4559+
$this->assertSame([
4560+
1 => [$share1, $share2],
4561+
], $manager->getSharesInFolder('user', $folder));
4562+
}
4563+
4564+
44964565
public function testGetAccessList(): void {
44974566
$factory = new DummyFactory2($this->createMock(IServerContainer::class));
44984567

0 commit comments

Comments
 (0)