diff options
-rw-r--r-- | compilerplugins/clang/unusedfields.writeonly.results | 4 | ||||
-rw-r--r-- | sw/qa/uitest/data/writeprotection.docx | bin | 0 -> 13990 bytes | |||
-rw-r--r-- | sw/qa/uitest/writer_tests6/tdf89383.py | 28 | ||||
-rw-r--r-- | writerfilter/Library_writerfilter.mk | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DocumentProtection.cxx | 239 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DocumentProtection.hxx | 88 | ||||
-rw-r--r-- | writerfilter/source/dmapper/DomainMapper_Impl.cxx | 4 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SettingsTable.cxx | 260 | ||||
-rw-r--r-- | writerfilter/source/dmapper/SettingsTable.hxx | 2 | ||||
-rw-r--r-- | writerfilter/source/dmapper/WriteProtection.cxx | 143 | ||||
-rw-r--r-- | writerfilter/source/dmapper/WriteProtection.hxx | 58 |
11 files changed, 590 insertions, 238 deletions
diff --git a/compilerplugins/clang/unusedfields.writeonly.results b/compilerplugins/clang/unusedfields.writeonly.results index 7bf4af94dc79..c97ce0cb37fc 100644 --- a/compilerplugins/clang/unusedfields.writeonly.results +++ b/compilerplugins/clang/unusedfields.writeonly.results @@ -1060,8 +1060,8 @@ writerfilter/source/dmapper/DomainMapperTableHandler.cxx:240 writerfilter::dmapper::TableInfo aTablePropertyIds std::vector<PropertyIds> writerfilter/source/dmapper/PropertyMap.hxx:219 writerfilter::dmapper::SectionPropertyMap m_nDebugSectionNumber sal_Int32 -writerfilter/source/dmapper/SettingsTable.cxx:264 - writerfilter::dmapper::SettingsTable_Impl m_sRedlineProtectionKey class rtl::OUString +writerfilter/source/dmapper/DocumentProtection.hxx:50 + writerfilter::dmapper::DocumentProtection m_sRedlineProtectionKey class rtl::OUString xmlhelp/source/cxxhelp/provider/databases.hxx:249 chelp::Databases m_aDatabases chelp::Databases::DatabasesTable xmlhelp/source/cxxhelp/provider/databases.hxx:255 diff --git a/sw/qa/uitest/data/writeprotection.docx b/sw/qa/uitest/data/writeprotection.docx Binary files differnew file mode 100644 index 000000000000..f0fab46a9d8f --- /dev/null +++ b/sw/qa/uitest/data/writeprotection.docx diff --git a/sw/qa/uitest/writer_tests6/tdf89383.py b/sw/qa/uitest/writer_tests6/tdf89383.py new file mode 100644 index 000000000000..26f559460100 --- /dev/null +++ b/sw/qa/uitest/writer_tests6/tdf89383.py @@ -0,0 +1,28 @@ +# -*- 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 get_url_for_data_file +from libreoffice.uno.propertyvalue import mkPropertyValues + +#Bug 89383 - Read-only passwords on OOXML files are not working + +class tdf89383(UITestCase): + def test_tdf89383_DOCX(self): + with self.ui_test.load_file(get_url_for_data_file("writeprotection.docx")): + document = self.ui_test.get_component() + + # Without the fix in place, this test would have failed with + # AssertionError: False is not true + self.assertTrue(document.isReadonly()) + + with self.ui_test.execute_dialog_through_command(".uno:EditDoc") as xDialog: + xPassword = xDialog.getChild("newpassEntry") + xPassword.executeAction("TYPE", mkPropertyValues({"TEXT": "a"})) + + self.assertFalse(document.isReadonly()) + +# vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/writerfilter/Library_writerfilter.mk b/writerfilter/Library_writerfilter.mk index add7c20bb2ea..2b974536557b 100644 --- a/writerfilter/Library_writerfilter.mk +++ b/writerfilter/Library_writerfilter.mk @@ -78,6 +78,7 @@ $(eval $(call gb_Library_add_exception_objects,writerfilter,\ writerfilter/source/dmapper/CellColorHandler \ writerfilter/source/dmapper/CellMarginHandler \ writerfilter/source/dmapper/ConversionHelper \ + writerfilter/source/dmapper/DocumentProtection \ writerfilter/source/dmapper/DomainMapper \ writerfilter/source/dmapper/DomainMapperTableHandler \ writerfilter/source/dmapper/DomainMapperTableManager \ @@ -113,6 +114,7 @@ $(eval $(call gb_Library_add_exception_objects,writerfilter,\ writerfilter/source/dmapper/TblStylePrHandler \ writerfilter/source/dmapper/ThemeTable \ writerfilter/source/dmapper/WrapPolygonHandler \ + writerfilter/source/dmapper/WriteProtection \ writerfilter/source/dmapper/util \ writerfilter/source/filter/RtfFilter \ writerfilter/source/filter/WriterFilter \ diff --git a/writerfilter/source/dmapper/DocumentProtection.cxx b/writerfilter/source/dmapper/DocumentProtection.cxx new file mode 100644 index 000000000000..dddf964c4022 --- /dev/null +++ b/writerfilter/source/dmapper/DocumentProtection.cxx @@ -0,0 +1,239 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "DocumentProtection.hxx" +#include "TagLogger.hxx" +#include <vector> +#include <comphelper/sequence.hxx> + +using namespace com::sun::star; + +namespace writerfilter::dmapper +{ +DocumentProtection::DocumentProtection() + : LoggedProperties("DocumentProtection") + , m_nEdit( + NS_ooxml:: + LN_Value_doc_ST_DocProtect_none) // Specifies that no editing restrictions have been applied to the document + , m_bProtectForm(false) + , m_bRedlineProtection(false) + , m_bReadOnly(false) + , m_bEnforcement(false) + , m_bFormatting(false) + , m_nCryptProviderType(NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) + , m_sCryptAlgorithmClass("hash") + , m_sCryptAlgorithmType("typeAny") + , m_CryptSpinCount(0) +{ +} + +DocumentProtection::~DocumentProtection() {} + +void DocumentProtection::lcl_attribute(Id nName, Value& val) +{ + int nIntValue = val.getInt(); + OUString sStringValue = val.getString(); + + switch (nName) + { + case NS_ooxml::LN_CT_DocProtect_edit: // 92037 + m_nEdit = nIntValue; + // multiple DocProtect_edits should not exist. If they do, last one wins + m_bRedlineProtection = false; + m_bProtectForm = false; + m_bReadOnly = false; + switch (nIntValue) + { + case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges: + { + m_bRedlineProtection = true; + m_sRedlineProtectionKey = m_sHash; + break; + } + case NS_ooxml::LN_Value_doc_ST_DocProtect_forms: + m_bProtectForm = true; + break; + case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly: + m_bReadOnly = true; + break; + } + break; + case NS_ooxml::LN_CT_DocProtect_enforcement: // 92039 + m_bEnforcement = (nIntValue != 0); + break; + case NS_ooxml::LN_CT_DocProtect_formatting: // 92038 + m_bFormatting = (nIntValue != 0); + break; + case NS_ooxml::LN_AG_Password_cryptProviderType: // 92025 + m_nCryptProviderType = nIntValue; + break; + case NS_ooxml::LN_AG_Password_cryptAlgorithmClass: // 92026 + if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgClass_hash) // 92023 + m_sCryptAlgorithmClass = "hash"; + break; + case NS_ooxml::LN_AG_Password_cryptAlgorithmType: // 92027 + if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgType_typeAny) // 92024 + m_sCryptAlgorithmType = "typeAny"; + break; + case NS_ooxml::LN_AG_Password_cryptAlgorithmSid: // 92028 + m_sCryptAlgorithmSid = sStringValue; + break; + case NS_ooxml::LN_AG_Password_cryptSpinCount: // 92029 + m_CryptSpinCount = nIntValue; + break; + case NS_ooxml::LN_AG_Password_hash: // 92035 + m_sHash = sStringValue; + break; + case NS_ooxml::LN_AG_Password_salt: // 92036 + m_sSalt = sStringValue; + break; + default: + { +#ifdef DBG_UTIL + TagLogger::getInstance().element("unhandled"); +#endif + } + } +} + +void DocumentProtection::lcl_sprm(Sprm& /*rSprm*/) {} + +uno::Sequence<beans::PropertyValue> DocumentProtection::toSequence() const +{ + std::vector<beans::PropertyValue> documentProtection; + + if (enabled()) + { + // w:edit + { + beans::PropertyValue aValue; + aValue.Name = "edit"; + + switch (m_nEdit) + { + case NS_ooxml::LN_Value_doc_ST_DocProtect_none: + aValue.Value <<= OUString("none"); + break; + case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly: + aValue.Value <<= OUString("readOnly"); + break; + case NS_ooxml::LN_Value_doc_ST_DocProtect_comments: + aValue.Value <<= OUString("comments"); + break; + case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges: + aValue.Value <<= OUString("trackedChanges"); + break; + case NS_ooxml::LN_Value_doc_ST_DocProtect_forms: + aValue.Value <<= OUString("forms"); + break; + default: + { +#ifdef DBG_UTIL + TagLogger::getInstance().element("unhandled"); +#endif + } + } + + documentProtection.push_back(aValue); + } + + // w:enforcement + if (m_bEnforcement) + { + beans::PropertyValue aValue; + aValue.Name = "enforcement"; + aValue.Value <<= OUString("1"); + documentProtection.push_back(aValue); + } + + // w:formatting + if (m_bFormatting) + { + beans::PropertyValue aValue; + aValue.Name = "formatting"; + aValue.Value <<= OUString("1"); + documentProtection.push_back(aValue); + } + + // w:cryptProviderType + { + beans::PropertyValue aValue; + aValue.Name = "cryptProviderType"; + if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) + aValue.Value <<= OUString("rsaAES"); + else if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull) + aValue.Value <<= OUString("rsaFull"); + documentProtection.push_back(aValue); + } + + // w:cryptAlgorithmClass + { + beans::PropertyValue aValue; + aValue.Name = "cryptAlgorithmClass"; + aValue.Value <<= m_sCryptAlgorithmClass; + documentProtection.push_back(aValue); + } + + // w:cryptAlgorithmType + { + beans::PropertyValue aValue; + aValue.Name = "cryptAlgorithmType"; + aValue.Value <<= m_sCryptAlgorithmType; + documentProtection.push_back(aValue); + } + + // w:cryptAlgorithmSid + { + beans::PropertyValue aValue; + aValue.Name = "cryptAlgorithmSid"; + aValue.Value <<= m_sCryptAlgorithmSid; + documentProtection.push_back(aValue); + } + + // w:cryptSpinCount + { + beans::PropertyValue aValue; + aValue.Name = "cryptSpinCount"; + aValue.Value <<= OUString::number(m_CryptSpinCount); + documentProtection.push_back(aValue); + } + + // w:hash + { + beans::PropertyValue aValue; + aValue.Name = "hash"; + aValue.Value <<= m_sHash; + documentProtection.push_back(aValue); + } + + // w:salt + { + beans::PropertyValue aValue; + aValue.Name = "salt"; + aValue.Value <<= m_sSalt; + documentProtection.push_back(aValue); + } + } + + return comphelper::containerToSequence(documentProtection); +} + +} //namespace writerfilter::dmapper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DocumentProtection.hxx b/writerfilter/source/dmapper/DocumentProtection.hxx new file mode 100644 index 000000000000..2ec0f3f21c41 --- /dev/null +++ b/writerfilter/source/dmapper/DocumentProtection.hxx @@ -0,0 +1,88 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include "LoggedResources.hxx" +#include <com/sun/star/beans/PropertyValue.hpp> +#include <ooxml/resourceids.hxx> + +namespace writerfilter::dmapper +{ +/** Document protection restrictions + * + * This element specifies the set of document protection restrictions which have been applied to the contents of a + * WordprocessingML document.These restrictions should be enforced by applications editing this document + * when the enforcement attribute is turned on, and ignored(but persisted) otherwise.Document protection is a + * set of restrictions used to prevent unintentional changes to all or part of a WordprocessingML document. + */ +class DocumentProtection : public LoggedProperties +{ +private: + /** Document Editing Restrictions + * + * Possible values: + * - NS_ooxml::LN_Value_doc_ST_DocProtect_none + * - NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly + * - NS_ooxml::LN_Value_doc_ST_DocProtect_comments + * - NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges + * - NS_ooxml::LN_Value_doc_ST_DocProtect_forms + */ + sal_Int32 m_nEdit; + bool m_bProtectForm; + bool m_bRedlineProtection; + OUString m_sRedlineProtectionKey; + bool m_bReadOnly; + bool m_bEnforcement; + bool m_bFormatting; + + /** Provider type + * + * Possible values: + * "rsaAES" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES + * "rsaFull" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull + */ + sal_Int32 m_nCryptProviderType; + OUString m_sCryptAlgorithmClass; + OUString m_sCryptAlgorithmType; + OUString m_sCryptAlgorithmSid; + sal_Int32 m_CryptSpinCount; + OUString m_sHash; + OUString m_sSalt; + + virtual void lcl_attribute(Id Name, Value& val) override; + virtual void lcl_sprm(Sprm& sprm) override; + + bool enabled() const { return !isNone(); } + bool isNone() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_none; }; + +public: + DocumentProtection(); + virtual ~DocumentProtection() override; + + css::uno::Sequence<css::beans::PropertyValue> toSequence() const; + + bool getProtectForm() const { return m_bProtectForm; } + bool getRedlineProtection() const { return m_bRedlineProtection; } + bool getReadOnly() const { return m_bReadOnly; } + bool getEnforcement() const { return m_bEnforcement; } +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx b/writerfilter/source/dmapper/DomainMapper_Impl.cxx index 616b09755a81..f11add33d7ca 100644 --- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx +++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx @@ -7710,6 +7710,10 @@ void DomainMapper_Impl::ApplySettingsTable() { xSettings->setPropertyValue("GutterAtTop", uno::makeAny(true)); } + uno::Sequence<beans::PropertyValue> aWriteProtection + = m_pSettingsTable->GetWriteProtectionSettings(); + if (aWriteProtection.hasElements()) + xSettings->setPropertyValue("ModifyPasswordInfo", uno::makeAny(aWriteProtection)); } catch(const uno::Exception&) { diff --git a/writerfilter/source/dmapper/SettingsTable.cxx b/writerfilter/source/dmapper/SettingsTable.cxx index a780635b5997..f97d0a00d893 100644 --- a/writerfilter/source/dmapper/SettingsTable.cxx +++ b/writerfilter/source/dmapper/SettingsTable.cxx @@ -18,7 +18,9 @@ */ #include "SettingsTable.hxx" +#include "DocumentProtection.hxx" #include "TagLogger.hxx" +#include "WriteProtection.hxx" #include <vector> @@ -32,7 +34,6 @@ #include <com/sun/star/style/XStyleFamiliesSupplier.hpp> #include <comphelper/propertysequence.hxx> #include <comphelper/sequence.hxx> -#include <ooxml/resourceids.hxx> #include "ConversionHelper.hxx" #include "DomainMapper.hxx" #include "util.hxx" @@ -61,176 +62,6 @@ sal_Int16 lcl_GetZoomType(Id nType) namespace dmapper { - namespace { - - /** Document protection restrictions - * - * This element specifies the set of document protection restrictions which have been applied to the contents of a - * WordprocessingML document.These restrictions should be enforced by applications editing this document - * when the enforcement attribute is turned on, and ignored(but persisted) otherwise.Document protection is a - * set of restrictions used to prevent unintentional changes to all or part of a WordprocessingML document. - */ - struct DocumentProtection_Impl - { - /** Document Editing Restrictions - * - * Possible values: - * - NS_ooxml::LN_Value_doc_ST_DocProtect_none - * - NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly - * - NS_ooxml::LN_Value_doc_ST_DocProtect_comments - * - NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges - * - NS_ooxml::LN_Value_doc_ST_DocProtect_forms - */ - sal_Int32 m_nEdit; - bool m_bEnforcement; - bool m_bFormatting; - - /** Provider type - * - * Possible values: - * "rsaAES" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES - * "rsaFull" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull - */ - sal_Int32 m_nCryptProviderType; - OUString m_sCryptAlgorithmClass; - OUString m_sCryptAlgorithmType; - OUString m_sCryptAlgorithmSid; - sal_Int32 m_CryptSpinCount; - OUString m_sHash; - OUString m_sSalt; - - DocumentProtection_Impl() - : m_nEdit(NS_ooxml::LN_Value_doc_ST_DocProtect_none) // Specifies that no editing restrictions have been applied to the document - , m_bEnforcement(false) - , m_bFormatting(false) - , m_nCryptProviderType(NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) - , m_sCryptAlgorithmClass("hash") - , m_sCryptAlgorithmType("typeAny") - , m_CryptSpinCount(0) - { - } - - css::uno::Sequence<css::beans::PropertyValue> toSequence() const; - - bool enabled() const - { - return ! isNone(); - } - - bool isNone() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_none; }; - }; - - } - - css::uno::Sequence<css::beans::PropertyValue> DocumentProtection_Impl::toSequence() const - { - std::vector<beans::PropertyValue> documentProtection; - - if (enabled()) - { - // w:edit - { - beans::PropertyValue aValue; - aValue.Name = "edit"; - - switch (m_nEdit) - { - case NS_ooxml::LN_Value_doc_ST_DocProtect_none: aValue.Value <<= OUString("none"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly: aValue.Value <<= OUString("readOnly"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_comments: aValue.Value <<= OUString("comments"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges: aValue.Value <<= OUString("trackedChanges"); break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_forms: aValue.Value <<= OUString("forms"); break; - default: - { -#ifdef DBG_UTIL - TagLogger::getInstance().element("unhandled"); -#endif - } - } - - documentProtection.push_back(aValue); - } - - // w:enforcement - if (m_bEnforcement) - { - beans::PropertyValue aValue; - aValue.Name = "enforcement"; - aValue.Value <<= OUString("1"); - documentProtection.push_back(aValue); - } - - // w:formatting - if (m_bFormatting) - { - beans::PropertyValue aValue; - aValue.Name = "formatting"; - aValue.Value <<= OUString("1"); - documentProtection.push_back(aValue); - } - - // w:cryptProviderType - { - beans::PropertyValue aValue; - aValue.Name = "cryptProviderType"; - if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) - aValue.Value <<= OUString("rsaAES"); - else if (m_nCryptProviderType == NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull) - aValue.Value <<= OUString("rsaFull"); - documentProtection.push_back(aValue); - } - - // w:cryptAlgorithmClass - { - beans::PropertyValue aValue; - aValue.Name = "cryptAlgorithmClass"; - aValue.Value <<= m_sCryptAlgorithmClass; - documentProtection.push_back(aValue); - } - - // w:cryptAlgorithmType - { - beans::PropertyValue aValue; - aValue.Name = "cryptAlgorithmType"; - aValue.Value <<= m_sCryptAlgorithmType; - documentProtection.push_back(aValue); - } - - // w:cryptAlgorithmSid - { - beans::PropertyValue aValue; - aValue.Name = "cryptAlgorithmSid"; - aValue.Value <<= m_sCryptAlgorithmSid; - documentProtection.push_back(aValue); - } - - // w:cryptSpinCount - { - beans::PropertyValue aValue; - aValue.Name = "cryptSpinCount"; - aValue.Value <<= OUString::number(m_CryptSpinCount); - documentProtection.push_back(aValue); - } - - // w:hash - { - beans::PropertyValue aValue; - aValue.Name = "hash"; - aValue.Value <<= m_sHash; - documentProtection.push_back(aValue); - } - - // w:salt - { - beans::PropertyValue aValue; - aValue.Name = "salt"; - aValue.Value <<= m_sSalt; - documentProtection.push_back(aValue); - } - } - - return comphelper::containerToSequence(documentProtection); - } struct SettingsTable_Impl { @@ -259,10 +90,6 @@ struct SettingsTable_Impl bool m_bSplitPgBreakAndParaMark; bool m_bMirrorMargin; bool m_bDoNotExpandShiftReturn; - bool m_bProtectForm; - bool m_bRedlineProtection; - OUString m_sRedlineProtectionKey; - bool m_bReadOnly; bool m_bDisplayBackgroundShape; bool m_bNoLeading = false; OUString m_sDecimalSymbol; @@ -274,7 +101,8 @@ struct SettingsTable_Impl uno::Sequence<beans::PropertyValue> m_pCurrentCompatSetting; OUString m_sCurrentDatabaseDataSource; - DocumentProtection_Impl m_DocumentProtection; + std::shared_ptr<DocumentProtection> m_pDocumentProtection; + std::shared_ptr<WriteProtection> m_pWriteProtection; bool m_bGutterAtTop = false; SettingsTable_Impl() : @@ -301,9 +129,6 @@ struct SettingsTable_Impl , m_bSplitPgBreakAndParaMark(false) , m_bMirrorMargin(false) , m_bDoNotExpandShiftReturn(false) - , m_bProtectForm(false) - , m_bRedlineProtection(false) - , m_bReadOnly(false) , m_bDisplayBackgroundShape(false) , m_sDecimalSymbol(".") , m_sListSeparator(",") @@ -325,6 +150,8 @@ SettingsTable::SettingsTable(const DomainMapper& rDomainMapper) // Longer space sequence is opt-in for RTF, and not in OOXML. m_pImpl->m_bLongerSpaceSequence = true; } + m_pImpl->m_pDocumentProtection = std::make_shared<DocumentProtection>(); + m_pImpl->m_pWriteProtection = std::make_shared<WriteProtection>(); } SettingsTable::~SettingsTable() @@ -371,57 +198,6 @@ void SettingsTable::lcl_attribute(Id nName, Value & val) m_pImpl->m_pCurrentCompatSetting[2].Name = "val"; m_pImpl->m_pCurrentCompatSetting[2].Value <<= sStringValue; break; - case NS_ooxml::LN_CT_DocProtect_edit: // 92037 - m_pImpl->m_DocumentProtection.m_nEdit = nIntValue; - // multiple DocProtect_edits should not exist. If they do, last one wins - m_pImpl->m_bRedlineProtection = false; - m_pImpl->m_bProtectForm = false; - m_pImpl->m_bReadOnly = false; - switch (nIntValue) - { - case NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges: - { - m_pImpl->m_bRedlineProtection = true; - m_pImpl->m_sRedlineProtectionKey = m_pImpl->m_DocumentProtection.m_sHash; - break; - } - case NS_ooxml::LN_Value_doc_ST_DocProtect_forms: - m_pImpl->m_bProtectForm = true; - break; - case NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly: - m_pImpl->m_bReadOnly = true; - break; - } - break; - case NS_ooxml::LN_CT_DocProtect_enforcement: // 92039 - m_pImpl->m_DocumentProtection.m_bEnforcement = (nIntValue != 0); - break; - case NS_ooxml::LN_CT_DocProtect_formatting: // 92038 - m_pImpl->m_DocumentProtection.m_bFormatting = (nIntValue != 0); - break; - case NS_ooxml::LN_AG_Password_cryptProviderType: // 92025 - m_pImpl->m_DocumentProtection.m_nCryptProviderType = nIntValue; - break; - case NS_ooxml::LN_AG_Password_cryptAlgorithmClass: // 92026 - if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgClass_hash) // 92023 - m_pImpl->m_DocumentProtection.m_sCryptAlgorithmClass = "hash"; - break; - case NS_ooxml::LN_AG_Password_cryptAlgorithmType: // 92027 - if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgType_typeAny) // 92024 - m_pImpl->m_DocumentProtection.m_sCryptAlgorithmType = "typeAny"; - break; - case NS_ooxml::LN_AG_Password_cryptAlgorithmSid: // 92028 - m_pImpl->m_DocumentProtection.m_sCryptAlgorithmSid = sStringValue; - break; - case NS_ooxml::LN_AG_Password_cryptSpinCount: // 92029 - m_pImpl->m_DocumentProtection.m_CryptSpinCount = nIntValue; - break; - case NS_ooxml::LN_AG_Password_hash: // 92035 - m_pImpl->m_DocumentProtection.m_sHash = sStringValue; - break; - case NS_ooxml::LN_AG_Password_salt: // 92036 - m_pImpl->m_DocumentProtection.m_sSalt = sStringValue; - break; case NS_ooxml::LN_CT_TrackChangesView_insDel: m_pImpl->m_bShowInsDelChanges = (nIntValue != 0); break; @@ -505,7 +281,10 @@ void SettingsTable::lcl_sprm(Sprm& rSprm) resolveSprmProps(*this, rSprm); break; case NS_ooxml::LN_CT_Settings_documentProtection: - resolveSprmProps(*this, rSprm); + resolveSprmProps(*(m_pImpl->m_pDocumentProtection), rSprm); + break; + case NS_ooxml::LN_CT_Settings_writeProtection: + resolveSprmProps(*(m_pImpl->m_pWriteProtection), rSprm); break; case NS_ooxml::LN_CT_Compat_usePrinterMetrics: m_pImpl->m_bUsePrinterMetrics = nIntValue; @@ -678,12 +457,15 @@ bool SettingsTable::GetDoNotExpandShiftReturn() const bool SettingsTable::GetProtectForm() const { - return m_pImpl->m_bProtectForm && m_pImpl->m_DocumentProtection.m_bEnforcement; + return m_pImpl->m_pDocumentProtection->getProtectForm() + && m_pImpl->m_pDocumentProtection->getEnforcement(); } bool SettingsTable::GetReadOnly() const { - return m_pImpl->m_bReadOnly && m_pImpl->m_DocumentProtection.m_bEnforcement; + return m_pImpl->m_pWriteProtection->getRecommended() + || (m_pImpl->m_pDocumentProtection->getReadOnly() + && m_pImpl->m_pDocumentProtection->getEnforcement()); } bool SettingsTable::GetNoHyphenateCaps() const @@ -733,9 +515,14 @@ uno::Sequence<beans::PropertyValue> SettingsTable::GetCompatSettings() const return comphelper::containerToSequence(m_pImpl->m_aCompatSettings); } -css::uno::Sequence<css::beans::PropertyValue> SettingsTable::GetDocumentProtectionSettings() const +uno::Sequence<beans::PropertyValue> SettingsTable::GetDocumentProtectionSettings() const +{ + return m_pImpl->m_pDocumentProtection->toSequence(); +} + +uno::Sequence<beans::PropertyValue> SettingsTable::GetWriteProtectionSettings() const { - return m_pImpl->m_DocumentProtection.toSequence(); + return m_pImpl->m_pWriteProtection->toSequence(); } const OUString & SettingsTable::GetCurrentDatabaseDataSource() const @@ -772,7 +559,8 @@ void SettingsTable::ApplyProperties(uno::Reference<text::XTextDocument> const& x { xDocProps->setPropertyValue("RecordChanges", uno::makeAny( m_pImpl->m_bRecordChanges ) ); // Password protected Record changes - if ( m_pImpl->m_bRecordChanges && m_pImpl->m_bRedlineProtection && m_pImpl->m_DocumentProtection.m_bEnforcement ) + if (m_pImpl->m_bRecordChanges && m_pImpl->m_pDocumentProtection->getRedlineProtection() + && m_pImpl->m_pDocumentProtection->getEnforcement()) { // use dummy protection key to forbid disabling of Record changes without a notice // (extending the recent GrabBag support) TODO support password verification... diff --git a/writerfilter/source/dmapper/SettingsTable.hxx b/writerfilter/source/dmapper/SettingsTable.hxx index 431bb5d7c671..a0af31bed6bb 100644 --- a/writerfilter/source/dmapper/SettingsTable.hxx +++ b/writerfilter/source/dmapper/SettingsTable.hxx @@ -87,6 +87,8 @@ public: css::uno::Sequence<css::beans::PropertyValue> GetDocumentProtectionSettings() const; + css::uno::Sequence<css::beans::PropertyValue> GetWriteProtectionSettings() const; + void ApplyProperties(css::uno::Reference<css::text::XTextDocument> const& xDoc); bool GetCompatSettingValue(std::u16string_view sCompatName) const; diff --git a/writerfilter/source/dmapper/WriteProtection.cxx b/writerfilter/source/dmapper/WriteProtection.cxx new file mode 100644 index 000000000000..724dbb77e783 --- /dev/null +++ b/writerfilter/source/dmapper/WriteProtection.cxx @@ -0,0 +1,143 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#include "WriteProtection.hxx" +#include "TagLogger.hxx" +#include <ooxml/resourceids.hxx> + +using namespace com::sun::star; + +namespace writerfilter::dmapper +{ +WriteProtection::WriteProtection() + : LoggedProperties("WriteProtection") + , m_nCryptProviderType(NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES) + , m_CryptSpinCount(0) + , m_bRecommended(false) +{ +} + +WriteProtection::~WriteProtection() {} + +void WriteProtection::lcl_attribute(Id nName, Value& val) +{ + int nIntValue = val.getInt(); + OUString sStringValue = val.getString(); + + switch (nName) + { + case NS_ooxml::LN_AG_Password_cryptProviderType: // 92025 + m_nCryptProviderType = nIntValue; + break; + case NS_ooxml::LN_AG_Password_cryptAlgorithmClass: // 92026 + if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgClass_hash) // 92023 + m_sCryptAlgorithmClass = "hash"; + break; + case NS_ooxml::LN_AG_Password_cryptAlgorithmType: // 92027 + if (nIntValue == NS_ooxml::LN_Value_doc_ST_AlgType_typeAny) // 92024 + m_sCryptAlgorithmType = "typeAny"; + break; + case NS_ooxml::LN_AG_Password_cryptAlgorithmSid: // 92028 + { + sal_Int32 nCryptAlgorithmSid = sStringValue.toInt32(); + switch (nCryptAlgorithmSid) + { + case 1: + m_sAlgorithmName = "MD2"; + break; + case 2: + m_sAlgorithmName = "MD4"; + break; + case 3: + m_sAlgorithmName = "MD5"; + break; + case 4: + m_sAlgorithmName = "SHA-1"; + break; + case 5: + m_sAlgorithmName = "MAC"; + break; + case 6: + m_sAlgorithmName = "RIPEMD"; + break; + case 7: + m_sAlgorithmName = "RIPEMD-160"; + break; + case 9: + m_sAlgorithmName = "HMAC"; + break; + case 12: + m_sAlgorithmName = "SHA-256"; + break; + case 13: + m_sAlgorithmName = "SHA-384"; + break; + case 14: + m_sAlgorithmName = "SHA-512"; + break; + default:; // 8, 10, 11, any other value: Undefined. + } + } + break; + case NS_ooxml::LN_AG_Password_cryptSpinCount: // 92029 + m_CryptSpinCount = nIntValue; + break; + case NS_ooxml::LN_AG_Password_hash: // 92035 + m_sHash = sStringValue; + break; + case NS_ooxml::LN_AG_Password_salt: // 92036 + m_sSalt = sStringValue; + break; + case NS_ooxml::LN_CT_WriteProtection_recommended: + m_bRecommended = nIntValue; + break; + default: + { +#ifdef DBG_UTIL + TagLogger::getInstance().element("unhandled"); +#endif + } + } +} + +void WriteProtection::lcl_sprm(Sprm& /*rSprm*/) {} + +uno::Sequence<beans::PropertyValue> WriteProtection::toSequence() const +{ + uno::Sequence<beans::PropertyValue> aResult; + if (!m_sAlgorithmName.isEmpty() && !m_sSalt.isEmpty() && !m_sHash.isEmpty() + && m_sCryptAlgorithmClass == "hash" && m_sCryptAlgorithmType == "typeAny") + { + aResult.realloc(4); + aResult[0].Name = "algorithm-name"; + aResult[0].Value <<= m_sAlgorithmName; + aResult[1].Name = "salt"; + aResult[1].Value <<= m_sSalt; + aResult[2].Name = "iteration-count"; + aResult[2].Value <<= m_CryptSpinCount; + aResult[3].Name = "hash"; + aResult[3].Value <<= m_sHash; + } + + return aResult; +} + +} //namespace writerfilter::dmapper + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/writerfilter/source/dmapper/WriteProtection.hxx b/writerfilter/source/dmapper/WriteProtection.hxx new file mode 100644 index 000000000000..21b420b4bcd9 --- /dev/null +++ b/writerfilter/source/dmapper/WriteProtection.hxx @@ -0,0 +1,58 @@ +/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ +/* + * This file is part of the LibreOffice project. + * + * 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/. + * + * This file incorporates work covered by the following license notice: + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed + * with this work for additional information regarding copyright + * ownership. The ASF licenses this file to you under the Apache + * License, Version 2.0 (the "License"); you may not use this file + * except in compliance with the License. You may obtain a copy of + * the License at http://www.apache.org/licenses/LICENSE-2.0 . + */ + +#pragma once + +#include "LoggedResources.hxx" +#include <com/sun/star/beans/PropertyValue.hpp> + +namespace writerfilter::dmapper +{ +class WriteProtection : public LoggedProperties +{ +private: + /** Provider type + * + * Possible values: + * "rsaAES" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaAES + * "rsaFull" - NS_ooxml::LN_Value_doc_ST_CryptProv_rsaFull + */ + sal_Int32 m_nCryptProviderType; + OUString m_sCryptAlgorithmClass; + OUString m_sCryptAlgorithmType; + sal_Int32 m_CryptSpinCount; + OUString m_sAlgorithmName; + OUString m_sHash; + OUString m_sSalt; + bool m_bRecommended; + + virtual void lcl_attribute(Id Name, Value& val) override; + virtual void lcl_sprm(Sprm& sprm) override; + +public: + WriteProtection(); + virtual ~WriteProtection() override; + + css::uno::Sequence<css::beans::PropertyValue> toSequence() const; + + bool getRecommended() const { return m_bRecommended; } +}; +} + +/* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |