diff options
author | Antoine A <> | 2024-03-07 12:33:23 +0100 |
---|---|---|
committer | Antoine A <> | 2024-03-07 12:33:23 +0100 |
commit | ff7e7905f53e4a6b7f82a9a9c64694fd5b323d1a (patch) | |
tree | 76478258a826ea3f392e8027c39e2df7f9995ed5 | |
parent | 4044e69399c8c911dd926c4f8d4164964a08e0f0 (diff) | |
download | libeufin-ff7e7905f53e4a6b7f82a9a9c64694fd5b323d1a.tar.gz libeufin-ff7e7905f53e4a6b7f82a9a9c64694fd5b323d1a.tar.bz2 libeufin-ff7e7905f53e4a6b7f82a9a9c64694fd5b323d1a.zip |
Replace all Ebics3 JAXB logic with custom XML DSL
-rw-r--r-- | ebics/src/main/kotlin/Ebics.kt | 80 | ||||
-rw-r--r-- | ebics/src/main/kotlin/XmlCombinators.kt | 23 | ||||
-rw-r--r-- | ebics/src/main/kotlin/ebics_h005/Ebics3Request.kt | 587 | ||||
-rw-r--r-- | ebics/src/main/kotlin/ebics_h005/Ebics3Response.kt | 347 | ||||
-rw-r--r-- | ebics/src/main/kotlin/ebics_h005/Ebics3Types.kt | 401 | ||||
-rw-r--r-- | ebics/src/main/kotlin/ebics_h005/package-info.java | 13 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt | 1 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt | 41 | ||||
-rw-r--r-- | nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt | 5 |
9 files changed, 90 insertions, 1408 deletions
diff --git a/ebics/src/main/kotlin/Ebics.kt b/ebics/src/main/kotlin/Ebics.kt index 5588ee7f..e3ec9175 100644 --- a/ebics/src/main/kotlin/Ebics.kt +++ b/ebics/src/main/kotlin/Ebics.kt @@ -27,11 +27,11 @@ package tech.libeufin.ebics import io.ktor.http.* import org.w3c.dom.Document import tech.libeufin.common.crypto.CryptoUtil +import tech.libeufin.common.* import tech.libeufin.ebics.ebics_h004.EbicsRequest import tech.libeufin.ebics.ebics_h004.EbicsResponse import tech.libeufin.ebics.ebics_h004.EbicsTypes import tech.libeufin.ebics.ebics_h004.HPBResponseOrderData -import tech.libeufin.ebics.ebics_h005.Ebics3Response import tech.libeufin.ebics.ebics_s001.UserSignatureData import java.io.InputStream import java.security.SecureRandom @@ -310,41 +310,53 @@ fun parseEbicsHpbOrder(orderDataRaw: InputStream): HpbResponseData { } fun ebics3toInternalRepr(response: Document): EbicsResponseContent { - // logger.debug("Converting bank resp to internal repr.: $response") - val resp: JAXBElement<Ebics3Response> = try { - XMLUtil.convertDomToJaxb(response) - } catch (e: Exception) { - throw EbicsProtocolError( - HttpStatusCode.InternalServerError, - "Could not transform string-response from bank into JAXB" + // TODO better ebics response type + return XmlDestructor.fromDoc(response, "ebicsResponse") { + var transactionID: String? = null + var numSegments: Int? = null + lateinit var technicalReturnCode: EbicsReturnCode + lateinit var bankReturnCode: EbicsReturnCode + lateinit var reportText: String + var orderID: String? = null + var segmentNumber: Int? = null + var orderDataEncChunk: String? = null + var dataEncryptionInfo: DataEncryptionInfo? = null + one("header") { + one("static") { + transactionID = opt("TransactionID")?.text() + numSegments = opt("NumSegments")?.text()?.toInt() + } + one("mutable") { + segmentNumber = opt("SegmentNumber")?.text()?.toInt() + orderID = opt("OrderID")?.text() + technicalReturnCode = EbicsReturnCode.lookup(one("ReturnCode").text()) + reportText = one("ReportText").text() + } + } + one("body") { + opt("DataTransfer") { + orderDataEncChunk = one("OrderData").text() + dataEncryptionInfo = opt("DataEncryptionInfo") { + DataEncryptionInfo( + one("TransactionKey").text().decodeBase64(), + one("EncryptionPubKeyDigest").text().decodeBase64() + ) + } + } + bankReturnCode = EbicsReturnCode.lookup(one("ReturnCode").text()) + } + EbicsResponseContent( + transactionID = transactionID, + orderID = orderID, + bankReturnCode = bankReturnCode, + technicalReturnCode = technicalReturnCode, + reportText = reportText, + orderDataEncChunk = orderDataEncChunk, + dataEncryptionInfo = dataEncryptionInfo, + numSegments = numSegments, + segmentNumber = segmentNumber ) } - val bankReturnCodeStr = resp.value.body.returnCode.value - val bankReturnCode = EbicsReturnCode.lookup(bankReturnCodeStr) - - val techReturnCodeStr = resp.value.header.mutable.returnCode - val techReturnCode = EbicsReturnCode.lookup(techReturnCodeStr) - - val reportText = resp.value.header.mutable.reportText - - val daeXml = resp.value.body.dataTransfer?.dataEncryptionInfo - val dataEncryptionInfo = if (daeXml == null) { - null - } else { - DataEncryptionInfo(daeXml.transactionKey, daeXml.encryptionPubKeyDigest.value) - } - - return EbicsResponseContent( - transactionID = resp.value.header._static.transactionID, - orderID = resp.value.header.mutable.orderID, - bankReturnCode = bankReturnCode, - technicalReturnCode = techReturnCode, - reportText = reportText, - orderDataEncChunk = resp.value.body.dataTransfer?.orderData?.value, - dataEncryptionInfo = dataEncryptionInfo, - numSegments = resp.value.header._static.numSegments?.toInt(), - segmentNumber = resp.value.header.mutable.segmentNumber?.value?.toInt() - ) } fun ebics25toInternalRepr(response: Document): EbicsResponseContent { diff --git a/ebics/src/main/kotlin/XmlCombinators.kt b/ebics/src/main/kotlin/XmlCombinators.kt index 9cb0b327..902e21ae 100644 --- a/ebics/src/main/kotlin/XmlCombinators.kt +++ b/ebics/src/main/kotlin/XmlCombinators.kt @@ -183,13 +183,22 @@ class XmlDestructor internal constructor(private val el: Element) { inline fun <reified T : Enum<T>> enum(): T = java.lang.Enum.valueOf(T::class.java, text()) fun attr(index: String): String = el.getAttribute(index) -} -fun <T> destructXml(xml: InputStream, root: String, f: XmlDestructor.() -> T): T { - val doc = XMLUtil.parseIntoDom(xml) - if (doc.documentElement.tagName != root) { - throw DestructionError("expected root '$root' got '${doc.documentElement.tagName}'") + companion object { + fun <T> fromStream(xml: InputStream, root: String, f: XmlDestructor.() -> T): T { + val doc = XMLUtil.parseIntoDom(xml) + return fromDoc(doc, root, f) + } + + fun <T> fromDoc(doc: Document, root: String, f: XmlDestructor.() -> T): T { + if (doc.documentElement.tagName != root) { + throw DestructionError("expected root '$root' got '${doc.documentElement.tagName}'") + } + val destr = XmlDestructor(doc.documentElement) + return f(destr) + } } - val destr = XmlDestructor(doc.documentElement) - return f(destr) } + +fun <T> destructXml(xml: InputStream, root: String, f: XmlDestructor.() -> T): T + = XmlDestructor.fromStream(xml, root, f) diff --git a/ebics/src/main/kotlin/ebics_h005/Ebics3Request.kt b/ebics/src/main/kotlin/ebics_h005/Ebics3Request.kt deleted file mode 100644 index bc48fa6f..00000000 --- a/ebics/src/main/kotlin/ebics_h005/Ebics3Request.kt +++ /dev/null @@ -1,587 +0,0 @@ -package tech.libeufin.ebics.ebics_h005 - -import org.apache.xml.security.binding.xmldsig.SignatureType -import tech.libeufin.common.crypto.CryptoUtil -import java.math.BigInteger -import java.security.interfaces.RSAPublicKey -import java.util.* -import javax.xml.bind.annotation.* -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter -import javax.xml.bind.annotation.adapters.HexBinaryAdapter -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter -import javax.xml.datatype.XMLGregorianCalendar - -@XmlAccessorType(XmlAccessType.NONE) -@XmlType(name = "", propOrder = ["header", "authSignature", "body"]) -@XmlRootElement(name = "ebicsRequest") -class Ebics3Request { - @get:XmlAttribute(name = "Version", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var version: String - - @get:XmlAttribute(name = "Revision") - var revision: Int? = null - - @get:XmlElement(name = "header", required = true) - lateinit var header: Header - - @get:XmlElement(name = "AuthSignature", required = true) - lateinit var authSignature: SignatureType - - @get:XmlElement(name = "body") - lateinit var body: Body - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["static", "mutable"]) - class Header { - @get:XmlElement(name = "static", required = true) - lateinit var static: StaticHeaderType - - @get:XmlElement(required = true) - lateinit var mutable: MutableHeader - - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType( - name = "", - propOrder = [ - "hostID", "nonce", "timestamp", "partnerID", "userID", "systemID", - "product", "orderDetails", "bankPubKeyDigests", "securityMedium", - "numSegments", "transactionID" - ] - ) - class StaticHeaderType { - @get:XmlElement(name = "HostID", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var hostID: String - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "Nonce", type = String::class) - @get:XmlJavaTypeAdapter(HexBinaryAdapter::class) - @get:XmlSchemaType(name = "hexBinary") - var nonce: ByteArray? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "Timestamp") - @get:XmlSchemaType(name = "dateTime") - var timestamp: XMLGregorianCalendar? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "PartnerID") - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - var partnerID: String? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "UserID") - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - var userID: String? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "SystemID") - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - var systemID: String? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "Product") - var product: Ebics3Types.Product? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "OrderDetails") - var orderDetails: OrderDetails? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "BankPubKeyDigests") - var bankPubKeyDigests: BankPubKeyDigests? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "SecurityMedium") - var securityMedium: String? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElement(name = "NumSegments") - var numSegments: BigInteger? = null - - /** - * Present only in the transaction / finalization phase. - */ - @get:XmlElement(name = "TransactionID") - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - var transactionID: String? = null - } - - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["transactionPhase", "segmentNumber"]) - class MutableHeader { - @get:XmlElement(name = "TransactionPhase", required = true) - @get:XmlSchemaType(name = "token") - lateinit var transactionPhase: Ebics3Types.TransactionPhaseType - - /** - * Number of the currently transmitted segment, if this message - * contains order data. - */ - @get:XmlElement(name = "SegmentNumber") - var segmentNumber: Ebics3Types.SegmentNumber? = null - - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType( - name = "", - propOrder = ["adminOrderType", "btdOrderParams", "btuOrderParams", "orderID", "orderParams"] - ) - class OrderDetails { - @get:XmlElement(name = "AdminOrderType", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var adminOrderType: String - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(propOrder = ["serviceName", "scope", "serviceOption", "container", "messageName"]) - class Service { - @get:XmlElement(name = "ServiceName", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var serviceName: String - - @get:XmlElement(name = "Scope", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var scope: String - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["value"]) - class MessageName { - @XmlValue - lateinit var value: String - - @XmlAttribute(name = "version") - var version: String? = null - } - - @get:XmlElement(name = "MsgName", required = true) - lateinit var messageName: MessageName - - @get:XmlElement(name = "ServiceOption", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - var serviceOption: String? = null - - @XmlAccessorType(XmlAccessType.NONE) - class Container { - @XmlAttribute(name = "containerType") - lateinit var containerType: String - } - - @get:XmlElement(name = "Container", required = true) - var container: Container? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(propOrder = ["service", "signatureFlag", "dateRange"]) - class BTUOrderParams { - @get:XmlElement(name = "Service", required = true) - lateinit var service: Service - - /** - * This element activates the ES signature scheme (disabling - * hence the EDS). It *would* admit a @requestEDS attribute, - * but its omission means false. - */ - @get:XmlElement(name = "SignatureFlag", required = true) - var signatureFlag: Boolean = true - - @get:XmlElement(name = "DateRange", required = true) - var dateRange: DateRange? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(propOrder = ["service", "dateRange"]) - class BTDOrderParams { - @get:XmlElement(name = "Service", required = true) - lateinit var service: Service - - @get:XmlElement(name = "DateRange", required = true) - var dateRange: DateRange? = null - } - - @get:XmlElement(name = "BTUOrderParams", required = true) - var btuOrderParams: BTUOrderParams? = null - - @get:XmlElement(name = "BTDOrderParams", required = true) - var btdOrderParams: BTDOrderParams? = null - - /** - * Only present if this ebicsRequest is an upload order - * relating to an already existing order. - */ - @get:XmlElement(name = "OrderID", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - var orderID: String? = null - - /** - * Present only in the initialization phase. - */ - @get:XmlElements( - XmlElement( - name = "StandardOrderParams", - type = StandardOrderParams::class // OrderParams inheritor - ), - XmlElement( - name = "GenericOrderParams", - type = GenericOrderParams::class // OrderParams inheritor - ) - ) - // Same as the 2.5 version. - var orderParams: OrderParams? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(propOrder = ["preValidation", "dataTransfer", "transferReceipt"]) - class Body { - @get:XmlElement(name = "PreValidation") - var preValidation: PreValidation? = null - - @get:XmlElement(name = "DataTransfer") - var dataTransfer: DataTransfer? = null - - @get:XmlElement(name = "TransferReceipt") - var transferReceipt: TransferReceipt? = null - } - - /** - * FIXME: not implemented yet - */ - @XmlAccessorType(XmlAccessType.NONE) - class PreValidation { - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - } - - @XmlAccessorType(XmlAccessType.NONE) - class SignatureData { - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - - @get:XmlValue - var value: ByteArray? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(propOrder = ["dataEncryptionInfo", "signatureData", "dataDigest", "orderData", "hostId"]) - class DataTransfer { - - @get:XmlElement(name = "DataEncryptionInfo") - var dataEncryptionInfo: Ebics3Types.DataEncryptionInfo? = null - - @get:XmlElement(name = "SignatureData") - var signatureData: SignatureData? = null - - @XmlAccessorType(XmlAccessType.NONE) - class DataDigest { - @get:XmlAttribute(name = "SignatureVersion", required = true) - var signatureVersion: String = "A006" - - @get:XmlValue - var value: ByteArray? = null - } - - @get:XmlElement(name = "DataDigest") - var dataDigest: DataDigest? = null - - @get:XmlElement(name = "OrderData") - var orderData: String? = null - - @get:XmlElement(name = "HostID") - var hostId: String? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["receiptCode"]) - class TransferReceipt { - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - - @get:XmlElement(name = "ReceiptCode") - var receiptCode: Int? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - abstract class OrderParams - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["dateRange"]) - class StandardOrderParams : OrderParams() { - @get:XmlElement(name = "DateRange") - var dateRange: DateRange? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["parameterList"]) - class GenericOrderParams : OrderParams() { - @get:XmlElement(type = Ebics3Types.Parameter::class) - var parameterList: List<Ebics3Types.Parameter> = LinkedList() - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["start", "end"]) - class DateRange { - @get:XmlElement(name = "Start") - @get:XmlSchemaType(name = "date") - lateinit var start: XMLGregorianCalendar - - @get:XmlElement(name = "End") - @get:XmlSchemaType(name = "date") - lateinit var end: XMLGregorianCalendar - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["authentication", "encryption"]) - class BankPubKeyDigests { - @get:XmlElement(name = "Authentication") - lateinit var authentication: Ebics3Types.PubKeyDigest - - @get:XmlElement(name = "Encryption") - lateinit var encryption: Ebics3Types.PubKeyDigest - } - - companion object { - - fun createForDownloadReceiptPhase( - transactionId: String, - hostId: String, - success: Boolean - ): Ebics3Request { - return Ebics3Request().apply { - header = Header().apply { - version = "H005" - revision = 1 - authenticate = true - static = StaticHeaderType().apply { - hostID = hostId - transactionID = transactionId - } - mutable = MutableHeader().apply { - transactionPhase = Ebics3Types.TransactionPhaseType.RECEIPT - } - } - authSignature = SignatureType() - - body = Body().apply { - transferReceipt = TransferReceipt().apply { - authenticate = true - receiptCode = if (success) 0 else 1 - } - } - } - } - - fun createForDownloadInitializationPhase( - userId: String, - partnerId: String, - hostId: String, - nonceArg: ByteArray, - date: XMLGregorianCalendar, - bankEncPub: RSAPublicKey, - bankAuthPub: RSAPublicKey, - myOrderParams: OrderDetails.BTDOrderParams? - ): Ebics3Request { - return Ebics3Request().apply { - version = "H005" - revision = 1 - authSignature = SignatureType() - body = Body() - header = Header().apply { - authenticate = true - static = StaticHeaderType().apply { - userID = userId - partnerID = partnerId - hostID = hostId - nonce = nonceArg - timestamp = date - partnerID = partnerId - orderDetails = OrderDetails().apply { - this.adminOrderType = if (myOrderParams == null) "HAC" else "BTD" - this.btdOrderParams = myOrderParams - } - bankPubKeyDigests = BankPubKeyDigests().apply { - authentication = Ebics3Types.PubKeyDigest().apply { - algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" - version = "X002" - value = CryptoUtil.getEbicsPublicKeyHash(bankAuthPub) - } - encryption = Ebics3Types.PubKeyDigest().apply { - algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" - version = "E002" - value = CryptoUtil.getEbicsPublicKeyHash(bankEncPub) - } - securityMedium = "0000" - } - } - mutable = MutableHeader().apply { - transactionPhase = - Ebics3Types.TransactionPhaseType.INITIALISATION - } - } - } - } - - fun createForUploadInitializationPhase( - encryptedTransactionKey: ByteArray, - encryptedSignatureData: ByteArray, - aDataDigest: ByteArray, - hostId: String, - nonceArg: ByteArray, - partnerId: String, - userId: String, - date: XMLGregorianCalendar, - bankAuthPub: RSAPublicKey, - bankEncPub: RSAPublicKey, - segmentsNumber: BigInteger, - aOrderService: OrderDetails.Service, - ): Ebics3Request { - - return Ebics3Request().apply { - header = Header().apply { - version = "H005" - revision = 1 - authenticate = true - static = StaticHeaderType().apply { - hostID = hostId - nonce = nonceArg - timestamp = date - partnerID = partnerId - userID = userId - orderDetails = OrderDetails().apply { - this.adminOrderType = "BTU" - this.btuOrderParams = OrderDetails.BTUOrderParams().apply { - service = aOrderService - } - } - bankPubKeyDigests = BankPubKeyDigests().apply { - authentication = Ebics3Types.PubKeyDigest().apply { - algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" - version = "X002" - value = CryptoUtil.getEbicsPublicKeyHash(bankAuthPub) - } - encryption = Ebics3Types.PubKeyDigest().apply { - algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" - version = "E002" - value = CryptoUtil.getEbicsPublicKeyHash(bankEncPub) - } - } - securityMedium = "0000" - numSegments = segmentsNumber - } - mutable = MutableHeader().apply { - transactionPhase = - Ebics3Types.TransactionPhaseType.INITIALISATION - } - } - authSignature = SignatureType() - body = Body().apply { - dataTransfer = DataTransfer().apply { - signatureData = SignatureData().apply { - authenticate = true - value = encryptedSignatureData - } - dataDigest = DataTransfer.DataDigest().apply { - value = aDataDigest - } - dataEncryptionInfo = Ebics3Types.DataEncryptionInfo().apply { - transactionKey = encryptedTransactionKey - authenticate = true - encryptionPubKeyDigest = Ebics3Types.PubKeyDigest().apply { - algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" - version = "E002" - value = CryptoUtil.getEbicsPublicKeyHash(bankEncPub) - } - } - } - } - } - } - - fun createForUploadTransferPhase( - hostId: String, - transactionId: String?, - segNumber: BigInteger, - encryptedData: String - ): Ebics3Request { - return Ebics3Request().apply { - header = Header().apply { - version = "H005" - revision = 1 - authenticate = true - static = StaticHeaderType().apply { - hostID = hostId - transactionID = transactionId - } - mutable = MutableHeader().apply { - transactionPhase = Ebics3Types.TransactionPhaseType.TRANSFER - segmentNumber = Ebics3Types.SegmentNumber().apply { - lastSegment = true - value = segNumber - } - } - } - - authSignature = SignatureType() - body = Body().apply { - dataTransfer = DataTransfer().apply { - orderData = encryptedData - } - } - } - } - - fun createForDownloadTransferPhase( - hostID: String, - transactionID: String?, - segmentNumber: Int, - numSegments: Int - ): Ebics3Request { - return Ebics3Request().apply { - version = "H005" - revision = 1 - authSignature = SignatureType() - body = Body() - header = Header().apply { - authenticate = true - static = StaticHeaderType().apply { - this.hostID = hostID - this.transactionID = transactionID - } - mutable = MutableHeader().apply { - transactionPhase = - Ebics3Types.TransactionPhaseType.TRANSFER - this.segmentNumber = Ebics3Types.SegmentNumber().apply { - this.value = BigInteger.valueOf(segmentNumber.toLong()) - this.lastSegment = segmentNumber == numSegments - } - } - } - } - } - } -}
\ No newline at end of file diff --git a/ebics/src/main/kotlin/ebics_h005/Ebics3Response.kt b/ebics/src/main/kotlin/ebics_h005/Ebics3Response.kt deleted file mode 100644 index dd4b18a2..00000000 --- a/ebics/src/main/kotlin/ebics_h005/Ebics3Response.kt +++ /dev/null @@ -1,347 +0,0 @@ -package tech.libeufin.ebics.ebics_h005 - -import org.apache.xml.security.binding.xmldsig.SignatureType -import tech.libeufin.common.crypto.CryptoUtil -import tech.libeufin.ebics.ebics_h004.EbicsTypes -import java.math.BigInteger -import javax.xml.bind.annotation.* -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter -import javax.xml.bind.annotation.adapters.NormalizedStringAdapter -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter -import kotlin.math.min - -@XmlAccessorType(XmlAccessType.NONE) -@XmlType(name = "", propOrder = ["header", "authSignature", "body"]) -@XmlRootElement(name = "ebicsResponse") -class Ebics3Response { - @get:XmlAttribute(name = "Version", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var version: String - - @get:XmlAttribute(name = "Revision") - var revision: Int? = null - - @get:XmlElement(required = true) - lateinit var header: Header - - @get:XmlElement(name = "AuthSignature", required = true) - lateinit var authSignature: SignatureType - - @get:XmlElement(required = true) - lateinit var body: Body - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["_static", "mutable"]) - class Header { - @get:XmlElement(name = "static", required = true) - lateinit var _static: StaticHeaderType - - @get:XmlElement(required = true) - lateinit var mutable: MutableHeaderType - - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["dataTransfer", "returnCode", "timestampBankParameter"]) - class Body { - @get:XmlElement(name = "DataTransfer") - var dataTransfer: DataTransferResponseType? = null - - @get:XmlElement(name = "ReturnCode", required = true) - lateinit var returnCode: ReturnCode - - @get:XmlElement(name = "TimestampBankParameter") - var timestampBankParameter: EbicsTypes.TimestampBankParameter? = null - } - - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType( - name = "", - propOrder = ["transactionPhase", "segmentNumber", "orderID", "returnCode", "reportText"] - ) - class MutableHeaderType { - @get:XmlElement(name = "TransactionPhase", required = true) - @get:XmlSchemaType(name = "token") - lateinit var transactionPhase: EbicsTypes.TransactionPhaseType - - @get:XmlElement(name = "SegmentNumber") - var segmentNumber: EbicsTypes.SegmentNumber? = null - - @get:XmlElement(name = "OrderID") - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - @get:XmlSchemaType(name = "token") - var orderID: String? = null - - @get:XmlElement(name = "ReturnCode", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - @get:XmlSchemaType(name = "token") - lateinit var returnCode: String - - @get:XmlElement(name = "ReportText", required = true) - @get:XmlJavaTypeAdapter(NormalizedStringAdapter::class) - @get:XmlSchemaType(name = "normalizedString") - lateinit var reportText: String - } - - @XmlAccessorType(XmlAccessType.NONE) - class OrderData { - @get:XmlValue - lateinit var value: String - } - - @XmlAccessorType(XmlAccessType.NONE) - class ReturnCode { - @get:XmlValue - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var value: String - - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "DataTransferResponseType", propOrder = ["dataEncryptionInfo", "orderData"]) - class DataTransferResponseType { - @get:XmlElement(name = "DataEncryptionInfo") - var dataEncryptionInfo: Ebics3Types.DataEncryptionInfo? = null - - @get:XmlElement(name = "OrderData", required = true) - lateinit var orderData: OrderData - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "ResponseStaticHeaderType", propOrder = ["transactionID", "numSegments"]) - class StaticHeaderType { - @get:XmlElement(name = "TransactionID") - var transactionID: String? = null - - @get:XmlElement(name = "NumSegments") - @get:XmlSchemaType(name = "positiveInteger") - var numSegments: BigInteger? = null - } - - companion object { - - fun createForUploadWithError( - errorText: String, errorCode: String, phase: EbicsTypes.TransactionPhaseType - ): Ebics3Response { - val resp = Ebics3Response().apply { - this.version = "H005" - this.revision = 1 - this.header = Header().apply { - this.authenticate = true - this.mutable = MutableHeaderType().apply { - this.reportText = errorText - this.returnCode = errorCode - this.transactionPhase = phase - } - _static = StaticHeaderType() - } - this.authSignature = SignatureType() - this.body = Body().apply { - this.returnCode = ReturnCode().apply { - this.authenticate = true - this.value = errorCode - } - } - } - return resp - } - - fun createForUploadInitializationPhase(transactionID: String, orderID: String): Ebics3Response { - return Ebics3Response().apply { - this.version = "H005" - this.revision = 1 - this.header = Header().apply { - this.authenticate = true - this._static = StaticHeaderType().apply { - this.transactionID = transactionID - } - this.mutable = MutableHeaderType().apply { - this.transactionPhase = - EbicsTypes.TransactionPhaseType.INITIALISATION - this.orderID = orderID - this.reportText = "[EBICS_OK] OK" - this.returnCode = "000000" - } - } - this.authSignature = SignatureType() - this.body = Body().apply { - this.returnCode = ReturnCode().apply { - this.authenticate = true - this.value = "000000" - } - } - } - } - - fun createForDownloadReceiptPhase(transactionID: String, positiveAck: Boolean): Ebics3Response { - return Ebics3Response().apply { - this.version = "H005" - this.revision = 1 - this.header = Header().apply { - this.authenticate = true - this._static = StaticHeaderType().apply { - this.transactionID = transactionID - } - this.mutable = MutableHeaderType().apply { - this.transactionPhase = - EbicsTypes.TransactionPhaseType.RECEIPT - if (positiveAck) { - this.reportText = "[EBICS_DOWNLOAD_POSTPROCESS_DONE] Received positive receipt" - this.returnCode = "011000" - } else { - this.reportText = "[EBICS_DOWNLOAD_POSTPROCESS_SKIPPED] Received negative receipt" - this.returnCode = "011001" - } - } - } - this.authSignature = SignatureType() - this.body = Body().apply { - this.returnCode = ReturnCode().apply { - this.authenticate = true - this.value = "000000" - } - } - } - } - - fun createForUploadTransferPhase( - transactionID: String, - segmentNumber: Int, - lastSegment: Boolean, - orderID: String - ): Ebics3Response { - return Ebics3Response().apply { - this.version = "H005" - this.revision = 1 - this.header = Header().apply { - this.authenticate = true - this._static = StaticHeaderType().apply { - this.transactionID = transactionID - } - this.mutable = MutableHeaderType().apply { - this.transactionPhase = - EbicsTypes.TransactionPhaseType.TRANSFER - this.segmentNumber = EbicsTypes.SegmentNumber().apply { - this.value = BigInteger.valueOf(segmentNumber.toLong()) - if (lastSegment) { - this.lastSegment = true - } - } - this.orderID = orderID - this.reportText = "[EBICS_OK] OK" - this.returnCode = "000000" - } - } - this.authSignature = SignatureType() - this.body = Body().apply { - this.returnCode = ReturnCode().apply { - this.authenticate = true - this.value = "000000" - } - } - } - } - - /** - * @param requestedSegment requested segment as a 1-based index - */ - fun createForDownloadTransferPhase( - transactionID: String, - numSegments: Int, - segmentSize: Int, - encodedData: String, - requestedSegment: Int - ): Ebics3Response { - return Ebics3Response().apply { - this.version = "H005" - this.revision = 1 - this.header = Header().apply { - this.authenticate = true - this._static = StaticHeaderType().apply { - this.transactionID = transactionID - this.numSegments = BigInteger.valueOf(numSegments.toLong()) - } - this.mutable = MutableHeaderType().apply { - this.transactionPhase = - EbicsTypes.TransactionPhaseType.TRANSFER - this.segmentNumber = EbicsTypes.SegmentNumber().apply { - this.lastSegment = numSegments == requestedSegment - this.value = BigInteger.valueOf(requestedSegment.toLong()) - } - this.reportText = "[EBICS_OK] OK" - this.returnCode = "000000" - } - } - this.authSignature = SignatureType() - this.body = Body().apply { - this.returnCode = ReturnCode().apply { - this.authenticate = true - this.value = "000000" - } - this.dataTransfer = DataTransferResponseType().apply { - this.orderData = OrderData().apply { - val start = segmentSize * (requestedSegment - 1) - this.value = encodedData.substring(start, min(start + segmentSize, encodedData.length)) - } - } - } - } - } - fun createForDownloadInitializationPhase( - transactionID: String, - numSegments: Int, - segmentSize: Int, - enc: CryptoUtil.EncryptionResult, - encodedData: String - ): Ebics3Response { - return Ebics3Response().apply { - this.version = "H005" - this.revision = 1 - this.header = Header().apply { - this.authenticate = true - this._static = StaticHeaderType().apply { - this.transactionID = transactionID - this.numSegments = BigInteger.valueOf(numSegments.toLong()) - } - this.mutable = MutableHeaderType().apply { - this.transactionPhase = - EbicsTypes.TransactionPhaseType.INITIALISATION - this.segmentNumber = EbicsTypes.SegmentNumber().apply { - this.lastSegment = (numSegments == 1) - this.value = BigInteger.valueOf(1) - } - this.reportText = "[EBICS_OK] OK" - this.returnCode = "000000" - } - } - this.authSignature = SignatureType() - this.body = Body().apply { - this.returnCode = ReturnCode().apply { - this.authenticate = true - this.value = "000000" - } - this.dataTransfer = DataTransferResponseType().apply { - this.dataEncryptionInfo = Ebics3Types.DataEncryptionInfo().apply { - this.authenticate = true - this.encryptionPubKeyDigest = Ebics3Types.PubKeyDigest() - .apply { - this.algorithm = "http://www.w3.org/2001/04/xmlenc#sha256" - this.version = "E002" - this.value = enc.pubKeyDigest - } - this.transactionKey = enc.encryptedTransactionKey - } - this.orderData = OrderData().apply { - this.value = encodedData.substring(0, min(segmentSize, encodedData.length)) - } - } - } - } - } - } -} diff --git a/ebics/src/main/kotlin/ebics_h005/Ebics3Types.kt b/ebics/src/main/kotlin/ebics_h005/Ebics3Types.kt deleted file mode 100644 index a469217c..00000000 --- a/ebics/src/main/kotlin/ebics_h005/Ebics3Types.kt +++ /dev/null @@ -1,401 +0,0 @@ -/* - * This file is part of LibEuFin. - * Copyright (C) 2019 Stanisci and Dold. - - * LibEuFin 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, or - * (at your option) any later version. - - * LibEuFin 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 LibEuFin; see the file COPYING. If not, see - * <http://www.gnu.org/licenses/> - */ - -package tech.libeufin.ebics.ebics_h005 - -import org.apache.xml.security.binding.xmldsig.RSAKeyValueType -import org.w3c.dom.Element -import java.math.BigInteger -import java.util.* -import javax.xml.bind.annotation.* -import javax.xml.bind.annotation.adapters.CollapsedStringAdapter -import javax.xml.bind.annotation.adapters.NormalizedStringAdapter -import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter -import javax.xml.datatype.XMLGregorianCalendar - - -/** - * EBICS type definitions that are shared between other requests / responses / order types. - */ -object Ebics3Types { - /** - * EBICS client product. Identifies the software that accesses the EBICS host. - */ - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "Product", propOrder = ["value"]) - class Product { - @get:XmlValue - @get:XmlJavaTypeAdapter(NormalizedStringAdapter::class) - lateinit var value: String - - @get:XmlAttribute(name = "Language", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var language: String - - @get:XmlAttribute(name = "InstituteID") - @get:XmlJavaTypeAdapter(NormalizedStringAdapter::class) - var instituteID: String? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["value"]) - class SegmentNumber { - @XmlValue - lateinit var value: BigInteger - - @XmlAttribute(name = "lastSegment") - var lastSegment: Boolean? = null - } - - @XmlType(name = "", propOrder = ["encryptionPubKeyDigest", "transactionKey"]) - @XmlAccessorType(XmlAccessType.NONE) - class DataEncryptionInfo { - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - - @get:XmlElement(name = "EncryptionPubKeyDigest", required = true) - lateinit var encryptionPubKeyDigest: PubKeyDigest - - @get:XmlElement(name = "TransactionKey", required = true) - lateinit var transactionKey: ByteArray - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["value"]) - class PubKeyDigest { - /** - * Version of the *digest* of the public key. - */ - @get:XmlAttribute(name = "Version", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var version: String - - @XmlAttribute(name = "Algorithm", required = true) - @XmlSchemaType(name = "anyURI") - lateinit var algorithm: String - - @get:XmlValue - lateinit var value: ByteArray - } - - @Suppress("UNUSED_PARAMETER") - enum class TransactionPhaseType(value: String) { - @XmlEnumValue("Initialisation") - INITIALISATION("Initialisation"), - - /** - * Auftragsdatentransfer - * - */ - @XmlEnumValue("Transfer") - TRANSFER("Transfer"), - - /** - * Quittungstransfer - * - */ - @XmlEnumValue("Receipt") - RECEIPT("Receipt"); - } - - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "") - class TimestampBankParameter { - @get:XmlValue - lateinit var value: XMLGregorianCalendar - - @get:XmlAttribute(name = "authenticate", required = true) - var authenticate: Boolean = false - } - - - - @XmlType( - name = "PubKeyValueType", propOrder = [ - "rsaKeyValue", - "timeStamp" - ] - ) - @XmlAccessorType(XmlAccessType.NONE) - class PubKeyValueType { - @get:XmlElement(name = "RSAKeyValue", namespace = "http://www.w3.org/2000/09/xmldsig#", required = true) - lateinit var rsaKeyValue: RSAKeyValueType - - @get:XmlElement(name = "TimeStamp", required = false) - @get:XmlSchemaType(name = "dateTime") - var timeStamp: XMLGregorianCalendar? = null - } - - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType( - name = "AuthenticationPubKeyInfoType", propOrder = [ - "x509Data", - "pubKeyValue", - "authenticationVersion" - ] - ) - class AuthenticationPubKeyInfoType { - @get:XmlAnyElement() - var x509Data: Element? = null - - @get:XmlElement(name = "PubKeyValue", required = true) - lateinit var pubKeyValue: PubKeyValueType - - @get:XmlElement(name = "AuthenticationVersion", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - @get:XmlSchemaType(name = "token") - lateinit var authenticationVersion: String - } - - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType( - name = "EncryptionPubKeyInfoType", propOrder = [ - "x509Data", - "pubKeyValue", - "encryptionVersion" - ] - ) - class EncryptionPubKeyInfoType { - @get:XmlAnyElement() - var x509Data: Element? = null - - @get:XmlElement(name = "PubKeyValue", required = true) - lateinit var pubKeyValue: PubKeyValueType - - @get:XmlElement(name = "EncryptionVersion", required = true) - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - @get:XmlSchemaType(name = "token") - lateinit var encryptionVersion: String - } - - @XmlAccessorType(XmlAccessType.NONE) - class FileFormatType { - @get:XmlAttribute(name = "CountryCode") - @get:XmlJavaTypeAdapter(CollapsedStringAdapter::class) - lateinit var language: String - - @get:XmlValue - @get:XmlJavaTypeAdapter(NormalizedStringAdapter::class) - lateinit var value: String - } - - /** - * Generic key-value pair. - */ - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["name", "value"]) - class Parameter { - @get:XmlAttribute(name = "Type", required = true) - lateinit var type: String - - @get:XmlElement(name = "Name", required = true) - lateinit var name: String - - @get:XmlElement(name = "Value", required = true) - lateinit var value: String - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["addressInfo", "bankInfo", "accountInfoList", "orderInfoList"]) - class PartnerInfo { - @get:XmlElement(name = "AddressInfo", required = true) - lateinit var addressInfo: AddressInfo - - @get:XmlElement(name = "BankInfo", required = true) - lateinit var bankInfo: BankInfo - - @get:XmlElement(name = "AccountInfo", type = AccountInfo::class) - var accountInfoList: List<AccountInfo>? = LinkedList<AccountInfo>() - - @get:XmlElement(name = "OrderInfo", type = AuthOrderInfoType::class) - var orderInfoList: List<AuthOrderInfoType> = LinkedList<AuthOrderInfoType>() - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType( - name = "", - propOrder = ["orderType", "fileFormat", "transferType", "orderFormat", "description", "numSigRequired"] - ) - class AuthOrderInfoType { - @get:XmlElement(name = "OrderType") - lateinit var orderType: String - - @get:XmlElement(name = "FileFormat") - val fileFormat: FileFormatType? = null - - @get:XmlElement(name = "TransferType") - lateinit var transferType: String - - @get:XmlElement(name = "OrderFormat", required = false) - var orderFormat: String? = null - - @get:XmlElement(name = "Description") - lateinit var description: String - - @get:XmlElement(name = "NumSigRequired") - var numSigRequired: Int? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - class UserIDType { - @get:XmlValue - lateinit var value: String - - @get:XmlAttribute(name = "Status") - var status: Int? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["userID", "name", "permissionList"]) - class UserInfo { - @get:XmlElement(name = "UserID", required = true) - lateinit var userID: UserIDType - - @get:XmlElement(name = "Name") - var name: String? = null - - @get:XmlElement(name = "Permission", type = UserPermission::class) - var permissionList: List<UserPermission>? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["orderTypes", "fileFormat", "accountID", "maxAmount"]) - class UserPermission { - @get:XmlAttribute(name = "AuthorizationLevel") - var authorizationLevel: String? = null - - @get:XmlElement(name = "OrderTypes") - var orderTypes: String? = null - - @get:XmlElement(name = "FileFormat") - val fileFormat: FileFormatType? = null - - @get:XmlElement(name = "AccountID") - val accountID: String? = null - - @get:XmlElement(name = "MaxAmount") - val maxAmount: String? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["name", "street", "postCode", "city", "region", "country"]) - class AddressInfo { - @get:XmlElement(name = "Name") - var name: String? = null - - @get:XmlElement(name = "Street") - var street: String? = null - - @get:XmlElement(name = "PostCode") - var postCode: String? = null - - @get:XmlElement(name = "City") - var city: String? = null - - @get:XmlElement(name = "Region") - var region: String? = null - - @get:XmlElement(name = "Country") - var country: String? = null - } - - - @XmlAccessorType(XmlAccessType.NONE) - class BankInfo { - @get:XmlElement(name = "HostID") - lateinit var hostID: String - - @get:XmlElement(type = Parameter::class) - var parameters: List<Parameter>? = null - } - - @XmlAccessorType(XmlAccessType.NONE) - @XmlType(name = "", propOrder = ["accountNumberList", "bankCodeList", "accountHolder"]) - class AccountInfo { - @get:XmlAttribute(name = "Currency") - var currency: String? = null - - @get:XmlAttribute(name = "ID") - lateinit var id: String - - @get:XmlAttribute(name = "Description") - var description: String? = null - - @get:XmlElements( - XmlElement(name = "AccountNumber", type = GeneralAccountNumber::class), - XmlElement(name = "NationalAccountNumber", type = NationalAccountNumber::class) - ) - var accountNumberList: List<AbstractAccountNumber>? = LinkedList<AbstractAccountNumber>() - - @get:XmlElements( - XmlElement(name = "BankCode", type = GeneralBankCode::class), - XmlElement(name = "NationalBankCode", type = NationalBankCode::class) - ) - var bankCodeList: List<AbstractBankCode>? = LinkedList<AbstractBankCode>() - - @get:XmlElement(name = "AccountHolder") - var accountHolder: String? = null - } - - interface AbstractAccountNumber - - @XmlAccessorType(XmlAccessType.NONE) - class GeneralAccountNumber : AbstractAccountNumber { - @get:XmlAttribute(name = "international") - var international: Boolean = true - - @get:XmlValue - lateinit var value: String - } - - @XmlAccessorType(XmlAccessType.NONE) - class NationalAccountNumber : AbstractAccountNumber { - @get:XmlAttribute(name = "format") - lateinit var format: String - - @get:XmlValue - lateinit var value: String - } - - interface AbstractBankCode - - @XmlAccessorType(XmlAccessType.NONE) - class GeneralBankCode : AbstractBankCode { - @get:XmlAttribute(name = "prefix") - var prefix: String? = null - - @get:XmlAttribute(name = "international") - var international: Boolean = true - - @get:XmlValue - lateinit var value: String - } - - @XmlAccessorType(XmlAccessType.NONE) - class NationalBankCode : AbstractBankCode { - @get:XmlValue - lateinit var value: String - - @get:XmlAttribute(name = "format") - lateinit var format: String - } -}
\ No newline at end of file diff --git a/ebics/src/main/kotlin/ebics_h005/package-info.java b/ebics/src/main/kotlin/ebics_h005/package-info.java deleted file mode 100644 index a5e16343..00000000 --- a/ebics/src/main/kotlin/ebics_h005/package-info.java +++ /dev/null @@ -1,13 +0,0 @@ -/** - * This package-info.java file defines the default namespace for the JAXB bindings - * defined in the package. - */ - -@XmlSchema( - namespace = "urn:org:ebics:H005", - elementFormDefault = XmlNsForm.QUALIFIED -) -package tech.libeufin.ebics.ebics_h005; - -import javax.xml.bind.annotation.XmlNsForm; -import javax.xml.bind.annotation.XmlSchema;
\ No newline at end of file diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt index f42f2571..def32a62 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt @@ -28,7 +28,6 @@ import io.ktor.client.plugins.* import kotlinx.coroutines.* import tech.libeufin.common.* import tech.libeufin.ebics.* -import tech.libeufin.ebics.ebics_h005.Ebics3Request import tech.libeufin.nexus.ebics.* import java.io.IOException import java.io.InputStream diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt index b4ff4877..f2d8c35c 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt @@ -22,7 +22,6 @@ import io.ktor.client.* import tech.libeufin.ebics.* import tech.libeufin.common.* import tech.libeufin.common.crypto.* -import tech.libeufin.ebics.ebics_h005.Ebics3Request import tech.libeufin.nexus.BankPublicKeysFile import tech.libeufin.nexus.ClientPrivateKeysFile import tech.libeufin.nexus.EbicsSetupConfig @@ -45,6 +44,19 @@ import javax.xml.datatype.DatatypeFactory fun Instant.xmlDate(): String = DateTimeFormatter.ISO_DATE.withZone(ZoneId.of("UTC")).format(this) fun Instant.xmlDateTime(): String = DateTimeFormatter.ISO_OFFSET_DATE_TIME.withZone(ZoneId.of("UTC")).format(this) +data class Ebics3Service( + val name: String, + val scope: String, + val messageName: String, + val messageVersion: String, + val container: String? +) + +data class Ebics3Order( + val type: String, + val service: Ebics3Service +) + class Ebics3Impl( private val cfg: EbicsSetupConfig, private val bankKeys: BankPublicKeysFile, @@ -69,7 +81,7 @@ class Ebics3Impl( return XMLUtil.convertDomToBytes(doc) } - fun uploadInitialization(preparedUploadData: PreparedUploadData): ByteArray { + fun uploadInitialization(service: Ebics3Service, preparedUploadData: PreparedUploadData): ByteArray { val nonce = getNonce(128) return signedRequest { el("header") { @@ -86,11 +98,11 @@ class Ebics3Impl( el("AdminOrderType", "BTU") el("BTUOrderParams") { el("Service") { - el("ServiceName", "MCT") - el("Scope", "CH") + el("ServiceName", service.name) + el("Scope", service.scope) el("MsgName") { - attr("version", "09") - text("pain.001") + attr("version", service.messageVersion) + text(service.messageName) } } el("SignatureFlag", "true") @@ -314,20 +326,19 @@ suspend fun submitPain001( bankkeys: BankPublicKeysFile, httpClient: HttpClient ): String { - val orderService: Ebics3Request.OrderDetails.Service = Ebics3Request.OrderDetails.Service().apply { - serviceName = "MCT" - scope = "CH" - messageName = Ebics3Request.OrderDetails.Service.MessageName().apply { - value = "pain.001" - version = "09" - } - } + val service = Ebics3Service( + name = "MCT", + scope = "CH", + messageName = "pain.001", + messageVersion = "09", + container = null + ) val maybeUploaded = doEbicsUpload( httpClient, cfg, clientKeys, bankkeys, - orderService, + service, pain001xml.toByteArray(Charsets.UTF_8), ) logger.debug("Payment submitted, report text is: ${maybeUploaded.reportText}," + diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt index 490156bb..157e53b2 100644 --- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt +++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt @@ -46,7 +46,6 @@ import io.ktor.utils.io.jvm.javaio.* import tech.libeufin.common.* import tech.libeufin.common.crypto.* import tech.libeufin.ebics.* -import tech.libeufin.ebics.ebics_h005.Ebics3Request import tech.libeufin.nexus.* import java.io.ByteArrayOutputStream import java.io.InputStream @@ -507,13 +506,13 @@ suspend fun doEbicsUpload( cfg: EbicsSetupConfig, clientKeys: ClientPrivateKeysFile, bankKeys: BankPublicKeysFile, - orderService: Ebics3Request.OrderDetails.Service, + service: Ebics3Service, payload: ByteArray, ): EbicsResponseContent = withContext(NonCancellable) { val impl = Ebics3Impl(cfg, bankKeys, clientKeys) // TODO use a lambda and pass the order detail there for atomicity ? val preparedPayload = prepareUploadPayload(cfg, clientKeys, bankKeys, payload) - val initXml = impl.uploadInitialization(preparedPayload) + val initXml = impl.uploadInitialization(service, preparedPayload) val initResp = postEbics( // may throw EbicsEarlyException client, cfg, |