Skip to content

Commit

Permalink
Introduce basic XML validation report
Browse files Browse the repository at this point in the history
DEVSIX-8610

Autoported commit.
Original commit hash: [dd25f1a8f]
Manual files:
sharpenConfiguration.xml
sign/src/main/java/com/itextpdf/signatures/validation/report/xml/XmlReportGenerator.java
sign/src/test/java/com/itextpdf/signatures/testutils/report/xml/ReportNamespaceContext.java
sign/src/test/java/com/itextpdf/signatures/testutils/report/xml/XmlReportTestTool.java
  • Loading branch information
glenner003 authored and AnhelinaM committed Nov 2, 2024
1 parent 10efd35 commit a29cd39
Show file tree
Hide file tree
Showing 43 changed files with 7,852 additions and 2 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Xml;
using System.Xml.Schema;
using System.Xml.XPath;
using iText.Signatures.Validation.Report.Xml;

namespace iText.Signatures.Testutils.Report.Xml {
public class XmlReportTestTool {
private static readonly String XSDROOT = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
.CurrentContext.TestDirectory) + "/resources/itext/signatures/validation/report/xml/";

private readonly XmlDocument xml;

private readonly String report;
private XPathNavigator navigator;
private XmlNamespaceManager manager;

public XmlReportTestTool(String report) {
this.report = report;
xml = new XmlDocument();
xml.LoadXml(report);

navigator = xml.CreateNavigator();
manager = new XmlNamespaceManager(navigator.NameTable);
manager.AddNamespace("r", XmlReportGenerator.DOC_NS);
manager.AddNamespace("ds", XmlReportGenerator.DS_NS);
manager.AddNamespace("xs", XmlReportGenerator.XS_NS);
manager.AddNamespace("xsi", XmlReportGenerator.XSI_NS);
}

public virtual XmlElement GetDocumentNode() {
return xml.DocumentElement;
}

public virtual int CountElements(String xPathQuery) {
return xml.SelectNodes(xPathQuery, manager).Count;
}

public virtual String GetElementContent(String xPathQuery) {
return xml.SelectSingleNode(xPathQuery, manager).InnerText;
}

public virtual XmlNodeList ExecuteXpathAsNodeList(String xPathQuery) {
return xml.SelectNodes(xPathQuery, manager);
}

public virtual XmlNode ExecuteXpathAsNode(String xPathQuery) {
return xml.SelectSingleNode(xPathQuery, manager);
}

public virtual String ExecuteXpathAsString(String xPathQuery) {
return (String)navigator.Evaluate(xPathQuery, manager);
}

public virtual double? ExecuteXpathAsNumber(String xPathQuery) {
return (double?)navigator.Evaluate(xPathQuery, manager);
}

public virtual bool? ExecuteXpathAsBoolean(String xPathQuery) {
return (bool?)navigator.Evaluate(xPathQuery, manager);
}

public virtual String ValidateXMLSchema() {
List<string> files = new List<string>();
files.AddAll(new[] {
XSDROOT + "xml.xsd",
XSDROOT + "XMLSchema.xsd",
XSDROOT + "XAdES.xsd",
XSDROOT + "ts_119612v020201_201601xsd.xsd",
XSDROOT + "1910202xmlSchema.xsd",
XSDROOT + "xmldsig-core-schema.xsd"
});

var schemas = files.Select(f => XmlSchema.Read(XmlReader.Create(f,
new XmlReaderSettings { DtdProcessing = DtdProcessing.Parse }), (s, e) => {
}));

XmlSchemaSet xmlSchemaSet = new XmlSchemaSet();
foreach (var s in schemas) {
xmlSchemaSet.Add(s);
}

XmlReaderSettings validationSettings = new XmlReaderSettings();
validationSettings.ValidationFlags = XmlSchemaValidationFlags.ProcessIdentityConstraints | XmlSchemaValidationFlags.ReportValidationWarnings | XmlSchemaValidationFlags.AllowXmlAttributes;
validationSettings.ValidationType = ValidationType.Schema;
validationSettings.Schemas.Add(xmlSchemaSet);
validationSettings.Schemas.Compile();
StringBuilder log = new StringBuilder();

validationSettings.ValidationEventHandler += (s, e) => {
log.Append("***\n");
log.Append("\tPosition:").Append(e.Exception.LineNumber).Append(':').Append(e.Exception.LinePosition).Append('\n');
log.Append("\tSeverity:").Append(e.Severity).Append('\n');
log.Append("\tMessage :").Append(e.Message).Append('\n');
};

XmlReader reader = XmlReader.Create(new StringReader(report), validationSettings);
while (reader.Read()) {}

String message = log.ToString();
if (String.IsNullOrEmpty(message)) {
return null;
}
return message;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
namespace iText.Signatures.Validation.Report.Xml {
public abstract class AbstractCollectableObjectTest : AbstractIdentifiableObjectTest {
private AbstractCollectableObjectTest.MockCollectableObjectVisitor mockVisitor;

[NUnit.Framework.SetUp]
public virtual void SetUpParent() {
mockVisitor = new AbstractCollectableObjectTest.MockCollectableObjectVisitor();
}

[NUnit.Framework.Test]
public virtual void TestVisitorUsage() {
AbstractCollectableObject sut = GetCollectableObjectUnderTest();
sut.Accept(mockVisitor);
NUnit.Framework.Assert.AreEqual(1, mockVisitor.calls);
}

//\cond DO_NOT_DOCUMENT
internal override AbstractIdentifiableObject GetIdentifiableObjectUnderTest() {
return GetCollectableObjectUnderTest();
}
//\endcond

//\cond DO_NOT_DOCUMENT
internal abstract AbstractCollectableObject GetCollectableObjectUnderTest();
//\endcond

private class MockCollectableObjectVisitor : CollectableObjectVisitor {
public int calls;

public virtual void Visit(CertificateWrapper certificateWrapper) {
calls++;
}

public virtual void Visit(POEValidationReport poeValidationReport) {
calls++;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using iText.Test;

namespace iText.Signatures.Validation.Report.Xml {
public abstract class AbstractIdentifiableObjectTest : ExtendedITextTest {
[NUnit.Framework.Test]
public virtual void TestIdentifiersAreUnique() {
AbstractIdentifiableObject sut1 = new AbstractIdentifiableObjectTest.TestIdentifiableObject("A");
AbstractIdentifiableObject sut2 = new AbstractIdentifiableObjectTest.TestIdentifiableObject("A");
NUnit.Framework.Assert.AreNotEqual(sut1.GetIdentifier().GetId(), sut2.GetIdentifier().GetId());
}

[NUnit.Framework.Test]
public virtual void TestEqualsForEqualIdentity() {
AbstractIdentifiableObject sut1 = GetIdentifiableObjectUnderTest();
AbstractIdentifiableObject sut2 = sut1;
// Equals is being tested here.
NUnit.Framework.Assert.IsTrue(sut1.Equals(sut2));
}

[NUnit.Framework.Test]
public virtual void TestEqualsForNull() {
AbstractIdentifiableObject sut = GetIdentifiableObjectUnderTest();
// Equals is being tested here.
NUnit.Framework.Assert.IsFalse(sut.Equals(null));
}

[NUnit.Framework.Test]
public virtual void TestEqualsForSomeObject() {
AbstractIdentifiableObject sut = GetIdentifiableObjectUnderTest();
// Equals is being tested here.
NUnit.Framework.Assert.IsFalse(sut.Equals("Test"));
}

[NUnit.Framework.Test]
public virtual void TestEqualsForEqualInstances() {
PerformTestEqualsForEqualInstances();
}

[NUnit.Framework.Test]
public virtual void TestHashForEqualInstances() {
PerformTestHashForEqualInstances();
}

[NUnit.Framework.Test]
public virtual void TestEqualsForDifferentInstances() {
PerformTestEqualsForDifferentInstances();
}

[NUnit.Framework.Test]
public virtual void TestHashForDifferentInstances() {
PerformTestHashForDifferentInstances();
}

protected internal abstract void PerformTestHashForEqualInstances();

protected internal abstract void PerformTestEqualsForEqualInstances();

protected internal abstract void PerformTestEqualsForDifferentInstances();

protected internal abstract void PerformTestHashForDifferentInstances();

//\cond DO_NOT_DOCUMENT
internal abstract AbstractIdentifiableObject GetIdentifiableObjectUnderTest();
//\endcond

private class TestIdentifiableObject : AbstractIdentifiableObject {
protected internal TestIdentifiableObject(String prefix)
: base(prefix) {
}

public override bool Equals(Object o) {
return false;
}

public override int GetHashCode() {
return 0;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
/*
This file is part of the iText (R) project.
Copyright (c) 1998-2024 Apryse Group NV
Authors: Apryse Software.
This program is offered under a commercial and under the AGPL license.
For commercial licensing, contact us at https://itextpdf.com/sales. For AGPL licensing, see below.
AGPL licensing:
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Affero General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License
along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
using System;
using iText.Bouncycastleconnector;
using iText.Commons.Bouncycastle;
using iText.Commons.Bouncycastle.Cert;
using iText.Commons.Utils;
using iText.Signatures.Testutils;

namespace iText.Signatures.Validation.Report.Xml {
[NUnit.Framework.Category("BouncyCastleUnitTest")]
public class CertificateWrapperTest : AbstractCollectableObjectTest {
private static readonly IBouncyCastleFactory FACTORY = BouncyCastleFactoryCreator.GetFactory();

private static readonly String CERTS_SRC = iText.Test.TestUtil.GetParentProjectDirectory(NUnit.Framework.TestContext
.CurrentContext.TestDirectory) + "/resources/itext/signatures/certs/";

private static IX509Certificate cert1;

private static IX509Certificate cert2;

[NUnit.Framework.OneTimeSetUp]
public static void SetUpFixture() {
cert1 = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "root.pem")[0];
cert2 = (IX509Certificate)PemFileHelper.ReadFirstChain(CERTS_SRC + "signCertDsa01.pem")[0];
}

[NUnit.Framework.Test]
public virtual void TestEqualInstancesHaveUniqueIds() {
CertificateWrapper sut1 = new CertificateWrapper(cert1);
CertificateWrapper sut2 = new CertificateWrapper(cert1);
NUnit.Framework.Assert.AreNotEqual(sut1.GetIdentifier().GetId(), sut2.GetIdentifier().GetId());
}

protected internal override void PerformTestHashForEqualInstances() {
CertificateWrapper sut1 = new CertificateWrapper(cert1);
CertificateWrapper sut2 = new CertificateWrapper(cert1);
NUnit.Framework.Assert.AreEqual(sut1.GetHashCode(), sut2.GetHashCode());
}

protected internal override void PerformTestEqualsForEqualInstances() {
CertificateWrapper sut1 = new CertificateWrapper(cert1);
CertificateWrapper sut2 = new CertificateWrapper(cert1);
NUnit.Framework.Assert.AreEqual(sut1, sut2);
}

protected internal override void PerformTestEqualsForDifferentInstances() {
CertificateWrapper sut1 = new CertificateWrapper(cert1);
CertificateWrapper sut2 = new CertificateWrapper(cert2);
NUnit.Framework.Assert.AreNotEqual(sut1, sut2);
}

protected internal override void PerformTestHashForDifferentInstances() {
CertificateWrapper sut1 = new CertificateWrapper(cert1);
CertificateWrapper sut2 = new CertificateWrapper(cert2);
NUnit.Framework.Assert.AreNotEqual(sut1.GetHashCode(), sut2.GetHashCode());
}

[NUnit.Framework.Test]
public virtual void TestGetBase64ASN1Structure() {
CertificateWrapper sut = new CertificateWrapper(cert1);
IX509Certificate sutCert = FACTORY.CreateX509Certificate(Convert.FromBase64String(sut.GetBase64ASN1Structure
()));
IX509Certificate origCert = FACTORY.CreateX509Certificate(cert1.GetEncoded());
NUnit.Framework.Assert.AreEqual(origCert, sutCert);
}

//\cond DO_NOT_DOCUMENT
internal override AbstractCollectableObject GetCollectableObjectUnderTest() {
return new CertificateWrapper(cert1);
}
//\endcond
}
}
Loading

0 comments on commit a29cd39

Please sign in to comment.