libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit ba6eee4075d6f1a702059a6ff2b6021e171d2907
parent 402ae71f9bff1650b140c2f5d0e70bbc487813b2
Author: Marcello Stanisci <stanisci.m@gmail.com>
Date:   Tue, 15 Oct 2019 19:54:09 +0200

INI handling.

Get to the point where the INI key gets uncompressed, and fed to
its JAXB constructor.  Fails now, therefore a new unit test case
has also been provided.

Diffstat:
Msandbox/src/main/kotlin/Main.kt | 62++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--
Msandbox/src/main/kotlin/XML.kt | 19+++++++++++++++++++
Asandbox/src/test/kotlin/IniLoadJaxbTest.kt | 27+++++++++++++++++++++++++++
Asandbox/src/test/resources/ebics_ini_inner_key.xml | 15+++++++++++++++
4 files changed, 121 insertions(+), 2 deletions(-)

diff --git a/sandbox/src/main/kotlin/Main.kt b/sandbox/src/main/kotlin/Main.kt @@ -36,15 +36,24 @@ import io.ktor.routing.post import io.ktor.routing.routing import io.ktor.server.engine.embeddedServer import io.ktor.server.netty.Netty +import io.ktor.util.decodeBase64 import org.jetbrains.exposed.sql.transactions.transaction import org.slf4j.LoggerFactory import org.w3c.dom.Document import org.w3c.dom.Element import tech.libeufin.messages.ebics.hev.HEVResponseDataType import tech.libeufin.messages.ebics.keyrequest.EbicsUnsecuredRequest +import tech.libeufin.messages.ebics.keyrequest.SignaturePubKeyOrderDataType import tech.libeufin.messages.ebics.keyrequest.UnsecuredReqOrderDetailsType +import java.nio.charset.StandardCharsets.US_ASCII import java.text.DateFormat +import java.util.* +import java.util.zip.GZIPInputStream import javax.xml.bind.JAXBElement +import java.nio.charset.StandardCharsets.UTF_8 +import java.util.zip.Inflater +import java.util.zip.InflaterInputStream + val logger = LoggerFactory.getLogger("tech.libeufin.sandbox") val xmlProcess = XML() @@ -214,6 +223,57 @@ private suspend fun ApplicationCall.ebicsweb() { logger.info("Serving a ${bodyJaxb.header.static.orderDetails.orderType} request") + when (bodyJaxb.header.static.orderDetails.orderType) { + + "INI" -> { + + /** + * NOTE: the JAXB interface has some automagic mechanism that decodes + * the Base64 string into its byte[] form _at the same time_ it instantiates + * the object; in other words, there is no need to perform here the decoding. + */ + val zkey = bodyJaxb.body.dataTransfer.orderData.value + + /** + * The validation enforces zkey to be a base64 value, but does not check + * whether it is given _empty_ or not; will check explicitly here. FIXME: + * shall the schema be patched to avoid having this if-block here? + */ + if (zkey.size == 0) { + logger.error("0-length key element given, invalid request") + respondText( + contentType = ContentType.Application.Xml, + status = HttpStatusCode.BadRequest + ) { "Bad request / invalid document" } + + return + } + + /** + * This value holds the bytes[] of a XML "SignaturePubKeyOrderData" document + * and at this point is valid and _never_ empty. + */ + val inflater = InflaterInputStream(zkey.inputStream()) + var result = ByteArray(1) {inflater.read().toByte()} + + while (inflater.available() == 1) { + result += inflater.read().toByte() + } + + inflater.close() + + println("That is the key element: ${result.toString(US_ASCII)}") + + val keyObject = xmlProcess.convertStringToJaxb<SignaturePubKeyOrderDataType>( + "tech.libeufin.messages.ebics.keyrequest", + result.toString(US_ASCII) + ) + + println(keyObject.signaturePubKeyInfo.signatureVersion) + + } + } + respond( HttpStatusCode.NotImplemented, SandboxError("Not implemented") @@ -253,8 +313,6 @@ private suspend fun ApplicationCall.ebicsweb() { return } } - - } fun main() { diff --git a/sandbox/src/main/kotlin/XML.kt b/sandbox/src/main/kotlin/XML.kt @@ -186,6 +186,25 @@ class XML { } /** + * Convert a XML string to the JAXB representation. + * + * @param packageName the package containing the ObjectFactory used to + * instantiate the wanted object. + * @param documentString the string to convert into JAXB. + * @return the JAXB object reflecting the original XML document. + */ + fun <T>convertStringToJaxb(packageName: String, documentString: String) : T { + + val jc = JAXBContext.newInstance(packageName) + + /* Marshalling the object into the document. */ + val m = jc.createUnmarshaller() + return m.unmarshal(StringReader(documentString)) as T // document "went" into Jaxb + } + + + + /** * Return the DOM representation of the Java object, using the JAXB * interface. FIXME: narrow input type to JAXB type! * diff --git a/sandbox/src/test/kotlin/IniLoadJaxbTest.kt b/sandbox/src/test/kotlin/IniLoadJaxbTest.kt @@ -0,0 +1,26 @@ +package tech.libeufin.sandbox + +import kotlinx.coroutines.io.jvm.javaio.toByteReadChannel +import org.junit.Assert +import org.junit.Test +import org.junit.Assert.* +import tech.libeufin.messages.ebics.keyrequest.SignaturePubKeyOrderDataType +import java.io.File +import javax.xml.transform.Source +import javax.xml.transform.stream.StreamSource + +class IniKeyMaterialTest { + + val processor = tech.libeufin.sandbox.XML() + + @Test + fun importKey(){ + val classLoader = ClassLoader.getSystemClassLoader() + val ini = classLoader.getResource("ebics_ini_inner_key.xml") + val obj = processor.convertStringToJaxb<SignaturePubKeyOrderDataType>( + "tech.libeufin.messages.ebics.keyrequest", + ini.readText() + ) + + } +} +\ No newline at end of file diff --git a/sandbox/src/test/resources/ebics_ini_inner_key.xml b/sandbox/src/test/resources/ebics_ini_inner_key.xml @@ -0,0 +1,14 @@ +<?xml version="1.0" encoding="utf-8"?> +<SignaturePubKeyOrderData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.ebics.org/S001 http://www.ebics.org/S001/ebics_signature.xsd" xmlns:ds="http://www.w3.org/2000/09/xmldsig#" xmlns="http://www.ebics.org/S001"> + <SignaturePubKeyInfo> + <PubKeyValue> + <ds:RSAKeyValue> + <ds:Modulus>s5ktpg3xGjbZZgVTYtW+0e6xsWg142UwvoM3mfuM+qrkIa5bPUGQLH6BRL9IejYosPhoA6jwMBSxO8LfaageyZJt2M5wHklJYz3fADtQrV1bk5R92OaY/9ZZdHxw3xY93tm5JfVrMDW9DEK5B1hUzYFdjuN/qu2/sdE9mwhx2YjYwwdSQzv6MhbtSK9OAJjPGo3fkxsht6maSmRCdgxplIOSO2mmP1wjUzbVUMcrRk9KDMvnb3kCxiTm+evvxX6J4wpY1bAWukolJbaALHlFtgTo1LnulUe/BxiKx9HpmuEAaPsk8kgduXsz5OqH2g/Vyw75x51aKVPxOTBPyP+4kQ==</ds:Modulus> + <ds:Exponent>AQAB</ds:Exponent> + </ds:RSAKeyValue> + </PubKeyValue> + <SignatureVersion>A006</SignatureVersion> + </SignaturePubKeyInfo> + <PartnerID>flo-kid</PartnerID> + <UserID>flo-uid</UserID> +</SignaturePubKeyOrderData> +\ No newline at end of file