[Libreoffice-commits] online.git: Branch 'distro/collabora/collabora-online-2-1' - common/Session.cpp common/Session.hpp common/Util.cpp common/Util.hpp kit/ChildSession.cpp kit/ChildSession.hpp kit/Kit.cpp kit/Kit.hpp loleaflet/src wsd/ClientSession.cpp wsd/ClientSession.hpp wsd/DocumentBroker.cpp wsd/Storage.cpp wsd/Storage.hpp

Ashod Nakashian ashod.nakashian at collabora.co.uk
Thu Jun 1 09:48:38 UTC 2017


 common/Session.cpp                    |   10 ++++++++--
 common/Session.hpp                    |    3 +++
 common/Util.cpp                       |   23 ++++++++++++++++++++++-
 common/Util.hpp                       |    3 +++
 kit/ChildSession.cpp                  |    2 +-
 kit/ChildSession.hpp                  |    1 +
 kit/Kit.cpp                           |   11 +++++++----
 kit/Kit.hpp                           |   28 +++++++++++++++++++++++++---
 loleaflet/src/map/Map.js              |    2 +-
 loleaflet/src/map/handler/Map.WOPI.js |    1 +
 wsd/ClientSession.cpp                 |   11 +++++++++--
 wsd/ClientSession.hpp                 |    1 +
 wsd/DocumentBroker.cpp                |    3 +++
 wsd/Storage.cpp                       |    4 +++-
 wsd/Storage.hpp                       |    4 ++++
 15 files changed, 92 insertions(+), 15 deletions(-)

New commits:
commit b001c6864810a6739e2c63ed7033410b6cc18cf5
Author: Ashod Nakashian <ashod.nakashian at collabora.co.uk>
Date:   Sun May 28 12:20:49 2017 -0400

    wsd: support per-user links and commands
    
    userextrainfo is a json array that contains
    extra user-specific links.
    
    Currently 'avatar' is assumed to hold the
    image url for the user's avatar.
    
    'mail' and other links can also be added.
    
    Change-Id: I37c4c68bfa0b7ee659e017b4867dcb8cf5c2ca2f
    Reviewed-on: https://gerrit.libreoffice.org/38120
    Reviewed-by: Ashod Nakashian <ashnakash at gmail.com>
    Tested-by: Ashod Nakashian <ashnakash at gmail.com>
    (cherry picked from commit da2d3cbc92bf76f0d29b67eab493f2f350d1b63c)
    Reviewed-on: https://gerrit.libreoffice.org/38138
    Reviewed-by: Jan Holesovsky <kendy at collabora.com>
    Tested-by: Jan Holesovsky <kendy at collabora.com>

diff --git a/common/Session.cpp b/common/Session.cpp
index 2b99ec79..a1cded5f 100644
--- a/common/Session.cpp
+++ b/common/Session.cpp
@@ -99,16 +99,22 @@ void Session::parseDocOptions(const std::vector<std::string>& tokens, int& part,
         }
         else if (tokens[i].find("authorid=") == 0)
         {
-            std::string userId = tokens[i].substr(strlen("authorid="));
+            const std::string userId = tokens[i].substr(strlen("authorid="));
             Poco::URI::decode(userId, _userId);
             ++offset;
         }
         else if (tokens[i].find("author=") == 0)
         {
-            std::string userName = tokens[i].substr(strlen("author="));
+            const std::string userName = tokens[i].substr(strlen("author="));
             Poco::URI::decode(userName, _userName);
             ++offset;
         }
+        else if (tokens[i].find("authorextrainfo=") == 0)
+        {
+            const std::string userExtraInfo= tokens[i].substr(strlen("authorextrainfo="));
+            Poco::URI::decode(userExtraInfo, _userExtraInfo);
+            ++offset;
+        }
         else if (tokens[i].find("readonly=") == 0)
         {
             _isReadOnly = tokens[i].substr(strlen("readonly=")) != "0";
diff --git a/common/Session.hpp b/common/Session.hpp
index b67466e3..63872c08 100644
--- a/common/Session.hpp
+++ b/common/Session.hpp
@@ -152,6 +152,9 @@ protected:
     /// Name of the user to whom the session belongs to
     std::string _userName;
 
+    /// Extra info per user, mostly mail, avatar, links, etc.
+    std::string _userExtraInfo;
+
     /// Language for the document based on what the user has in the UI.
     std::string _lang;
 };
diff --git a/common/Util.cpp b/common/Util.cpp
index 23a74c6f..b3bcb354 100644
--- a/common/Util.cpp
+++ b/common/Util.cpp
@@ -39,6 +39,9 @@
 #include <Poco/ConsoleChannel.h>
 #include <Poco/Exception.h>
 #include <Poco/Format.h>
+#include <Poco/JSON/JSON.h>
+#include <Poco/JSON/Object.h>
+#include <Poco/JSON/Parser.h>
 #include <Poco/Net/WebSocket.h>
 #include <Poco/Process.h>
 #include <Poco/RandomStream.h>
@@ -334,7 +337,25 @@ namespace Util
     std::string UniqueId()
     {
         static std::atomic_int counter(0);
-        return std::to_string(Poco::Process::id()) + "/" + std::to_string(counter++);
+        return std::to_string(Poco::Process::id()) + '/' + std::to_string(counter++);
+    }
+
+    std::map<std::string, std::string> JsonToMap(const std::string& jsonString)
+    {
+        Poco::JSON::Parser parser;
+        const auto result = parser.parse(jsonString);
+        const auto& json = result.extract<Poco::JSON::Object::Ptr>();
+
+        std::vector<std::string> names;
+        json->getNames(names);
+
+        std::map<std::string, std::string> map;
+        for (const auto& name : names)
+        {
+            map[name] = json->get(name).toString();
+        }
+
+        return map;
     }
 }
 
diff --git a/common/Util.hpp b/common/Util.hpp
index 22173634..93f25cf0 100644
--- a/common/Util.hpp
+++ b/common/Util.hpp
@@ -121,6 +121,9 @@ namespace Util
     /// Return a string that is unique across processes and calls.
     std::string UniqueId();
 
+    // Extract all json entries into a map.
+    std::map<std::string, std::string> JsonToMap(const std::string& jsonString);
+
     /// Trim spaces from the left. Just spaces.
     inline std::string& ltrim(std::string& s)
     {
diff --git a/kit/ChildSession.cpp b/kit/ChildSession.cpp
index d68bcf59..4fd77800 100644
--- a/kit/ChildSession.cpp
+++ b/kit/ChildSession.cpp
@@ -477,7 +477,7 @@ void insertUserNames(const std::map<int, UserInfo>& viewInfo, std::string& json)
                 int viewId = action->getValue<int>("viewId");
                 auto it = viewInfo.find(viewId);
                 if (it != viewInfo.end())
-                    action->set("userName", Poco::Dynamic::Var(it->second.username));
+                    action->set("userName", Poco::Dynamic::Var(it->second.Username));
             }
         }
     }
diff --git a/kit/ChildSession.hpp b/kit/ChildSession.hpp
index 703df776..7faef0ed 100644
--- a/kit/ChildSession.hpp
+++ b/kit/ChildSession.hpp
@@ -138,6 +138,7 @@ public:
     void setViewId(const int viewId) { _viewId = viewId; }
     const std::string& getViewUserId() const { return _userId; }
     const std::string& getViewUserName() const { return _userName; }
+    const std::string& getViewUserExtraInfo() const { return _userExtraInfo; }
 
     void loKitCallback(const int type, const std::string& payload);
 
diff --git a/kit/Kit.cpp b/kit/Kit.cpp
index 304a62e5..5415c760 100644
--- a/kit/Kit.cpp
+++ b/kit/Kit.cpp
@@ -1074,10 +1074,12 @@ private:
             }
             else
             {
-                oss << "\"userid\":\"" << itView->second.userid << "\",";
-                const auto username = itView->second.username;
+                oss << "\"userid\":\"" << itView->second.UserId << "\",";
+                const auto username = itView->second.Username;
                 oss << "\"username\":\"" << username << "\",";
-                const auto readonly = itView->second.isReadOnly;
+                if (!itView->second.UserExtraInfo.empty())
+                    oss << itView->second.UserExtraInfo << ',';
+                const auto readonly = itView->second.IsReadOnly;
                 oss << "\"readonly\":\"" << readonly << "\",";
                 const auto it = viewColorsMap.find(username);
                 if (it != viewColorsMap.end())
@@ -1248,7 +1250,8 @@ private:
 
         const int viewId = _loKitDocument->getView();
         session->setViewId(viewId);
-        _sessionUserInfo[viewId] = UserInfo({session->getViewUserId(), session->getViewUserName(), session->isReadOnly()});
+        _sessionUserInfo[viewId] = UserInfo(session->getViewUserId(), session->getViewUserName(),
+                                            session->getViewUserExtraInfo(), session->isReadOnly());
 
         _viewIdToCallbackDescr.emplace(viewId,
                                        std::unique_ptr<CallbackDescriptor>(new CallbackDescriptor({ this, viewId })));
diff --git a/kit/Kit.hpp b/kit/Kit.hpp
index f003e26a..bbaf1bba 100644
--- a/kit/Kit.hpp
+++ b/kit/Kit.hpp
@@ -9,6 +9,11 @@
 #ifndef INCLUDED_LOOLKIT_HPP
 #define INCLUDED_LOOLKIT_HPP
 
+#include <map>
+#include <string>
+
+#include <common/Util.hpp>
+
 void lokit_main(const std::string& childRoot,
                 const std::string& jailId,
                 const std::string& sysTemplate,
@@ -37,9 +42,26 @@ struct CallbackDescriptor
 /// after any child session goes away
 struct UserInfo
 {
-    std::string userid;
-    std::string username;
-    bool isReadOnly;
+    UserInfo()
+    {
+    }
+
+    UserInfo(const std::string& userId,
+             const std::string& username,
+             const std::string& userExtraInfo,
+             const bool readonly) :
+        UserId(userId),
+        Username(username),
+        IsReadOnly(readonly)
+    {
+        if (!userExtraInfo.empty())
+            UserExtraInfo = "\"userextrainfo\":[" + userExtraInfo + ']';
+    }
+
+    std::string UserId;
+    std::string Username;
+    std::string UserExtraInfo;
+    bool IsReadOnly;
 };
 
 /// Check the ForkCounter, and if non-zero, fork more of them accordingly.
diff --git a/loleaflet/src/map/Map.js b/loleaflet/src/map/Map.js
index 65575f0d..c809980e 100644
--- a/loleaflet/src/map/Map.js
+++ b/loleaflet/src/map/Map.js
@@ -160,7 +160,7 @@ L.Map = L.Evented.extend({
 
 	addView: function(viewInfo) {
 		this._viewInfo[viewInfo.id] = viewInfo;
-		this.fire('postMessage', {msgId: 'View_Added', args: {ViewId: viewInfo.id, UserId: viewInfo.userid, UserName: viewInfo.username, Color: viewInfo.color, ReadOnly: viewInfo.readonly}});
+		this.fire('postMessage', {msgId: 'View_Added', args: {ViewId: viewInfo.id, UserId: viewInfo.userid, UserName: viewInfo.username, UserExtraInfo: viewInfo.userextrainfo, Color: viewInfo.color, ReadOnly: viewInfo.readonly}});
 
 		// Fire last, otherwise not all events are handled correctly.
 		this.fire('addview', {viewId: viewInfo.id, username: viewInfo.username, extraInfo: viewInfo.userextrainfo, readonly: this.isViewReadOnly(viewInfo.id)});
diff --git a/loleaflet/src/map/handler/Map.WOPI.js b/loleaflet/src/map/handler/Map.WOPI.js
index 20d11a6f..fcb454ec 100644
--- a/loleaflet/src/map/handler/Map.WOPI.js
+++ b/loleaflet/src/map/handler/Map.WOPI.js
@@ -113,6 +113,7 @@ L.Map.WOPI = L.Handler.extend({
 					ViewId: viewInfoIdx,
 					UserName: this._map._viewInfo[viewInfoIdx].username,
 					UserId: this._map._viewInfo[viewInfoIdx].userid,
+					UserExtraInfo: this._map._viewInfo[viewInfoIdx].userextrainfo,
 					Color: this._map._viewInfo[viewInfoIdx].color
 				});
 			}
diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp
index 026b0513..a65959b8 100644
--- a/wsd/ClientSession.cpp
+++ b/wsd/ClientSession.cpp
@@ -259,11 +259,18 @@ bool ClientSession::loadDocument(const char* /*buffer*/, int /*length*/,
         {
             std::string encodedUserId;
             Poco::URI::encode(_userId, "", encodedUserId);
-            oss << " authorid=" + encodedUserId;
+            oss << " authorid=" << encodedUserId;
 
             std::string encodedUserName;
             Poco::URI::encode(_userName, "", encodedUserName);
-            oss << " author=" + encodedUserName;
+            oss << " author=" << encodedUserName;
+        }
+
+        if (!_userExtraInfo.empty())
+        {
+            std::string encodedUserExtraInfo;
+            Poco::URI::encode(_userExtraInfo, "", encodedUserExtraInfo);
+            oss << " authorextrainfo=" << encodedUserExtraInfo;
         }
 
         oss << " readonly=" << isReadOnly();
diff --git a/wsd/ClientSession.hpp b/wsd/ClientSession.hpp
index 96f090d7..17fca2a7 100644
--- a/wsd/ClientSession.hpp
+++ b/wsd/ClientSession.hpp
@@ -45,6 +45,7 @@ public:
     const std::string getUserId() const { return _userId; }
     void setUserId(const std::string& userId) { _userId = userId; }
     void setUserName(const std::string& userName) { _userName = userName; }
+    void setUserExtraInfo(const std::string& userExtraInfo) { _userExtraInfo = userExtraInfo; }
     void setDocumentOwner(const bool documentOwner) { _isDocumentOwner = documentOwner; }
     bool isDocumentOwner() const { return _isDocumentOwner; }
 
diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp
index 1e4870e1..c04fa850 100644
--- a/wsd/DocumentBroker.cpp
+++ b/wsd/DocumentBroker.cpp
@@ -395,6 +395,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
 
     // Call the storage specific fileinfo functions
     std::string userid, username;
+    std::string userExtraInfo;
     std::chrono::duration<double> getInfoCallDuration(0);
     WopiStorage* wopiStorage = dynamic_cast<WopiStorage*>(_storage.get());
     if (wopiStorage != nullptr)
@@ -402,6 +403,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
         std::unique_ptr<WopiStorage::WOPIFileInfo> wopifileinfo = wopiStorage->getWOPIFileInfo(session->getAccessToken());
         userid = wopifileinfo->_userid;
         username = wopifileinfo->_username;
+        userExtraInfo = wopifileinfo->_userExtraInfo;
 
         if (!wopifileinfo->_userCanWrite)
         {
@@ -462,6 +464,7 @@ bool DocumentBroker::load(const std::shared_ptr<ClientSession>& session, const s
     LOG_DBG("Setting username [" << username << "] and userId [" << userid << "] for session [" << sessionId << "]");
     session->setUserId(userid);
     session->setUserName(username);
+    session->setUserExtraInfo(userExtraInfo);
 
     // Basic file information was stored by the above getWOPIFileInfo() or getLocalFileInfo() calls
     const auto fileInfo = _storage->getFileInfo();
diff --git a/wsd/Storage.cpp b/wsd/Storage.cpp
index 4e6e6567..f67513ef 100644
--- a/wsd/Storage.cpp
+++ b/wsd/Storage.cpp
@@ -483,6 +483,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const st
     std::string ownerId;
     std::string userId;
     std::string userName;
+    std::string userExtraInfo;
     bool canWrite = false;
     bool enableOwnerTermination = false;
     std::string postMessageOrigin;
@@ -507,6 +508,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const st
         getWOPIValue(object, "OwnerId", ownerId);
         getWOPIValue(object, "UserId", userId);
         getWOPIValue(object, "UserFriendlyName", userName);
+        getWOPIValue(object, "UserExtraInfo", userExtraInfo);
         getWOPIValue(object, "UserCanWrite", canWrite);
         getWOPIValue(object, "PostMessageOrigin", postMessageOrigin);
         getWOPIValue(object, "HidePrintOption", hidePrintOption);
@@ -548,7 +550,7 @@ std::unique_ptr<WopiStorage::WOPIFileInfo> WopiStorage::getWOPIFileInfo(const st
 
     _fileInfo = FileInfo({filename, ownerId, modifiedTime, size});
 
-    return std::unique_ptr<WopiStorage::WOPIFileInfo>(new WOPIFileInfo({userId, userName, canWrite, postMessageOrigin, hidePrintOption, hideSaveOption, hideExportOption, enableOwnerTermination, disablePrint, disableExport, disableCopy, callDuration}));
+    return std::unique_ptr<WopiStorage::WOPIFileInfo>(new WOPIFileInfo({userId, userName, userExtraInfo, 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 d0dff593..34b56de3 100644
--- a/wsd/Storage.hpp
+++ b/wsd/Storage.hpp
@@ -182,6 +182,7 @@ public:
     public:
         WOPIFileInfo(const std::string& userid,
                      const std::string& username,
+                     const std::string& userExtraInfo,
                      const bool userCanWrite,
                      const std::string& postMessageOrigin,
                      const bool hidePrintOption,
@@ -205,12 +206,15 @@ public:
               _disableCopy(disableCopy),
               _callDuration(callDuration)
             {
+                _userExtraInfo = userExtraInfo;
             }
 
         /// User id of the user accessing the file
         std::string _userid;
         /// Display Name of user accessing the file
         std::string _username;
+        /// Extra info per user, typically mail and other links, as json.
+        std::string _userExtraInfo;
         /// If user accessing the file has write permission
         bool _userCanWrite;
         /// WOPI Post message property


More information about the Libreoffice-commits mailing list