gnunet-svn
[Top][All Lists]
Advanced

[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.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]