summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAntoine A <>2024-03-07 12:33:23 +0100
committerAntoine A <>2024-03-07 12:33:23 +0100
commitff7e7905f53e4a6b7f82a9a9c64694fd5b323d1a (patch)
tree76478258a826ea3f392e8027c39e2df7f9995ed5
parent4044e69399c8c911dd926c4f8d4164964a08e0f0 (diff)
downloadlibeufin-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.kt80
-rw-r--r--ebics/src/main/kotlin/XmlCombinators.kt23
-rw-r--r--ebics/src/main/kotlin/ebics_h005/Ebics3Request.kt587
-rw-r--r--ebics/src/main/kotlin/ebics_h005/Ebics3Response.kt347
-rw-r--r--ebics/src/main/kotlin/ebics_h005/Ebics3Types.kt401
-rw-r--r--ebics/src/main/kotlin/ebics_h005/package-info.java13
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt1
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt41
-rw-r--r--nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt5
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,