9485b4fe63
Loading documents from the local filesystem opens the door to security issues. By default filesystem storage is disabled, even if enabled in the config file. The only way to enable it is to set the allowlocalstorage command-line argument. Change-Id: Ib8f57377260817436d101a16757aab38276cbdcd Reviewed-on: https://gerrit.libreoffice.org/23881 Reviewed-by: Ashod Nakashian <ashnakash@gmail.com> Tested-by: Ashod Nakashian <ashnakash@gmail.com>
167 lines
4.7 KiB
C++
167 lines
4.7 KiB
C++
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4; fill-column: 100 -*- */
|
|
/*
|
|
* This file is part of the LibreOffice project.
|
|
*
|
|
* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
*/
|
|
|
|
// Storage abstraction.
|
|
#ifndef INCLUDED_STORAGE_HPP
|
|
#define INCLUDED_STORAGE_HPP
|
|
|
|
#include <string>
|
|
|
|
#include <Poco/Util/Application.h>
|
|
#include <Poco/URI.h>
|
|
|
|
#include "Auth.hpp"
|
|
#include "Util.hpp"
|
|
|
|
/// Base class of all Storage abstractions.
|
|
class StorageBase
|
|
{
|
|
public:
|
|
|
|
class FileInfo
|
|
{
|
|
public:
|
|
bool isValid() const
|
|
{
|
|
return !Filename.empty() && Size > 0;
|
|
}
|
|
|
|
std::string Filename;
|
|
Poco::Timestamp ModifiedTime;
|
|
size_t Size;
|
|
};
|
|
|
|
/// localStorePath the absolute root path of the chroot.
|
|
/// jailPath the path within the jail that the child uses.
|
|
StorageBase(const std::string& localStorePath,
|
|
const std::string& jailPath,
|
|
const std::string& uri) :
|
|
_localStorePath(localStorePath),
|
|
_jailPath(jailPath),
|
|
_uri(uri)
|
|
{
|
|
Log::debug("Storage ctor: " + uri);
|
|
}
|
|
|
|
std::string getLocalRootPath() const;
|
|
|
|
const std::string& getUri() const { return _uri; }
|
|
|
|
/// Returns information about the file.
|
|
virtual FileInfo getFileInfo(const Poco::URI& uri) = 0;
|
|
|
|
/// Returns a local file path for the given URI.
|
|
/// If necessary copies the file locally first.
|
|
virtual std::string loadStorageFileToLocal() = 0;
|
|
|
|
/// Writes the contents of the file back to the source.
|
|
/// TODO: Should we save to the specific client's URI?
|
|
/// The advantage is that subseqent views (to the first)
|
|
/// will not depend on the token of the first.
|
|
virtual bool saveLocalFileToStorage() = 0;
|
|
|
|
static
|
|
size_t getFileSize(const std::string& filename);
|
|
|
|
protected:
|
|
const std::string _localStorePath;
|
|
const std::string _jailPath;
|
|
const std::string _uri;
|
|
std::string _jailedFilePath;
|
|
FileInfo _fileInfo;
|
|
};
|
|
|
|
/// Trivial implementation of local storage that does not need do anything.
|
|
class LocalStorage : public StorageBase
|
|
{
|
|
public:
|
|
LocalStorage(const std::string& localStorePath,
|
|
const std::string& jailPath,
|
|
const std::string& uri) :
|
|
StorageBase(localStorePath, jailPath, uri),
|
|
_isCopy(false)
|
|
{
|
|
}
|
|
|
|
FileInfo getFileInfo(const Poco::URI& uri) override;
|
|
|
|
std::string loadStorageFileToLocal() override;
|
|
|
|
bool saveLocalFileToStorage() override;
|
|
|
|
private:
|
|
/// True if the jailed file is not linked but copied.
|
|
bool _isCopy;
|
|
};
|
|
|
|
class WopiStorage : public StorageBase
|
|
{
|
|
public:
|
|
WopiStorage(const std::string& localStorePath,
|
|
const std::string& jailPath,
|
|
const std::string& uri) :
|
|
StorageBase(localStorePath, jailPath, uri)
|
|
{
|
|
}
|
|
|
|
FileInfo getFileInfo(const Poco::URI& uri) override;
|
|
|
|
/// uri format: http://server/<...>/wopi*/files/<id>/content
|
|
std::string loadStorageFileToLocal() override;
|
|
|
|
bool saveLocalFileToStorage() override;
|
|
};
|
|
|
|
class WebDAVStorage : public StorageBase
|
|
{
|
|
public:
|
|
WebDAVStorage(const std::string& localStorePath,
|
|
const std::string& jailPath,
|
|
const std::string& uri,
|
|
std::unique_ptr<AuthBase> authAgent) :
|
|
StorageBase(localStorePath, jailPath, uri),
|
|
_authAgent(std::move(authAgent))
|
|
{
|
|
}
|
|
|
|
FileInfo getFileInfo(const Poco::URI& uri) override;
|
|
|
|
std::string loadStorageFileToLocal() override;
|
|
|
|
bool saveLocalFileToStorage() override;
|
|
|
|
private:
|
|
std::unique_ptr<AuthBase> _authAgent;
|
|
};
|
|
|
|
inline
|
|
std::unique_ptr<StorageBase> createStorage(const std::string& jailRoot, const std::string& jailPath, const Poco::URI& uri)
|
|
{
|
|
if (uri.isRelative() || uri.getScheme() == "file")
|
|
{
|
|
if (!Poco::Util::Application::instance().config().getBool("storage.filesystem[@allow]", false))
|
|
{
|
|
Log::error("Local Storage is disabled by default. Specify allowlocalstorage on the command-line to enable.");
|
|
return nullptr;
|
|
}
|
|
|
|
Log::info("Public URI [" + uri.toString() + "] is a file.");
|
|
return std::unique_ptr<StorageBase>(new LocalStorage(jailRoot, jailPath, uri.getPath()));
|
|
}
|
|
else
|
|
{
|
|
Log::info("Public URI [" + uri.toString() +
|
|
"] assuming cloud storage.");
|
|
//TODO: Configure the storage to use. For now, assume it's WOPI.
|
|
return std::unique_ptr<StorageBase>(new WopiStorage(jailRoot, jailPath, uri.toString()));
|
|
}
|
|
}
|
|
|
|
#endif
|
|
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|