[Libreoffice-commits] core.git: Branch 'libreoffice-7-2' - include/unotools include/xmloff sw/qa unotools/source xmloff/source

László Németh (via logerrit) logerrit at kemper.freedesktop.org
Thu Jun 17 17:46:59 UTC 2021


 include/unotools/securityoptions.hxx       |   12 +++
 include/xmloff/xmlexp.hxx                  |    6 +
 sw/qa/uitest/data/redline-autocorrect.fodt |   24 ++++++
 sw/qa/uitest/writer_tests7/tdf90401.py     |  103 +++++++++++++++++++++++++++++
 unotools/source/config/securityoptions.cxx |   14 +++
 xmloff/source/core/xmlexp.cxx              |    3 
 xmloff/source/draw/sdxmlexp.cxx            |   16 +++-
 xmloff/source/text/XMLRedlineExport.cxx    |   24 +++++-
 xmloff/source/text/txtflde.cxx             |   13 +++
 9 files changed, 205 insertions(+), 10 deletions(-)

New commits:
commit 658e947b699ad1e08810f0fefd5c901e750ad919
Author:     László Németh <nemeth at numbertext.org>
AuthorDate: Mon Jun 14 20:46:17 2021 +0200
Commit:     Adolfo Jayme Barrientos <fitojb at ubuntu.com>
CommitDate: Thu Jun 17 19:46:23 2021 +0200

    tdf#90401 xmloff: remove personal info of comments and changes
    
    If Options → LibreOffice → Security → Security Options
    and Warnings → Options... → Security Options → Remove personal
    information on saving" is enabled.
    
    Use the same time (1970-01-01T00:00:00) for mandatory
    time stamps, and replace authors and creator-initials with
    "1", "2", "3" etc., also to avoid of joining adjacent
    redline ranges.
    
    Note: to see the work of the unit test in Linux command line:
    
    (cd sw && make UITest_writer_tests7 UITEST_TEST_NAME="tdf90401.tdf90401.test_tdf90401_remove_personal_info" SAL_USE_VCLPLUGIN=gen)
    
    Change-Id: I3b4d710dbeeee12177aff378597cd2b683ca6c25
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117319
    Tested-by: Jenkins
    Reviewed-by: László Németh <nemeth at numbertext.org>
    (cherry picked from commit 12da70f88517bf3c053afe1c504bb70bd27573f2)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/117301
    Reviewed-by: Adolfo Jayme Barrientos <fitojb at ubuntu.com>

diff --git a/include/unotools/securityoptions.hxx b/include/unotools/securityoptions.hxx
index 7a339a90bcf8..944e6fba5a34 100644
--- a/include/unotools/securityoptions.hxx
+++ b/include/unotools/securityoptions.hxx
@@ -25,6 +25,7 @@
 #include <rtl/ustring.hxx>
 #include <unotools/options.hxx>
 #include <memory>
+#include <unordered_map>
 
 namespace osl { class Mutex; }
 
@@ -184,6 +185,17 @@ class SAL_WARN_UNUSED UNOTOOLS_DLLPUBLIC SvtSecurityOptions final : public utl::
 
 };      // class SvtSecurityOptions
 
+// map personal info strings, e.g. authors to 1, 2, 3... for removing personal info
+typedef ::std::unordered_map< OUString, size_t > SvtSecurityMapPersonalInfoType;
+
+class UNOTOOLS_DLLPUBLIC SvtSecurityMapPersonalInfo final
+{
+    SvtSecurityMapPersonalInfoType aInfoIDs;
+
+public:
+    size_t GetInfoID( const OUString sPersonalInfo );
+};
+
 #endif // INCLUDED_UNOTOOLS_SECURITYOPTIONS_HXX
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/include/xmloff/xmlexp.hxx b/include/xmloff/xmlexp.hxx
index adba9e653077..5b72788313ef 100644
--- a/include/xmloff/xmlexp.hxx
+++ b/include/xmloff/xmlexp.hxx
@@ -43,6 +43,7 @@
 #include <com/sun/star/container/XNamed.hpp>
 
 #include <unotools/saveopt.hxx>
+#include <unotools/securityoptions.hxx>
 
 #include <xmloff/XMLPageExport.hxx>
 #include <comphelper/servicehelper.hxx>
@@ -69,6 +70,7 @@ namespace com::sun::star::xml::sax { class XExtendedDocumentHandler; }
 namespace com::sun::star::xml::sax { class XLocator; }
 
 class SvXMLNamespaceMap;
+class SvtSecurityMapPersonalInfo;
 class SvXMLExport_Impl;
 class ProgressBarHelper;
 class XMLEventExport;
@@ -135,6 +137,7 @@ class XMLOFF_DLLPUBLIC SvXMLExport : public cppu::WeakImplHelper<
     OUString     msFilterName;
     OUString     msImgFilterName;
     std::unique_ptr<SvXMLNamespaceMap> mpNamespaceMap;    // the namespace map
+    std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; // map authors to remove personal info
     SvXMLUnitConverter          maUnitConv;        // the unit converter
     std::unique_ptr<SvXMLNumFmtExport> mpNumExport;
     std::unique_ptr<ProgressBarHelper> mpProgressBarHelper;
@@ -390,6 +393,9 @@ public:
     // Get (const) namespace map.
     const SvXMLNamespaceMap& GetNamespaceMap() const { return *mpNamespaceMap; }
 
+    // Get author id to remove personal info
+    size_t GetInfoID( const OUString sPersonalInfo ) const { return mpAuthorIDs->GetInfoID(sPersonalInfo); }
+
     // Get unit converter
     const SvXMLUnitConverter& GetMM100UnitConverter() const { return maUnitConv; }
 
diff --git a/sw/qa/uitest/data/redline-autocorrect.fodt b/sw/qa/uitest/data/redline-autocorrect.fodt
new file mode 100644
index 000000000000..ce874d299a8f
--- /dev/null
+++ b/sw/qa/uitest/data/redline-autocorrect.fodt
@@ -0,0 +1,24 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<office:document xmlns:office="urn:oasis:names:tc:opendocument:xmlns:office:1.0" xmlns:style="urn:oasis:names:tc:opendocument:xmlns:style:1.0" xmlns:text="urn:oasis:names:tc:opendocument:xmlns:text:1.0" xmlns:fo="urn:oasis:names:tc:opendocument:xmlns:xsl-fo-compatible:1.0" xmlns:officeooo="http://openoffice.org/2009/office" office:version="1.2" office:mimetype="application/vnd.oasis.opendocument.text" xmlns:dc="http://purl.org/dc/elements/1.1/">
+ <office:styles>
+  <style:style style:name="Standard" style:family="paragraph" style:class="text"/>
+  <style:default-style style:family="paragraph">
+   <style:text-properties fo:language="en" fo:country="US"/>
+  </style:default-style>
+ </office:styles>
+ <office:body>
+  <office:text>
+   <text:tracked-changes text:track-changes="false">
+    <text:changed-region xml:id="ct94099223789984" text:id="ct94099223789984">
+     <text:deletion>
+      <office:change-info>
+       <dc:creator>NL</dc:creator>
+       <dc:date>2020-11-03T19:19:05</dc:date>
+      </office:change-info>
+     </text:deletion>
+    </text:changed-region>
+   </text:tracked-changes>
+   <text:p text:style-name="P1"><text:change-start text:change-id="ct94099223789984"/>t<text:change-end text:change-id="ct94099223789984"/>s</text:p>
+  </office:text>
+ </office:body>
+</office:document>
diff --git a/sw/qa/uitest/writer_tests7/tdf90401.py b/sw/qa/uitest/writer_tests7/tdf90401.py
new file mode 100644
index 000000000000..7260ae914268
--- /dev/null
+++ b/sw/qa/uitest/writer_tests7/tdf90401.py
@@ -0,0 +1,103 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+from uitest.framework import UITestCase
+#from uitest.uihelper.common import type_text
+from uitest.uihelper.common import get_state_as_dict
+from uitest.uihelper.common import get_url_for_data_file
+from uitest.uihelper.common import select_pos
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from org.libreoffice.unotest import systemPathToFileUrl
+from tempfile import TemporaryDirectory
+import os.path
+#Bug 90401 - remove personal info on redlines and annotations
+
+class tdf90401(UITestCase):
+
+   def test_tdf90401_remove_personal_info(self):
+
+        # load a test document with a tracked change, and add a comment
+
+        writer_doc = self.ui_test.load_file(get_url_for_data_file('redline-autocorrect.fodt'))
+        xWriterDoc = self.xUITest.getTopFocusWindow()
+        xWriterEdit = xWriterDoc.getChild('writer_edit')
+
+        document = self.ui_test.get_component()
+        selection = self.xUITest.executeCommand('.uno:SelectAll')
+        self.xUITest.executeCommand('.uno:InsertAnnotation')
+
+        # enable remove personal info security option
+
+        self.ui_test.execute_dialog_through_command('.uno:OptionsTreeDialog')  #optionsdialog
+        xDialog = self.xUITest.getTopFocusWindow()
+
+        xPages = xDialog.getChild('pages')
+        xGenEntry = xPages.getChild('0')
+        xSecurityPage = xGenEntry.getChild('6')
+        xSecurityPage.executeAction('SELECT', tuple())
+        # Click Button Options...
+        xOptions = xDialog.getChild('options')
+        def handle_options_dlg(dialog):
+            xRemovePersonal = dialog.getChild('removepersonal')
+            xRemovePersonal.executeAction('CLICK', tuple())
+            #Click on its button Close
+            xOkBtn = dialog.getChild('ok')
+            xOkBtn.executeAction('CLICK', tuple())
+
+        self.ui_test.execute_blocking_action(xOptions.executeAction, args=('CLICK', ()),
+                dialog_handler=handle_options_dlg)
+
+        xOKBtn = xDialog.getChild('ok')
+        self.ui_test.close_dialog_through_button(xOKBtn)
+
+        # save and reload the document to remove personal info
+
+        with TemporaryDirectory() as tempdir:
+            xFilePath = os.path.join(tempdir, 'tdf90401-tmp.fodt')
+
+            # Save Copy as
+            self.ui_test.execute_dialog_through_command('.uno:SaveAs')
+            xDialog = self.xUITest.getTopFocusWindow()
+
+            xFileName = xDialog.getChild('file_name')
+            xFileName.executeAction('TYPE', mkPropertyValues({'KEYCODE':'CTRL+A'}))
+            xFileName.executeAction('TYPE', mkPropertyValues({'KEYCODE':'BACKSPACE'}))
+            xFileName.executeAction('TYPE', mkPropertyValues({'TEXT': xFilePath}))
+
+            xOpenBtn = xDialog.getChild('open')
+            self.ui_test.close_dialog_through_button(xOpenBtn)
+
+            # Close the Writer document
+            self.ui_test.close_doc()
+
+            self.ui_test.load_file(systemPathToFileUrl(xFilePath))
+            document = self.ui_test.get_component()
+
+            # check removed personal info on comments
+
+            textfields = document.getTextFields()
+            author = ""
+            year = -1
+            for textfield in textfields:
+                if textfield.supportsService("com.sun.star.text.TextField.Annotation"):
+                    author = textfield.Author
+                    year = textfield.Date.Year
+            # This was 'Unknown Author'
+            self.assertEqual(author, 'Author2')
+            # This was 2021
+            self.assertEqual(year, 0)
+
+            # check removed personal info on tracked changes
+
+            self.ui_test.execute_modeless_dialog_through_command('.uno:AcceptTrackedChanges')
+            xTrackDlg = self.xUITest.getTopFocusWindow()
+            xTreeList = xTrackDlg.getChild('writerchanges')
+            state = get_state_as_dict(xTreeList)
+            # This was 'NL\t11/03/2020 19:19:05\t', containing personal info
+            self.assertEqual(state['SelectEntryText'], 'Author1\t01/01/1970 00:00:00\t')
+
+        self.ui_test.close_doc()
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/unotools/source/config/securityoptions.cxx b/unotools/source/config/securityoptions.cxx
index 7acb0ff2d3c0..ff10bcb584b9 100644
--- a/unotools/source/config/securityoptions.cxx
+++ b/unotools/source/config/securityoptions.cxx
@@ -933,4 +933,18 @@ Mutex& SvtSecurityOptions::GetInitMutex()
     return theSecurityOptionsMutex::get();
 }
 
+// map personal info strings to 1, 2, ... to remove personal info
+size_t SvtSecurityMapPersonalInfo::GetInfoID( const OUString sPersonalInfo )
+{
+    SvtSecurityMapPersonalInfoType::iterator aIter = aInfoIDs.find( sPersonalInfo );
+    if ( aIter == aInfoIDs.end() )
+    {
+        size_t nNewID = aInfoIDs.size() + 1;
+        aInfoIDs[sPersonalInfo] = nNewID;
+        return nNewID;
+    }
+
+    return aIter->second;
+}
+
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/xmloff/source/core/xmlexp.cxx b/xmloff/source/core/xmlexp.cxx
index 05d44229e321..d73783994271 100644
--- a/xmloff/source/core/xmlexp.cxx
+++ b/xmloff/source/core/xmlexp.cxx
@@ -459,6 +459,7 @@ SvXMLExport::SvXMLExport(
     m_xContext(xContext), m_implementationName(implementationName),
     mxAttrList( new SvXMLAttributeList ),
     mpNamespaceMap( new SvXMLNamespaceMap ),
+    mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
     maUnitConv(xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit, getSaneDefaultVersion()),
     meClass( eClass ),
     mnExportFlags( nExportFlags ),
@@ -484,6 +485,7 @@ SvXMLExport::SvXMLExport(
     mxAttrList( new SvXMLAttributeList ),
     msOrigFileName( rFileName ),
     mpNamespaceMap( new SvXMLNamespaceMap ),
+    mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
     maUnitConv(xContext, util::MeasureUnit::MM_100TH, eDefaultMeasureUnit, getSaneDefaultVersion()),
     meClass( XML_TOKEN_INVALID ),
     mnExportFlags( SvXMLExportFlags::NONE ),
@@ -517,6 +519,7 @@ SvXMLExport::SvXMLExport(
     mxAttrList( new SvXMLAttributeList ),
     msOrigFileName( rFileName ),
     mpNamespaceMap( new SvXMLNamespaceMap ),
+    mpAuthorIDs( new SvtSecurityMapPersonalInfo ),
     maUnitConv( xContext,
                 util::MeasureUnit::MM_100TH,
                 SvXMLUnitConverter::GetMeasureUnit(eDefaultFieldUnit),
diff --git a/xmloff/source/draw/sdxmlexp.cxx b/xmloff/source/draw/sdxmlexp.cxx
index 652bce79610d..db1542fc511f 100644
--- a/xmloff/source/draw/sdxmlexp.cxx
+++ b/xmloff/source/draw/sdxmlexp.cxx
@@ -2516,6 +2516,10 @@ void SdXMLExport::exportAnnotations( const Reference<XDrawPage>& xDrawPage )
         Reference< XAnnotationEnumeration > xAnnotationEnumeration( xAnnotationAccess->createAnnotationEnumeration() );
         if( xAnnotationEnumeration.is() && xAnnotationEnumeration->hasMoreElements() )
         {
+            SvtSecurityOptions aSecOpt;
+            bool bRemovePersonalInfo = aSecOpt.IsOptionSet(
+                SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo );
+
             OUStringBuffer sStringBuffer;
             do
             {
@@ -2551,7 +2555,9 @@ void SdXMLExport::exportAnnotations( const Reference<XDrawPage>& xDrawPage )
                 if( !aAuthor.isEmpty() )
                 {
                     SvXMLElementExport aCreatorElem( *this, XML_NAMESPACE_DC, XML_CREATOR, true, false );
-                    Characters(aAuthor);
+                    Characters( bRemovePersonalInfo
+                            ? "Author" + OUString::number( SvXMLExport::GetInfoID(aAuthor) )
+                            : aAuthor );
                 }
 
                 // initials
@@ -2567,7 +2573,9 @@ void SdXMLExport::exportAnnotations( const Reference<XDrawPage>& xDrawPage )
                                 ? XML_CREATOR_INITIALS
                                 : XML_SENDER_INITIALS,
                             true, false );
-                    Characters(aInitials);
+                    Characters( bRemovePersonalInfo
+                            ? OUString::number( SvXMLExport::GetInfoID(aInitials) )
+                            : aInitials );
                 }
 
                 {
@@ -2575,7 +2583,9 @@ void SdXMLExport::exportAnnotations( const Reference<XDrawPage>& xDrawPage )
                     css::util::DateTime aDate( xAnnotation->getDateTime() );
                     ::sax::Converter::convertDateTime(sStringBuffer, aDate, nullptr, true);
                     SvXMLElementExport aDateElem( *this, XML_NAMESPACE_DC, XML_DATE, true, false );
-                    Characters(sStringBuffer.makeStringAndClear());
+                    Characters( bRemovePersonalInfo
+                            ? "1970-01-01T00:00::00"
+                            : sStringBuffer.makeStringAndClear() );
                 }
 
                 css::uno::Reference < css::text::XText > xText( xAnnotation->getTextRange() );
diff --git a/xmloff/source/text/XMLRedlineExport.cxx b/xmloff/source/text/XMLRedlineExport.cxx
index e309b1d86731..fad527a77b59 100644
--- a/xmloff/source/text/XMLRedlineExport.cxx
+++ b/xmloff/source/text/XMLRedlineExport.cxx
@@ -42,6 +42,7 @@
 #include <xmloff/xmlnamespace.hxx>
 #include <xmloff/xmlexp.hxx>
 #include <xmloff/xmluconv.hxx>
+#include <unotools/securityoptions.hxx>
 
 
 using namespace ::com::sun::star;
@@ -433,6 +434,9 @@ OUString XMLRedlineExport::GetRedlineID(
 void XMLRedlineExport::ExportChangeInfo(
     const Reference<XPropertySet> & rPropSet)
 {
+    SvtSecurityOptions aSecOpt;
+    bool bRemovePersonalInfo = aSecOpt.IsOptionSet(
+            SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo );
 
     SvXMLElementExport aChangeInfo(rExport, XML_NAMESPACE_OFFICE,
                                    XML_CHANGE_INFO, true, true);
@@ -445,7 +449,9 @@ void XMLRedlineExport::ExportChangeInfo(
         SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC,
                                           XML_CREATOR, true,
                                           false );
-        rExport.Characters(sTmp);
+        rExport.Characters(bRemovePersonalInfo
+                ? "Author" + OUString::number(rExport.GetInfoID(sTmp))
+                : sTmp );
     }
 
     aAny = rPropSet->getPropertyValue("RedlineDateTime");
@@ -457,7 +463,9 @@ void XMLRedlineExport::ExportChangeInfo(
         SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC,
                                           XML_DATE, true,
                                           false );
-        rExport.Characters(sBuf.makeStringAndClear());
+        rExport.Characters(bRemovePersonalInfo
+                ? "1970-01-01T00:00:00"
+                :  sBuf.makeStringAndClear());
     }
 
     // comment as <text:p> sequence
@@ -470,6 +478,9 @@ void XMLRedlineExport::ExportChangeInfo(
     const Sequence<PropertyValue> & rPropertyValues)
 {
     OUString sComment;
+    SvtSecurityOptions aSecOpt;
+    bool bRemovePersonalInfo = aSecOpt.IsOptionSet(
+            SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo );
 
     for(const PropertyValue& rVal : rPropertyValues)
     {
@@ -479,7 +490,9 @@ void XMLRedlineExport::ExportChangeInfo(
             rVal.Value >>= sTmp;
             if (!sTmp.isEmpty())
             {
-                rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CHG_AUTHOR, sTmp);
+                rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CHG_AUTHOR, bRemovePersonalInfo
+                        ? "Author" + OUString::number(rExport.GetInfoID(sTmp))
+                        : sTmp);
             }
         }
         else if( rVal.Name == "RedlineComment" )
@@ -492,8 +505,9 @@ void XMLRedlineExport::ExportChangeInfo(
             rVal.Value >>= aDateTime;
             OUStringBuffer sBuf;
             ::sax::Converter::convertDateTime(sBuf, aDateTime, nullptr);
-            rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CHG_DATE_TIME,
-                                 sBuf.makeStringAndClear());
+            rExport.AddAttribute(XML_NAMESPACE_OFFICE, XML_CHG_DATE_TIME, bRemovePersonalInfo
+                    ? "1970-01-01T00:00:00"
+                    : sBuf.makeStringAndClear());
         }
         else if( rVal.Name == "RedlineType" )
         {
diff --git a/xmloff/source/text/txtflde.cxx b/xmloff/source/text/txtflde.cxx
index 962e30e995d4..93f43ee6c082 100644
--- a/xmloff/source/text/txtflde.cxx
+++ b/xmloff/source/text/txtflde.cxx
@@ -1746,6 +1746,10 @@ void XMLTextFieldExport::ExportFieldHelper(
         DBG_ASSERT(sPresentation.isEmpty(),
                    "Unexpected presentation for annotation field");
 
+        SvtSecurityOptions aSecOpt;
+        bool bRemovePersonalInfo = aSecOpt.IsOptionSet(
+            SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo );
+
         // annotation element + content
         OUString aName;
         rPropSet->getPropertyValue(gsPropertyName) >>= aName;
@@ -1774,11 +1778,14 @@ void XMLTextFieldExport::ExportFieldHelper(
             SvXMLElementExport aCreatorElem( GetExport(), XML_NAMESPACE_DC,
                                               XML_CREATOR, true,
                                               false );
-            GetExport().Characters(aAuthor);
+            GetExport().Characters( bRemovePersonalInfo
+                    ? "Author" + OUString::number( rExport.GetInfoID(aAuthor) )
+                    : aAuthor );
         }
 
         // date time
         util::DateTime aDate( GetDateTimeProperty(gsPropertyDateTimeValue, rPropSet) );
+        if ( !bRemovePersonalInfo )
         {
             OUStringBuffer aBuffer;
             ::sax::Converter::convertDateTime(aBuffer, aDate, nullptr, true);
@@ -1804,7 +1811,9 @@ void XMLTextFieldExport::ExportFieldHelper(
                             ? XML_CREATOR_INITIALS
                             : XML_SENDER_INITIALS,
                         true, false );
-                GetExport().Characters(aInitials);
+                GetExport().Characters( bRemovePersonalInfo
+                        ? OUString::number( rExport.GetInfoID(aInitials) )
+                        : aInitials);
             }
         }
 


More information about the Libreoffice-commits mailing list