Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
35 changes: 29 additions & 6 deletions apps/files_sharing/lib/Cache.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

use OC\Files\Cache\FailedCache;
use OC\Files\Cache\Wrapper\CacheJail;
use OC\Files\Storage\Wrapper\Jail;
use OCP\Files\Cache\ICacheEntry;

/**
Expand Down Expand Up @@ -61,12 +62,30 @@ public function __construct($storage, ICacheEntry $sourceRootInfo) {
$this->storage = $storage;
$this->sourceRootInfo = $sourceRootInfo;
$this->numericId = $sourceRootInfo->getStorageId();

parent::__construct(
null,
$this->sourceRootInfo->getPath()
null
);
}

protected function getRoot() {
if (is_null($this->root)) {
$absoluteRoot = $this->sourceRootInfo->getPath();

// the sourceRootInfo path is the absolute path of the folder in the "real" storage
// in the case where a folder is shared from a Jail we need to ensure that the share Jail
// has it's root set relative to the source Jail
$currentStorage = $this->storage->getSourceStorage();
if ($currentStorage->instanceOfStorage(Jail::class)) {
/** @var Jail $currentStorage */
$absoluteRoot = $currentStorage->getJailedPath($absoluteRoot);
}
$this->root = $absoluteRoot;
}
return $this->root;
}

public function getCache() {
if (is_null($this->cache)) {
$sourceStorage = $this->storage->getSourceStorage();
Expand All @@ -90,7 +109,7 @@ public function getNumericStorageId() {

public function get($file) {
if ($this->rootUnchanged && ($file === '' || $file === $this->sourceRootInfo->getId())) {
return $this->formatCacheEntry(clone $this->sourceRootInfo);
return $this->formatCacheEntry(clone $this->sourceRootInfo, '');
}
return parent::get($file);
}
Expand All @@ -115,16 +134,20 @@ public function moveFromCache(\OCP\Files\Cache\ICache $sourceCache, $sourcePath,
return parent::moveFromCache($sourceCache, $sourcePath, $targetPath);
}

protected function formatCacheEntry($entry) {
$path = isset($entry['path']) ? $entry['path'] : '';
$entry = parent::formatCacheEntry($entry);
protected function formatCacheEntry($entry, $path = null) {
if (is_null($path)) {
$path = isset($entry['path']) ? $entry['path'] : '';
$entry['path'] = $this->getJailedPath($path);
} else {
$entry['path'] = $path;
}
$sharePermissions = $this->storage->getPermissions($path);
if (isset($entry['permissions'])) {
$entry['permissions'] &= $sharePermissions;
} else {
$entry['permissions'] = $sharePermissions;
}
$entry['uid_owner'] = $this->storage->getOwner($path);
$entry['uid_owner'] = $this->storage->getOwner('');
$entry['displayname_owner'] = $this->getOwnerDisplayName();
if ($path === '') {
$entry['is_share_mount_point'] = true;
Expand Down
39 changes: 39 additions & 0 deletions apps/files_sharing/tests/CacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,8 @@

namespace OCA\Files_Sharing\Tests;

use OC\Files\Storage\Temporary;
use OC\Files\Storage\Wrapper\Jail;
use OCA\Files_Sharing\SharedStorage;

/**
Expand Down Expand Up @@ -552,4 +554,41 @@ public function testNumericStorageId() {

$this->assertEquals($sourceStorage->getCache()->getNumericStorageId(), $sharedStorage->getCache()->getNumericStorageId());
}

public function testShareJailedStorage() {
$sourceStorage = new Temporary();
$sourceStorage->mkdir('jail');
$sourceStorage->mkdir('jail/sub');
$sourceStorage->file_put_contents('jail/sub/foo.txt', 'foo');
$jailedSource = new Jail([
'storage' => $sourceStorage,
'root' => 'jail'
]);
$sourceStorage->getScanner()->scan('');
$this->registerMount(self::TEST_FILES_SHARING_API_USER1, $jailedSource, '/' . self::TEST_FILES_SHARING_API_USER1 . '/files/foo');

self::loginHelper(self::TEST_FILES_SHARING_API_USER1);

$rootFolder = \OC::$server->getUserFolder(self::TEST_FILES_SHARING_API_USER1);
$node = $rootFolder->get('foo/sub');
$share = $this->shareManager->newShare();
$share->setNode($node)
->setShareType(\OCP\Share::SHARE_TYPE_USER)
->setSharedWith(self::TEST_FILES_SHARING_API_USER2)
->setSharedBy(self::TEST_FILES_SHARING_API_USER1)
->setPermissions(\OCP\Constants::PERMISSION_ALL);
$this->shareManager->createShare($share);
\OC_Util::tearDownFS();

self::loginHelper(self::TEST_FILES_SHARING_API_USER2);
$this->assertEquals('foo', \OC\Files\Filesystem::file_get_contents('/sub/foo.txt'));

\OC\Files\Filesystem::file_put_contents('/sub/bar.txt', 'bar');
/** @var SharedStorage $sharedStorage */
list($sharedStorage) = \OC\Files\Filesystem::resolvePath('/' . self::TEST_FILES_SHARING_API_USER2 . '/files/sub');

$this->assertTrue($sharedStorage->getCache()->inCache('bar.txt'));

$this->assertTrue($sourceStorage->getCache()->inCache('jail/sub/bar.txt'));
}
}
23 changes: 14 additions & 9 deletions lib/private/Files/Cache/Wrapper/CacheJail.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
*/

namespace OC\Files\Cache\Wrapper;

use OC\Files\Cache\Cache;
use OCP\Files\Cache\ICacheEntry;
use OCP\Files\Search\ISearchQuery;
Expand All @@ -48,11 +49,15 @@ public function __construct($cache, $root) {
$this->root = $root;
}

protected function getRoot() {
return $this->root;
}

protected function getSourcePath($path) {
if ($path === '') {
return $this->root;
return $this->getRoot();
} else {
return $this->root . '/' . ltrim($path, '/');
return $this->getRoot() . '/' . ltrim($path, '/');
}
}

Expand All @@ -61,13 +66,13 @@ protected function getSourcePath($path) {
* @return null|string the jailed path or null if the path is outside the jail
*/
protected function getJailedPath($path) {
if ($this->root === '') {
if ($this->getRoot() === '') {
return $path;
}
$rootLength = strlen($this->root) + 1;
if ($path === $this->root) {
$rootLength = strlen($this->getRoot()) + 1;
if ($path === $this->getRoot()) {
return '';
} else if (substr($path, 0, $rootLength) === $this->root . '/') {
} else if (substr($path, 0, $rootLength) === $this->getRoot() . '/') {
return substr($path, $rootLength);
} else {
return null;
Expand All @@ -86,8 +91,8 @@ protected function formatCacheEntry($entry) {
}

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

/**
Expand Down Expand Up @@ -189,7 +194,7 @@ protected function getMoveInfo($path) {
* remove all entries for files that are stored on the storage from the cache
*/
public function clear() {
$this->getCache()->remove($this->root);
$this->getCache()->remove($this->getRoot());
}

/**
Expand Down
11 changes: 11 additions & 0 deletions lib/private/Files/Storage/Wrapper/Jail.php
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,17 @@ public function getUnjailedPath($path) {
}
}

public function getJailedPath($path) {
$root = rtrim($this->rootPath, '/') . '/';

if (strpos($path, $root) !== 0) {
return null;
} else {
$path = substr($path, strlen($this->rootPath));
return trim($path, '/');
}
}

public function getId() {
return parent::getId();
}
Expand Down