libeufin

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

commit fcd692b9cd2754a31ad5a9672767509f7a202ec6
parent 15977a23724d993e6dc01d55b0947e5f20a91085
Author: Florian Dold <florian.dold@gmail.com>
Date:   Tue,  4 Feb 2020 16:39:58 +0100

wip

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 99+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----
Msandbox/src/main/python/libeufin-cli | 44+++++++++++++++++++++++++++++++++++++++++++-
Mutil/src/main/kotlin/ebics_h004/EbicsRequest.kt | 1-
3 files changed, 138 insertions(+), 6 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt @@ -140,7 +140,6 @@ fun main() { call.respondText("Bad backup, or passphrase incorrect\n", ContentType.Text.Plain, HttpStatusCode.BadRequest) } - exception<UnparsableResponse> { cause -> logger.error("Exception while handling '${call.request.uri}'", cause) call.respondText("Could not parse bank response (${cause.message})\n", ContentType.Text.Plain, HttpStatusCode @@ -192,6 +191,77 @@ fun main() { call.respondText("Hello by Nexus!\n") return@get } + + post("/ebics/subscribers/{id}/sendPTK") { + val id = expectId(call.parameters["id"]) + val subscriberData = transaction { + containerInit( + EbicsSubscriberEntity.findById( + id + ) ?: throw SubscriberNotFoundError( + HttpStatusCode.NotFound + ) + ) + } + val response = client.postToBankSigned<EbicsRequest, EbicsResponse>( + subscriberData.ebicsUrl, + createDownloadInitializationPhase( + subscriberData, + "PTK", + getNonce(128), + getGregorianDate() + ), + subscriberData.customerAuthPriv + ) + val payload: ByteArray = + decryptAndDecompressResponse( + response.value, + subscriberData.customerAuthPriv + ) + call.respondText( + payload.toString(Charsets.UTF_8), + ContentType.Text.Plain, + HttpStatusCode.OK) + + return@post + } + + post("/ebics/subscribers/{id}/sendHAC") { + val id = expectId(call.parameters["id"]) + + val subscriberData = transaction { + containerInit( + EbicsSubscriberEntity.findById( + id + ) ?: throw SubscriberNotFoundError( + HttpStatusCode.NotFound + ) + ) + } + val response = client.postToBankSigned<EbicsRequest, EbicsResponse>( + subscriberData.ebicsUrl, + createDownloadInitializationPhase( + subscriberData, + "HAC", + getNonce(128), + getGregorianDate() + ), + subscriberData.customerAuthPriv + ) + val payload: ByteArray = + decryptAndDecompressResponse( + response.value, + subscriberData.customerAuthPriv + ) + call.respondText( + payload.toString(Charsets.UTF_8), + ContentType.Text.Plain, + HttpStatusCode.OK) + + return@post + } + + post("/ebics/subscribers/{id}/sendC52") { val id = expectId(call.parameters["id"]) val body = call.receive<EbicsDateRange>() @@ -216,16 +286,36 @@ fun main() { "C52", getNonce(128), getGregorianDate(), - getGregorianDate(startDate.year, startDate.monthOfYear, startDate.dayOfMonth), - getGregorianDate(endDate.year, endDate.monthOfYear, endDate.dayOfMonth) + getGregorianDate(startDate.year, startDate.monthOfYear - 1, startDate.dayOfMonth), + getGregorianDate(endDate.year, endDate.monthOfYear - 1, endDate.dayOfMonth) ), subscriberData.customerAuthPriv ) val payload: ByteArray = decryptAndDecompressResponse( response.value, - subscriberData.customerEncPriv + subscriberData.customerAuthPriv ) + val ackRequest = EbicsRequest.createForDownloadReceiptPhase( + response.value.header._static.transactionID ?: throw BankInvalidResponse( + HttpStatusCode.ExpectationFailed + ), + subscriberData.hostId + ) + + val ackResponse = client.postToBankSignedAndVerify<EbicsRequest, EbicsResponse>( + subscriberData.ebicsUrl, + ackRequest, + subscriberData.bankAuthPub ?: throw BankKeyMissing( + HttpStatusCode.PreconditionFailed + ), + subscriberData.customerAuthPriv + ) + logger.debug("C52 final response: " + XMLUtil.convertJaxbToString<EbicsResponse>(response.value)) + if (ackResponse.value.body.returnCode.value != "000000") { + throw EbicsError(response.value.body.returnCode.value) + } + call.respondText( payload.toString(Charsets.UTF_8), ContentType.Text.Plain, @@ -282,6 +372,7 @@ fun main() { ), subscriberData.hostId ) + val ackResponse = client.postToBankSignedAndVerify<EbicsRequest, EbicsResponse>( subscriberData.ebicsUrl, ackRequest, diff --git a/sandbox/src/main/python/libeufin-cli b/sandbox/src/main/python/libeufin-cli @@ -255,7 +255,49 @@ def c52(obj, account_id, nexus_base_url): url = urljoin(nexus_base_url, "/ebics/subscribers/{}/sendC52".format(account_id)) try: - resp = post(url, json=dict(start="1970-01-01", end="2020-12-31")) + resp = post(url, json=dict(start="2020-01-15", end="2020-02-03")) + except Exception: + print("Could not reach the bank") + return + + print(resp.content.decode("utf-8")) + + +@ebics.command(help="Send PTK message") +@click.pass_obj +@click.option( + "--account-id", + help="Numerical ID of the customer at the Nexus", + required=True +) +@click.argument( + "nexus-base-url" +) +def ptk(obj, account_id, nexus_base_url): + url = urljoin(nexus_base_url, "/ebics/subscribers/{}/sendPTK".format(account_id)) + try: + resp = post(url) + except Exception: + print("Could not reach the bank") + return + + print(resp.content.decode("utf-8")) + + +@ebics.command(help="Send HAC message") +@click.pass_obj +@click.option( + "--account-id", + help="Numerical ID of the customer at the Nexus", + required=True +) +@click.argument( + "nexus-base-url" +) +def hac(obj, account_id, nexus_base_url): + url = urljoin(nexus_base_url, "/ebics/subscribers/{}/sendHAC".format(account_id)) + try: + resp = post(url) except Exception: print("Could not reach the bank") return diff --git a/util/src/main/kotlin/ebics_h004/EbicsRequest.kt b/util/src/main/kotlin/ebics_h004/EbicsRequest.kt @@ -356,7 +356,6 @@ class EbicsRequest { bankEncPub: RSAPublicKey, bankAuthPub: RSAPublicKey, aOrderType: String - ): EbicsRequest { return EbicsRequest().apply {