added relative_path functionality to getGroupFolderDirectory

This commit is contained in:
Jonathan Treffler 2024-01-23 22:02:48 +01:00 committed by root
parent 93cf10d00d
commit c13e8dfcb2

View file

@ -5,50 +5,68 @@ namespace OCA\GroupfolderFilesystemSnapshots\Manager;
use OCP\IConfig; use OCP\IConfig;
use OCP\Files\IRootFolder; use OCP\Files\IRootFolder;
use OCA\GroupFolders\Folder\FolderManager; use OCA\GroupFolders\Folder\FolderManager;
use OCA\GroupFolders\Mount\MountProvider;
class PathManager { class PathManager {
private IConfig $config; private IConfig $config;
private IRootFolder $rootFolder; private IRootFolder $rootFolder;
private FolderManager $groupfolderFolderManager; private FolderManager $groupfolderFolderManager;
/** @var MountProvider */
protected $mountProvider;
const FILESYSTEM_ROOT_PATH = "/srv/nextcloud/files/"; const FILESYSTEM_ROOT_PATH = "/srv/nextcloud/files/";
const FILESYSTEM_SNAPSHOT_PATH = "/srv/nextcloud/files/.zfs/snapshot/"; const FILESYSTEM_SNAPSHOT_PATH = "/srv/nextcloud/files/.zfs/snapshot/";
public function __construct(IConfig $config, IRootFolder $rootFolder, FolderManager $manager){ public function __construct(
$this->config = $config; IConfig $config,
$this->groupfolderFolderManager = $manager; IRootFolder $rootFolder,
$this->rootFolder = $rootFolder; FolderManager $manager,
} MountProvider $mountProvider,
){
$this->config = $config;
$this->groupfolderFolderManager = $manager;
$this->rootFolder = $rootFolder;
$this->mountProvider = $mountProvider;
}
public function getFilesystemSnapshotPath() { public function getFilesystemSnapshotPath() {
return self::FILESYSTEM_SNAPSHOT_PATH; return self::FILESYSTEM_SNAPSHOT_PATH;
} }
// Nextcloud general // Nextcloud general
public function getDataDirectory() { public function getDataDirectory() {
return $this->config->getSystemValue("datadirectory"); return $this->config->getSystemValue("datadirectory");
} }
private function getRootFolderStorageId(): ?int { private function getRootFolderStorageId(): ?int {
return $this->rootFolder->getMountPoint()->getNumericStorageId(); return $this->rootFolder->getMountPoint()->getNumericStorageId();
} }
// Snapshots // Snapshots
public function getSnapshotPath(string $snapshotId) { public function getSnapshotPath(string $snapshotId) {
return realpath(self::FILESYSTEM_SNAPSHOT_PATH . DIRECTORY_SEPARATOR . $snapshotId . DIRECTORY_SEPARATOR); return realpath(self::FILESYSTEM_SNAPSHOT_PATH . DIRECTORY_SEPARATOR . $snapshotId . DIRECTORY_SEPARATOR);
} }
public function convertToSnapshotPath(string $filesystemPath, string $snapshotId) { public function convertToSnapshotPath(string $filesystemPath, string $snapshotId) {
$filesystemPath = realpath($filesystemPath); $filesystemPath = realpath($filesystemPath);
if(!str_starts_with($filesystemPath, self::FILESYSTEM_ROOT_PATH)) { if(!str_starts_with($filesystemPath, self::FILESYSTEM_ROOT_PATH)) {
return false; return false;
} }
return str_replace(self::FILESYSTEM_ROOT_PATH, $this->getSnapshotPath($snapshotId) . DIRECTORY_SEPARATOR, $filesystemPath); return str_replace(self::FILESYSTEM_ROOT_PATH, $this->getSnapshotPath($snapshotId) . DIRECTORY_SEPARATOR, $filesystemPath);
} }
// Groupfolders // Groupfolders
public function getGroupfolderById(int $groupfolderId) {
$storageId = $this->getRootFolderStorageId();
if (!is_null($storageId)) {
return $this->groupfolderFolderManager->getFolder($groupfolderId, $storageId);
}
}
public function getGroupfolderMountById(int $groupfolderId) {
return $this->mountProvider->getFolder($groupfolderId, False);
}
private function checkIfGroupfolderExists(int $groupfolderId): bool { private function checkIfGroupfolderExists(int $groupfolderId): bool {
$storageId = $this->getRootFolderStorageId(); $storageId = $this->getRootFolderStorageId();
if ($storageId === null) { if ($storageId === null) {
@ -63,16 +81,27 @@ class PathManager {
return true; return true;
} }
public function getGroupFolderDirectory(int $groupfolderId) { public function getGroupFolderDirectory(int $groupfolderId, string $relativePath) {
$folderExistsCheck = $this->checkIfGroupfolderExists($groupfolderId); $groupFolder = $this->getGroupfolderMountById($groupfolderId);
if(!$folderExistsCheck) { $relativeToDataDirectoryPath = $groupFolder->get($relativePath)->getInternalPath();
return $folderExistsCheck; $minPath = realpath($this->getDataDirectory() . DIRECTORY_SEPARATOR . $groupFolder->getInternalPath() . DIRECTORY_SEPARATOR);
} $realPath = realpath($this->getDataDirectory() . DIRECTORY_SEPARATOR . $relativeToDataDirectoryPath . DIRECTORY_SEPARATOR);
return realpath($this->getDataDirectory() . DIRECTORY_SEPARATOR . "__groupfolders" . DIRECTORY_SEPARATOR . $groupfolderId . DIRECTORY_SEPARATOR); // Data directory and groupfolder directory have to actually exist
if(!file_exists($minPath) || !file_exists($realPath)) {
return false;
}
// the group subfolder directory always has to start with the groupfolder directory
// prevents usage of ".." in relativePath to escape out of groupfolder or even data directory
if(!str_starts_with($realPath, $minPath)) {
return false;
}
return $realPath;
} }
public function getGroupFolderSnapshotDirectory(int $groupfolderId, string $snapshotId) { public function getGroupFolderSnapshotDirectory(int $groupfolderId, string $relativePath, string $snapshotId) {
return $this->convertToSnapshotPath($this->getGroupFolderDirectory($groupfolderId), $snapshotId); return $this->convertToSnapshotPath($this->getGroupFolderDirectory($groupfolderId, $relativePath), $snapshotId);
} }
} }