loleaflet/debug/document/loleaflet.html | 4 ++ loleaflet/html/loleaflet.html.m4 | 1 loleaflet/js/main.js | 13 ++++++-- loolwsd.xml.in | 5 +-- wsd/FileServer.cpp | 28 ++++++++--------- wsd/Storage.cpp | 52 ++++++++++++++++++++++++++------ wsd/Storage.hpp | 13 ++++++-- 7 files changed, 86 insertions(+), 30 deletions(-)
New commits: commit 8deecf4ea6966c059458bdc71e365be426238e09 Author: Ashod Nakashian <[email protected]> AuthorDate: Mon Aug 26 21:16:54 2019 -0400 Commit: Andras Timar <[email protected]> CommitDate: Wed Aug 28 14:15:20 2019 +0200 Reuse cookies from the browser Change-Id: I96bbdd3e71bc9d0ecfddea7debc0ebcc303a49ae Reviewed-on: https://gerrit.libreoffice.org/78195 Reviewed-by: Andras Timar <[email protected]> Tested-by: Andras Timar <[email protected]> diff --git a/loleaflet/debug/document/loleaflet.html b/loleaflet/debug/document/loleaflet.html index 868e4f504..8736916dc 100644 --- a/loleaflet/debug/document/loleaflet.html +++ b/loleaflet/debug/document/loleaflet.html @@ -94,12 +94,16 @@ var wopiSrc = getParameterByName('WOPISrc'); var access_token = '%ACCESS_TOKEN%'; var access_header = '%ACCESS_HEADER%'; + var reuse_cookies = '%REUSE_COOKIES%'; if (wopiSrc !== '' && access_token !== '') { wopiSrc += '?access_token=' + access_token; } else if (wopiSrc !== '' && access_header !== '') { wopiSrc += '?access_header=' + access_header; } + else if (wopiSrc !== '' && reuse_cookies !== '') { + wopiSrc += '?reuse_cookies=' + reuse_cookies; + } var host = '%HOST%'; var filePath = getParameterByName('file_path'); diff --git a/loleaflet/html/loleaflet.html.m4 b/loleaflet/html/loleaflet.html.m4 index bc16fb254..a897aafc5 100644 --- a/loleaflet/html/loleaflet.html.m4 +++ b/loleaflet/html/loleaflet.html.m4 @@ -169,6 +169,7 @@ ifelse(MOBILEAPP,[true], window.loleafletLogging = '%LOLEAFLET_LOGGING%'; window.outOfFocusTimeoutSecs = %OUT_OF_FOCUS_TIMEOUT_SECS%; window.idleTimeoutSecs = %IDLE_TIMEOUT_SECS%; + window.reuseCookies = '%REUSE_COOKIES%'; window.tileSize = 256;]) </script> <script> diff --git a/loleaflet/js/main.js b/loleaflet/js/main.js index 54180dcaf..50c421369 100644 --- a/loleaflet/js/main.js +++ b/loleaflet/js/main.js @@ -1,6 +1,6 @@ /* -*- js-indent-level: 8 -*- */ -/* global errorMessages getParameterByName accessToken accessTokenTTL accessHeader vex host */ -/* global serviceRoot idleTimeoutSecs outOfFocusTimeoutSecs setupToolbar*/ +/* global errorMessages getParameterByName accessToken accessTokenTTL accessHeader reuseCookies */ +/* global vex host serviceRoot idleTimeoutSecs outOfFocusTimeoutSecs setupToolbar*/ /*eslint indent: [error, "tab", { "outerIIFEBody": 0 }]*/ (function (global) { @@ -14,6 +14,15 @@ else if (wopiSrc !== '' && accessHeader !== '') { wopiParams = { 'access_header': accessHeader }; } +if (reuseCookies !== '') { + if (wopiParams) { + wopiParams['reuse_cookies'] = reuseCookies; + } + else { + wopiParams = { 'reuse_cookies': reuseCookies }; + } +} + var filePath = getParameterByName('file_path'); var permission = getParameterByName('permission') || 'edit'; var timestamp = getParameterByName('timestamp'); diff --git a/loolwsd.xml.in b/loolwsd.xml.in index be2b53da8..012d74ffc 100644 --- a/loolwsd.xml.in +++ b/loolwsd.xml.in @@ -18,7 +18,7 @@ <per_document desc="Document-specific settings, including LO Core settings."> <max_concurrency desc="The maximum number of threads to use while processing a document." type="uint" default="4">4</max_concurrency> <document_signing_url desc="The endpoint URL of signing server, if empty the document signing is disabled" type="string" default="@VEREIGN_URL@">@VEREIGN_URL@</document_signing_url> - <redlining_as_comments desc="If true show red-lines as comments" type="bool" default="true">true</redlining_as_comments> + <redlining_as_comments desc="If true show red-lines as comments" type="bool" default="true">true</redlining_as_comments> <idle_timeout_secs desc="The maximum number of seconds before unloading an idle document. Defaults to 1 hour." type="uint" default="3600">3600</idle_timeout_secs> <!-- Idle save and auto save are checked every 30 seconds --> <!-- They are disabled when the value is zero or negative. --> @@ -29,7 +29,7 @@ <limit_stack_mem_kb desc="The maximum stack size allowed to each document process. 0 for unlimited." type="uint">8000</limit_stack_mem_kb> <limit_file_size_mb desc="The maximum file size allowed to each document process to write. 0 for unlimited." type="uint">0</limit_file_size_mb> <limit_num_open_files desc="The maximum number of files allowed to each document process to open. 0 for unlimited." type="uint">0</limit_num_open_files> - <limit_load_secs desc="Maximum number of seconds to wait for a document load to succeed. 0 for unlimited." type="uint" default="100">100</limit_load_secs> + <limit_load_secs desc="Maximum number of seconds to wait for a document load to succeed. 0 for unlimited." type="uint" default="100">100</limit_load_secs> </per_document> <per_view desc="View-specific settings."> @@ -116,6 +116,7 @@ <host desc="Regex pattern of hostname to allow or deny." allow="true">192\.168\.[0-9]{1,3}\.[0-9]{1,3}</host> <host desc="Regex pattern of hostname to allow or deny." allow="false">192\.168\.1\.1</host> <max_file_size desc="Maximum document size in bytes to load. 0 for unlimited." type="uint">0</max_file_size> + <reuse_cookies desc="When enabled, cookies from the browser will be captured and set on WOPI requests." type="bool" default="false">false</reuse_cookies> </wopi> <webdav desc="Allow/deny webdav storage. Mutually exclusive with wopi." allow="false"> <host desc="Hostname to allow" allow="false">localhost</host> diff --git a/wsd/FileServer.cpp b/wsd/FileServer.cpp index 6ce5c7b67..33d42766c 100644 --- a/wsd/FileServer.cpp +++ b/wsd/FileServer.cpp @@ -656,6 +656,20 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: const std::string idleTimeoutSecs= config.getString("per_view.idle_timeout_secs", "900"); Poco::replaceInPlace(preprocess, std::string("%IDLE_TIMEOUT_SECS%"), idleTimeoutSecs); + // Capture cookies so we can optionally reuse them for the storage requests. + { + NameValueCollection cookies; + request.getCookies(cookies); + std::ostringstream cookieTokens; + for (auto it = cookies.begin(); it != cookies.end(); it++) + cookieTokens << (*it).first << "=" << (*it).second << (std::next(it) != cookies.end() ? ":" : ""); + + const std::string cookiesString = cookieTokens.str(); + if (!cookiesString.empty()) + LOG_DBG("Captured cookies: " << cookiesString); + Poco::replaceInPlace(preprocess, std::string("%REUSE_COOKIES%"), cookiesString); + } + const std::string mimeType = "text/html"; std::ostringstream oss; @@ -671,20 +685,6 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request, Poco:: << "X-XSS-Protection: 1; mode=block\r\n" << "Referrer-Policy: no-referrer\r\n"; - const std::string reuseCookie = form.get("reuse_cookies_for_storage", ""); - if (reuseCookie == "true") - { - NameValueCollection cookies; - request.getCookies(cookies); - std::ostringstream cookieTokens; - - for (auto it = cookies.begin(); it != cookies.end(); it++) - { - cookieTokens << (*it).first << "=" << (*it).second << (std::next(it) != cookies.end() ? ":" : ""); - } - setenv("LOOL_REUSE_STORAGE_COOKIE", cookieTokens.str().c_str(), 1); - } - // Document signing: if endpoint URL is configured, whitelist that for // iframe purposes. std::ostringstream cspOss; diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp index 83466fde7..94c05d5e7 100644 --- a/wsd/Storage.cpp +++ b/wsd/Storage.cpp @@ -379,7 +379,7 @@ Poco::Net::HTTPClientSession* getHTTPClientSession(const Poco::URI& uri) : new Poco::Net::HTTPClientSession(uri.getHost(), uri.getPort()); } -void addStorageDebugCookie(Poco::Net::HTTPRequest& request) +static void addStorageDebugCookie(Poco::Net::HTTPRequest& request) { (void) request; #if ENABLE_DEBUG @@ -397,26 +397,26 @@ void addStorageDebugCookie(Poco::Net::HTTPRequest& request) #endif } -void addStorageReuseCookie(Poco::Net::HTTPRequest& request) +static void addStorageReuseCookie(Poco::Net::HTTPRequest& request, const std::string& reuseStorageCookies) { - if (std::getenv("LOOL_REUSE_STORAGE_COOKIE")) + if (!reuseStorageCookies.empty()) { Poco::Net::NameValueCollection nvcCookies; - std::vector<std::string> cookies = LOOLProtocol::tokenize(std::string(std::getenv("LOOL_REUSE_STORAGE_COOKIE")), ':'); + std::vector<std::string> cookies = LOOLProtocol::tokenize(reuseStorageCookies, ':'); for (auto cookie : cookies) { std::vector<std::string> cookieTokens = LOOLProtocol::tokenize(cookie, '='); if (cookieTokens.size() == 2) { nvcCookies.add(cookieTokens[0], cookieTokens[1]); - LOG_TRC("Added storage reuse cookie [" << cookieTokens[0] << "=" << cookieTokens[1] << "]."); + LOG_DBG("Added storage reuse cookie [" << cookieTokens[0] << "=" << cookieTokens[1] << "]."); } } request.setCookies(nvcCookies); } } -Poco::Timestamp iso8601ToTimestamp(const std::string& iso8601Time, const std::string& name) +static Poco::Timestamp iso8601ToTimestamp(const std::string& iso8601Time, const std::string& name) { Poco::Timestamp timestamp = Poco::Timestamp::fromEpochTime(0); try @@ -447,6 +447,16 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au auth.authorizeURI(uriObject); const std::string uriAnonym = LOOLWSD::anonymizeUrl(uriObject.toString()); + std::string reuseStorageCookies; + for (const auto& param : uriObject.getQueryParameters()) + { + if (param.first == "reuse_cookies") + { + reuseStorageCookies = param.second; + break; + } + } + LOG_DBG("Getting info for wopi uri [" << uriAnonym << "]."); std::string wopiResponse; @@ -457,7 +467,8 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Au request.set("User-Agent", WOPI_AGENT_STRING); auth.authorizeRequest(request); addStorageDebugCookie(request); - addStorageReuseCookie(request); + if (_reuseCookies) + addStorageReuseCookie(request, reuseStorageCookies); const auto startTime = std::chrono::steady_clock::now(); std::unique_ptr<Poco::Net::HTTPClientSession> psession(getHTTPClientSession(uriObject)); @@ -649,6 +660,16 @@ std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth) uriObject.setPath(uriObject.getPath() + "/contents"); auth.authorizeURI(uriObject); + std::string reuseStorageCookies; + for (const auto& param : uriObject.getQueryParameters()) + { + if (param.first == "reuse_cookies") + { + reuseStorageCookies = param.second; + break; + } + } + Poco::URI uriObjectAnonym(getUri()); uriObjectAnonym.setPath(LOOLWSD::anonymizeUrl(uriObjectAnonym.getPath()) + "/contents"); const std::string uriAnonym = uriObjectAnonym.toString(); @@ -664,7 +685,8 @@ std::string WopiStorage::loadStorageFileToLocal(const Authorization& auth) request.set("User-Agent", WOPI_AGENT_STRING); auth.authorizeRequest(request); addStorageDebugCookie(request); - addStorageReuseCookie(request); + if (_reuseCookies) + addStorageReuseCookie(request, reuseStorageCookies); psession->sendRequest(request); Poco::Net::HTTPResponse response; @@ -729,6 +751,17 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization& Poco::URI uriObject(getUri()); uriObject.setPath(isSaveAs || isRename? uriObject.getPath(): uriObject.getPath() + "/contents"); auth.authorizeURI(uriObject); + + std::string reuseStorageCookies; + for (const auto& param : uriObject.getQueryParameters()) + { + if (param.first == "reuse_cookies") + { + reuseStorageCookies = param.second; + break; + } + } + const std::string uriAnonym = LOOLWSD::anonymizeUrl(uriObject.toString()); LOG_INF("Uploading URI via WOPI [" << uriAnonym << "] from [" << filePathAnonym + "]."); @@ -805,7 +838,8 @@ StorageBase::SaveResult WopiStorage::saveLocalFileToStorage(const Authorization& request.setContentType("application/octet-stream"); request.setContentLength(size); addStorageDebugCookie(request); - addStorageReuseCookie(request); + if (_reuseCookies) + addStorageReuseCookie(request, reuseStorageCookies); std::ostream& os = psession->sendRequest(request); std::ifstream ifs(filePath); diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp index 02539b8f1..baa0317ad 100644 --- a/wsd/Storage.hpp +++ b/wsd/Storage.hpp @@ -290,10 +290,15 @@ public: const std::string& localStorePath, const std::string& jailPath) : StorageBase(uri, localStorePath, jailPath), - _wopiLoadDuration(0) + _wopiLoadDuration(0), + _reuseCookies(false) { - LOG_INF("WopiStorage ctor with localStorePath: [" << localStorePath << - "], jailPath: [" << jailPath << "], uri: [" << LOOLWSD::anonymizeUrl(uri.toString()) << "]."); + const auto& app = Poco::Util::Application::instance(); + _reuseCookies = app.config().getBool("storage.wopi.reuse_cookies", false); + LOG_INF("WopiStorage ctor with localStorePath: [" + << localStorePath << "], jailPath: [" << jailPath << "], uri: [" + << LOOLWSD::anonymizeUrl(uri.toString()) << "], reuseCookies: [" << _reuseCookies + << "]."); } class WOPIFileInfo @@ -490,6 +495,8 @@ public: private: // Time spend in loading the file from storage std::chrono::duration<double> _wopiLoadDuration; + /// Whether or not to re-use cookies from the browser for the WOPI requests. + bool _reuseCookies; }; /// WebDAV protocol backed storage. _______________________________________________ Libreoffice-commits mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits
