commit a726581fd09950b3feb373b4266057fe24ac8679
parent c8363449c3d11534b249727874a18fd97b2ea152
Author: Florian Dold <florian.dold@gmail.com>
Date: Tue, 9 Jun 2020 01:29:18 +0530
sandbox support for multi-segment EBICS download transactions
Diffstat:
3 files changed, 63 insertions(+), 2 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -786,6 +786,19 @@ private data class RequestContext(
val downloadTransaction: EbicsDownloadTransactionEntity?
)
+private fun handleEbicsDownloadTransactionTransfer(requestContext: RequestContext): EbicsResponse {
+ val segmentNumber = requestContext.requestObject.header.mutable.segmentNumber?.value ?: throw EbicsInvalidRequestError()
+ val transactionID = requestContext.requestObject.header.static.transactionID ?: throw EbicsInvalidRequestError()
+ val downloadTransaction = requestContext.downloadTransaction ?: throw AssertionError()
+ return EbicsResponse.createForDownloadTransferPhase(
+ transactionID,
+ downloadTransaction.numSegments,
+ downloadTransaction.segmentSize,
+ downloadTransaction.encodedResponse,
+ segmentNumber.toInt()
+ )
+}
+
private fun handleEbicsDownloadTransactionInitialization(requestContext: RequestContext): EbicsResponse {
val orderType =
@@ -1072,7 +1085,7 @@ suspend fun ApplicationCall.ebicsweb() {
if (requestContext.uploadTransaction != null) {
handleEbicsUploadTransactionTransmission(requestContext)
} else if (requestContext.downloadTransaction != null) {
- throw NotImplementedError()
+ handleEbicsDownloadTransactionTransfer(requestContext)
} else {
throw AssertionError()
}
diff --git a/util/src/main/kotlin/CryptoUtil.kt b/util/src/main/kotlin/CryptoUtil.kt
@@ -45,6 +45,7 @@ object CryptoUtil {
*/
data class RsaCrtKeyPair(val private: RSAPrivateCrtKey, val public: RSAPublicKey)
+ // FIXME(dold): This abstraction needs to be improved.
class EncryptionResult(
val encryptedTransactionKey: ByteArray,
val pubKeyDigest: ByteArray,
diff --git a/util/src/main/kotlin/ebics_h004/EbicsResponse.kt b/util/src/main/kotlin/ebics_h004/EbicsResponse.kt
@@ -7,6 +7,7 @@ import javax.xml.bind.annotation.*
import javax.xml.bind.annotation.adapters.CollapsedStringAdapter
import javax.xml.bind.annotation.adapters.NormalizedStringAdapter
import javax.xml.bind.annotation.adapters.XmlJavaTypeAdapter
+import kotlin.math.min
@XmlAccessorType(XmlAccessType.NONE)
@XmlType(name = "", propOrder = ["header", "authSignature", "body"])
@@ -220,6 +221,52 @@ class EbicsResponse {
}
}
+ /**
+ * @param requestedSegment requested segment as a 1-based index
+ */
+ fun createForDownloadTransferPhase(
+ transactionID: String,
+ numSegments: Int,
+ segmentSize: Int,
+ encodedData: String,
+ requestedSegment: Int
+ ): EbicsResponse {
+ return EbicsResponse().apply {
+ this.version = "H004"
+ this.revision = 1
+ this.header = Header().apply {
+ this.authenticate = true
+ this._static = StaticHeaderType().apply {
+ this.transactionID = transactionID
+ this.numSegments = BigInteger.valueOf(numSegments.toLong())
+ }
+ this.mutable = MutableHeaderType().apply {
+ this.transactionPhase =
+ EbicsTypes.TransactionPhaseType.TRANSFER
+ this.segmentNumber = EbicsTypes.SegmentNumber().apply {
+ this.lastSegment = numSegments == requestedSegment
+ this.value = BigInteger.valueOf(requestedSegment.toLong())
+ }
+ this.reportText = "[EBICS_OK] OK"
+ this.returnCode = "000000"
+ }
+ }
+ this.authSignature = SignatureType()
+ this.body = Body().apply {
+ this.returnCode = ReturnCode().apply {
+ this.authenticate = true
+ this.value = "000000"
+ }
+ this.dataTransfer = DataTransferResponseType().apply {
+ this.orderData = OrderData().apply {
+ val start = segmentSize * (requestedSegment - 1)
+ this.value = encodedData.substring(start, min(start + segmentSize, encodedData.length))
+ }
+ }
+ }
+ }
+ }
+
fun createForDownloadInitializationPhase(
transactionID: String,
numSegments: Int,
@@ -265,7 +312,7 @@ class EbicsResponse {
this.transactionKey = enc.encryptedTransactionKey
}
this.orderData = OrderData().apply {
- this.value = encodedData.substring(0, Math.min(segmentSize, encodedData.length))
+ this.value = encodedData.substring(0, min(segmentSize, encodedData.length))
}
}
}