[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: nexus fetch: helpers to craft a camt.0
From: |
gnunet |
Subject: |
[libeufin] branch master updated: nexus fetch: helpers to craft a camt.052 request |
Date: |
Wed, 08 Nov 2023 12:54:35 +0100 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
The following commit(s) were added to refs/heads/master by this push:
new 55c355a7 nexus fetch: helpers to craft a camt.052 request
55c355a7 is described below
commit 55c355a71b389b23963c389ae8be77cbfae10b33
Author: MS <ms@taler.net>
AuthorDate: Wed Nov 8 12:54:11 2023 +0100
nexus fetch: helpers to craft a camt.052 request
---
.../main/kotlin/tech/libeufin/nexus/EbicsFetch.kt | 53 +++++++++++
.../kotlin/tech/libeufin/nexus/ebics/Ebics2.kt | 4 +-
.../kotlin/tech/libeufin/nexus/ebics/Ebics3.kt | 102 ++++++++++++++++++++-
.../tech/libeufin/nexus/ebics/EbicsCommon.kt | 6 +-
util/src/main/kotlin/Ebics.kt | 40 ++------
util/src/main/kotlin/ebics_h005/Ebics3Request.kt | 15 +--
6 files changed, 165 insertions(+), 55 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt
index 5afbc02a..23ccf7d4 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt
@@ -4,9 +4,62 @@ import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.option
import io.ktor.client.*
+import tech.libeufin.util.ebics_h005.Ebics3Request
+import tech.libeufin.util.getXmlDate
+import java.time.Instant
import kotlin.concurrent.fixedRateTimer
import kotlin.system.exitProcess
+/**
+ * Crafts a date range object, when the caller needs a time range.
+ *
+ * @param startDate inclusive starting date for the returned banking events.
+ * @param endDate inclusive ending date for the returned banking events.
+ * @return [Ebics3Request.DateRange]
+ */
+fun getEbics3DateRange(
+ startDate: Instant,
+ endDate: Instant
+): Ebics3Request.DateRange {
+ return Ebics3Request.DateRange().apply {
+ start = getXmlDate(startDate)
+ end = getXmlDate(endDate)
+ }
+}
+
+/**
+ * Prepares the request for camt.052/intraday records.
+ *
+ * @param startDate inclusive starting date for the returned banking events.
+ * @param endDate inclusive ending date for the returned banking events. NOTE:
+ * if startDate is NOT null and endDate IS null, endDate gets defaulted
+ * to the current UTC time.
+ *
+ * @return [Ebics3Request.OrderDetails.BTOrderParams]
+ */
+fun prepReportRequest(
+ startDate: Instant? = null,
+ endDate: Instant? = null
+): Ebics3Request.OrderDetails.BTOrderParams {
+ val service = Ebics3Request.OrderDetails.Service().apply {
+ serviceName = "STM"
+ scope = "CH"
+ container = Ebics3Request.OrderDetails.Service.Container().apply {
+ containerType = "ZIP"
+ }
+ messageName = Ebics3Request.OrderDetails.Service.MessageName().apply {
+ value = "camt.052"
+ version = "08"
+ }
+ }
+ return Ebics3Request.OrderDetails.BTOrderParams().apply {
+ this.service = service
+ this.dateRange = if (startDate != null)
+ getEbics3DateRange(startDate, endDate ?: Instant.now())
+ else null
+ }
+}
+
/**
* Fetches the banking records via EBICS, calling the CAMT
* parsing logic and finally updating the database accordingly.
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
index 2c4cf45b..cdda0c26 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
@@ -135,7 +135,7 @@ fun createEbics25DownloadInit(
* should receive this receipt.
* @return receipt request in XML.
*/
-fun createEbics25ReceiptPhase(
+fun createEbics25DownloadReceiptPhase(
cfg: EbicsSetupConfig,
clientKeys: ClientPrivateKeysFile,
transactionId: String
@@ -163,7 +163,7 @@ fun createEbics25ReceiptPhase(
* @param transactionId ID of the EBICS transaction that transports all the
segments.
* @return raw XML string of the request.
*/
-fun createEbics25TransferPhase(
+fun createEbics25DownloadTransferPhase(
cfg: EbicsSetupConfig,
clientKeys: ClientPrivateKeysFile,
segNumber: Int,
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt
index 982763ce..2f141cbc 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics3.kt
@@ -9,11 +9,109 @@ import tech.libeufin.util.PreparedUploadData
import tech.libeufin.util.XMLUtil
import tech.libeufin.util.ebics_h005.Ebics3Request
import tech.libeufin.util.getNonce
-import tech.libeufin.util.toHexString
import java.math.BigInteger
import java.util.*
import javax.xml.datatype.DatatypeFactory
+/**
+ * Crafts an EBICS request for the receipt phase of a
+ * download transaction.
+ *
+ * @param cfg config handle
+ * @param clientKeys subscriber private keys.
+ * @param transactionId EBICS transaction ID as assigned by the
+ * bank to any successful transaction.
+ * @return the raw XML of the EBICS request.
+ */
+fun createEbics3DownloadReceiptPhase(
+ cfg: EbicsSetupConfig,
+ clientKeys: ClientPrivateKeysFile,
+ transactionId: String
+): String {
+ val req = Ebics3Request.createForDownloadReceiptPhase(
+ transactionId,
+ cfg.ebicsHostId
+ )
+ val doc = XMLUtil.convertJaxbToDocument(req)
+ XMLUtil.signEbicsDocument(
+ doc,
+ clientKeys.authentication_private_key,
+ withEbics3 = true
+ )
+ return XMLUtil.convertDomToString(doc)
+}
+
+/**
+ * Crafts an EBICS download request for the transfer phase.
+ *
+ * @param cfg config handle
+ * @param clientKeys subscriber private keys
+ * @param transactionId EBICS transaction ID. That came from the
+ * bank after the initialization phase ended successfully.
+ * @param segmentNumber which (payload's) segment number this requests wants.
+ * @param howManySegments total number of segments that the payload is split
to.
+ * @return the raw XML EBICS request.
+ */
+fun createEbics3DownloadTransferPhase(
+ cfg: EbicsSetupConfig,
+ clientKeys: ClientPrivateKeysFile,
+ transactionId: String,
+ segmentNumber: Int,
+ howManySegments: Int
+): String {
+ val req = Ebics3Request.createForDownloadTransferPhase(
+ cfg.ebicsHostId,
+ transactionId,
+ segmentNumber,
+ howManySegments
+ )
+ val doc = XMLUtil.convertJaxbToDocument(req)
+ XMLUtil.signEbicsDocument(
+ doc,
+ clientKeys.authentication_private_key,
+ withEbics3 = true
+ )
+ return XMLUtil.convertDomToString(doc)
+}
+
+/**
+ * Creates the EBICS 3 document for the init phase of a download
+ * transaction.
+ *
+ * @param cfg configuration handle.
+ * @param bankkeys bank public keys.
+ * @param clientKeys client private keys.
+ * @param orderService EBICS 3 document defining the request type
+ */
+fun createEbics3DownloadInitialization(
+ cfg: EbicsSetupConfig,
+ bankkeys: BankPublicKeysFile,
+ clientKeys: ClientPrivateKeysFile,
+ orderParams: Ebics3Request.OrderDetails.BTOrderParams
+): String {
+ val nonce = getNonce(128)
+ val req = Ebics3Request.createForDownloadInitializationPhase(
+ cfg.ebicsUserId,
+ cfg.ebicsPartnerId,
+ cfg.ebicsHostId,
+ nonce,
+
DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar()),
+ bankAuthPub = bankkeys.bank_authentication_public_key,
+ bankEncPub = bankkeys.bank_encryption_public_key,
+ myOrderParams = orderParams
+ )
+ val doc = XMLUtil.convertJaxbToDocument(
+ req,
+ withSchemaLocation = "urn:org:ebics:H005 ebics_request_H005.xsd"
+ )
+ XMLUtil.signEbicsDocument(
+ doc,
+ clientKeys.authentication_private_key,
+ withEbics3 = true
+ )
+ return XMLUtil.convertDomToString(doc)
+}
+
/**
* Creates the EBICS 3 document for the init phase of an upload
* transaction.
@@ -51,8 +149,6 @@ fun createEbics3RequestForUploadInitialization(
req,
withSchemaLocation = "urn:org:ebics:H005 ebics_request_H005.xsd"
)
- tech.libeufin.util.logger.debug("Created EBICS 3 document for upload
initialization," +
- " nonce: ${nonce.toHexString()}")
XMLUtil.signEbicsDocument(
doc,
clientKeys.authentication_private_key,
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt
index 50b8005d..772192dc 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/EbicsCommon.kt
@@ -254,7 +254,7 @@ private fun areCodesOk(ebicsResponseContent:
EbicsResponseContent) =
* @param cfg configuration handle.
* @param clientKeys client EBICS private keys.
* @param bankKeys bank EBICS public keys.
- * @param reqXml raw EBICS XML request.
+ * @param reqXml raw EBICS XML request of the init phase.
* @return the bank response as an XML string, or null if one
* error took place. NOTE: any return code other than
* EBICS_OK constitutes an error.
@@ -297,7 +297,7 @@ suspend fun doEbicsDownload(
// proceed with the transfer phase.
for (x in 2 .. howManySegments) {
// request segment number x.
- val transReq = createEbics25TransferPhase(cfg, clientKeys, x,
howManySegments, tId)
+ val transReq = createEbics25DownloadTransferPhase(cfg, clientKeys, x,
howManySegments, tId)
val transResp = postEbics(client, cfg, bankKeys, transReq, isEbics3)
if (!areCodesOk(transResp)) { // FIXME: consider tolerating
EBICS_NO_DOWNLOAD_DATA_AVAILABLE.
tech.libeufin.nexus.logger.error("EBICS transfer segment #$x
failed.")
@@ -317,7 +317,7 @@ suspend fun doEbicsDownload(
ebicsChunks
)
// payload reconstructed, ack to the bank.
- val ackXml = createEbics25ReceiptPhase(cfg, clientKeys, tId)
+ val ackXml = createEbics25DownloadReceiptPhase(cfg, clientKeys, tId)
try {
postEbics(
client,
diff --git a/util/src/main/kotlin/Ebics.kt b/util/src/main/kotlin/Ebics.kt
index 9659a0c0..49898660 100644
--- a/util/src/main/kotlin/Ebics.kt
+++ b/util/src/main/kotlin/Ebics.kt
@@ -37,6 +37,7 @@ import java.math.BigInteger
import java.security.SecureRandom
import java.security.interfaces.RSAPrivateCrtKey
import java.security.interfaces.RSAPublicKey
+import java.time.Instant
import java.time.ZoneId
import java.time.ZonedDateTime
import java.util.*
@@ -106,7 +107,11 @@ fun getNonce(size: Int): ByteArray {
return ret
}
-private fun getXmlDate(d: ZonedDateTime): XMLGregorianCalendar {
+fun getXmlDate(i: Instant): XMLGregorianCalendar {
+ val zonedTimestamp = ZonedDateTime.ofInstant(i, ZoneId.of("UTC"))
+ return getXmlDate(zonedTimestamp)
+}
+fun getXmlDate(d: ZonedDateTime): XMLGregorianCalendar {
return DatatypeFactory.newInstance()
.newXMLGregorianCalendar(
d.year,
@@ -364,39 +369,6 @@ fun createEbicsRequestForDownloadInitialization(
return XMLUtil.convertDomToString(doc)
}
-fun createEbicsRequestForDownloadInitialization(
- subscriberDetails: EbicsClientSubscriberDetails,
- ebics3OrderService: Ebics3Request.OrderDetails.Service,
- orderParams: EbicsOrderParams,
-): String {
- val nonce = getNonce(128)
- val req = Ebics3Request.createForDownloadInitializationPhase(
- subscriberDetails.userId,
- subscriberDetails.partnerId,
- subscriberDetails.hostId,
- nonce,
-
DatatypeFactory.newInstance().newXMLGregorianCalendar(GregorianCalendar(
- TimeZone.getTimeZone(ZoneId.systemDefault())
- )),
- subscriberDetails.bankEncPub ?: throw EbicsProtocolError(
- HttpStatusCode.BadRequest,
- "Invalid subscriber state 'bankEncPub' missing, please send HPB
first"
- ),
- subscriberDetails.bankAuthPub ?: throw EbicsProtocolError(
- HttpStatusCode.BadRequest,
- "Invalid subscriber state 'bankAuthPub' missing, please send HPB
first"
- ),
- ebics3OrderService
- )
- val doc = XMLUtil.convertJaxbToDocument(req)
- XMLUtil.signEbicsDocument(
- doc,
- subscriberDetails.customerAuthPriv,
- withEbics3 = true
- )
- return XMLUtil.convertDomToString(doc)
-}
-
fun createEbicsRequestForDownloadTransferPhase(
subscriberDetails: EbicsClientSubscriberDetails,
transactionID: String?,
diff --git a/util/src/main/kotlin/ebics_h005/Ebics3Request.kt
b/util/src/main/kotlin/ebics_h005/Ebics3Request.kt
index 2af81601..b1bd7eb3 100644
--- a/util/src/main/kotlin/ebics_h005/Ebics3Request.kt
+++ b/util/src/main/kotlin/ebics_h005/Ebics3Request.kt
@@ -3,7 +3,6 @@ package tech.libeufin.util.ebics_h005
import org.apache.xml.security.binding.xmldsig.SignatureType
import tech.libeufin.util.CryptoUtil
import tech.libeufin.util.EbicsStandardOrderParams
-import tech.libeufin.util.EbicsOrderParams
import tech.libeufin.util.makeEbics3DateRange
import java.math.BigInteger
import java.security.interfaces.RSAPublicKey
@@ -388,8 +387,7 @@ class Ebics3Request {
date: XMLGregorianCalendar,
bankEncPub: RSAPublicKey,
bankAuthPub: RSAPublicKey,
- myOrderService: OrderDetails.Service,
- myOrderParams: EbicsOrderParams? = null
+ myOrderParams: OrderDetails.BTOrderParams
): Ebics3Request {
return Ebics3Request().apply {
version = "H005"
@@ -407,16 +405,7 @@ class Ebics3Request {
partnerID = partnerId
orderDetails = OrderDetails().apply {
this.adminOrderType = "BTD"
- this.btdOrderParams =
OrderDetails.BTOrderParams().apply {
- service = myOrderService
- // Order params only used for date ranges so
far.
- when (myOrderParams) {
- is EbicsStandardOrderParams -> {
- this.dateRange =
makeEbics3DateRange(myOrderParams.dateRange)
- }
- else -> {}
- }
- }
+ this.btdOrderParams = myOrderParams
}
bankPubKeyDigests = BankPubKeyDigests().apply {
authentication = Ebics3Types.PubKeyDigest().apply {
--
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: nexus fetch: helpers to craft a camt.052 request,
gnunet <=