Remove unused document signing code.
Signed-off-by: Gökay Şatır <gokaysatir@collabora.com> Change-Id: I30cf381d1fa282cf222ab5abc676374ab7eefb6cpull/6298/head
parent
ff02dc7381
commit
9d6296e4b3
|
@ -17,7 +17,6 @@
|
|||
<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>
|
||||
<batch_priority desc="A (lower) priority for use by batch eg. convert-to processes to avoid starving interactive ones" type="uint" default="5">5</batch_priority>
|
||||
<document_signing_url desc="The endpoint URL of signing server, if empty the document signing is disabled" type="string" default=""></document_signing_url>
|
||||
<redlining_as_comments desc="If true show red-lines as comments" type="bool" default="false">false</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 -->
|
||||
|
|
|
@ -351,7 +351,6 @@ COOL_JS_LST =\
|
|||
src/control/Control.FormulaBarJSDialog.js \
|
||||
src/control/Control.SheetsBar.js \
|
||||
src/control/Control.PresentationBar.js \
|
||||
src/control/Control.SigningBar.js \
|
||||
src/control/Control.TopToolbar.js \
|
||||
src/control/Control.UIManager.js \
|
||||
src/control/Control.DocumentNameInput.js \
|
||||
|
|
|
@ -259,14 +259,6 @@ m4_ifelse(MOBILEAPP,[true],
|
|||
</tr>
|
||||
</table>
|
||||
|
||||
<!--%DOCUMENT_SIGNING_DIV%-->
|
||||
<script>
|
||||
m4_ifelse(MOBILEAPP,[true],
|
||||
[ window.documentSigningURL = ''; ],
|
||||
[ window.documentSigningURL = decodeURIComponent('%DOCUMENT_SIGNING_URL%'); ]
|
||||
)
|
||||
</script>
|
||||
|
||||
<input id="insertgraphic" aria-labelledby="menu-insertgraphic" type="file" accept="image/*" style="position: fixed; top: -100em">
|
||||
<input id="selectbackground" aria-labelledby="menu-selectbackground" type="file" accept="image/*" style="position: fixed; top: -100em">
|
||||
|
||||
|
|
|
@ -2263,7 +2263,6 @@ L.Control.JSDialogBuilder = L.Control.extend({
|
|||
'modifypage': 'sidebar',
|
||||
'parapropertypanel': 'paragraphdialog',
|
||||
'tablecellbackgroundcolor': 'fillcolor',
|
||||
'signdocument':'signature',
|
||||
'zoteroArtwork': 'zoteroThesis',
|
||||
'zoteroAudioRecording': 'zoteroThesis',
|
||||
'zoteroBill': 'zoteroThesis',
|
||||
|
|
|
@ -82,7 +82,6 @@ L.Control.Menubar = L.Control.extend({
|
|||
{name: _('Word Document (.docx)'), id: 'downloadas-docx', type: 'action'},
|
||||
{name: _('Rich Text (.rtf)'), id: 'downloadas-rtf', type: 'action'},
|
||||
{name: _('EPUB (.epub)'), id: !window.ThisIsAMobileApp ? 'exportepub' : 'downloadas-epub', type: 'action'}]},
|
||||
{name: _('Sign document'), id: 'signdocument', type: 'action'},
|
||||
{name: _UNO('.uno:SetDocumentProperties', 'text'), uno: '.uno:SetDocumentProperties', id: 'properties'},
|
||||
{type: 'separator'},
|
||||
{name: L.Control.MenubarShortcuts.addShortcut(_UNO('.uno:Print', 'text'), L.Control.MenubarShortcuts.shortcuts.PRINT), id: 'print', type: 'action'},
|
||||
|
@ -893,7 +892,6 @@ L.Control.Menubar = L.Control.extend({
|
|||
]},
|
||||
{name: _('Share...'), id:'shareas', type: 'action'},
|
||||
{name: _('See revision history'), id: 'rev-history', type: 'action'},
|
||||
{name: _('Sign document'), id: 'signdocument', type: 'action'},
|
||||
{type: 'separator'},
|
||||
{name: _UNO('.uno:Print', 'text'), id: 'print', type: 'action'},
|
||||
{name: _UNO('.uno:SetDocumentProperties', 'text'), uno: '.uno:SetDocumentProperties', id: 'properties'}
|
||||
|
@ -1806,8 +1804,6 @@ L.Control.Menubar = L.Control.extend({
|
|||
|| id === 'remotelink'
|
||||
|| id === 'toggledarktheme') {
|
||||
this._map.dispatch(id);
|
||||
} else if (id === 'signdocument') {
|
||||
this._map.showSignDocument();
|
||||
} else if (id === 'insertcomment') {
|
||||
this._map.insertComment();
|
||||
} else if (id === 'insertgraphic') {
|
||||
|
@ -1972,9 +1968,6 @@ L.Control.Menubar = L.Control.extend({
|
|||
if (menuItem.id === 'about' && (L.DomUtil.get('about-dialog') === null)) {
|
||||
return false;
|
||||
}
|
||||
if (menuItem.id === 'signdocument' && (L.DomUtil.get('document-signing-bar') === null)) {
|
||||
return false;
|
||||
}
|
||||
if (menuItem.id === 'fontworkgalleryfloater' && !this._isFileODF) {
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -93,7 +93,6 @@ L.Control.NotebookbarWriter = L.Control.Notebookbar.extend({
|
|||
},
|
||||
|
||||
getFileTab: function() {
|
||||
var hasSigning = L.DomUtil.get('document-signing-bar') !== null;
|
||||
var hasRevisionHistory = L.Params.revHistoryEnabled;
|
||||
var hasPrint = !this._map['wopi'].HidePrintOption;
|
||||
var hasRepair = !this._map['wopi'].HideRepairOption;
|
||||
|
@ -261,16 +260,10 @@ L.Control.NotebookbarWriter = L.Control.Notebookbar.extend({
|
|||
'children': [
|
||||
hasRepair? {
|
||||
'id': 'repair',
|
||||
'type': (hasSigning ? '' : 'big') + 'menubartoolitem',
|
||||
'type': 'bigmenubartoolitem',
|
||||
'text': _('Repair'),
|
||||
'command': _('Repair')
|
||||
} : {},
|
||||
hasSigning? {
|
||||
'id': 'signdocument',
|
||||
'type': 'menubartoolitem',
|
||||
'text': _('Sign document'),
|
||||
'command': ''
|
||||
} : {}
|
||||
],
|
||||
'vertical': 'true'
|
||||
});
|
||||
|
|
|
@ -1,65 +0,0 @@
|
|||
/* -*- js-indent-level: 8 -*- */
|
||||
/*
|
||||
* L.Control.SigningBar
|
||||
*/
|
||||
|
||||
/* global $ w2ui */
|
||||
L.Control.SigningBar = L.Control.extend({
|
||||
|
||||
onAdd: function (map) {
|
||||
this.map = map;
|
||||
this.create();
|
||||
|
||||
map.on('doclayerinit', this.onDocLayerInit, this);
|
||||
},
|
||||
|
||||
create: function() {
|
||||
var that = this;
|
||||
if (L.DomUtil.get('document-signing-bar') !== null) {
|
||||
var toolbar = $('#document-signing-bar');
|
||||
toolbar.w2toolbar({
|
||||
name: 'document-signing-bar',
|
||||
items: this.map.setupSigningToolbarItems(),
|
||||
onClick: function (e) {
|
||||
that.onClick(e, e.target);
|
||||
window.hideTooltip(this, e.target);
|
||||
},
|
||||
onRefresh: function() {
|
||||
}
|
||||
});
|
||||
this.map.uiManager.enableTooltip(toolbar);
|
||||
|
||||
toolbar.bind('touchstart', function() {
|
||||
w2ui['document-signing-bar'].touchStarted = true;
|
||||
});
|
||||
}
|
||||
},
|
||||
|
||||
onClick: function(e, id, item) {
|
||||
if ('document-signing-bar' in w2ui && w2ui['document-signing-bar'].get(id) !== null) {
|
||||
var toolbar = w2ui['document-signing-bar'];
|
||||
item = toolbar.get(id);
|
||||
}
|
||||
|
||||
// In the iOS app we don't want clicking on the toolbar to pop up the keyboard.
|
||||
if (!window.ThisIsTheiOSApp && id !== 'zoomin' && id !== 'zoomout' && id !== 'mobile_wizard' && id !== 'insertion_mobile_wizard') {
|
||||
this.map.focus(this.map.canAcceptKeyboardInput()); // Maintain same keyboard state.
|
||||
}
|
||||
|
||||
if (item.disabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.map.handleSigningClickEvent(id, item); // this handles a bunch of signing bar click events
|
||||
},
|
||||
|
||||
onDocLayerInit: function() {
|
||||
if (L.DomUtil.get('document-signing-bar') !== null) {
|
||||
this.map.signingInitializeBar();
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
L.control.signingBar = function () {
|
||||
return new L.Control.SigningBar();
|
||||
};
|
|
@ -145,7 +145,6 @@ L.Control.UIManager = L.Control.extend({
|
|||
this.map.addControl(this.map.topToolbar);
|
||||
}
|
||||
|
||||
this.map.addControl(L.control.signingBar());
|
||||
this.map.addControl(L.control.statusBar());
|
||||
|
||||
this.map.jsdialog = L.control.jsDialog();
|
||||
|
|
|
@ -1692,10 +1692,6 @@ L.CanvasTileLayer = L.Layer.extend({
|
|||
var signstatus = textMsg.substring('signaturestatus:'.length + 1);
|
||||
this._map.onChangeSignStatus(signstatus);
|
||||
}
|
||||
else if (textMsg.startsWith('signeddocumentuploadstatus:')) {
|
||||
var status = textMsg.substring('signeddocumentuploadstatus:'.length + 1);
|
||||
this._map.onVereignUploadStatus(status);
|
||||
}
|
||||
else if (textMsg.startsWith('removesession')) {
|
||||
var viewId = parseInt(textMsg.substring('removesession'.length + 1));
|
||||
if (this._map._docLayer._viewId === viewId) {
|
||||
|
|
|
@ -91,7 +91,6 @@ data = data.replace(/%SOCKET_PROXY%/g, 'false');
|
|||
data = data.replace(/%UI_DEFAULTS%/g, '{}');
|
||||
data = data.replace(/%HEXIFY_URL%/g, '""');
|
||||
data = data.replace(/%GROUP_DOWNLOAD_AS%/g, 'false');
|
||||
data = data.replace(/%DOCUMENT_SIGNING_URL%/g, '');
|
||||
|
||||
window = new JSDOM(data, {
|
||||
runScripts: 'dangerously',
|
||||
|
|
|
@ -245,8 +245,7 @@ namespace COOLProtocol
|
|||
if (tokens.equals(0, "key") || tokens.equals(0, "outlinestate") ||
|
||||
tokens.equals(0, "paste") || tokens.equals(0, "insertfile") ||
|
||||
tokens.equals(0, "textinput") || tokens.equals(0, "windowkey") ||
|
||||
tokens.equals(0, "windowmouse") || tokens.equals(0, "windowgesture") ||
|
||||
tokens.equals(0, "signdocument"))
|
||||
tokens.equals(0, "windowmouse") || tokens.equals(0, "windowgesture"))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -97,9 +97,6 @@
|
|||
/* Default value of feature_lock.unlock_title */
|
||||
#undef UNLOCK_TITLE
|
||||
|
||||
/* Default value of per_documents.document_signing_url */
|
||||
#undef VEREIGN_URL
|
||||
|
||||
/* The welcome url of the build. */
|
||||
#undef WELCOME_URL
|
||||
|
||||
|
|
11
configure.ac
11
configure.ac
|
@ -369,10 +369,6 @@ AC_ARG_ENABLE([werror],
|
|||
AS_HELP_STRING([--disable-werror],
|
||||
[Do not turn warnings into errors.]))
|
||||
|
||||
AC_ARG_ENABLE([vereign],
|
||||
AS_HELP_STRING([--enable-vereign],
|
||||
[Set Vereign document_signing_url configuration key to the default app.vereign.com.]))
|
||||
|
||||
AC_ARG_ENABLE([cypress],
|
||||
AS_HELP_STRING([--enable-cypress],
|
||||
[Enable cypress tests.]))
|
||||
|
@ -914,13 +910,6 @@ AC_DEFINE_UNQUOTED([ENABLE_WELCOME_MESSAGE],$ENABLE_WELCOME_MESSAGE,[Should the
|
|||
AM_CONDITIONAL([ENABLE_WELCOME_MESSAGE], [test "$ENABLE_WELCOME_MESSAGE" = "1"])
|
||||
AC_DEFINE_UNQUOTED([WELCOME_URL],["$WELCOME_URL"],[The welcome url of the build.])
|
||||
|
||||
VEREIGN_URL=
|
||||
if test "$enable_vereign" = "yes"; then
|
||||
VEREIGN_URL="https://app.vereign.com"
|
||||
fi
|
||||
AC_DEFINE_UNQUOTED([VEREIGN_URL],["$VEREIGN_URL"],[Default value of per_documents.document_signing_url])
|
||||
AC_SUBST(VEREIGN_URL)
|
||||
|
||||
# Test for build environment
|
||||
|
||||
AS_IF([test "$ENABLE_GTKAPP" != true],
|
||||
|
|
|
@ -45,7 +45,6 @@
|
|||
<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>
|
||||
<batch_priority desc="A (lower) priority for use by batch eg. convert-to processes to avoid starving interactive ones" type="uint" default="5">5</batch_priority>
|
||||
<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="false">false</redlining_as_comments>
|
||||
<pdf_resolution_dpi desc="The resolution, in DPI, used to render PDF documents as image. Memory consumption grows proportionally. Must be a positive value less than 385. Defaults to 96." type="uint" default="96">96</pdf_resolution_dpi>
|
||||
<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>
|
||||
|
|
|
@ -124,8 +124,5 @@
|
|||
/* Define to 1 if you have the ANSI C header files. */
|
||||
#define STDC_HEADERS 1
|
||||
|
||||
/* Default value of per_documents.document_signing_url */
|
||||
#define VEREIGN_URL ""
|
||||
|
||||
/* Version number of package */
|
||||
/* #undef VERSION */
|
||||
|
|
|
@ -428,9 +428,6 @@ bool ChildSession::_handleInput(const char *buffer, int length)
|
|||
tokens.equals(0, "userinactive") ||
|
||||
tokens.equals(0, "windowcommand") ||
|
||||
tokens.equals(0, "asksignaturestatus") ||
|
||||
tokens.equals(0, "signdocument") ||
|
||||
tokens.equals(0, "uploadsigneddocument") ||
|
||||
tokens.equals(0, "exportsignanduploaddocument") ||
|
||||
tokens.equals(0, "rendershapeselection") ||
|
||||
tokens.equals(0, "removetextcontext") ||
|
||||
tokens.equals(0, "dialogevent") ||
|
||||
|
@ -564,24 +561,10 @@ bool ChildSession::_handleInput(const char *buffer, int length)
|
|||
{
|
||||
sendWindowCommand(tokens);
|
||||
}
|
||||
else if (tokens.equals(0, "signdocument"))
|
||||
{
|
||||
signDocumentContent(buffer, length, tokens);
|
||||
}
|
||||
else if (tokens.equals(0, "asksignaturestatus"))
|
||||
{
|
||||
askSignatureStatus(buffer, length, tokens);
|
||||
}
|
||||
#if !MOBILEAPP
|
||||
else if (tokens.equals(0, "uploadsigneddocument"))
|
||||
{
|
||||
return uploadSignedDocument(buffer, length, tokens);
|
||||
}
|
||||
else if (tokens.equals(0, "exportsignanduploaddocument"))
|
||||
{
|
||||
return exportSignAndUploadDocument(buffer, length, tokens);
|
||||
}
|
||||
#endif
|
||||
else if (tokens.equals(0, "rendershapeselection"))
|
||||
{
|
||||
return renderShapeSelection(tokens);
|
||||
|
@ -666,118 +649,6 @@ std::string getMimeFromFileType(const std::string & fileType)
|
|||
return std::string();
|
||||
}
|
||||
|
||||
bool ChildSession::uploadSignedDocument(const char* buffer, int length, const StringVector& /*tokens*/)
|
||||
{
|
||||
std::string filename;
|
||||
std::string wopiUrl;
|
||||
std::string token;
|
||||
std::string filetype;
|
||||
|
||||
{ // parse JSON
|
||||
const std::string firstLine = getFirstLine(buffer, length);
|
||||
|
||||
const char* data = buffer + firstLine.size() + 1;
|
||||
const int size = length - firstLine.size() - 1;
|
||||
std::string json(data, size);
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr root = parser.parse(json).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
filename = JsonUtil::getJSONValue<std::string>(root, "filename");
|
||||
wopiUrl = JsonUtil::getJSONValue<std::string>(root, "wopiUrl");
|
||||
token = JsonUtil::getJSONValue<std::string>(root, "token");
|
||||
filetype = JsonUtil::getJSONValue<std::string>(root, "type");
|
||||
}
|
||||
|
||||
if (filetype.empty() || filename.empty() || wopiUrl.empty() || token.empty())
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=uploadsigneddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string mimetype = getMimeFromFileType(filetype);
|
||||
if (mimetype.empty())
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=uploadsigneddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
const std::string tmpDir = FileUtil::createRandomDir(JAILED_DOCUMENT_ROOT);
|
||||
const Poco::Path filenameParam(filename);
|
||||
const std::string url = JAILED_DOCUMENT_ROOT + tmpDir + '/' + filenameParam.getFileName();
|
||||
|
||||
getLOKitDocument()->saveAs(url.c_str(),
|
||||
filetype.empty() ? nullptr : filetype.c_str(),
|
||||
nullptr);
|
||||
|
||||
Authorization authorization(Authorization::Type::Token, token);
|
||||
Poco::URI uriObject(wopiUrl + '/' + filename + "/contents");
|
||||
|
||||
authorization.authorizeURI(uriObject);
|
||||
|
||||
try
|
||||
{
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::Context::Params sslClientParams;
|
||||
sslClientParams.verificationMode = Poco::Net::Context::VERIFY_NONE;
|
||||
Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler> consoleClientHandler = new Poco::Net::KeyConsoleHandler(false);
|
||||
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> invalidClientCertHandler = new Poco::Net::AcceptCertificateHandler(false);
|
||||
Poco::Net::Context::Ptr sslClientContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, sslClientParams);
|
||||
Poco::Net::SSLManager::instance().initializeClient(consoleClientHandler, invalidClientCertHandler, sslClientContext);
|
||||
|
||||
std::unique_ptr<Poco::Net::HTTPClientSession> psession
|
||||
= Util::make_unique<Poco::Net::HTTPSClientSession>(
|
||||
uriObject.getHost(),
|
||||
uriObject.getPort(),
|
||||
Poco::Net::SSLManager::instance().defaultClientContext());
|
||||
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.set("User-Agent", WOPI_AGENT_STRING);
|
||||
authorization.authorizeRequest(request);
|
||||
|
||||
request.set("X-WOPI-Override", "PUT");
|
||||
|
||||
// If we can't access the file, reading it will throw.
|
||||
const FileUtil::Stat fileStat(url);
|
||||
const std::size_t filesize = (fileStat.good() ? fileStat.size() : 0);
|
||||
|
||||
request.setContentType(mimetype);
|
||||
request.setContentLength(filesize);
|
||||
|
||||
std::ostream& httpOutputStream = psession->sendRequest(request);
|
||||
|
||||
std::ifstream inputFileStream(url);
|
||||
Poco::StreamCopier::copyStream(inputFileStream, httpOutputStream);
|
||||
|
||||
Poco::Net::HTTPResponse response;
|
||||
std::istream& responseStream = psession->receiveResponse(response);
|
||||
|
||||
std::ostringstream outputStringStream;
|
||||
Poco::StreamCopier::copyStream(responseStream, outputStringStream);
|
||||
std::string responseString = outputStringStream.str();
|
||||
|
||||
if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_OK &&
|
||||
response.getStatus() != Poco::Net::HTTPResponse::HTTP_CREATED)
|
||||
{
|
||||
LOG_ERR("Upload signed document HTTP Response Error: " << response.getStatus() << ' '
|
||||
<< response.getReason());
|
||||
|
||||
sendTextFrameAndLogError("error: cmd=uploadsigneddocument kind=httpresponse");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception& pocoException)
|
||||
{
|
||||
LOG_ERR("Upload signed document Exception: " + pocoException.displayText());
|
||||
|
||||
sendTextFrameAndLogError("error: cmd=uploadsigneddocument kind=failure");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool ChildSession::loadDocument(const StringVector& tokens)
|
||||
|
@ -2189,238 +2060,8 @@ std::string extractCertificate(const std::string & certificate)
|
|||
return certificate.substr(pos1, pos2);
|
||||
}
|
||||
|
||||
std::string extractPrivateKey(const std::string & privateKey)
|
||||
{
|
||||
const std::string header("-----BEGIN PRIVATE KEY-----");
|
||||
const std::string footer("-----END PRIVATE KEY-----");
|
||||
|
||||
std::string result;
|
||||
|
||||
size_t pos1 = privateKey.find(header);
|
||||
if (pos1 == std::string::npos)
|
||||
return result;
|
||||
|
||||
size_t pos2 = privateKey.find(footer, pos1 + 1);
|
||||
if (pos2 == std::string::npos)
|
||||
return result;
|
||||
|
||||
pos1 = pos1 + std::string(header).length();
|
||||
pos2 = pos2 - pos1;
|
||||
|
||||
return privateKey.substr(pos1, pos2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
bool ChildSession::signDocumentContent(const char* buffer, int length, const StringVector& /*tokens*/)
|
||||
{
|
||||
bool bResult = true;
|
||||
|
||||
const std::string firstLine = getFirstLine(buffer, length);
|
||||
const char* data = buffer + firstLine.size() + 1;
|
||||
const int size = length - firstLine.size() - 1;
|
||||
std::string json(data, size);
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr root = parser.parse(json).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
for (auto& rChainPtr : *root->getArray("chain"))
|
||||
{
|
||||
if (!rChainPtr.isString())
|
||||
return false;
|
||||
|
||||
std::string chainCertificate = rChainPtr;
|
||||
std::vector<unsigned char> binaryChainCertificate = decodeBase64(extractCertificate(chainCertificate));
|
||||
|
||||
bResult = getLOKitDocument()->addCertificate(
|
||||
binaryChainCertificate.data(),
|
||||
binaryChainCertificate.size());
|
||||
|
||||
if (!bResult)
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string x509Certificate = JsonUtil::getJSONValue<std::string>(root, "x509Certificate");
|
||||
std::vector<unsigned char> binaryCertificate = decodeBase64(extractCertificate(x509Certificate));
|
||||
|
||||
std::string privateKey = JsonUtil::getJSONValue<std::string>(root, "privateKey");
|
||||
std::vector<unsigned char> binaryPrivateKey = decodeBase64(extractPrivateKey(privateKey));
|
||||
|
||||
bResult = getLOKitDocument()->insertCertificate(
|
||||
binaryCertificate.data(), binaryCertificate.size(),
|
||||
binaryPrivateKey.data(), binaryPrivateKey.size());
|
||||
|
||||
return bResult;
|
||||
}
|
||||
|
||||
#if !MOBILEAPP
|
||||
|
||||
bool ChildSession::exportSignAndUploadDocument(const char* buffer, int length, const StringVector& /*tokens*/)
|
||||
{
|
||||
bool bResult = false;
|
||||
|
||||
std::string filename;
|
||||
std::string wopiUrl;
|
||||
std::string token;
|
||||
std::string filetype;
|
||||
std::string x509Certificate;
|
||||
std::string privateKey;
|
||||
std::vector<std::string> certificateChain;
|
||||
|
||||
{ // parse JSON
|
||||
const std::string firstLine = getFirstLine(buffer, length);
|
||||
const char* data = buffer + firstLine.size() + 1;
|
||||
const int size = length - firstLine.size() - 1;
|
||||
std::string json(data, size);
|
||||
|
||||
Poco::JSON::Parser parser;
|
||||
Poco::JSON::Object::Ptr root = parser.parse(json).extract<Poco::JSON::Object::Ptr>();
|
||||
|
||||
filename = JsonUtil::getJSONValue<std::string>(root, "filename");
|
||||
wopiUrl = JsonUtil::getJSONValue<std::string>(root, "wopiUrl");
|
||||
token = JsonUtil::getJSONValue<std::string>(root, "token");
|
||||
filetype = JsonUtil::getJSONValue<std::string>(root, "type");
|
||||
x509Certificate = JsonUtil::getJSONValue<std::string>(root, "x509Certificate");
|
||||
privateKey = JsonUtil::getJSONValue<std::string>(root, "privateKey");
|
||||
|
||||
for (auto& rChainPtr : *root->getArray("chain"))
|
||||
{
|
||||
if (!rChainPtr.isString())
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
std::string chainCertificate = rChainPtr;
|
||||
certificateChain.push_back(chainCertificate);
|
||||
}
|
||||
}
|
||||
|
||||
if (filetype.empty() || filename.empty() || wopiUrl.empty() || token.empty() || x509Certificate.empty() || privateKey.empty())
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string mimetype = getMimeFromFileType(filetype);
|
||||
if (mimetype.empty())
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
|
||||
// add certificate chain
|
||||
for (auto const & certificate : certificateChain)
|
||||
{
|
||||
std::vector<unsigned char> binaryChainCertificate = decodeBase64(extractCertificate(certificate));
|
||||
|
||||
bResult = getLOKitDocument()->addCertificate(
|
||||
binaryChainCertificate.data(),
|
||||
binaryChainCertificate.size());
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// export document to a temp file
|
||||
const std::string aTempDir = FileUtil::createRandomDir(JAILED_DOCUMENT_ROOT);
|
||||
const Poco::Path filenameParam(filename);
|
||||
const std::string aTempDocumentURL
|
||||
= JAILED_DOCUMENT_ROOT + aTempDir + '/' + filenameParam.getFileName();
|
||||
|
||||
getLOKitDocument()->saveAs(aTempDocumentURL.c_str(), filetype.c_str(), nullptr);
|
||||
|
||||
// sign document
|
||||
{
|
||||
std::vector<unsigned char> binaryCertificate = decodeBase64(extractCertificate(x509Certificate));
|
||||
std::vector<unsigned char> binaryPrivateKey = decodeBase64(extractPrivateKey(privateKey));
|
||||
|
||||
bResult = _docManager->getLOKit()->signDocument(aTempDocumentURL.c_str(),
|
||||
binaryCertificate.data(), binaryCertificate.size(),
|
||||
binaryPrivateKey.data(), binaryPrivateKey.size());
|
||||
|
||||
if (!bResult)
|
||||
{
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=syntax");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// upload
|
||||
Authorization authorization(Authorization::Type::Token, token);
|
||||
Poco::URI uriObject(wopiUrl + '/' + filename + "/contents");
|
||||
|
||||
authorization.authorizeURI(uriObject);
|
||||
|
||||
try
|
||||
{
|
||||
Poco::Net::initializeSSL();
|
||||
Poco::Net::Context::Params sslClientParams;
|
||||
sslClientParams.verificationMode = Poco::Net::Context::VERIFY_NONE;
|
||||
Poco::SharedPtr<Poco::Net::PrivateKeyPassphraseHandler> consoleClientHandler = new Poco::Net::KeyConsoleHandler(false);
|
||||
Poco::SharedPtr<Poco::Net::InvalidCertificateHandler> invalidClientCertHandler = new Poco::Net::AcceptCertificateHandler(false);
|
||||
Poco::Net::Context::Ptr sslClientContext = new Poco::Net::Context(Poco::Net::Context::CLIENT_USE, sslClientParams);
|
||||
Poco::Net::SSLManager::instance().initializeClient(consoleClientHandler, invalidClientCertHandler, sslClientContext);
|
||||
|
||||
std::unique_ptr<Poco::Net::HTTPClientSession> psession
|
||||
= Util::make_unique<Poco::Net::HTTPSClientSession>(
|
||||
uriObject.getHost(),
|
||||
uriObject.getPort(),
|
||||
Poco::Net::SSLManager::instance().defaultClientContext());
|
||||
|
||||
Poco::Net::HTTPRequest request(Poco::Net::HTTPRequest::HTTP_POST, uriObject.getPathAndQuery(), Poco::Net::HTTPMessage::HTTP_1_1);
|
||||
request.set("User-Agent", WOPI_AGENT_STRING);
|
||||
authorization.authorizeRequest(request);
|
||||
|
||||
request.set("X-WOPI-Override", "PUT");
|
||||
|
||||
// If we can't access the file, reading it will throw.
|
||||
const FileUtil::Stat fileStat(aTempDocumentURL);
|
||||
const std::size_t filesize = (fileStat.good() ? fileStat.size() : 0);
|
||||
|
||||
request.setContentType(mimetype);
|
||||
request.setContentLength(filesize);
|
||||
|
||||
std::ostream& httpOutputStream = psession->sendRequest(request);
|
||||
|
||||
std::ifstream inputFileStream(aTempDocumentURL);
|
||||
Poco::StreamCopier::copyStream(inputFileStream, httpOutputStream);
|
||||
|
||||
Poco::Net::HTTPResponse response;
|
||||
std::istream& responseStream = psession->receiveResponse(response);
|
||||
|
||||
std::ostringstream outputStringStream;
|
||||
Poco::StreamCopier::copyStream(responseStream, outputStringStream);
|
||||
std::string responseString = outputStringStream.str();
|
||||
|
||||
if (response.getStatus() != Poco::Net::HTTPResponse::HTTP_OK &&
|
||||
response.getStatus() != Poco::Net::HTTPResponse::HTTP_CREATED)
|
||||
{
|
||||
LOG_ERR("Upload signed document HTTP Response Error: " << response.getStatus() << ' ' << response.getReason());
|
||||
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=httpresponse");
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
catch (const Poco::Exception& pocoException)
|
||||
{
|
||||
LOG_ERR("Upload signed document Exception: " + pocoException.displayText());
|
||||
|
||||
sendTextFrameAndLogError("error: cmd=exportsignanduploaddocument kind=failure");
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
sendTextFrame("signeddocumentuploadstatus: OK");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
bool ChildSession::askSignatureStatus(const char* buffer, int length, const StringVector& /*tokens*/)
|
||||
{
|
||||
bool bResult = true;
|
||||
|
|
|
@ -309,10 +309,7 @@ private:
|
|||
bool moveSelectedClientParts(const StringVector& tokens);
|
||||
bool setPage(const StringVector& tokens);
|
||||
bool sendWindowCommand(const StringVector& tokens);
|
||||
bool signDocumentContent(const char* buffer, int length, const StringVector& tokens);
|
||||
bool askSignatureStatus(const char* buffer, int length, const StringVector& tokens);
|
||||
bool uploadSignedDocument(const char* buffer, int length, const StringVector& tokens);
|
||||
bool exportSignAndUploadDocument(const char* buffer, int length, const StringVector& tokens);
|
||||
bool renderShapeSelection(const StringVector& tokens);
|
||||
bool removeTextContext(const StringVector& tokens);
|
||||
#if ENABLE_FEATURE_LOCK || ENABLE_FEATURE_RESTRICTION
|
||||
|
|
|
@ -2003,7 +2003,6 @@ void COOLWSD::innerInitialize(Application& self)
|
|||
{ "per_document.cleanup.limit_cpu_per", "85" },
|
||||
{ "per_document.cleanup.lost_kit_grace_period_secs", "120" },
|
||||
{ "per_document.cleanup[@enable]", "false" },
|
||||
{ "per_document.document_signing_url", VEREIGN_URL },
|
||||
{ "per_document.idle_timeout_secs", "3600" },
|
||||
{ "per_document.idlesave_duration_secs", "30" },
|
||||
{ "per_document.limit_file_size_mb", "0" },
|
||||
|
|
|
@ -1036,10 +1036,7 @@ bool ClientSession::_handleInput(const char *buffer, int length)
|
|||
tokens.equals(0, "userinactive") ||
|
||||
tokens.equals(0, "paintwindow") ||
|
||||
tokens.equals(0, "windowcommand") ||
|
||||
tokens.equals(0, "signdocument") ||
|
||||
tokens.equals(0, "asksignaturestatus") ||
|
||||
tokens.equals(0, "uploadsigneddocument") ||
|
||||
tokens.equals(0, "exportsignanduploaddocument") ||
|
||||
tokens.equals(0, "rendershapeselection") ||
|
||||
tokens.equals(0, "resizewindow") ||
|
||||
tokens.equals(0, "removetextcontext") ||
|
||||
|
|
|
@ -977,18 +977,6 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request,
|
|||
Poco::replaceInPlace(preprocess, std::string("<!--%BRANDING_JS%-->"), brandJS);
|
||||
Poco::replaceInPlace(preprocess, std::string("<!--%CSS_VARIABLES%-->"), cssVarsToStyle(cssVars));
|
||||
|
||||
// Customization related to document signing.
|
||||
std::string documentSigningDiv;
|
||||
std::string escapedDocumentSigningURL;
|
||||
const std::string documentSigningURL = config.getString("per_document.document_signing_url", "");
|
||||
if (!documentSigningURL.empty())
|
||||
{
|
||||
documentSigningDiv = "<div id=\"document-signing-bar\"></div>";
|
||||
Poco::URI::encode(documentSigningURL, "'", escapedDocumentSigningURL);
|
||||
}
|
||||
Poco::replaceInPlace(preprocess, std::string("<!--%DOCUMENT_SIGNING_DIV%-->"), documentSigningDiv);
|
||||
Poco::replaceInPlace(preprocess, std::string("%DOCUMENT_SIGNING_URL%"), escapedDocumentSigningURL);
|
||||
|
||||
const auto coolLogging = stringifyBoolFromConfig(config, "browser_logging", false);
|
||||
Poco::replaceInPlace(preprocess, std::string("%BROWSER_LOGGING%"), coolLogging);
|
||||
const auto groupDownloadAs = stringifyBoolFromConfig(config, "per_view.group_download_as", true);
|
||||
|
@ -1067,12 +1055,9 @@ void FileServerRequestHandler::preprocessFile(const HTTPRequest& request,
|
|||
|
||||
const std::string mimeType = "text/html";
|
||||
|
||||
// Document signing: if endpoint URL is configured, whitelist that for
|
||||
// iframe purposes.
|
||||
std::ostringstream cspOss;
|
||||
cspOss << "Content-Security-Policy: default-src 'none'; "
|
||||
"frame-src 'self' " << WELCOME_URL << " " << FEEDBACK_URL << " " << buyProduct <<
|
||||
" blob: " << documentSigningURL << "; "
|
||||
"frame-src 'self' " << WELCOME_URL << " " << FEEDBACK_URL << " " << buyProduct << "; "
|
||||
"connect-src 'self' https://www.zotero.org https://api.zotero.org "
|
||||
<< cnxDetails.getWebSocketUrl() << " " << cnxDetails.getWebServerUrl() << " "
|
||||
<< indirectionURI.getAuthority() << "; "
|
||||
|
|
|
@ -315,10 +315,6 @@ asksignaturestatus
|
|||
|
||||
Requests a signing status of the document.
|
||||
|
||||
signdocument
|
||||
|
||||
Sign the current document with the input certificate and private key.
|
||||
|
||||
rendershapeselection mimetype=<mimeType>
|
||||
|
||||
Request rendering of selected shapes into an SVG format.
|
||||
|
|
Loading…
Reference in New Issue