sc/qa/unit/data/ods/change-tracking.ods |binary sc/qa/unit/subsequent_export_test4.cxx | 23 +++++++++++++++++ sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx | 19 ++++++++++---- sw/qa/extras/rtfexport/data/text-change-tracking.rtf | 17 ++++++++++++ sw/qa/extras/rtfexport/rtfexport8.cxx | 23 +++++++++++++++++ sw/source/filter/ww8/rtfattributeoutput.cxx | 19 +++++++++----- sw/source/filter/ww8/rtfattributeoutput.hxx | 3 -- sw/source/filter/ww8/rtfexport.cxx | 14 +++++++++- sw/source/filter/ww8/rtfexport.hxx | 10 +++++++ 9 files changed, 113 insertions(+), 15 deletions(-)
New commits: commit fbfe026ecd1c6d6f0ba0ccb0ab6948be6de958ca Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Thu Jun 20 10:51:11 2024 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jun 24 18:53:40 2024 +0200 ods: Don't export changes author/date when in privacy mode Change-Id: I8c542f398bb70da96a64b61a9931398b6a78ea72 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169258 Tested-by: Jenkins Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> (cherry picked from commit 2d60017a66cca4668c87f64f6d048566656b3b1c) Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169434 Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org> diff --git a/sc/qa/unit/data/ods/change-tracking.ods b/sc/qa/unit/data/ods/change-tracking.ods new file mode 100644 index 000000000000..01077fffc749 Binary files /dev/null and b/sc/qa/unit/data/ods/change-tracking.ods differ diff --git a/sc/qa/unit/subsequent_export_test4.cxx b/sc/qa/unit/subsequent_export_test4.cxx index 041a7b0bb9cf..0814c915d81b 100644 --- a/sc/qa/unit/subsequent_export_test4.cxx +++ b/sc/qa/unit/subsequent_export_test4.cxx @@ -1868,6 +1868,29 @@ CPPUNIT_TEST_FIXTURE(ScExportTest4, testTdf157318) static_cast<sal_uInt16>(pDoc->GetRangeName(0)->size())); } +CPPUNIT_TEST_FIXTURE(ScExportTest4, testChangesAuthorDate) +{ + createScDoc("ods/change-tracking.ods"); + + auto pBatch(comphelper::ConfigurationChanges::create()); + // Remove all personal info + officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(true, pBatch); + pBatch->commit(); + + save(u"calc8"_ustr); + xmlDocUniquePtr pXmlDoc = parseExport(u"content.xml"_ustr); + CPPUNIT_ASSERT(pXmlDoc); + + assertXPathContent( + pXmlDoc, + "/office:document-content/office:body/office:spreadsheet/table:tracked-changes/table:cell-content-change[1]/office:change-info/dc:creator"_ostr, + u"Author1"_ustr); + assertXPathContent( + pXmlDoc, + "/office:document-content/office:body/office:spreadsheet/table:tracked-changes/table:cell-content-change[1]/office:change-info/dc:date"_ostr, + u"1970-01-01T12:00:00"_ustr); +} + CPPUNIT_PLUGIN_IMPLEMENT(); /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx index 1a3b22e6aad0..80f70da9f53e 100644 --- a/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx +++ b/sc/source/filter/xml/XMLChangeTrackingExportHelper.cxx @@ -37,6 +37,8 @@ #include <svl/sharedstring.hxx> #include <sal/log.hxx> +#include <com/sun/star/util/DateTime.hpp> + using namespace ::com::sun::star; using namespace xmloff::token; @@ -94,21 +96,28 @@ void ScChangeTrackingExportHelper::WriteBigRange(const ScBigRange& rBigRange, XM void ScChangeTrackingExportHelper::WriteChangeInfo(const ScChangeAction* pAction) { + bool bRemovePersonalInfo + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnKeepRedlineInfo); + SvXMLElementExport aElemInfo (rExport, XML_NAMESPACE_OFFICE, XML_CHANGE_INFO, true, true); { SvXMLElementExport aCreatorElem( rExport, XML_NAMESPACE_DC, XML_CREATOR, true, false ); - rExport.Characters(pAction->GetUser()); + rExport.Characters(bRemovePersonalInfo + ? "Author" + OUString::number(rExport.GetInfoID(pAction->GetUser())) + : pAction->GetUser()); } { OUStringBuffer sDate; - ScXMLConverter::ConvertDateTimeToString(pAction->GetDateTimeUTC(), sDate); - SvXMLElementExport aDateElem( rExport, XML_NAMESPACE_DC, - XML_DATE, true, - false ); + ScXMLConverter::ConvertDateTimeToString(bRemovePersonalInfo + ? util::DateTime(0, 0, 0, 12, 1, 1, 1970, true) + : pAction->GetDateTimeUTC(), + sDate); + SvXMLElementExport aDateElem(rExport, XML_NAMESPACE_DC, XML_DATE, true, false); rExport.Characters(sDate.makeStringAndClear()); } commit 8f174cdce16bbc142a3dc131323df124fa893889 Author: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> AuthorDate: Mon Jun 17 11:51:41 2024 +0200 Commit: Xisco Fauli <xiscofa...@libreoffice.org> CommitDate: Mon Jun 24 18:53:29 2024 +0200 rtf: Don't export changes author/date when in privacy mode Change-Id: Id8f8dea4563df3cfb0ea9009783886bdabf91b11 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/168996 Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de> Tested-by: Jenkins Signed-off-by: Xisco Fauli <xiscofa...@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/169262 diff --git a/sw/qa/extras/rtfexport/data/text-change-tracking.rtf b/sw/qa/extras/rtfexport/data/text-change-tracking.rtf new file mode 100644 index 000000000000..c6f72ceeade5 --- /dev/null +++ b/sw/qa/extras/rtfexport/data/text-change-tracking.rtf @@ -0,0 +1,17 @@ +{ tf1nsi\deff3deflang1025 +{onttbl{0romanprq2charset0 Liberat;}{1romanprq2charset2 Symbol;}{2 swissprq2charset0 Arial;}{3romanprq2charset0 Liberation Serif{\*alt Times New Roman};}{4swissprq2charset0 Liberation Sans{\*alt Arial};}{5 nilprq2charset0 Noto Sans CJK SC;}{6nilprq2charset0 Noto Sans Devanagari;}{7swissprq0charset0 Noto Sans Devanagari;}} +{+{\stylesheet{\s0\snext0 tlchf6fs24lang1081 \ltrch\lang1031\langfe2052\hichf3\loch\widctlpar\hyphpar0spalpha\ltrpar+{\*+{\s16\sbasedon0\snext17 tlchf6fs28 \ltrch\hichf4\loch\sb240\sa120\keepn4s28\dbchf5 Heading;} +{\s17\sbasedon0\snext17\loch\sl276\slmult1\sb0\sa140 Body Text;} +{\s18\sbasedon17\snext18 tlchf7 \ltrch List;} +{\s19\sbasedon0\snext19 tlchf7fs24i \ltrch\loch\sb120\sa120 olines24\i caption;} +{\s20\sbasedon0\snext20 tlchf7 \ltrch\loch oline Index;} +}{\* evtbl {Unknown;}{Max Mustermann;}} +{\*\generator LibreOfficeDev/25.2.0.0.alpha0$Linux_X86_64 LibreOffice_project/c558004906bfaef6d1983e09473e4c236de730d3}{\info{+\hyphauto1 iewscale130 evisionsormshade obrkwrptbl\paperh16838\paperw11906\margl1134\margr1134\margt1134\margb1134\sectd\sbknone\sftnnar\saftnnrlc\sectunlocked1\pgwsxn11906\pghsxn16838\marglsxn1134\margrsxn1134\margtsxn1134\margbsxn1134 tnbjtnstart1tnrstconttnnaretftnrstcontftnstart1ftnnrlc +{\*tnsep+Test}{ evised evauth1 evdttm667323072 \loch +Deleted} +\par } \ No newline at end of file diff --git a/sw/qa/extras/rtfexport/rtfexport8.cxx b/sw/qa/extras/rtfexport/rtfexport8.cxx index 0860ccb51710..daea552a3e9e 100644 --- a/sw/qa/extras/rtfexport/rtfexport8.cxx +++ b/sw/qa/extras/rtfexport/rtfexport8.cxx @@ -480,6 +480,29 @@ CPPUNIT_TEST_FIXTURE(Test, testNotesAuthorDate) CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aRtfContent.indexOf("\atndate", 0)); } +CPPUNIT_TEST_FIXTURE(Test, testChangesAuthor) +{ + createSwDoc("text-change-tracking.rtf"); + + auto pBatch(comphelper::ConfigurationChanges::create()); + // Remove all personal info + officecfg::Office::Common::Security::Scripting::RemovePersonalInfoOnSaving::set(true, pBatch); + pBatch->commit(); + saveAndReload(mpFilter); + + SvStream* pStream = maTempFile.GetStream(StreamMode::READ); + CPPUNIT_ASSERT(pStream); + OString aRtfContent(read_uInt8s_ToOString(*pStream, pStream->TellEnd())); + + // Make sure user name was anonymized + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), + aRtfContent.indexOf("\revtbl {Unknown;}{Max Mustermann;}", 0)); + CPPUNIT_ASSERT(aRtfContent.indexOf("\revtbl {Author1;}{Author2;}", 0) >= 0); + + // Make sure no date is set + CPPUNIT_ASSERT_EQUAL(sal_Int32(-1), aRtfContent.indexOf("\revdttmdel", 0)); +} + CPPUNIT_TEST_FIXTURE(Test, testTdf158982) { auto verify = [this]() { diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx b/sw/source/filter/ww8/rtfattributeoutput.cxx index 97b1587434c9..c8751574b04f 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.cxx +++ b/sw/source/filter/ww8/rtfattributeoutput.cxx @@ -626,13 +626,19 @@ void RtfAttributeOutput::Redline(const SwRedlineData* pRedline) if (!pRedline) return; + bool bRemoveCommentAuthorDates + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet( + SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo); + if (pRedline->GetType() == RedlineType::Insert) { m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVISED); m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTH); m_aRun->append(static_cast<sal_Int32>( m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())))); - m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM); + if (!bRemoveCommentAuthorDates) + m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTM); } else if (pRedline->GetType() == RedlineType::Delete) { @@ -640,9 +646,11 @@ void RtfAttributeOutput::Redline(const SwRedlineData* pRedline) m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVAUTHDEL); m_aRun->append(static_cast<sal_Int32>( m_rExport.GetRedline(SW_MOD()->GetRedlineAuthor(pRedline->GetAuthor())))); - m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL); + if (!bRemoveCommentAuthorDates) + m_aRun->append(OOO_STRING_SVTOOLS_RTF_REVDTTMDEL); } - m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()))); + if (!bRemoveCommentAuthorDates) + m_aRun->append(static_cast<sal_Int32>(sw::ms::DateTime2DTTM(pRedline->GetTimeStamp()))); m_aRun->append(' '); } @@ -4091,10 +4099,10 @@ void RtfAttributeOutput::PostitField(const SwField* pField) return; } OUString sAuthor(bRemoveCommentAuthorDates - ? "Author" + OUString::number(mpAuthorIDs->GetInfoID(rPField.GetPar1())) + ? "Author" + OUString::number(m_rExport.GetInfoID(rPField.GetPar1())) : rPField.GetPar1()); OUString sInitials(bRemoveCommentAuthorDates - ? "A" + OUString::number(mpAuthorIDs->GetInfoID(rPField.GetPar1())) + ? "A" + OUString::number(m_rExport.GetInfoID(rPField.GetPar1())) : rPField.GetInitials()); m_aRunText->append("{" OOO_STRING_SVTOOLS_RTF_IGNORE OOO_STRING_SVTOOLS_RTF_ATNID " "); m_aRunText->append(OUStringToOString(sInitials, m_rExport.GetCurrentEncoding())); @@ -4168,7 +4176,6 @@ RtfAttributeOutput::RtfAttributeOutput(RtfExport& rExport) , m_nParaBeforeSpacing(0) , m_bParaAfterAutoSpacing(false) , m_nParaAfterSpacing(0) - , mpAuthorIDs(new SvtSecurityMapPersonalInfo) { } diff --git a/sw/source/filter/ww8/rtfattributeoutput.hxx b/sw/source/filter/ww8/rtfattributeoutput.hxx index 7642918332ff..8ba84bed6055 100644 --- a/sw/source/filter/ww8/rtfattributeoutput.hxx +++ b/sw/source/filter/ww8/rtfattributeoutput.hxx @@ -666,9 +666,6 @@ private: editeng::WordPageMargins m_aPageMargins; - /// map authors to remove personal info - std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; - public: explicit RtfAttributeOutput(RtfExport& rExport); diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx index 88a3086c6dfc..4eb04d4f8bbf 100644 --- a/sw/source/filter/ww8/rtfexport.cxx +++ b/sw/source/filter/ww8/rtfexport.cxx @@ -56,6 +56,7 @@ #include <svtools/rtfkeywd.hxx> #include <filter/msfilter/rtfutil.hxx> #include <unotools/docinfohelper.hxx> +#include <unotools/securityoptions.hxx> #include <xmloff/odffields.hxx> #include <o3tl/string_view.hxx> #include <osl/diagnose.h> @@ -272,6 +273,11 @@ void RtfExport::WriteRevTab() GetRedline(SW_MOD()->GetRedlineAuthor(pRedl->GetAuthor())); } + bool bRemoveCommentAuthorDates + = SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::DocWarnRemovePersonalInfo) + && !SvtSecurityOptions::IsOptionSet( + SvtSecurityOptions::EOption::DocWarnKeepNoteAuthorDateInfo); + // Now write the table Strm() .WriteChar('{') @@ -283,7 +289,12 @@ void RtfExport::WriteRevTab() const OUString* pAuthor = GetRedline(i); Strm().WriteChar('{'); if (pAuthor) - Strm().WriteOString(msfilter::rtfutil::OutString(*pAuthor, m_eDefaultEncoding)); + { + OUString sAuthor(bRemoveCommentAuthorDates + ? "Author" + OUString::number(GetInfoID(*pAuthor)) + : *pAuthor); + Strm().WriteOString(msfilter::rtfutil::OutString(sAuthor, m_eDefaultEncoding)); + } Strm().WriteOString(";}"); } Strm().WriteChar('}').WriteOString(SAL_NEWLINE_STRING); @@ -1155,6 +1166,7 @@ RtfExport::RtfExport(RtfExportFilter* pFilter, SwDoc& rDocument, , m_eCurrentEncoding(m_eDefaultEncoding) , m_bRTFFlySyntax(false) , m_nCurrentNodeIndex(0) + , mpAuthorIDs(new SvtSecurityMapPersonalInfo) { m_bExportModeRTF = true; // the attribute output for the document diff --git a/sw/source/filter/ww8/rtfexport.hxx b/sw/source/filter/ww8/rtfexport.hxx index 1a24aaf3e151..9f56549b7ea0 100644 --- a/sw/source/filter/ww8/rtfexport.hxx +++ b/sw/source/filter/ww8/rtfexport.hxx @@ -23,6 +23,8 @@ #include <memory> #include "wrtww8.hxx" +#include <unotools/securityoptions.hxx> + class RtfAttributeOutput; class RtfExportFilter; class RtfSdrExport; @@ -202,6 +204,12 @@ public: const SfxItemSet* GetFirstPageItemSet() const { return m_pFirstPageItemSet; } + // Get author id to remove personal info + size_t GetInfoID(const OUString sPersonalInfo) const + { + return mpAuthorIDs->GetInfoID(sPersonalInfo); + } + private: void WriteFonts(); void WriteStyles(); @@ -229,6 +237,8 @@ private: std::unique_ptr<SvMemoryStream> m_pStream; /// Item set of the first page during export of a follow page format. const SfxItemSet* m_pFirstPageItemSet = nullptr; + /// map authors to remove personal info + std::unique_ptr<SvtSecurityMapPersonalInfo> mpAuthorIDs; }; #endif // INCLUDED_SW_SOURCE_FILTER_WW8_RTFEXPORT_HXX