summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAshod Nakashian <ashod.nakashian@collabora.co.uk>2017-08-02 22:19:00 -0400
committerAshod Nakashian <ashnakash@gmail.com>2017-08-04 04:33:01 +0200
commit57446e0b60b9edbe1d72b13d664857f8d09c5048 (patch)
tree3984e8ec8f61bea3542ac6083f4a4ff6a6f540be
parent80095665bfcb8dd22b7cfe4fcc7d7a3023712385 (diff)
sw: store paragraph signature as rdf metadata
Change-Id: I13e6079e2aa3bee3dac10b11b0a23e9b798e02a3 Reviewed-on: https://gerrit.libreoffice.org/40722 Tested-by: Jenkins <ci@libreoffice.org> Reviewed-by: Ashod Nakashian <ashnakash@gmail.com>
-rw-r--r--sw/inc/rdfhelper.hxx11
-rw-r--r--sw/source/core/doc/rdfhelper.cxx50
-rw-r--r--sw/source/core/edit/edfcol.cxx24
3 files changed, 79 insertions, 6 deletions
diff --git a/sw/inc/rdfhelper.hxx b/sw/inc/rdfhelper.hxx
index f89d470300ed..d7c03279cd7d 100644
--- a/sw/inc/rdfhelper.hxx
+++ b/sw/inc/rdfhelper.hxx
@@ -22,10 +22,17 @@ class SwTextNode;
class SW_DLLPUBLIC SwRDFHelper
{
public:
- /// Gets all (rNode, key, value) statements in RDF graphs of type rType.
- static std::map<OUString, OUString> getTextNodeStatements(const OUString& rType, const SwTextNode& rNode);
+ /// Gets all (rTextNode, key, value) statements in RDF graphs of type rType.
+ static std::map<OUString, OUString> getTextNodeStatements(const OUString& rType, const SwTextNode& rTextNode);
+
/// Add an (rTextNode, key, value) statement in the graph of type rType -- or if it does not exist, create a graph at rPath first.
static void addTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue);
+
+ /// Remove an (rTextNode, key, value) statement in the graph of type rType.
+ static void removeTextNodeStatement(const OUString& rType, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue);
+
+ /// Update an (rTextNode, key, value) statement in the graph of type rType from old value to new. Creates the graph at rPath if doesn't exist.
+ static void updateTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rOldValue, const OUString& rNewValue);
};
#endif // INCLUDED_SW_INC_RDFHELPER_HXX
diff --git a/sw/source/core/doc/rdfhelper.cxx b/sw/source/core/doc/rdfhelper.cxx
index a139dfc0ba57..d43660dd258e 100644
--- a/sw/source/core/doc/rdfhelper.cxx
+++ b/sw/source/core/doc/rdfhelper.cxx
@@ -73,4 +73,54 @@ void SwRDFHelper::addTextNodeStatement(const OUString& rType, const OUString& rP
xGraph->addStatement(xSubject, xKey, xValue);
}
+void SwRDFHelper::removeTextNodeStatement(const OUString& rType, SwTextNode& rTextNode, const OUString& rKey, const OUString& rValue)
+{
+ uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
+ uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+ uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = xDocumentMetadataAccess->getMetadataGraphsWithType(xType);
+ if (!aGraphNames.hasElements())
+ return;
+
+ uno::Reference<rdf::XURI> xGraphName = aGraphNames[0];
+ uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
+ uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
+ uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
+ uno::Reference<rdf::XLiteral> xValue = rdf::Literal::create(xComponentContext, rValue);
+ xGraph->removeStatements(xSubject, xKey, xValue);
+}
+
+void SwRDFHelper::updateTextNodeStatement(const OUString& rType, const OUString& rPath, SwTextNode& rTextNode, const OUString& rKey, const OUString& rOldValue, const OUString& rNewValue)
+{
+ uno::Reference<uno::XComponentContext> xComponentContext(comphelper::getProcessComponentContext());
+ uno::Reference<rdf::XURI> xType = rdf::URI::create(xComponentContext, rType);
+ uno::Reference<rdf::XDocumentMetadataAccess> xDocumentMetadataAccess(rTextNode.GetDoc()->GetDocShell()->GetBaseModel(), uno::UNO_QUERY);
+ uno::Sequence< uno::Reference<rdf::XURI> > aGraphNames = xDocumentMetadataAccess->getMetadataGraphsWithType(xType);
+ uno::Reference<rdf::XURI> xGraphName;
+ if (aGraphNames.hasElements())
+ {
+ xGraphName = aGraphNames[0];
+ }
+ else
+ {
+ uno::Sequence< uno::Reference<rdf::XURI> > xTypes = { xType };
+ xGraphName = xDocumentMetadataAccess->addMetadataFile(rPath, xTypes);
+ }
+
+ uno::Reference<rdf::XNamedGraph> xGraph = xDocumentMetadataAccess->getRDFRepository()->getGraph(xGraphName);
+ uno::Reference<rdf::XResource> xSubject(SwXParagraph::CreateXParagraph(*rTextNode.GetDoc(), &rTextNode), uno::UNO_QUERY);
+ uno::Reference<rdf::XURI> xKey = rdf::URI::create(xComponentContext, rKey);
+
+ if (aGraphNames.hasElements())
+ {
+ // Remove the old value.
+ uno::Reference<rdf::XLiteral> xOldValue = rdf::Literal::create(xComponentContext, rOldValue);
+ xGraph->removeStatements(xSubject, xKey, xOldValue);
+ }
+
+ // Now add it with new value.
+ uno::Reference<rdf::XLiteral> xNewValue = rdf::Literal::create(xComponentContext, rNewValue);
+ xGraph->addStatement(xSubject, xKey, xNewValue);
+}
+
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/edit/edfcol.cxx b/sw/source/core/edit/edfcol.cxx
index 28d2907c939b..6dfbded172ff 100644
--- a/sw/source/core/edit/edfcol.cxx
+++ b/sw/source/core/edit/edfcol.cxx
@@ -60,6 +60,7 @@
#include <unoprnms.hxx>
#include <rootfrm.hxx>
#include <pagefrm.hxx>
+#include <rdfhelper.hxx>
#include <sfx2/watermarkitem.hxx>
#include <cppuhelper/bootstrap.hxx>
@@ -579,17 +580,32 @@ void SwEditShell::SignParagraph(SwPaM* pPaM)
// 3. Sign it.
svl::crypto::Signing signing(xCert);
signing.AddDataRange(text.getStr(), text.getLength());
- OStringBuffer signature;
- if (!signing.Sign(signature))
+ OStringBuffer sigBuf;
+ if (!signing.Sign(sigBuf))
return;
+ const OString signature = sigBuf.makeStringAndClear();
const auto pData = reinterpret_cast<const unsigned char*>(text.getStr());
const std::vector<unsigned char> data(pData, pData + text.getLength());
- const std::vector<unsigned char> sig(svl::crypto::DecodeHexString(signature.makeStringAndClear()));
+ const std::vector<unsigned char> sig(svl::crypto::DecodeHexString(signature));
if (!svl::crypto::Signing::Verify(data, true, sig, aInfo))
return;
- // 4. Add metadata.
+ // 4. Add metadata
+ static const OUString metaNS("urn:bails");
+ static const OUString metaFile("bails.rdf");
+
+ std::map<OUString, OUString> aStatements = SwRDFHelper::getTextNodeStatements(metaNS, *pNode);
+ OUString name = "loext:signature:index";
+ const OUString indexOld = aStatements[name];
+
+ // Update the index
+ const OUString index = OUString::number(indexOld.isEmpty() ? 1 : (indexOld.toInt32() + 1));
+ SwRDFHelper::updateTextNodeStatement(metaNS, metaFile, *pNode, name, indexOld, index);
+
+ // Add the signature
+ name = "loext:signature:signature" + index;
+ SwRDFHelper::addTextNodeStatement(metaNS, metaFile, *pNode, name, OStringToOUString(signature, RTL_TEXTENCODING_UTF8, 0));
}
}