[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: support multiple EBICS download segmen
From: |
gnunet |
Subject: |
[libeufin] branch master updated: support multiple EBICS download segments |
Date: |
Mon, 08 Jun 2020 23:58:39 +0200 |
This is an automated email from the git hooks/post-receive script.
dold pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new c8bb455 support multiple EBICS download segments
c8bb455 is described below
commit c8bb455941b274526cf46b8f5a9e91b0bd1012fd
Author: Florian Dold <florian.dold@gmail.com>
AuthorDate: Tue Jun 9 02:56:15 2020 +0530
support multiple EBICS download segments
---
integration-tests/start-testenv.py | 8 +++--
integration-tests/test-ebics.py | 9 +++++
integration-tests/util.py | 4 +--
.../main/kotlin/tech/libeufin/nexus/EbicsClient.kt | 38 ++++++++++++++++++++++
util/src/main/kotlin/Ebics.kt | 36 +++++++++++++++++---
util/src/main/kotlin/ebics_h004/EbicsRequest.kt | 38 +++++++++++++++++++---
6 files changed, 120 insertions(+), 13 deletions(-)
diff --git a/integration-tests/start-testenv.py
b/integration-tests/start-testenv.py
index cc78840..78a0555 100755
--- a/integration-tests/start-testenv.py
+++ b/integration-tests/start-testenv.py
@@ -53,8 +53,6 @@ def assertResponse(response):
return response
-os.chdir("..")
-
startNexus("nexus-testenv.sqlite3")
startSandbox()
@@ -204,4 +202,8 @@ if len(resp.json().get("transactions")) != 1:
fail("Unexpected number of transactions; should be 1")
-input("press enter to stop LibEuFin test environment ...")
+try:
+ input("press enter to stop LibEuFin test environment ...")
+except:
+ pass
+print("exiting!")
diff --git a/integration-tests/test-ebics.py b/integration-tests/test-ebics.py
index 04d1c81..a74efe6 100755
--- a/integration-tests/test-ebics.py
+++ b/integration-tests/test-ebics.py
@@ -167,6 +167,15 @@ assertResponse(
)
)
+# Test download transaction (TSD, LibEuFin-specific test order type)
+assertResponse(
+ post(
+ "http://localhost:5001/bank-connections/my-ebics/ebics/download/tsd",
+ json=dict(),
+ headers=dict(Authorization=USER_AUTHORIZATION_HEADER),
+ )
+)
+
# 2.c, fetch bank account information
assertResponse(
post(
diff --git a/integration-tests/util.py b/integration-tests/util.py
index 02cd634..cdef69f 100644
--- a/integration-tests/util.py
+++ b/integration-tests/util.py
@@ -18,7 +18,7 @@ def checkPort(port):
exit(77)
-def startSandbox(dbname):
+def startSandbox(dbname="sandbox-test.sqlite3"):
db_full_path = str(Path.cwd() / dbname)
check_call(["rm", "-f", db_full_path])
check_call(["../gradlew", "-p", "..", "sandbox:assemble"])
@@ -43,7 +43,7 @@ def startSandbox(dbname):
break
-def startNexus(dbname):
+def startNexus(dbname="nexus-test.sqlite3"):
db_full_path = str(Path.cwd() / dbname)
check_call(["rm", "-f", "--", db_full_path])
check_call(
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsClient.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsClient.kt
index ea0a058..1e3ffa2 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsClient.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsClient.kt
@@ -95,6 +95,44 @@ suspend fun doEbicsDownloadTransaction(
payloadChunks.add(initOrderDataEncChunk)
+ val numSegments = initResponse.numSegments
+ ?: throw NexusError(HttpStatusCode.FailedDependency, "missing segment
number in EBICS download init response")
+
+ // Transfer phase
+
+ for (x in 2..numSegments) {
+ val transferReqStr =
+ createEbicsRequestForDownloadTransferPhase(subscriberDetails,
transactionID, x, numSegments)
+ val transferResponseStr =
client.postToBank(subscriberDetails.ebicsUrl, transferReqStr)
+ val transferResponse =
parseAndValidateEbicsResponse(subscriberDetails, transferResponseStr)
+ when (transferResponse.technicalReturnCode) {
+ EbicsReturnCode.EBICS_OK -> {
+ // Success, nothing to do!
+ }
+ else -> {
+ throw NexusError(
+ HttpStatusCode.FailedDependency,
+ "unexpected technical return code
${transferResponse.technicalReturnCode}"
+ )
+ }
+ }
+ when (transferResponse.bankReturnCode) {
+ EbicsReturnCode.EBICS_OK -> {
+ // Success, nothing to do!
+ }
+ else -> {
+ logger.warn("Bank return code was:
${transferResponse.bankReturnCode}")
+ return
EbicsDownloadBankErrorResult(transferResponse.bankReturnCode)
+ }
+ }
+ val transferOrderDataEncChunk = transferResponse.orderDataEncChunk
+ ?: throw NexusError(
+ HttpStatusCode.InternalServerError,
+ "transfer response for download transaction does not contain
data transfer"
+ )
+ payloadChunks.add(transferOrderDataEncChunk)
+ }
+
val respPayload = decryptAndDecompressResponse(subscriberDetails,
encryptionInfo, payloadChunks)
// Acknowledgement phase
diff --git a/util/src/main/kotlin/Ebics.kt b/util/src/main/kotlin/Ebics.kt
index feaf4bd..077a47d 100644
--- a/util/src/main/kotlin/Ebics.kt
+++ b/util/src/main/kotlin/Ebics.kt
@@ -260,6 +260,23 @@ fun createEbicsRequestForDownloadInitialization(
return XMLUtil.convertDomToString(doc)
}
+fun createEbicsRequestForDownloadTransferPhase(
+ subscriberDetails: EbicsClientSubscriberDetails,
+ transactionID: String,
+ segmentNumber: Int,
+ numSegments: Int
+): String {
+ val req = EbicsRequest.createForDownloadTransferPhase(
+ subscriberDetails.hostId,
+ transactionID,
+ segmentNumber,
+ numSegments
+ )
+ val doc = XMLUtil.convertJaxbToDocument(req)
+ XMLUtil.signEbicsDocument(doc, subscriberDetails.customerAuthPriv)
+ return XMLUtil.convertDomToString(doc)
+}
+
fun createEbicsRequestForUploadTransferPhase(
subscriberDetails: EbicsClientSubscriberDetails,
@@ -329,7 +346,10 @@ data class EbicsResponseContent(
val dataEncryptionInfo: DataEncryptionInfo?,
val orderDataEncChunk: String?,
val technicalReturnCode: EbicsReturnCode,
- val bankReturnCode: EbicsReturnCode
+ val bankReturnCode: EbicsReturnCode,
+ val segmentNumber: Int?,
+ // Only present in init phase
+ val numSegments: Int?
)
data class EbicsKeyManagementResponseContent(
@@ -404,7 +424,10 @@ fun parseAndValidateEbicsResponse(
val responseDocument = try {
XMLUtil.parseStringIntoDom(responseStr)
} catch (e: Exception) {
- throw EbicsProtocolError(HttpStatusCode.InternalServerError, "Invalid
XML (as EbicsResponse) received from bank")
+ throw EbicsProtocolError(
+ HttpStatusCode.InternalServerError,
+ "Invalid XML (as EbicsResponse) received from bank"
+ )
}
if (!XMLUtil.verifyEbicsDocument(
@@ -420,7 +443,10 @@ fun parseAndValidateEbicsResponse(
val resp = try {
XMLUtil.convertStringToJaxb<EbicsResponse>(responseStr)
} catch (e: Exception) {
- throw EbicsProtocolError(HttpStatusCode.InternalServerError, "Could
not transform string-response from bank into JAXB")
+ throw EbicsProtocolError(
+ HttpStatusCode.InternalServerError,
+ "Could not transform string-response from bank into JAXB"
+ )
}
val bankReturnCodeStr = resp.value.body.returnCode.value
@@ -441,7 +467,9 @@ fun parseAndValidateEbicsResponse(
bankReturnCode = bankReturnCode,
technicalReturnCode = techReturnCode,
orderDataEncChunk = resp.value.body.dataTransfer?.orderData?.value,
- dataEncryptionInfo = dataEncryptionInfo
+ dataEncryptionInfo = dataEncryptionInfo,
+ numSegments = resp.value.header._static.numSegments?.toInt(),
+ segmentNumber = resp.value.header.mutable.segmentNumber?.value?.toInt()
)
}
diff --git a/util/src/main/kotlin/ebics_h004/EbicsRequest.kt
b/util/src/main/kotlin/ebics_h004/EbicsRequest.kt
index 71f5f8e..c5d053e 100644
--- a/util/src/main/kotlin/ebics_h004/EbicsRequest.kt
+++ b/util/src/main/kotlin/ebics_h004/EbicsRequest.kt
@@ -5,6 +5,7 @@ import tech.libeufin.util.CryptoUtil
import java.math.BigInteger
import java.security.interfaces.RSAPublicKey
import java.util.*
+import javax.swing.text.Segment
import javax.xml.bind.annotation.*
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter
import javax.xml.bind.annotation.adapters.HexBinaryAdapter
@@ -360,10 +361,10 @@ class EbicsRequest {
}
securityMedium = "0000"
}
- mutable = MutableHeader().apply {
- transactionPhase =
- EbicsTypes.TransactionPhaseType.INITIALISATION
- }
+ }
+ mutable = MutableHeader().apply {
+ transactionPhase =
+ EbicsTypes.TransactionPhaseType.INITIALISATION
}
}
}
@@ -473,5 +474,34 @@ class EbicsRequest {
}
}
}
+
+ fun createForDownloadTransferPhase(
+ hostID: String,
+ transactionID: String,
+ segmentNumber: Int,
+ numSegments: Int
+ ): EbicsRequest {
+ return EbicsRequest().apply {
+ version = "H004"
+ revision = 1
+ authSignature = SignatureType()
+ body = Body()
+ header = Header().apply {
+ authenticate = true
+ static = StaticHeaderType().apply {
+ this.hostID = hostID
+ this.transactionID = transactionID
+ }
+ mutable = MutableHeader().apply {
+ transactionPhase =
+ EbicsTypes.TransactionPhaseType.TRANSFER
+ this.segmentNumber = EbicsTypes.SegmentNumber().apply {
+ this.value =
BigInteger.valueOf(segmentNumber.toLong())
+ this.lastSegment = segmentNumber == numSegments
+ }
+ }
+ }
+ }
+ }
}
}
\ No newline at end of file
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: support multiple EBICS download segments,
gnunet <=