libeufin

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

commit dd9869d57f8bb310927c8827aa4f921b94c6ec20
parent 4f5778e01dd7f56b4e22408cd4543b342d9d4a70
Author: Marcello Stanisci <ms@taler.net>
Date:   Thu, 30 Apr 2020 15:32:59 +0200

HTD response content comes from DB now.

Diffstat:
Mintegration-tests/test-ebics.py | 2++
Msandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt | 2++
Msandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 221++++++++++++++++++++++++++++---------------------------------------------------
Msandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt | 9+++++++++
Msandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt | 3++-
5 files changed, 92 insertions(+), 145 deletions(-)

diff --git a/integration-tests/test-ebics.py b/integration-tests/test-ebics.py @@ -38,6 +38,7 @@ EBICS_VERSION = "H004" SUBSCRIBER_IBAN="GB33BUKB20201555555555" SUBSCRIBER_BIC="BUKBGB22" SUBSCRIBER_NAME="Oliver Smith" +BANK_ACCOUNT_LABEL="savings" #0.a resp = post( @@ -74,6 +75,7 @@ resp = post( iban=SUBSCRIBER_IBAN, bic=SUBSCRIBER_BIC, name=SUBSCRIBER_NAME + label=BANK_ACCOUNT_LABEL ) ) diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt @@ -253,6 +253,7 @@ object BankAccountsTable : IntIdTable() { val iban = text("iban") val bic = text("bic") val name = text("name") + val label = text("label") val subscriber = reference("subscriber", EbicsSubscribersTable) } class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) { @@ -260,6 +261,7 @@ class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) { var iban by BankAccountsTable.iban var bic by BankAccountsTable.bic var name by BankAccountsTable.name + var label by BankAccountsTable.label var subscriber by EbicsSubscriberEntity referencedOn BankAccountsTable.subscriber } diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -50,6 +50,7 @@ import java.util.zip.InflaterInputStream import javax.sql.rowset.serial.SerialBlob import javax.xml.datatype.DatatypeFactory import org.apache.commons.compress.utils.IOUtils +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.joda.time.DateTime import org.joda.time.Instant import java.io.BufferedInputStream @@ -634,86 +635,79 @@ private suspend fun ApplicationCall.receiveEbicsXml(): Document { return requestDocument } -fun handleEbicsHtd(): ByteArray { - val htd = HTDResponseOrderData().apply { - this.partnerInfo = EbicsTypes.PartnerInfo().apply { - this.accountInfoList = listOf( - EbicsTypes.AccountInfo().apply { - this.id = "acctid1" - this.accountHolder = "Mina Musterfrau" - this.accountNumberList = listOf( - EbicsTypes.GeneralAccountNumber().apply { - this.international = true - this.value = "DE21500105174751659277" - } - ) - this.currency = "EUR" - this.description = "ACCT" - this.bankCodeList = listOf( - EbicsTypes.GeneralBankCode().apply { - this.international = true - this.value = "INGDDEFFXXX" - } - ) - }, - EbicsTypes.AccountInfo().apply { - this.id = "glsdemo" - this.accountHolder = "Mina Musterfrau" - this.accountNumberList = listOf( - EbicsTypes.GeneralAccountNumber().apply { - this.international = true - this.value = "DE91430609670123123123" - } - ) - this.currency = "EUR" - this.description = "glsdemoacct" - this.bankCodeList = listOf( - EbicsTypes.GeneralBankCode().apply { - this.international = true - this.value = "GENODEM1GLS" - } - ) - } - ) - this.addressInfo = EbicsTypes.AddressInfo().apply { - this.name = "Foo" - } - this.bankInfo = EbicsTypes.BankInfo().apply { - this.hostID = "host01" +private fun makePartnerInfo(subscriber: EbicsSubscriberEntity): EbicsTypes.PartnerInfo { + val bankAccount = getBankAccountFromSubscriber(subscriber) + return EbicsTypes.PartnerInfo().apply { + this.accountInfoList = listOf( + EbicsTypes.AccountInfo().apply { + this.id = bankAccount.label + this.accountHolder = bankAccount.name + this.accountNumberList = listOf( + EbicsTypes.GeneralAccountNumber().apply { + this.international = true + this.value = bankAccount.iban + } + ) + this.currency = "EUR" + this.description = "Ordinary Bank Account" + this.bankCodeList = listOf( + EbicsTypes.GeneralBankCode().apply { + this.international = true + this.value = bankAccount.bic + } + ) } - this.orderInfoList = listOf( - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo1" - this.orderType = "C53" - this.transferType = "Download" - }, - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo2" - this.orderType = "C52" - this.transferType = "Download" - }, - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo3" - this.orderType = "CCC" - this.transferType = "Upload" - }, - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo4" - this.orderType = "VMK" - this.transferType = "Download" - }, - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo5" - this.orderType = "STA" - this.transferType = "Download" - } - ) + ) + this.addressInfo = EbicsTypes.AddressInfo().apply { + this.name = "Address Info Object" + } + this.bankInfo = EbicsTypes.BankInfo().apply { + this.hostID = subscriber.hostId } + this.orderInfoList = listOf( + EbicsTypes.AuthOrderInfoType().apply { + this.description = "Transactions statement" + this.orderType = "C53" + this.transferType = "Download" + }, + EbicsTypes.AuthOrderInfoType().apply { + this.description = "Transactions report" + this.orderType = "C52" + this.transferType = "Download" + }, + EbicsTypes.AuthOrderInfoType().apply { + this.description = "Payment initiation (ZIPped payload)" + this.orderType = "CCC" + this.transferType = "Upload" + }, + EbicsTypes.AuthOrderInfoType().apply { + this.description = "Payment initiation (plain text payload)" + this.orderType = "CCT" + this.transferType = "Upload" + }, + EbicsTypes.AuthOrderInfoType().apply { + this.description = "vmk" + this.orderType = "VMK" + this.transferType = "Download" + }, + EbicsTypes.AuthOrderInfoType().apply { + this.description = "sta" + this.orderType = "STA" + this.transferType = "Download" + } + ) + } +} + +private fun handleEbicsHtd(requestContext: RequestContext): ByteArray { + val bankAccount = getBankAccountFromSubscriber(requestContext.subscriber) + val htd = HTDResponseOrderData().apply { + this.partnerInfo = makePartnerInfo(requestContext.subscriber) this.userInfo = EbicsTypes.UserInfo().apply { this.name = "Some User" this.userID = EbicsTypes.UserIDType().apply { this.status = 5 - this.value = "USER1" + this.value = requestContext.subscriber.userId } this.permissionList = listOf( EbicsTypes.UserPermission().apply { @@ -727,78 +721,15 @@ fun handleEbicsHtd(): ByteArray { return str.toByteArray() } - -fun handleEbicsHkd(): ByteArray { +private fun handleEbicsHkd(requestContext: RequestContext): ByteArray { val hkd = HKDResponseOrderData().apply { - this.partnerInfo = EbicsTypes.PartnerInfo().apply { - this.accountInfoList = listOf( - EbicsTypes.AccountInfo().apply { - this.id = "acctid1" - this.accountHolder = "Mina Musterfrau" - this.accountNumberList = listOf( - EbicsTypes.GeneralAccountNumber().apply { - this.international = true - this.value = "DE21500105174751659277" - } - ) - this.currency = "EUR" - this.description = "ACCT" - this.bankCodeList = listOf( - EbicsTypes.GeneralBankCode().apply { - this.international = true - this.value = "INGDDEFFXXX" - } - ) - }, - EbicsTypes.AccountInfo().apply { - this.id = "glsdemo" - this.accountHolder = "Mina Musterfrau" - this.accountNumberList = listOf( - EbicsTypes.GeneralAccountNumber().apply { - this.international = true - this.value = "DE91430609670123123123" - } - ) - this.currency = "EUR" - this.description = "glsdemoacct" - this.bankCodeList = listOf( - EbicsTypes.GeneralBankCode().apply { - this.international = true - this.value = "GENODEM1GLS" - } - ) - } - ) - this.addressInfo = EbicsTypes.AddressInfo().apply { - this.name = "Foo" - } - this.bankInfo = EbicsTypes.BankInfo().apply { - this.hostID = "host01" - } - this.orderInfoList = listOf( - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo" - this.orderType = "C53" - this.transferType = "Download" - }, - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo" - this.orderType = "C52" - this.transferType = "Download" - }, - EbicsTypes.AuthOrderInfoType().apply { - this.description = "foo" - this.orderType = "CCC" - this.transferType = "Upload" - } - ) - } + this.partnerInfo = makePartnerInfo(requestContext.subscriber) this.userInfoList = listOf( EbicsTypes.UserInfo().apply { this.name = "Some User" this.userID = EbicsTypes.UserIDType().apply { this.status = 1 - this.value = "USER1" + this.value = requestContext.subscriber.userId } this.permissionList = listOf( EbicsTypes.UserPermission().apply { @@ -832,8 +763,8 @@ private fun handleEbicsDownloadTransactionInitialization(requestContext: Request requestContext.requestObject.header.static.orderDetails?.orderType ?: throw EbicsInvalidRequestError() println("handling initialization for order type $orderType") val response = when (orderType) { - "HTD" -> handleEbicsHtd() - "HKD" -> handleEbicsHkd() + "HTD" -> handleEbicsHtd(requestContext) + "HKD" -> handleEbicsHkd(requestContext) /* Temporarily handling C52/C53 with same logic */ "C53" -> handleEbicsC53(requestContext) "TSD" -> handleEbicsTSD(requestContext) @@ -1048,7 +979,6 @@ private fun makeReqestContext(requestObject: EbicsRequest): RequestContext { ) } - suspend fun ApplicationCall.ebicsweb() { val requestDocument = receiveEbicsXml() @@ -1140,7 +1070,10 @@ suspend fun ApplicationCall.ebicsweb() { LOGGER.info("Unknown message, just logging it!") respond( HttpStatusCode.NotImplemented, - SandboxError("Not Implemented") + SandboxError( + HttpStatusCode.NotImplemented, + "Not Implemented" + ) ) } } diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt @@ -1,9 +1,18 @@ package tech.libeufin.sandbox import io.ktor.http.HttpStatusCode +import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.transactions.transaction +fun getBankAccountFromSubscriber(subscriber: EbicsSubscriberEntity): BankAccountEntity { + return transaction { + BankAccountEntity.find(BankAccountsTable.subscriber eq subscriber.id) + }.firstOrNull() ?: throw SandboxError( + HttpStatusCode.NotFound, + "Subscriber doesn't have any bank account" + ) +} fun getEbicsSubscriberFromDetails(userID: String, partnerID: String, hostID: String): EbicsSubscriberEntity { return transaction { EbicsSubscriberEntity.find { diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt @@ -62,5 +62,6 @@ data class BankAccountRequest( val subscriber: EbicsSubscriberElement, val iban: String, val bic: String, - val name: String + val name: String, + val label: String )