libeufin

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

commit f81d6bd521ce29b0e801703da7a635c0390a9df3
parent b86b5a2fd7e13adeaa5d49f7ee459a584730b30e
Author: Florian Dold <florian.dold@gmail.com>
Date:   Mon, 15 Jun 2020 20:47:07 +0530

fix EBICS subscriber state transition at sandbox

Diffstat:
Mintegration-tests/start-testenv.py | 2--
Mnexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt | 2+-
Msandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 37+++++++++++++++++++++++++++++++------
3 files changed, 32 insertions(+), 9 deletions(-)

diff --git a/integration-tests/start-testenv.py b/integration-tests/start-testenv.py @@ -201,7 +201,6 @@ assertResponse( assertResponse( post( f"http://localhost:5001/bank-accounts/{BANK_ACCOUNT_LABEL}/fetch-transactions", - json=dict(), headers=dict(Authorization=USER_AUTHORIZATION_HEADER), ) ) @@ -249,7 +248,6 @@ assertResponse( assertResponse( post( f"http://localhost:5001/bank-accounts/{BANK_ACCOUNT_LABEL}/fetch-transactions", - json=dict(), headers=dict(Authorization=USER_AUTHORIZATION_HEADER), ) ) diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsNexus.kt @@ -289,7 +289,7 @@ fun Route.ebicsBankConnectionRoutes(client: HttpClient) { */ post("/import-accounts") { val subscriberDetails = transaction { - val user = authenticateRequest(call.request) + authenticateRequest(call.request) val conn = requireBankConnection(call, "connid") if (conn.type != "ebics") { throw NexusError(HttpStatusCode.BadRequest, "bank connection is not of type 'ebics'") diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -537,12 +537,20 @@ private suspend fun ApplicationCall.handleEbicsHia(header: EbicsUnsecuredRequest val encPub = CryptoUtil.loadRsaPublicKeyFromComponents(encPubXml.modulus, encPubXml.exponent) val authPub = CryptoUtil.loadRsaPublicKeyFromComponents(authPubXml.modulus, authPubXml.exponent) - transaction { + val ok = transaction { val ebicsSubscriber = findEbicsSubscriber(header.static.partnerID, header.static.userID, header.static.systemID) if (ebicsSubscriber == null) { LOGGER.warn("ebics subscriber not found") throw EbicsInvalidRequestError() } + when (ebicsSubscriber.state) { + SubscriberState.NEW -> {} + SubscriberState.PARTIALLY_INITIALIZED_INI -> {} + SubscriberState.PARTIALLY_INITIALIZED_HIA, SubscriberState.INITIALIZED, SubscriberState.READY -> { + return@transaction false + } + } + ebicsSubscriber.authenticationKey = EbicsSubscriberPublicKeyEntity.new { this.rsaPublicKey = ExposedBlob(authPub.encoded) state = KeyState.NEW @@ -554,10 +562,15 @@ private suspend fun ApplicationCall.handleEbicsHia(header: EbicsUnsecuredRequest ebicsSubscriber.state = when (ebicsSubscriber.state) { SubscriberState.NEW -> SubscriberState.PARTIALLY_INITIALIZED_HIA SubscriberState.PARTIALLY_INITIALIZED_INI -> SubscriberState.INITIALIZED - else -> ebicsSubscriber.state + else -> throw Exception("internal invariant failed") } + return@transaction true + } + if (ok) { + respondEbicsKeyManagement("[EBICS_OK]", "000000", "000000") + } else { + respondEbicsKeyManagement("[EBICS_INVALID_USER_OR_USER_STATE]", "091002", "000000") } - respondEbicsKeyManagement("[EBICS_OK]", "000000", "000000") } @@ -571,13 +584,20 @@ private suspend fun ApplicationCall.handleEbicsIni(header: EbicsUnsecuredRequest val sigPubXml = keyObject.signaturePubKeyInfo.pubKeyValue.rsaKeyValue val sigPub = CryptoUtil.loadRsaPublicKeyFromComponents(sigPubXml.modulus, sigPubXml.exponent) - transaction { + val ok = transaction { val ebicsSubscriber = findEbicsSubscriber(header.static.partnerID, header.static.userID, header.static.systemID) if (ebicsSubscriber == null) { LOGGER.warn("ebics subscriber ('${header.static.partnerID}' / '${header.static.userID}' / '${header.static.systemID}') not found") throw EbicsInvalidRequestError() } + when (ebicsSubscriber.state) { + SubscriberState.NEW -> {} + SubscriberState.PARTIALLY_INITIALIZED_HIA -> {} + SubscriberState.PARTIALLY_INITIALIZED_INI, SubscriberState.INITIALIZED, SubscriberState.READY -> { + return@transaction false + } + } ebicsSubscriber.signatureKey = EbicsSubscriberPublicKeyEntity.new { this.rsaPublicKey = ExposedBlob(sigPub.encoded) state = KeyState.NEW @@ -585,11 +605,16 @@ private suspend fun ApplicationCall.handleEbicsIni(header: EbicsUnsecuredRequest ebicsSubscriber.state = when (ebicsSubscriber.state) { SubscriberState.NEW -> SubscriberState.PARTIALLY_INITIALIZED_INI SubscriberState.PARTIALLY_INITIALIZED_HIA -> SubscriberState.INITIALIZED - else -> ebicsSubscriber.state + else -> throw Error("internal invariant failed") } + return@transaction true } LOGGER.info("Signature key inserted in database _and_ subscriber state changed accordingly") - respondEbicsKeyManagement("[EBICS_OK]", "000000", bankReturnCode = "000000", orderId = "OR01") + if (ok) { + respondEbicsKeyManagement("[EBICS_OK]", "000000", "000000") + } else { + respondEbicsKeyManagement("[EBICS_INVALID_USER_OR_USER_STATE]", "091002", "000000") + } } private suspend fun ApplicationCall.handleEbicsHpb(