summaryrefslogtreecommitdiff
path: root/desktop
diff options
context:
space:
mode:
authorMichael Stahl <mstahl@redhat.com>2016-01-22 13:39:32 +0100
committerMiklos Vajna <vmiklos@collabora.co.uk>2016-01-29 17:24:14 +0100
commit9dd1b28174e590a019fa4162b6dc5a069e9af0a5 (patch)
treefbd02bcf4abd23294629e455ff3223c33cc12d02 /desktop
parenteb583e76b016540aed3f6658a6711570e8f7214c (diff)
libreofficekit: password interaction optional and off by default
Add setOptionalFeatures() function that clients must call during initialization, and enum LibreOfficeKitOptionalFeatures. Reviewed-on: https://gerrit.libreoffice.org/21809 Reviewed-by: Jan Holesovsky <kendy@collabora.com> Tested-by: Jan Holesovsky <kendy@collabora.com> (cherry picked from commit 23a0ee3c01c3588472e1c19605909d6b9401253c) libreofficekit: ask for password when loading encrypted documents (cherry picked from commit 2b63e576a5cf06f4af877d63403ad7955ac71b72) desktop: use x prefix for uno::Reference (cherry picked from commit 0101cd3da6262169fa273309a86ba5e7cfe573bf) loplugin:defaultparams (cherry picked from commit 95c8b8e85d3328bfbe906ef3f69145842aae01db) (cherry picked from commit 2241a7fd97b8b70d2d3106ac531cc72192ad708f) Conflicts: desktop/inc/lib/init.hxx desktop/source/lib/lokinteractionhandler.hxx libreofficekit/source/gtk/lokdocview.cxx Change-Id: I73035193c87033052921c3aad94fdc057fe81111
Diffstat (limited to 'desktop')
-rw-r--r--desktop/inc/lib/init.hxx12
-rw-r--r--desktop/source/lib/init.cxx38
-rw-r--r--desktop/source/lib/lokinteractionhandler.cxx107
-rw-r--r--desktop/source/lib/lokinteractionhandler.hxx15
4 files changed, 165 insertions, 7 deletions
diff --git a/desktop/inc/lib/init.hxx b/desktop/inc/lib/init.hxx
index cb7df6f43f0d..b836052143b6 100644
--- a/desktop/inc/lib/init.hxx
+++ b/desktop/inc/lib/init.hxx
@@ -7,15 +7,19 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/.
*/
#include <LibreOfficeKit/LibreOfficeKit.h>
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/lang/XComponent.hpp>
#include <boost/shared_ptr.hpp>
+#include <map>
#include "../../source/inc/desktopdllapi.h"
#include <osl/thread.h>
using namespace css;
using namespace boost;
+class LOKInteractionHandler;
+
namespace desktop {
struct DESKTOP_DLLPUBLIC LibLODocument_Impl : public _LibreOfficeKitDocument
{
@@ -35,7 +39,15 @@ namespace desktop {
oslThread maThread;
LibreOfficeKitCallback mpCallback;
void *mpCallbackData;
+ int64_t mOptionalFeatures;
+ std::map<OString, rtl::Reference<LOKInteractionHandler>> mInteractionMap;
LibLibreOffice_Impl();
+ ~LibLibreOffice_Impl();
+
+ bool hasOptionalFeature(LibreOfficeKitOptionalFeatures const feature)
+ {
+ return (mOptionalFeatures & feature) != 0;
+ }
};
}
diff --git a/desktop/source/lib/init.cxx b/desktop/source/lib/init.cxx
index 81d2a9900220..ccb2e4059928 100644
--- a/desktop/source/lib/init.cxx
+++ b/desktop/source/lib/init.cxx
@@ -449,11 +449,16 @@ static void lo_registerCallback (LibreOfficeKit* pThis,
LibreOfficeKitCallback pCallback,
void* pData);
static char* lo_getFilterTypes(LibreOfficeKit* pThis);
+static void lo_setOptionalFeatures(LibreOfficeKit* pThis, uint64_t features);
+static void lo_setDocumentPassword(LibreOfficeKit* pThis,
+ const char* pURL,
+ const char* pPassword);
LibLibreOffice_Impl::LibLibreOffice_Impl()
: maThread(0)
, mpCallback(nullptr)
, mpCallbackData(nullptr)
+ , mOptionalFeatures(0)
{
if(!(m_pOfficeClass = gOfficeClass.lock())) {
m_pOfficeClass.reset(new LibreOfficeKitClass);
@@ -466,6 +471,8 @@ LibLibreOffice_Impl::LibLibreOffice_Impl()
m_pOfficeClass->documentLoadWithOptions = lo_documentLoadWithOptions;
m_pOfficeClass->registerCallback = lo_registerCallback;
m_pOfficeClass->getFilterTypes = lo_getFilterTypes;
+ m_pOfficeClass->setOptionalFeatures = lo_setOptionalFeatures;
+ m_pOfficeClass->setDocumentPassword = lo_setDocumentPassword;
gOfficeClass = m_pOfficeClass;
}
@@ -473,6 +480,10 @@ LibLibreOffice_Impl::LibLibreOffice_Impl()
pClass = m_pOfficeClass.get();
}
+LibLibreOffice_Impl::~LibLibreOffice_Impl()
+{
+}
+
namespace
{
@@ -534,7 +545,10 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
uno::makeAny(OUString::createFromAscii(pOptions)),
beans::PropertyState_DIRECT_VALUE);
- uno::Reference<task::XInteractionHandler2> xInteraction(new LOKInteractionHandler(::comphelper::getProcessComponentContext()));
+ rtl::Reference<LOKInteractionHandler> const pInteraction(
+ new LOKInteractionHandler(::comphelper::getProcessComponentContext(), pLib));
+ auto const pair(pLib->mInteractionMap.insert(std::make_pair(aURL.toUtf8(), pInteraction)));
+ uno::Reference<task::XInteractionHandler2> const xInteraction(pInteraction.get());
aFilterOptions[1].Name = "InteractionHandler";
aFilterOptions[1].Value <<= xInteraction;
@@ -553,6 +567,12 @@ static LibreOfficeKitDocument* lo_documentLoadWithOptions(LibreOfficeKit* pThis,
aURL, OUString("_blank"), 0,
aFilterOptions);
+ assert(!xComponent.is() || pair.second); // concurrent loading of same URL ought to fail
+ if (!pair.second)
+ {
+ pLib->mInteractionMap.erase(aURL.toUtf8());
+ }
+
if (!xComponent.is())
{
pLib->maLastExceptionMsg = "loadComponentFromURL returned an empty reference";
@@ -1657,6 +1677,22 @@ static char* lo_getFilterTypes(LibreOfficeKit* pThis)
return strdup(aStream.str().c_str());
}
+static void lo_setOptionalFeatures(LibreOfficeKit* pThis, uint64_t const features)
+{
+ LibLibreOffice_Impl *const pLib = static_cast<LibLibreOffice_Impl*>(pThis);
+ pLib->mOptionalFeatures = features;
+}
+
+static void lo_setDocumentPassword(LibreOfficeKit* pThis,
+ const char* pURL, const char* pPassword)
+{
+ assert(pThis);
+ assert(pURL);
+ LibLibreOffice_Impl *const pLib = static_cast<LibLibreOffice_Impl*>(pThis);
+ assert(pLib->mInteractionMap.find(OString(pURL)) != pLib->mInteractionMap.end());
+ pLib->mInteractionMap.find(OString(pURL))->second->SetPassword(pPassword);
+}
+
static void force_c_locale()
{
// force locale (and resource files loaded) to en-US
diff --git a/desktop/source/lib/lokinteractionhandler.cxx b/desktop/source/lib/lokinteractionhandler.cxx
index 1d20b0219e28..50a79721ff69 100644
--- a/desktop/source/lib/lokinteractionhandler.cxx
+++ b/desktop/source/lib/lokinteractionhandler.cxx
@@ -19,14 +19,28 @@
#include "lokinteractionhandler.hxx"
+#include <rtl/ref.hxx>
#include <cppuhelper/supportsservice.hxx>
+#include <com/sun/star/task/XInteractionAbort.hpp>
#include <com/sun/star/task/XInteractionApprove.hpp>
+#include <com/sun/star/task/XInteractionPassword2.hpp>
+#include <com/sun/star/task/DocumentPasswordRequest2.hpp>
+
+#define LOK_USE_UNSTABLE_API
+#include <../../inc/lib/init.hxx>
+
+#include <LibreOfficeKit/LibreOfficeKitEnums.h>
using namespace com::sun::star;
-LOKInteractionHandler::LOKInteractionHandler(uno::Reference<uno::XComponentContext> const & /*rxContext*/)
+LOKInteractionHandler::LOKInteractionHandler(
+ uno::Reference<uno::XComponentContext> const & /*rxContext*/,
+ desktop::LibLibreOffice_Impl *const pLOKit)
+ : m_pLOKit(pLOKit)
+ , m_usePassword(false)
{
+ assert(m_pLOKit);
}
LOKInteractionHandler::~LOKInteractionHandler()
@@ -58,15 +72,84 @@ void SAL_CALL LOKInteractionHandler::initialize(uno::Sequence<uno::Any> const &
{
}
-void SAL_CALL LOKInteractionHandler::handle(uno::Reference<task::XInteractionRequest> const & rRequest) throw (uno::RuntimeException, std::exception)
+void SAL_CALL LOKInteractionHandler::handle(
+ uno::Reference<task::XInteractionRequest> const & xRequest)
+throw (uno::RuntimeException, std::exception)
{
// just do the same thing in both cases
- handleInteractionRequest(rRequest);
+ handleInteractionRequest(xRequest);
}
-sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(const uno::Reference<task::XInteractionRequest >& rRequest) throw ( uno::RuntimeException, std::exception )
+sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(
+ const uno::Reference<task::XInteractionRequest>& xRequest)
+throw (uno::RuntimeException, std::exception)
{
- uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations = rRequest->getContinuations();
+ uno::Sequence<uno::Reference<task::XInteractionContinuation>> const &rContinuations = xRequest->getContinuations();
+
+ uno::Any const request(xRequest->getRequest());
+ task::DocumentPasswordRequest2 passwordRequest;
+ if (request >>= passwordRequest)
+ {
+ if (m_pLOKit->hasOptionalFeature((passwordRequest.IsRequestPasswordToModify)
+ ? LOK_FEATURE_DOCUMENT_PASSWORD_TO_MODIFY
+ : LOK_FEATURE_DOCUMENT_PASSWORD))
+ {
+ OString const url(passwordRequest.Name.toUtf8());
+ m_pLOKit->mpCallback(passwordRequest.IsRequestPasswordToModify
+ ? LOK_CALLBACK_DOCUMENT_PASSWORD_TO_MODIFY
+ : LOK_CALLBACK_DOCUMENT_PASSWORD,
+ url.getStr(),
+ m_pLOKit->mpCallbackData);
+
+ // block until SetPassword is called
+ m_havePassword.wait();
+ m_havePassword.reset();
+ }
+
+ for (sal_Int32 i = 0; i < rContinuations.getLength(); ++i)
+ {
+ if (m_usePassword)
+ {
+ if (passwordRequest.IsRequestPasswordToModify)
+ {
+ uno::Reference<task::XInteractionPassword2> const xIPW2(
+ rContinuations[i], uno::UNO_QUERY);
+ xIPW2->setPasswordToModify(m_Password);
+ xIPW2->select();
+ }
+ else
+ {
+ uno::Reference<task::XInteractionPassword> const xIPW(
+ rContinuations[i], uno::UNO_QUERY);
+ if (xIPW.is())
+ {
+ xIPW->setPassword(m_Password);
+ xIPW->select();
+ }
+ }
+ }
+ else
+ {
+ if (passwordRequest.IsRequestPasswordToModify)
+ {
+ uno::Reference<task::XInteractionPassword2> const xIPW2(
+ rContinuations[i], uno::UNO_QUERY);
+ xIPW2->setRecommendReadOnly(true);
+ xIPW2->select();
+ }
+ else
+ {
+ uno::Reference<task::XInteractionAbort> const xAbort(
+ rContinuations[i], uno::UNO_QUERY);
+ if (xAbort.is())
+ {
+ xAbort->select();
+ }
+ }
+ }
+ }
+ return sal_True;
+ }
// TODO: add LOK api that allows handling this for real, for the moment we
// just set the interaction as 'Approved'
@@ -80,4 +163,18 @@ sal_Bool SAL_CALL LOKInteractionHandler::handleInteractionRequest(const uno::Ref
return sal_True;
}
+void LOKInteractionHandler::SetPassword(char const*const pPassword)
+{
+ if (pPassword)
+ {
+ m_Password = OUString(pPassword, strlen(pPassword), RTL_TEXTENCODING_UTF8);
+ m_usePassword = true;
+ }
+ else
+ {
+ m_usePassword = false;
+ }
+ m_havePassword.set();
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/desktop/source/lib/lokinteractionhandler.hxx b/desktop/source/lib/lokinteractionhandler.hxx
index 6d4aa8231daf..2999cbbcb96e 100644
--- a/desktop/source/lib/lokinteractionhandler.hxx
+++ b/desktop/source/lib/lokinteractionhandler.hxx
@@ -20,12 +20,15 @@
#ifndef INCLUDED_DESKTOP_SOURCE_LIB_LOKINTERACTIONHANDLER_HXX
#define INCLUDED_DESKTOP_SOURCE_LIB_LOKINTERACTIONHANDLER_HXX
+#include <osl/conditn.hxx>
#include <cppuhelper/implbase.hxx>
#include <com/sun/star/lang/XInitialization.hpp>
#include <com/sun/star/lang/XServiceInfo.hpp>
#include <com/sun/star/task/InteractionHandler.hpp>
+namespace desktop { struct LibLibreOffice_Impl; }
+
/** InteractionHandler is an interface that provides the user with various dialogs / error messages.
We need an own implementation for the LibreOfficeKit so that we can route the
@@ -38,11 +41,21 @@ class LOKInteractionHandler: public cppu::WeakImplHelper<com::sun::star::lang::X
com::sun::star::lang::XInitialization,
com::sun::star::task::XInteractionHandler2>
{
+private:
+ desktop::LibLibreOffice_Impl * m_pLOKit;
+ OUString m_Password;
+ bool m_usePassword;
+ osl::Condition m_havePassword;
+
LOKInteractionHandler(const LOKInteractionHandler&) SAL_DELETED_FUNCTION;
LOKInteractionHandler& operator=(const LOKInteractionHandler&) SAL_DELETED_FUNCTION;
public:
- explicit LOKInteractionHandler(com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const & rxContext);
+ void SetPassword(char const* pPassword);
+
+ explicit LOKInteractionHandler(
+ com::sun::star::uno::Reference<com::sun::star::uno::XComponentContext> const & rxContext,
+ desktop::LibLibreOffice_Impl *);
virtual ~LOKInteractionHandler();