From 22e789a42032b749b96de1e94f13c12e0a247026 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Hubert=20Figui=C3=A8re?= Date: Wed, 1 May 2024 12:23:10 -0400 Subject: [PATCH] impress: restrict presentation in readonly mode MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit When export is disabled or watermarks are enabled, presentation in readonly mode is disabled. This is checked in the frontend by the WOPI property `DisablePresentation` that is synthesized in the wsd. Also check when calling the presentation command. WOPIFileInfo::getWatermarkText() is stubbed on mobile. Signed-off-by: Hubert Figuière Change-Id: I4f7aff9f670f7523dfcf396f6009a272df9d5af8 --- browser/src/control/Control.Menubar.js | 5 ++++- browser/src/map/handler/Map.SlideShow.js | 20 ++++++++++++++++++++ browser/src/map/handler/Map.WOPI.js | 2 ++ common/MobileApp.hpp | 1 + wsd/ClientSession.cpp | 6 ++++++ wsd/DocumentBroker.cpp | 2 ++ 6 files changed, 35 insertions(+), 1 deletion(-) diff --git a/browser/src/control/Control.Menubar.js b/browser/src/control/Control.Menubar.js index 1ee4b31874..daa989bb1b 100644 --- a/browser/src/control/Control.Menubar.js +++ b/browser/src/control/Control.Menubar.js @@ -1324,7 +1324,6 @@ L.Control.Menubar = L.Control.extend({ !window.ThisIsAMobileApp ? 'exportdirectpdf' : 'downloadas-pdf', !window.ThisIsAMobileApp ? 'exportepub' : 'downloadas-epub', // file menu 'downloadas-ods', 'downloadas-xls', 'downloadas-xlsx', 'downloadas-csv', 'closedocument', // file menu 'fullscreen', 'zoomin', 'zoomout', 'zoomreset', 'showstatusbar', 'togglemenubar', 'showresolved', 'toggledarktheme', // view menu - 'fullscreen-presentation', 'presentation-currentslide', 'present-in-window', // slide menu 'about', 'keyboard-shortcuts', 'latestupdates', 'feedback', 'online-help', 'report-an-issue', // help menu 'insertcomment' ] @@ -1341,6 +1340,10 @@ L.Control.Menubar = L.Control.extend({ // Use original template as provided by server this._menubarCont = map.mainMenuTemplate.cloneNode(true); $('#main-menu-state').after(this._menubarCont); + + if (!this._map['wopi'].DisablePresentation) + this.options.allowedViewModeActions = this.options.allowedViewModeActions.concat(['fullscreen-presentation', 'presentation-currentslide', 'present-in-window']); + this._initializeMenu(this.options.initial); map.on('doclayerinit', this._onDocLayerInit, this); diff --git a/browser/src/map/handler/Map.SlideShow.js b/browser/src/map/handler/Map.SlideShow.js index 4bbb3fc7d0..47ed3b36a8 100644 --- a/browser/src/map/handler/Map.SlideShow.js +++ b/browser/src/map/handler/Map.SlideShow.js @@ -36,6 +36,11 @@ L.Map.SlideShow = L.Handler.extend({ }, _onFullScreen: function (e) { + if (this._checkPresentationDisabled()) { + this._notifyPresentationDisabled(); + return; + } + if (this._checkAlreadyPresenting()) { this._notifyAlreadyPresenting(); return; @@ -94,6 +99,11 @@ L.Map.SlideShow = L.Handler.extend({ }, _onPresentWindow: function (e) { + if (this._checkPresentationDisabled()) { + this._notifyPresentationDisabled(); + return; + } + if (this._checkAlreadyPresenting()) { this._notifyAlreadyPresenting(); return; @@ -295,6 +305,16 @@ L.Map.SlideShow = L.Handler.extend({ _('OK'), null, false); }, + _checkPresentationDisabled: function() { + return this._map['wopi'].DisablePresentation; + }, + + _notifyPresentationDisabled: function() { + this._map.uiManager.showInfoModal('presentation-disabled-modal', + _('Presentation disabled'), + _('Presentation mode has been disabled for this document'), '', + _('OK'), null, false); + }, _onSlideWindowKeyPress: function(e) { if (e.code === 'Escape') { diff --git a/browser/src/map/handler/Map.WOPI.js b/browser/src/map/handler/Map.WOPI.js index 154a39256a..d0575a32a4 100644 --- a/browser/src/map/handler/Map.WOPI.js +++ b/browser/src/map/handler/Map.WOPI.js @@ -32,6 +32,7 @@ L.Map.WOPI = L.Handler.extend({ SupportsRename: false, UserCanRename: false, UserCanWrite: false, + DisablePresentation: false, _appLoadedConditions: { docloaded: false, @@ -127,6 +128,7 @@ L.Map.WOPI = L.Handler.extend({ this.UserCanRename = !!wopiInfo['UserCanRename']; this.EnableShare = !!wopiInfo['EnableShare']; this.UserCanWrite = !!wopiInfo['UserCanWrite']; + this.DisablePresentation = wopiInfo['DisablePresentation']; if (this.UserCanWrite && !app.isReadOnly()) // There are 2 places that set the file permissions, WOPI and URI. Don't change permission if URI doesn't allow. app.setPermission('edit'); diff --git a/common/MobileApp.hpp b/common/MobileApp.hpp index 9ff8532af6..fb646d0f3b 100644 --- a/common/MobileApp.hpp +++ b/common/MobileApp.hpp @@ -81,6 +81,7 @@ public: bool getDisableExport() const { return false; } bool getDisableCopy() const { return false; } bool getEnableOwnerTermination() const { return false; } + std::string getWatermarkText() const { return std::string(); } TriState getDisableChangeTrackingShow() const { return TriState::Unset; } TriState getDisableChangeTrackingRecord() const { return TriState::Unset; } diff --git a/wsd/ClientSession.cpp b/wsd/ClientSession.cpp index 11cf8776db..70003ce10b 100644 --- a/wsd/ClientSession.cpp +++ b/wsd/ClientSession.cpp @@ -1493,6 +1493,12 @@ bool ClientSession::filterMessage(const std::string& message) const allowed = false; LOG_WRN("WOPI host has disabled export for this session"); } + else if (id == "slideshow" && _wopiFileInfo && + (_wopiFileInfo->getDisableExport() || !_wopiFileInfo->getWatermarkText().empty())) + { + allowed = false; + LOG_WRN("WOPI host has disabled slideshow for this session"); + } } else { diff --git a/wsd/DocumentBroker.cpp b/wsd/DocumentBroker.cpp index 8142e7f934..6de814fd42 100644 --- a/wsd/DocumentBroker.cpp +++ b/wsd/DocumentBroker.cpp @@ -1230,6 +1230,8 @@ DocumentBroker::updateSessionWithWopiInfo(const std::shared_ptr& wopiInfo->set("HideChangeTrackingControls", wopiFileInfo->getHideChangeTrackingControls() == WopiStorage::WOPIFileInfo::TriState::True); wopiInfo->set("IsOwner", session->isDocumentOwner()); + bool disablePresentation = !watermarkText.empty() || wopiFileInfo->getDisableExport() || wopiFileInfo->getHideExportOption(); + wopiInfo->set("DisablePresentation", disablePresentation); std::ostringstream ossWopiInfo; wopiInfo->stringify(ossWopiInfo);