Kaydet (Commit) 26941629 authored tarafından Serge Krot's avatar Serge Krot Kaydeden (comit) Thorsten Behrens

tdf#66398 Import/export docx document protection properties

Added:
+ import/export of all doc protection properties
+ unit test

Change-Id: I7b65cf4f5c7add2a96fef407c243081fcc2b6d8d
Reviewed-on: https://gerrit.libreoffice.org/43156Tested-by: 's avatarJenkins <ci@libreoffice.org>
Reviewed-by: 's avatarThorsten Behrens <Thorsten.Behrens@CIB.de>
üst b567cfb9
......@@ -945,6 +945,22 @@ DECLARE_OOXMLEXPORT_TEST(testSectionProtection, "sectionprot.odt")
}
}
DECLARE_OOXMLEXPORT_TEST(tdf66398_permissions, "tdf66398_permissions.docx")
{
if (xmlDocPtr pXmlSettings = parseExport("word/settings.xml"))
{
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "edit", "readOnly");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "enforcement", "1");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "cryptProviderType", "rsaAES");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "cryptAlgorithmClass","hash");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "cryptAlgorithmType", "typeAny");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "cryptAlgorithmSid", "14");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "cryptSpinCount", "100000");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "hash", "A0/Xy6KcXljJlZjP0TwJMPJuW2rc46UwXqn2ctxckc2nCECE5i89M85z2Noh3ZEA5NBQ9RJ5ycxiUH6nzmJaKw==");
assertXPath(pXmlSettings, "/w:settings/w:documentProtection", "salt", "B8k6wb1pkjUs4Nv/8QBk/w==");
}
}
DECLARE_OOXMLEXPORT_TEST(testSectionHeader, "sectionprot.odt")
{
if (xmlDocPtr pXmlDoc = parseExport("word/document.xml"))
......
......@@ -21,6 +21,7 @@
#include "docxexportfilter.hxx"
#include "docxattributeoutput.hxx"
#include "docxsdrexport.hxx"
#include "docxhelper.hxx"
#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
......@@ -935,6 +936,7 @@ void DocxExport::WriteSettings()
{
pFS->singleElementNS( XML_w, XML_documentProtection, FSNS(XML_w, XML_edit), "forms", FSNS(XML_w, XML_enforcement), "1", FSEND );
}
// Do not justify lines with manual break
if( m_pDoc->getIDocumentSettingAccess().get( DocumentSettingId::DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK ))
{
......@@ -942,6 +944,7 @@ void DocxExport::WriteSettings()
pFS->singleElementNS( XML_w, XML_doNotExpandShiftReturn, FSEND );
pFS->endElementNS( XML_w, XML_compat );
}
// Automatic hyphenation: it's a global setting in Word, it's a paragraph setting in Writer.
// Use the setting from the default style.
SwTextFormatColl* pColl = m_pDoc->getIDocumentStylePoolAccess().GetTextCollFromPool(RES_POOLCOLL_STANDARD, /*bRegardLanguage=*/false);
......@@ -969,11 +972,12 @@ void DocxExport::WriteSettings()
uno::Reference< beans::XPropertySet > xPropSet( m_pDoc->GetDocShell()->GetBaseModel(), uno::UNO_QUERY_THROW );
uno::Reference< beans::XPropertySetInfo > xPropSetInfo = xPropSet->getPropertySetInfo();
OUString aGrabBagName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
const OUString aGrabBagName = UNO_NAME_MISC_OBJ_INTEROPGRABBAG;
if ( xPropSetInfo->hasPropertyByName( aGrabBagName ) )
{
uno::Sequence< beans::PropertyValue > propList;
xPropSet->getPropertyValue( aGrabBagName ) >>= propList;
for( sal_Int32 i=0; i < propList.getLength(); ++i )
{
if ( propList[i].Name == "ThemeFontLangProps" )
......@@ -1002,6 +1006,7 @@ void DocxExport::WriteSettings()
uno::Sequence< beans::PropertyValue > aCompatSettingsSequence;
propList[i].Value >>= aCompatSettingsSequence;
for(sal_Int32 j=0; j < aCompatSettingsSequence.getLength(); ++j)
{
uno::Sequence< beans::PropertyValue > aCompatSetting;
......@@ -1025,8 +1030,43 @@ void DocxExport::WriteSettings()
FSNS( XML_w, XML_val ), OUStringToOString(aValue, RTL_TEXTENCODING_UTF8).getStr(),
FSEND);
}
pFS->endElementNS( XML_w, XML_compat );
}
else if (propList[i].Name == "DocumentProtection")
{
sax_fastparser::FastAttributeList* pAttributeList = sax_fastparser::FastSerializerHelper::createAttrList();
uno::Sequence< beans::PropertyValue > rAttributeList;
propList[i].Value >>= rAttributeList;
for (sal_Int32 j = 0; j < rAttributeList.getLength(); ++j)
{
static DocxStringTokenMap const aTokens[] =
{
{ "edit", XML_edit },
{ "enforcement", XML_enforcement },
{ "formatting", XML_formatting },
{ "cryptProviderType", XML_cryptProviderType },
{ "cryptAlgorithmClass", XML_cryptAlgorithmClass },
{ "cryptAlgorithmType", XML_cryptAlgorithmType },
{ "cryptAlgorithmSid", XML_cryptAlgorithmSid },
{ "cryptSpinCount", XML_cryptSpinCount },
{ "hash", XML_hash },
{ "salt", XML_salt },
{ nullptr, 0 }
};
if (sal_Int32 nToken = DocxStringGetToken(aTokens, rAttributeList[j].Name))
pAttributeList->add(FSNS(XML_w, nToken), rAttributeList[j].Value.get<OUString>().toUtf8());
}
if (rAttributeList.getLength())
{
sax_fastparser::XFastAttributeListRef xAttributeList(pAttributeList);
pFS->singleElementNS(XML_w, XML_documentProtection, xAttributeList);
}
}
}
}
......
......@@ -206,10 +206,16 @@ DomainMapper::~DomainMapper()
// Grab-bag handling
comphelper::SequenceAsHashMap aProperties;
// Add the saved w:themeFontLang setting
aProperties["ThemeFontLangProps"] <<= m_pImpl->GetSettingsTable()->GetThemeFontLangProperties();
// Add the saved compat settings
aProperties["CompatSettings"] <<= m_pImpl->GetSettingsTable()->GetCompatSettings();
// Add the saved DocumentProtection settings
aProperties["DocumentProtection"] <<= m_pImpl->GetSettingsTable()->GetDocumentProtectionSettings();
uno::Reference<beans::XPropertySet> xDocProps(m_pImpl->GetTextDocument(), uno::UNO_QUERY);
if (xDocProps.is())
{
......@@ -2810,6 +2816,11 @@ void DomainMapper::sprmWithProps( Sprm& rSprm, const PropertyMapPtr& rContext )
pProperties->resolve(*this);
}
break;
case NS_ooxml::LN_EG_RunLevelElts_permStart: // 93164
case NS_ooxml::LN_EG_RunLevelElts_permEnd: // 93165
{
break;
}
default:
{
#ifdef DEBUG_WRITERFILTER
......
......@@ -39,6 +39,176 @@ namespace writerfilter {
namespace 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.
*/
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; };
// bool isReadOnly() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_readOnly; };
// bool isComments() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_comments; };
// bool isTrackChanges() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_trackedChanges; };
bool isForms() const { return m_nEdit == NS_ooxml::LN_Value_doc_ST_DocProtect_forms; };
};
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 DEBUG_WRITERFILTER
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
{
......@@ -71,6 +241,8 @@ struct SettingsTable_Impl
std::vector<beans::PropertyValue> m_aCompatSettings;
uno::Sequence<beans::PropertyValue> m_pCurrentCompatSetting;
DocumentProtection_Impl m_DocumentProtection;
SettingsTable_Impl() :
m_nDefaultTabStop( 720 ) //default is 1/2 in
, m_bRecordChanges(false)
......@@ -147,12 +319,40 @@ 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:
m_pImpl->m_bProtectForm = (nIntValue == NS_ooxml::LN_Value_doc_ST_DocProtect_forms);
case NS_ooxml::LN_CT_DocProtect_edit: // 92037
m_pImpl->m_DocumentProtection.m_nEdit = nIntValue;
m_pImpl->m_bProtectForm = m_pImpl->m_DocumentProtection.isForms();
break;
case NS_ooxml::LN_CT_DocProtect_enforcement:
case NS_ooxml::LN_CT_DocProtect_enforcement: // 92039
m_pImpl->m_DocumentProtection.m_bEnforcement = (nIntValue != 0);
m_pImpl->m_bProtectForm &= (bool)nIntValue;
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;
default:
{
#ifdef DEBUG_WRITERFILTER
......@@ -184,9 +384,7 @@ void SettingsTable::lcl_sprm(Sprm& rSprm)
case NS_ooxml::LN_CT_Settings_view:
//PropertySetValues - need to be resolved
{
writerfilter::Reference<Properties>::Pointer_t pProperties = rSprm.getProps();
if( pProperties.get())
pProperties->resolve(*this);
resolveSprmProps(*this, rSprm);
}
break;
case NS_ooxml::LN_CT_Settings_stylePaneFormatFilter: // 92493;
......@@ -226,9 +424,7 @@ void SettingsTable::lcl_sprm(Sprm& rSprm)
}
break;
case NS_ooxml::LN_CT_Settings_documentProtection:
{
resolveSprmProps(*this, rSprm);
}
resolveSprmProps(*this, rSprm);
break;
case NS_ooxml::LN_CT_Compat_usePrinterMetrics:
m_pImpl->m_bUsePrinterMetrics = nIntValue;
......@@ -376,6 +572,11 @@ uno::Sequence<beans::PropertyValue> SettingsTable::GetCompatSettings() const
return comphelper::containerToSequence(m_pImpl->m_aCompatSettings);
}
css::uno::Sequence<css::beans::PropertyValue> SettingsTable::GetDocumentProtectionSettings() const
{
return m_pImpl->m_DocumentProtection.toSequence();
}
static bool lcl_isDefault(const uno::Reference<beans::XPropertyState>& xPropertyState, const OUString& rPropertyName)
{
return xPropertyState->getPropertyState(rPropertyName) == beans::PropertyState_DEFAULT_VALUE;
......
......@@ -79,6 +79,8 @@ class SettingsTable : public LoggedProperties, public LoggedTable
css::uno::Sequence<css::beans::PropertyValue> GetCompatSettings() const;
css::uno::Sequence<css::beans::PropertyValue> GetDocumentProtectionSettings() const;
void ApplyProperties(css::uno::Reference<css::text::XTextDocument> const& xDoc);
private:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment