Skip to content

Commit 5dd15c4

Browse files
authored
Merge pull request #7323 from nextcloud/shared-jailed-source-root-12
[12]Use the correct root for shared jail when the source storage is also a jail
2 parents 53fa7fb + 4144580 commit 5dd15c4

File tree

4 files changed

+93
-15
lines changed

4 files changed

+93
-15
lines changed

apps/files_sharing/lib/Cache.php

Lines changed: 29 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@
2929

3030
use OC\Files\Cache\FailedCache;
3131
use OC\Files\Cache\Wrapper\CacheJail;
32+
use OC\Files\Storage\Wrapper\Jail;
3233
use OCP\Files\Cache\ICacheEntry;
3334

3435
/**
@@ -61,12 +62,30 @@ public function __construct($storage, ICacheEntry $sourceRootInfo) {
6162
$this->storage = $storage;
6263
$this->sourceRootInfo = $sourceRootInfo;
6364
$this->numericId = $sourceRootInfo->getStorageId();
65+
6466
parent::__construct(
6567
null,
66-
$this->sourceRootInfo->getPath()
68+
null
6769
);
6870
}
6971

72+
protected function getRoot() {
73+
if (is_null($this->root)) {
74+
$absoluteRoot = $this->sourceRootInfo->getPath();
75+
76+
// the sourceRootInfo path is the absolute path of the folder in the "real" storage
77+
// in the case where a folder is shared from a Jail we need to ensure that the share Jail
78+
// has it's root set relative to the source Jail
79+
$currentStorage = $this->storage->getSourceStorage();
80+
if ($currentStorage->instanceOfStorage(Jail::class)) {
81+
/** @var Jail $currentStorage */
82+
$absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
83+
}
84+
$this->root = $absoluteRoot;
85+
}
86+
return $this->root;
87+
}
88+
7089
public function getCache() {
7190
if (is_null($this->cache)) {
7291
$sourceStorage = $this->storage->getSourceStorage();
@@ -90,7 +109,7 @@ public function getNumericStorageId() {
90109

91110
public function get($file) {
92111
if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
93-
return $this->formatCacheEntry(clone $this->sourceRootInfo);
112+
return $this->formatCacheEntry(clone $this->sourceRootInfo, '');
94113
}
95114
return parent::get($file);
96115
}
@@ -115,16 +134,20 @@ public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath,
115134
return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
116135
}
117136

118-
protected function formatCacheEntry($entry) {
119-
$path = isset($entry['path']) ? $entry['path'] : '';
120-
$entry = parent::formatCacheEntry($entry);
137+
protected function formatCacheEntry($entry, $path = null) {
138+
if (is_null($path)) {
139+
$path = isset($entry['path']) ? $entry['path'] : '';
140+
$entry['path'] = $this->getJailedPath($path);
141+
} else {
142+
$entry['path'] = $path;
143+
}
121144
$sharePermissions = $this->storage->getPermissions($path);
122145
if (isset($entry['permissions'])) {
123146
$entry['permissions'] &= $sharePermissions;
124147
} else {
125148
$entry['permissions'] = $sharePermissions;
126149
}
127-
$entry['uid_owner'] = $this->storage->getOwner($path);
150+
$entry['uid_owner'] = $this->storage->getOwner('');
128151
$entry['displayname_owner'] = $this->getOwnerDisplayName();
129152
if ($path === '') {
130153
$entry['is_share_mount_point'] = true;

apps/files_sharing/tests/CacheTest.php

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,8 @@
3030

3131
namespace OCA\Files_Sharing\Tests;
3232

33+
use OC\Files\Storage\Temporary;
34+
use OC\Files\Storage\Wrapper\Jail;
3335
use OCA\Files_Sharing\SharedStorage;
3436

3537
/**
@@ -552,4 +554,41 @@ public function testNumericStorageId() {
552554

553555
$this->assertEquals($sourceStorage->getCache()->getNumericStorageId(), $sharedStorage->getCache()->getNumericStorageId());
554556
}
557+
558+
public function testShareJailedStorage() {
559+
$sourceStorage = new Temporary();
560+
$sourceStorage->mkdir('jail');
561+
$sourceStorage->mkdir('jail/sub');
562+
$sourceStorage->file_put_contents('jail/sub/foo.txt', 'foo');
563+
$jailedSource = new Jail([
564+
'storage' => $sourceStorage,
565+
'root' => 'jail'
566+
]);
567+
$sourceStorage->getScanner()->scan('');
568+
$this->registerMount(self::TEST_FILES_SHARING_API_USER1, $jailedSource, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');
569+
570+
self::loginHelper(self::TEST_FILES_SHARING_API_USER1);
571+
572+
$rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
573+
$node = $rootFolder->get('foo/sub');
574+
$share = $this->shareManager->newShare();
575+
$share->setNode($node)
576+
->setShareType(\OCP\Share::SHARE_TYPE_USER)
577+
->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
578+
->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
579+
->setPermissions(\OCP\Constants::PERMISSION_ALL);
580+
$this->shareManager->createShare($share);
581+
\OC_Util::tearDownFS();
582+
583+
self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
584+
$this->assertEquals('foo', \OC\Files\Filesystem::file_get_contents('/sub/foo.txt'));
585+
586+
\OC\Files\Filesystem::file_put_contents('/sub/bar.txt', 'bar');
587+
/** @var SharedStorage $sharedStorage */
588+
list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/sub');
589+
590+
$this->assertTrue($sharedStorage->getCache()->inCache('bar.txt'));
591+
592+
$this->assertTrue($sourceStorage->getCache()->inCache('jail/sub/bar.txt'));
593+
}
555594
}

lib/private/Files/Cache/Wrapper/CacheJail.php

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
*/
2727

2828
namespace OC\Files\Cache\Wrapper;
29+
2930
use OC\Files\Cache\Cache;
3031
use OCP\Files\Cache\ICacheEntry;
3132
use OCP\Files\Search\ISearchQuery;
@@ -48,11 +49,15 @@ public function __construct($cache, $root) {
4849
$this->root = $root;
4950
}
5051

52+
protected function getRoot() {
53+
return $this->root;
54+
}
55+
5156
protected function getSourcePath($path) {
5257
if ($path === '') {
53-
return $this->root;
58+
return $this->getRoot();
5459
} else {
55-
return $this->root . '/' . ltrim($path, '/');
60+
return $this->getRoot() . '/' . ltrim($path, '/');
5661
}
5762
}
5863

@@ -61,13 +66,13 @@ protected function getSourcePath($path) {
6166
* @return null|string the jailed path or null if the path is outside the jail
6267
*/
6368
protected function getJailedPath($path) {
64-
if ($this->root === '') {
69+
if ($this->getRoot() === '') {
6570
return $path;
6671
}
67-
$rootLength = strlen($this->root) + 1;
68-
if ($path === $this->root) {
72+
$rootLength = strlen($this->getRoot()) + 1;
73+
if ($path === $this->getRoot()) {
6974
return '';
70-
} else if (substr($path, 0, $rootLength) === $this->root . '/') {
75+
} else if (substr($path, 0, $rootLength) === $this->getRoot() . '/') {
7176
return substr($path, $rootLength);
7277
} else {
7378
return null;
@@ -86,8 +91,8 @@ protected function formatCacheEntry($entry) {
8691
}
8792

8893
protected function filterCacheEntry($entry) {
89-
$rootLength = strlen($this->root) + 1;
90-
return ($entry['path'] === $this->root) or (substr($entry['path'], 0, $rootLength) === $this->root . '/');
94+
$rootLength = strlen($this->getRoot()) + 1;
95+
return ($entry['path'] === $this->getRoot()) or (substr($entry['path'], 0, $rootLength) === $this->getRoot() . '/');
9196
}
9297

9398
/**
@@ -189,7 +194,7 @@ protected function getMoveInfo($path) {
189194
* remove all entries for files that are stored on the storage from the cache
190195
*/
191196
public function clear() {
192-
$this->getCache()->remove($this->root);
197+
$this->getCache()->remove($this->getRoot());
193198
}
194199

195200
/**

lib/private/Files/Storage/Wrapper/Jail.php

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ public function getUnjailedPath($path) {
5858
}
5959
}
6060

61+
public function getJailedPath($path) {
62+
$root = rtrim($this->rootPath, '/') . '/';
63+
64+
if (strpos($path, $root) !== 0) {
65+
return null;
66+
} else {
67+
$path = substr($path, strlen($this->rootPath));
68+
return trim($path, '/');
69+
}
70+
}
71+
6172
public function getId() {
6273
return parent::getId();
6374
}

0 commit comments

Comments
 (0)