Skip to content

Commit

Permalink
Refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
Bombino1024 committed Jul 7, 2023
1 parent f80b752 commit fa95afd
Show file tree
Hide file tree
Showing 3 changed files with 83 additions and 73 deletions.
19 changes: 18 additions & 1 deletion src/main/java/digital/slovensko/autogram/core/SigningJob.java
Original file line number Diff line number Diff line change
Expand Up @@ -100,7 +100,7 @@ private String transform() {

var xmlSource = new DOMSource(document);
if (isXDC())
xmlSource = XDCTransformer.extractFromXDC(document, builderFactory);
xmlSource = extractFromXDC(document, builderFactory);

var outputTarget = new StreamResult(new StringWriter());
var transformer = TransformerFactory.newInstance().newTransformer(
Expand All @@ -114,6 +114,23 @@ private String transform() {
}
}

private DOMSource extractFromXDC(Document document, DocumentBuilderFactory builderFactory)
throws ParserConfigurationException {
var xdc = document.getDocumentElement();

var xmlData = xdc.getElementsByTagNameNS("http://data.gov.sk/def/container/xmldatacontainer+xml/1.1", "XMLData")
.item(0);

if (xmlData == null)
throw new RuntimeException("XMLData not found in XDC"); // TODO catch somewhere

document = builderFactory.newDocumentBuilder().newDocument();
var node = document.importNode(xmlData.getFirstChild(), true);
document.appendChild(node);

return new DOMSource(document);
}

public String getDocumentAsHTML() {
return transform();
}
Expand Down
82 changes: 60 additions & 22 deletions src/main/java/digital/slovensko/autogram/core/XDCTransformer.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;

import javax.xml.XMLConstants;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
Expand Down Expand Up @@ -71,7 +74,22 @@ private XDCTransformer(String identifier, String xsdSchema, String xsltSchema, S
this.mediaDestinationTypeDescription = mediaDestinationTypeDescription;
}

public XDCTransformer(String xsdSchema, String xsltSchema, String canonicalizationMethod,
public static XDCTransformer buildFromSigningParametersAndDocument(SigningParameters sp, InMemoryDocument document) {
try {
var builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);

return new XDCTransformer(sp.getSchema(),
sp.getTransformation(),
sp.getPropertiesCanonicalization(),
sp.getDigestAlgorithm(),
builderFactory.newDocumentBuilder().parse(new InputSource(document.openStream())));
} catch (Exception e) {
throw new RuntimeException("Unable to create XDC transformer from signing parameters and document", e);
}
}

private XDCTransformer(String xsdSchema, String xsltSchema, String canonicalizationMethod,
DigestAlgorithm digestAlgorithm, Document document) {
this.xsdSchema = xsdSchema;
this.xsltSchema = xsltSchema;
Expand Down Expand Up @@ -228,21 +246,20 @@ private static String toNamespacedString(DigestAlgorithm digestAlgorithm) {
return "urn:oid:" + digestAlgorithm.getOid();
}

public static DOMSource extractFromXDC(Document document, DocumentBuilderFactory builderFactory)
throws ParserConfigurationException {
var xdc = document.getDocumentElement();

var xmlData = xdc.getElementsByTagNameNS("http://data.gov.sk/def/container/xmldatacontainer+xml/1.1", "XMLData")
.item(0);

if (xmlData == null)
throw new RuntimeException("XMLData not found in XDC"); // TODO catch somewhere
public boolean validateXsdAndXsltHashes() {
return validateXsd() && validateXslt();
}

document = builderFactory.newDocumentBuilder().newDocument();
var node = document.importNode(xmlData.getFirstChild(), true);
document.appendChild(node);
private boolean validateXsd() {
String xsdSchemaHash = computeDigest(xsdSchema);
String xsdDigestValue = getDigestValueFromElement("UsedXSDReference");
return xsdSchemaHash.equals(xsdDigestValue);
}

return new DOMSource(document);
private boolean validateXslt() {
String xsltSchemaHash = computeDigest(xsltSchema);
String xsltDigestValue = getDigestValueFromElement("UsedPresentationSchemaReference");
return xsltSchemaHash.equals(xsltDigestValue);
}

private String getDigestValueFromElement(String elementLocalName) {
Expand All @@ -264,16 +281,37 @@ private String getDigestValueFromElement(String elementLocalName) {
return digestValue.getNodeValue();
}

public boolean validateXsd() {
String xsdSchemaHash = computeDigest(xsdSchema);
String xsdDigestValue = getDigestValueFromElement("UsedXSDReference");
return xsdSchemaHash.equals(xsdDigestValue);
public String getContentFromXdc() {
var xdc = document.getDocumentElement();

var xmlData = xdc.getElementsByTagNameNS("http://data.gov.sk/def/container/xmldatacontainer+xml/1.1", "XMLData")
.item(0);

if (xmlData == null)
throw new RuntimeException("XMLData not found in XDC");

return transformElementToString(xmlData.getFirstChild());
}

public boolean validateXslt() {
String xsltSchemaHash = computeDigest(xsltSchema);
String xsltDigestValue = getDigestValueFromElement("UsedPresentationSchemaReference");
return xsltSchemaHash.equals(xsltDigestValue);
private String transformElementToString(Node element) {
try {
var builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);

var document = builderFactory.newDocumentBuilder().newDocument();
var node = document.importNode(element, true);
document.appendChild(node);

TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(new DOMSource(document), new StreamResult(writer));

return writer.toString();
} catch (Exception e) {
throw new RuntimeException("Unable to transform element to string", e);
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -79,15 +79,14 @@ private void validateXml(SigningParameters signingParameters) {
String xsdSchema = signingParameters.getSchema();
String xmlContent;

if (isXdc()) {
if (!validateXsdAndXsltHashes(signingParameters)) {
boolean isXdc = getDocument().getMimeType().equals(AutogramMimeType.XML_DATACONTAINER);
if (isXdc) {
XDCTransformer xdcTransformer = XDCTransformer.buildFromSigningParametersAndDocument(signingParameters, getDocument());
if (!xdcTransformer.validateXsdAndXsltHashes()) {
throw new RequestValidationException("XML validation failed", "Invalid xsd scheme or xslt transformation");
}

xmlContent = getContentFromXdc();
if (xmlContent == null) {
throw new RequestValidationException("XML validation failed", "Unable to get content from xdc container");
}
xmlContent = xdcTransformer.getContentFromXdc();
} else {
xmlContent = getDecodedContent();
}
Expand All @@ -97,50 +96,6 @@ private void validateXml(SigningParameters signingParameters) {
}
}

private boolean isXdc() {
return getDocument().getMimeType().equals(AutogramMimeType.XML_DATACONTAINER);
}

private boolean validateXsdAndXsltHashes(SigningParameters sp) {
try {
var builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);

XDCTransformer xdcTransformer = new XDCTransformer(
sp.getSchema(),
sp.getTransformation(),
sp.getPropertiesCanonicalization(),
sp.getDigestAlgorithm(),
builderFactory.newDocumentBuilder().parse(new InputSource(getDocument().openStream()))
);

return xdcTransformer.validateXsd() && xdcTransformer.validateXslt();
} catch (Exception e) {
return false;
}
}

private String getContentFromXdc() {
try {
var builderFactory = DocumentBuilderFactory.newInstance();
builderFactory.setNamespaceAware(true);
var document = builderFactory.newDocumentBuilder().parse(new InputSource(getDocument().openStream()));
var element = XDCTransformer.extractFromXDC(document, builderFactory);
return transformElementToString(element);
} catch (Exception e) {
return null;
}
}

private static String transformElementToString(DOMSource element) throws TransformerException {
TransformerFactory factory = TransformerFactory.newInstance();
Transformer transformer = factory.newTransformer();
transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
StringWriter writer = new StringWriter();
transformer.transform(element, new StreamResult(writer));
return writer.toString();
}

private String getDecodedContent() {
return isBase64() ? new String(Base64.getDecoder().decode(document.getContent())) : document.getContent();
}
Expand Down

0 comments on commit fa95afd

Please sign in to comment.