[Libreoffice-commits] online.git: 6 commits - loleaflet/src wsd/ClientSession.cpp wsd/ClientSession.hpp wsd/DocumentBroker.cpp wsd/protocol.txt wsd/Storage.cpp wsd/Storage.hpp

Pranav Kant pranavk at collabora.co.uk
Tue Dec 13 12:15:48 UTC 2016


 loleaflet/src/control/Toolbar.js      |    2 -
 loleaflet/src/layer/tile/TileLayer.js |    2 -
 wsd/ClientSession.cpp                 |   42 ++++++++++++++++++++++++++++++----
 wsd/ClientSession.hpp                 |    7 +++++
 wsd/DocumentBroker.cpp                |   31 +++++++++++++------------
 wsd/Storage.cpp                       |   14 ++++++++---
 wsd/Storage.hpp                       |   16 +++++++++++-
 wsd/protocol.txt                      |    5 +++-
 8 files changed, 92 insertions(+), 27 deletions(-)

New commits:
commit 3ce8c3158a6b9375d4b8ca862ea5b50490af4c35
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 13 17:43:51 2016 +0530

    wsd: Allow disabling copy/paste to/from the document to browser
    
    Change-Id: I73c70f46f1db11d69ebff582f72127d304689aa2

diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index c06ffac..f1188b5 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -418,6 +418,14 @@ bool ClientSession::filterMessage(const std::string& message) const
                 LOG_WRN("No value of id in downloadas message");
         }
     }
+    else if (tokens[0] == "gettextselection" || tokens[0] == "paste" || tokens[0] == "insertfile")
+    {
+        if (_wopiFileInfo && _wopiFileInfo->_disableCopy)
+        {
+            allowed = false;
+            LOG_WRN("WOPI host has disabled copying to/from the document");
+        }
+    }
     else if (isReadOnly())
     {
         // By default, don't allow anything
commit 6affbb307c5408fa3b3c090bf2cdfdb0b2529dc5
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 13 17:00:43 2016 +0530

    wsd: Allow hosts to disable print, export
    
    using these WOPI protocol extensions: DisablePrint,
    DisableExport, DisableCopy. All assumed to be false if not
    provided.
    
    Change-Id: I415597d710107f9d8cbb8757f361365cc2a88eb1

diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index eeaf5b7..c06ffac 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -394,10 +394,35 @@ bool ClientSession::filterMessage(const std::string& message) const
 {
     bool allowed = true;
     StringTokenizer tokens(message, " ", StringTokenizer::TOK_IGNORE_EMPTY | StringTokenizer::TOK_TRIM);
-    if (isReadOnly())
+
+    // Set allowed flag to false depending on if particular WOPI properties are set
+    if (tokens[0] == "downloadas")
+    {
+        std::string id;
+        if (getTokenString(tokens[2], "id", id))
+        {
+            if (id == "print" && _wopiFileInfo && _wopiFileInfo->_disablePrint)
+            {
+                allowed = false;
+                LOG_WRN("WOPI host has disabled print for this session");
+            }
+            else if (id == "export" && _wopiFileInfo && _wopiFileInfo->_disableExport)
+            {
+                allowed = false;
+                LOG_WRN("WOPI host has disabled export for this session");
+            }
+        }
+        else
+        {
+                allowed = false;
+                LOG_WRN("No value of id in downloadas message");
+        }
+    }
+    else if (isReadOnly())
     {
+        // By default, don't allow anything
         allowed = false;
-        if (tokens[0] == "downloadas" || tokens[0] == "userinactive" || tokens[0] == "useractive")
+        if (tokens[0] == "userinactive" || tokens[0] == "useractive")
         {
             allowed = true;
         }
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index b99c556..585711f 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -390,6 +390,9 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Po
     bool hidePrintOption = false;
     bool hideSaveOption = false;
     bool hideExportOption = false;
+    bool disablePrint = false;
+    bool disableExport = false;
+    bool disableCopy = false;
     std::string resMsg;
     Poco::StreamCopier::copyToString(rs, resMsg);
 
@@ -414,6 +417,9 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Po
         getWOPIValue(object, "HideSaveOption", hideSaveOption);
         getWOPIValue(object, "HideExportOption", hideExportOption);
         getWOPIValue(object, "EnableOwnerTermination", enableOwnerTermination);
+        getWOPIValue(object, "DisablePrint", disablePrint);
+        getWOPIValue(object, "DisableExport", disableExport);
+        getWOPIValue(object, "DisableCopy", disableCopy);
     }
     else
         Log::error("WOPI::CheckFileInfo is missing JSON payload");
@@ -424,7 +430,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Po
         _fileInfo = FileInfo({filename, ownerId, Poco::Timestamp(), size});
     }
 
-    return std::unique_ptr<WopiStorage::WOPIFileInfo>(new WOPIFileInfo({userId, userName, canWrite, postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, enableOwnerTermination, callDuration}));
+    return std::unique_ptr<WopiStorage::WOPIFileInfo>(new WOPIFileInfo({userId, userName, canWrite, postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, enableOwnerTermination, disablePrint, disableExport, disableCopy, callDuration}));
 }
 
 /// uri format: http://server/<...>/wopi*/files/<id>/content
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 689f7db..58d7ecb 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -180,6 +180,9 @@ public:
                      const bool hideSaveOption,
                      const bool hideExportOption,
                      const bool enableOwnerTermination,
+                     const bool disablePrint,
+                     const bool disableExport,
+                     const bool disableCopy,
                      const std::chrono::duration<double> callDuration)
             : _userid(userid),
               _username(username),
@@ -189,6 +192,9 @@ public:
               _hideSaveOption(hideSaveOption),
               _hideExportOption(hideExportOption),
               _enableOwnerTermination(enableOwnerTermination),
+              _disablePrint(disablePrint),
+              _disableExport(disableExport),
+              _disableCopy(disableCopy),
               _callDuration(callDuration)
             {
             }
@@ -209,6 +215,12 @@ public:
         bool _hideExportOption;
         /// If WOPI host has enabled owner termination feature on
         bool _enableOwnerTermination;
+        /// If WOPI host has allowed the user to print the document
+        bool _disablePrint;
+        /// If WOPI host has allowed the user to export the document
+        bool _disableExport;
+        /// If WOPI host has allowed the user to copy to/from the document
+        bool _disableCopy;
         /// Time it took to call WOPI's CheckFileInfo
         std::chrono::duration<double> _callDuration;
     };
commit 1ddd85c77c2d8683a48c5060c7c07e421f0d8dc0
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 13 15:38:18 2016 +0530

    Document downloadas protocol message
    
    Change-Id: Iad8775c441e8fbb531b4608bd6ccb391435e7dcf

diff --git a/wsd/protocol.txt b/wsd/protocol.txt
index 513c27b..d20b598 100644
--- a/wsd/protocol.txt
+++ b/wsd/protocol.txt
@@ -34,7 +34,10 @@ canceltiles
 downloadas name=<fileName> id=<id> format=<document format> options=<SkipImages, etc>
 
     Exports the current document to the desired format and returns a download URL
-    The id identifies the request on the client.
+    The id identifies the request on the client. id can take following values:
+    * 'print': When request for download is basically for print purposes
+    * 'slideshow': When request for download is for showing slideshow
+    * 'export': Just a simple download
 
 getchildid
 
commit 8135e678bb3ae51b638002e1e6f990021a4cb0b3
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 13 15:36:33 2016 +0530

    loleaflet: Use readable id= argument in downloadas
    
    Change-Id: Ica9ba833f487f2c75f8629fd91f31b216c4797b5

diff --git a/loleaflet/src/control/Toolbar.js b/loleaflet/src/control/Toolbar.js
index 3de887f..5fe402f 100644
--- a/loleaflet/src/control/Toolbar.js
+++ b/loleaflet/src/control/Toolbar.js
@@ -58,7 +58,7 @@ L.Map.include({
 		if (options === undefined || options === null) {
 			options = '';
 		}
-		id = id || -1; // not a special download
+		id = id || 'export'; // not any special download, simple export
 
 		this.showBusy(_('Downloading...'), false);
 		this._socket.sendMessage('downloadas ' +
diff --git a/loleaflet/src/layer/tile/TileLayer.js b/loleaflet/src/layer/tile/TileLayer.js
index b4af6da..a4856f1 100644
--- a/loleaflet/src/layer/tile/TileLayer.js
+++ b/loleaflet/src/layer/tile/TileLayer.js
@@ -477,7 +477,7 @@ L.TileLayer = L.GridLayer.extend({
 		else if (command.id === 'slideshow') {
 			this._map.fire('slidedownloadready', {url: url});
 		}
-		else {
+		else if (command.id === 'export') {
 			this._map._fileDownloader.src = url;
 		}
 	},
commit 348653a73ceb72a2892530ca79c7db897d33248f
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 13 14:46:34 2016 +0530

    wsd: Use EnableOwnerTermination property for ownertermination
    
    We want document owners (sessions with their WOPI UserId =
    OwnerId) close the document (for all sessions) only if
    EnableOwnerTermination property is specified. Note that
    EnableOwnerTermination is an extension to WOPI, and not part of
    original WOPI standard.
    
    Change-Id: I7237d172c4c54477572bc132336910250af075a3

diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 1707650..eeaf5b7 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -176,8 +176,9 @@ bool ClientSession::_handleInput(const char *buffer, int length)
     }
     else if (tokens[0] == "closedocument")
     {
-        // If this session is the owner of the file, let it close all sessions
-        if (_isDocumentOwner)
+        // If this session is the owner of the file & 'EnableOwnerTermination' feature
+        // is turned on by WOPI, let it close all sessions
+        if (_isDocumentOwner && _wopiFileInfo && _wopiFileInfo->_enableOwnerTermination)
         {
             LOG_DBG("Session [" + getId() + "] requested owner termination");
             docBroker->closeDocument("ownertermination");
commit 3e2a9df6dd0eb44958875d9f443c5c3fe0b96698
Author: Pranav Kant <pranavk at collabora.co.uk>
Date:   Tue Dec 13 14:43:58 2016 +0530

    wsd: Store wopifileinfo separately per client session
    
    Client needs to act accordingly as per permissions/settings set
    by the WOPI host.
    
    Change-Id: I7c9f311be50d4aff2562da0cfef2fff889f111d0

diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 25007a4..a96d807 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -11,6 +11,7 @@
 #define INCLUDED_CLIENTSSESSION_HPP
 
 #include "Session.hpp"
+#include "Storage.hpp"
 #include "MessageQueue.hpp"
 
 #include <Poco/URI.h>
@@ -64,6 +65,9 @@ public:
     /// client made the request to us
     const Poco::URI& getPublicUri() const { return _uriPublic; }
 
+    /// Set WOPI fileinfo object
+    void setWopiFileInfo(std::unique_ptr<WopiStorage::WOPIFileInfo>& wopiFileInfo) { _wopiFileInfo = std::move(wopiFileInfo); }
+
 private:
     virtual bool _handleInput(const char* buffer, int length) override;
 
@@ -110,6 +114,9 @@ private:
     MessageQueue _saveAsQueue;
 
     int _loadPart;
+
+    /// Wopi FileInfo object
+    std::unique_ptr<WopiStorage::WOPIFileInfo> _wopiFileInfo;
 };
 
 #endif
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index bb8b9f6..319b3e8 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -244,16 +244,16 @@ bool DocumentBroker::load(std::shared_ptr<ClientSession>& session, const std::st
 
     assert(_storage != nullptr);
 
-    // Call the storage specific file info functions
+    // Call the storage specific fileinfo functions
     std::string userid, username;
     std::chrono::duration<double> getInfoCallDuration(0);
     if (dynamic_cast<WopiStorage*>(_storage.get()) != nullptr)
     {
-        const WopiStorage::WOPIFileInfo wopifileinfo = static_cast<WopiStorage*>(_storage.get())->getWOPIFileInfo(uriPublic);
-        userid = wopifileinfo._userid;
-        username = wopifileinfo._username;
+        std::unique_ptr<WopiStorage::WOPIFileInfo> wopifileinfo = static_cast<WopiStorage*>(_storage.get())->getWOPIFileInfo(uriPublic);
+        userid = wopifileinfo->_userid;
+        username = wopifileinfo->_username;
 
-        if (!wopifileinfo._userCanWrite)
+        if (!wopifileinfo->_userCanWrite)
         {
             LOG_DBG("Setting the session as readonly");
             session->setReadOnly();
@@ -261,14 +261,14 @@ bool DocumentBroker::load(std::shared_ptr<ClientSession>& session, const std::st
 
         // Construct a JSON containing relevant WOPI host properties
         Object::Ptr wopiInfo = new Object();
-        if (!wopifileinfo._postMessageOrigin.empty())
+        if (!wopifileinfo->_postMessageOrigin.empty())
         {
-            wopiInfo->set("PostMessageOrigin", wopifileinfo._postMessageOrigin);
+            wopiInfo->set("PostMessageOrigin", wopifileinfo->_postMessageOrigin);
         }
 
-        wopiInfo->set("HidePrintOption", wopifileinfo._hidePrintOption);
-        wopiInfo->set("HideSaveOption", wopifileinfo._hideSaveOption);
-        wopiInfo->set("HideExportOption", wopifileinfo._hideExportOption);
+        wopiInfo->set("HidePrintOption", wopifileinfo->_hidePrintOption);
+        wopiInfo->set("HideSaveOption", wopifileinfo->_hideSaveOption);
+        wopiInfo->set("HideExportOption", wopifileinfo->_hideExportOption);
 
         std::ostringstream ossWopiInfo;
         wopiInfo->stringify(ossWopiInfo);
@@ -281,13 +281,16 @@ bool DocumentBroker::load(std::shared_ptr<ClientSession>& session, const std::st
             session->setDocumentOwner(true);
         }
 
-        getInfoCallDuration = wopifileinfo._callDuration;
+        getInfoCallDuration = wopifileinfo->_callDuration;
+
+        // Pass the ownership to client session
+        session->setWopiFileInfo(wopifileinfo);
     }
     else if (dynamic_cast<LocalStorage*>(_storage.get()) != nullptr)
     {
-        const LocalStorage::LocalFileInfo localfileinfo = static_cast<LocalStorage*>(_storage.get())->getLocalFileInfo(uriPublic);
-        userid = localfileinfo._userid;
-        username = localfileinfo._username;
+        std::unique_ptr<LocalStorage::LocalFileInfo> localfileinfo = static_cast<LocalStorage*>(_storage.get())->getLocalFileInfo(uriPublic);
+        userid = localfileinfo->_userid;
+        username = localfileinfo->_username;
     }
 
     LOG_DBG("Setting username [" << username << "] and userId [" << userid << "] for session [" << sessionId << "]");
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index a2ca75b..b99c556 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -186,7 +186,7 @@ std::unique_ptr<StorageBase> StorageBase::create(const Poco::URI& uri, const std
 
 std::atomic<unsigned> LocalStorage::LastLocalStorageId;
 
-LocalStorage::LocalFileInfo LocalStorage::getLocalFileInfo(const Poco::URI& uriPublic)
+std::unique_ptr<LocalStorage::LocalFileInfo> LocalStorage::getLocalFileInfo(const Poco::URI& uriPublic)
 {
     const auto path = Poco::Path(uriPublic.getPath());
     Log::debug("Getting info for local uri [" + uriPublic.toString() + "], path [" + path.toString() + "].");
@@ -202,7 +202,7 @@ LocalStorage::LocalFileInfo LocalStorage::getLocalFileInfo(const Poco::URI& uriP
     }
 
     // Set automatic userid and username
-    return LocalFileInfo({"localhost", std::string("Local Host #") + std::to_string(LastLocalStorageId++)});
+    return std::unique_ptr<LocalStorage::LocalFileInfo>(new LocalFileInfo({"localhost", std::string("Local Host #") + std::to_string(LastLocalStorageId++)}));
 }
 
 std::string LocalStorage::loadStorageFileToLocal()
@@ -355,7 +355,7 @@ void getWOPIValue(const Poco::JSON::Object::Ptr &object, const std::string& key,
 
 } // anonymous namespace
 
-WopiStorage::WOPIFileInfo WopiStorage::getWOPIFileInfo(const Poco::URI& uriPublic)
+std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const Poco::URI& uriPublic)
 {
     Log::debug("Getting info for wopi uri [" + uriPublic.toString() + "].");
 
@@ -424,7 +424,7 @@ WopiStorage::WOPIFileInfo WopiStorage::getWOPIFileInfo(const Poco::URI& uriPubli
         _fileInfo = FileInfo({filename, ownerId, Poco::Timestamp(), size});
     }
 
-    return WOPIFileInfo({userId, userName, canWrite, postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, enableOwnerTermination, callDuration});
+    return std::unique_ptr<WopiStorage::WOPIFileInfo>(new WOPIFileInfo({userId, userName, canWrite, postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, enableOwnerTermination, callDuration}));
 }
 
 /// uri format: http://server/<...>/wopi*/files/<id>/content
diff --git a/wsd/Storage.hpp b/wsd/Storage.hpp
index 684488f..689f7db 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -143,7 +143,7 @@ public:
     /// Returns the URI specific file data
     /// Also stores the basic file information which can then be
     /// obtained using getFileInfo method
-    LocalFileInfo getLocalFileInfo(const Poco::URI& uriPublic);
+    std::unique_ptr<LocalFileInfo> getLocalFileInfo(const Poco::URI& uriPublic);
 
     std::string loadStorageFileToLocal() override;
 
@@ -216,7 +216,7 @@ public:
     /// Returns the response of CheckFileInfo WOPI call for given URI
     /// Also extracts the basic file information from the response
     /// which can then be obtained using getFileInfo()
-    WOPIFileInfo getWOPIFileInfo(const Poco::URI& uriPublic);
+    std::unique_ptr<WOPIFileInfo> getWOPIFileInfo(const Poco::URI& uriPublic);
 
     /// uri format: http://server/<...>/wopi*/files/<id>/content
     std::string loadStorageFileToLocal() override;


More information about the Libreoffice-commits mailing list