libeufin

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

commit 1c58a511f1e13db3b9267706e1937d4757349a1f
parent 2a438b1e515e2dffff379c59d6e21026b5cc7294
Author: ms <ms@taler.net>
Date:   Sat, 13 Nov 2021 07:52:07 +0100

fixes after wallet harness tests

- avoid having default values for withdrawal 'abort'

- define dedicate exception for EBICS_NO_DOWNLOAD_DATA_AVAILABLE,
  so as to avoid throwing stack traces when Camt has a void history

Diffstat:
Msandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 43++++++++++++++++++++++++++++++++++++++-----
Msandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt | 2+-
Msandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt | 30++++++------------------------
3 files changed, 45 insertions(+), 30 deletions(-)

diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -20,7 +20,7 @@ package tech.libeufin.sandbox -import io.ktor.application.ApplicationCall +import io.ktor.application.* import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode import io.ktor.request.receiveText @@ -73,6 +73,11 @@ open class EbicsRequestError( val errorCode: String ) : Exception("EBICS request error: $errorText ($errorCode)") +class EbicsNoDownloadDataAvailable(camtType: Int) : EbicsRequestError( + "[EBICS_NO_DOWNLOAD_DATA_AVAILABLE] for Camt $camtType", + "090005" +) + class EbicsInvalidRequestError : EbicsRequestError( "[EBICS_INVALID_REQUEST] Invalid request", "060102" @@ -114,6 +119,36 @@ class EbicsProcessingError(detail: String) : EbicsRequestError( "091116" ) +suspend fun respondEbicsTransfer( + call: ApplicationCall, + errorText: String, + errorCode: String +) { + val resp = EbicsResponse.createForUploadWithError( + errorText, + errorCode, + // For now, phase gets hard-coded as TRANSFER, + // because errors during initialization should have + // already been caught by the chunking logic. + EbicsTypes.TransactionPhaseType.TRANSFER + ) + val hostAuthPriv = transaction { + val host = EbicsHostEntity.find { + EbicsHostsTable.hostID.upperCase() eq call.attributes[EbicsHostIdAttribute] + .uppercase() + }.firstOrNull() ?: throw SandboxError( + io.ktor.http.HttpStatusCode.InternalServerError, + "Requested Ebics host ID not found." + ) + CryptoUtil.loadRsaPrivateKey(host.authenticationPrivateKey.bytes) + } + call.respondText( + signEbicsResponse(resp, hostAuthPriv), + ContentType.Application.Xml, + HttpStatusCode.OK + ) +} + private suspend fun ApplicationCall.respondEbicsKeyManagement( errorText: String, errorCode: String, @@ -549,10 +584,8 @@ private fun constructCamtResponse( } } } - if (ret.size == 0) throw EbicsRequestError( - "[EBICS_NO_DOWNLOAD_DATA_AVAILABLE] as Camt $type", - "090005" - ) + if (ret.size == 0) throw EbicsNoDownloadDataAvailable(type) + return ret } diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt @@ -123,7 +123,7 @@ data class TalerWithdrawalStatus( val wire_types: List<String> = listOf("iban"), val suggested_exchange: String? = null, val sender_wire: String? = null, - val aborted: Boolean = false, + val aborted: Boolean ) data class TalerWithdrawalSelection( diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt @@ -477,29 +477,7 @@ val sandboxApp: Application.() -> Unit = { } exception<EbicsRequestError> { e -> logger.debug("Handling EbicsRequestError: $e") - val resp = tech.libeufin.util.ebics_h004.EbicsResponse.createForUploadWithError( - e.errorText, - e.errorCode, - // assuming that the phase is always transfer, - // as errors during initialization should have - // already been caught by the chunking logic. - tech.libeufin.util.ebics_h004.EbicsTypes.TransactionPhaseType.TRANSFER - ) - val hostAuthPriv = transaction { - val host = EbicsHostEntity.find { - EbicsHostsTable.hostID.upperCase() eq call.attributes.get(tech.libeufin.sandbox.EbicsHostIdAttribute) - .uppercase() - }.firstOrNull() ?: throw SandboxError( - io.ktor.http.HttpStatusCode.InternalServerError, - "Requested Ebics host ID not found." - ) - CryptoUtil.loadRsaPrivateKey(host.authenticationPrivateKey.bytes) - } - call.respondText( - XMLUtil.signEbicsResponse(resp, hostAuthPriv), - ContentType.Application.Xml, - HttpStatusCode.OK - ) + respondEbicsTransfer(call, e.errorText, e.errorCode) } exception<Throwable> { cause -> logger.error("Exception while handling '${call.request.uri}'", cause) @@ -938,6 +916,9 @@ val sandboxApp: Application.() -> Unit = { else -> throw EbicsProcessingError("Unknown LibEuFin error code: ${e.errorCode}.") } } + catch (e: EbicsNoDownloadDataAvailable) { + respondEbicsTransfer(call, e.errorText, e.errorCode) + } catch (e: EbicsRequestError) { logger.error(e) // Preventing the last catch-all block @@ -1082,7 +1063,8 @@ val sandboxApp: Application.() -> Unit = { selection_done = wo.selectionDone, transfer_done = wo.confirmationDone, amount = "${demobank.currency}:${wo.amount}", - suggested_exchange = demobank.suggestedExchangeBaseUrl + suggested_exchange = demobank.suggestedExchangeBaseUrl, + aborted = wo.aborted ) call.respond(ret) return@get