|
|
|
@ -44,6 +44,7 @@ use OCP\EventDispatcher\IEventDispatcher;
|
|
|
|
use OCP\Files\Config\IUserMountCache;
|
|
|
|
use OCP\Files\Config\IUserMountCache;
|
|
|
|
use OCP\Files\Events\Node\FilesystemTornDownEvent;
|
|
|
|
use OCP\Files\Events\Node\FilesystemTornDownEvent;
|
|
|
|
use OCP\Files\IRootFolder;
|
|
|
|
use OCP\Files\IRootFolder;
|
|
|
|
|
|
|
|
use OCP\Files\Mount\IMountPoint;
|
|
|
|
use OCP\Files\NotFoundException;
|
|
|
|
use OCP\Files\NotFoundException;
|
|
|
|
use OCP\Files\NotPermittedException;
|
|
|
|
use OCP\Files\NotPermittedException;
|
|
|
|
use OCP\IUser;
|
|
|
|
use OCP\IUser;
|
|
|
|
@ -216,7 +217,7 @@ class Root extends Folder implements IRootFolder {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param string $targetPath
|
|
|
|
* @param string $targetPath
|
|
|
|
* @return \OC\Files\Node\Node
|
|
|
|
* @return Node
|
|
|
|
* @throws \OCP\Files\NotPermittedException
|
|
|
|
* @throws \OCP\Files\NotPermittedException
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function rename($targetPath) {
|
|
|
|
public function rename($targetPath) {
|
|
|
|
@ -229,7 +230,7 @@ class Root extends Folder implements IRootFolder {
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
/**
|
|
|
|
* @param string $targetPath
|
|
|
|
* @param string $targetPath
|
|
|
|
* @return \OC\Files\Node\Node
|
|
|
|
* @return Node
|
|
|
|
* @throws \OCP\Files\NotPermittedException
|
|
|
|
* @throws \OCP\Files\NotPermittedException
|
|
|
|
*/
|
|
|
|
*/
|
|
|
|
public function copy($targetPath) {
|
|
|
|
public function copy($targetPath) {
|
|
|
|
@ -404,4 +405,82 @@ class Root extends Folder implements IRootFolder {
|
|
|
|
public function getUserMountCache() {
|
|
|
|
public function getUserMountCache() {
|
|
|
|
return $this->userMountCache;
|
|
|
|
return $this->userMountCache;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
|
|
|
* @param int $id
|
|
|
|
|
|
|
|
* @return Node[]
|
|
|
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
public function getByIdInPath(int $id, string $path): array {
|
|
|
|
|
|
|
|
$mountCache = $this->getUserMountCache();
|
|
|
|
|
|
|
|
if (strpos($path, '/', 1) > 0) {
|
|
|
|
|
|
|
|
[, $user] = explode('/', $path);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
$user = null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
$mountsContainingFile = $mountCache->getMountsForFileId($id, $user);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// when a user has access trough the same storage trough multiple paths
|
|
|
|
|
|
|
|
// (such as an external storage that is both mounted for a user and shared to the user)
|
|
|
|
|
|
|
|
// the mount cache will only hold a single entry for the storage
|
|
|
|
|
|
|
|
// this can lead to issues as the different ways the user has access to a storage can have different permissions
|
|
|
|
|
|
|
|
//
|
|
|
|
|
|
|
|
// so instead of using the cached entries directly, we instead filter the current mounts by the rootid of the cache entry
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$mountRootIds = array_map(function ($mount) {
|
|
|
|
|
|
|
|
return $mount->getRootId();
|
|
|
|
|
|
|
|
}, $mountsContainingFile);
|
|
|
|
|
|
|
|
$mountRootPaths = array_map(function ($mount) {
|
|
|
|
|
|
|
|
return $mount->getRootInternalPath();
|
|
|
|
|
|
|
|
}, $mountsContainingFile);
|
|
|
|
|
|
|
|
$mountProviders = array_unique(array_map(function ($mount) {
|
|
|
|
|
|
|
|
return $mount->getMountProvider();
|
|
|
|
|
|
|
|
}, $mountsContainingFile));
|
|
|
|
|
|
|
|
$mountRoots = array_combine($mountRootIds, $mountRootPaths);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$mounts = $this->mountManager->getMountsByMountProvider($path, $mountProviders);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$mountsContainingFile = array_filter($mounts, function ($mount) use ($mountRoots) {
|
|
|
|
|
|
|
|
return isset($mountRoots[$mount->getStorageRootId()]);
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
if (count($mountsContainingFile) === 0) {
|
|
|
|
|
|
|
|
if ($user === $this->getAppDataDirectoryName()) {
|
|
|
|
|
|
|
|
$folder = $this->get($path);
|
|
|
|
|
|
|
|
if ($folder instanceof Folder) {
|
|
|
|
|
|
|
|
return $folder->getByIdInRootMount($id);
|
|
|
|
|
|
|
|
} else {
|
|
|
|
|
|
|
|
throw new \Exception("getByIdInPath with non folder");
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
return [];
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$nodes = array_map(function (IMountPoint $mount) use ($id, $mountRoots) {
|
|
|
|
|
|
|
|
$rootInternalPath = $mountRoots[$mount->getStorageRootId()];
|
|
|
|
|
|
|
|
$cacheEntry = $mount->getStorage()->getCache()->get($id);
|
|
|
|
|
|
|
|
if (!$cacheEntry) {
|
|
|
|
|
|
|
|
return null;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// cache jails will hide the "true" internal path
|
|
|
|
|
|
|
|
$internalPath = ltrim($rootInternalPath . '/' . $cacheEntry->getPath(), '/');
|
|
|
|
|
|
|
|
$pathRelativeToMount = substr($internalPath, strlen($rootInternalPath));
|
|
|
|
|
|
|
|
$pathRelativeToMount = ltrim($pathRelativeToMount, '/');
|
|
|
|
|
|
|
|
$absolutePath = rtrim($mount->getMountPoint() . $pathRelativeToMount, '/');
|
|
|
|
|
|
|
|
return $this->createNode($absolutePath, new FileInfo(
|
|
|
|
|
|
|
|
$absolutePath, $mount->getStorage(), $cacheEntry->getPath(), $cacheEntry, $mount,
|
|
|
|
|
|
|
|
\OC::$server->getUserManager()->get($mount->getStorage()->getOwner($pathRelativeToMount))
|
|
|
|
|
|
|
|
));
|
|
|
|
|
|
|
|
}, $mountsContainingFile);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$nodes = array_filter($nodes);
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
$folders = array_filter($nodes, function (Node $node) use ($path) {
|
|
|
|
|
|
|
|
return PathHelper::getRelativePath($path, $node->getPath()) !== null;
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
usort($folders, function ($a, $b) {
|
|
|
|
|
|
|
|
return $b->getPath() <=> $a->getPath();
|
|
|
|
|
|
|
|
});
|
|
|
|
|
|
|
|
return $folders;
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|