gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[libeufin] branch master updated: Adjust transport retrieval.


From: gnunet
Subject: [libeufin] branch master updated: Adjust transport retrieval.
Date: Tue, 12 May 2020 13:55:31 +0200

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 e71407e  Adjust transport retrieval.
e71407e is described below

commit e71407eb7689bc66d11ab3712b8e292c8f3fb74a
Author: Marcello Stanisci <address@hidden>
AuthorDate: Tue May 12 13:53:10 2020 +0200

    Adjust transport retrieval.
    
    In particular, the default case needed to be handled.
    For now, the default is nothing more than a random transport
    instance belonging to the querying user.
---
 .../src/main/kotlin/tech/libeufin/nexus/Helpers.kt | 101 ++++++++++++++++-
 nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt  |  20 +++-
 nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt  | 123 +++++++--------------
 .../kotlin/tech/libeufin/nexus/MainDeprecated.kt   |   2 +-
 4 files changed, 159 insertions(+), 87 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
index 18035c2..1826ae3 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Helpers.kt
@@ -1,5 +1,7 @@
 package tech.libeufin.nexus
 
+import io.ktor.application.ApplicationCall
+import io.ktor.client.HttpClient
 import io.ktor.http.HttpStatusCode
 import org.jetbrains.exposed.sql.and
 import org.jetbrains.exposed.sql.transactions.transaction
@@ -99,7 +101,7 @@ fun getBankAccountsFromNexusUserId(id: String): 
MutableList<BankAccountEntity> {
     return ret
 }
 
-fun getSubscriberDetailsInternal(subscriber: EbicsSubscriberEntity): 
EbicsClientSubscriberDetails {
+fun getSubscriberDetails(subscriber: EbicsSubscriberEntity): 
EbicsClientSubscriberDetails {
     var bankAuthPubValue: RSAPublicKey? = null
     if (subscriber.bankAuthenticationPublicKey != null) {
         bankAuthPubValue = CryptoUtil.loadRsaPublicKey(
@@ -127,7 +129,102 @@ fun getSubscriberDetailsInternal(subscriber: 
EbicsSubscriberEntity): EbicsClient
     )
 }
 
-fun getTransport()
+/**
+ * Retrieve Ebics subscriber details given a Transport
+ * object and handling the default case.
+ */
+fun getEbicsSubscriberDetails(userId: String, transportId: String?): 
EbicsClientSubscriberDetails {
+    val transport = transaction {
+        if (transportId == null) {
+            return@transaction EbicsSubscriberEntity.all().first()
+        }
+        return@transaction EbicsSubscriberEntity.findById(transportId)
+    }
+        ?: throw NexusError(
+            HttpStatusCode.NotFound,
+            "Could not find ANY Ebics transport for user $userId"
+        )
+    if (transport.nexusUser.id.value != userId) {
+        throw NexusError(
+            HttpStatusCode.Forbidden,
+            "No rights over transport $transportId"
+        )
+    }
+    // transport exists and belongs to caller.
+    return getSubscriberDetails(transport)
+}
+
+suspend fun downloadAndPersistC5xEbics(
+    historyType: String,
+    client: HttpClient,
+    userId: String,
+    start: String?, // dashed date YYYY-MM(01-12)-DD(01-31)
+    end: String?, // dashed date YYYY-MM(01-12)-DD(01-31)
+    transportId: String?
+) {
+    val subscriberDetails = getEbicsSubscriberDetails(userId, transportId)
+    val orderParamsJson = EbicsStandardOrderParamsJson(
+        EbicsDateRangeJson(start, end)
+    )
+    /** More types C52/C54 .. forthcoming */
+    if (historyType != "C53") throw NexusError(
+        HttpStatusCode.InternalServerError,
+        "Ebics query tried on unknown message $historyType"
+    )
+    val response = doEbicsDownloadTransaction(
+        client,
+        subscriberDetails,
+        historyType,
+        orderParamsJson.toOrderParams()
+    )
+    when (response) {
+        is EbicsDownloadSuccessResult -> {
+            response.orderData.unzipWithLambda {
+                logger.debug("Camt entry: ${it.second}")
+                val fileName = it.first
+                val camt53doc = XMLUtil.parseStringIntoDom(it.second)
+                transaction {
+                    RawBankTransactionEntity.new {
+                        bankAccount = 
getBankAccountFromIban(camt53doc.pickString("//*[local-name()='Stmt']/Acct/Id/IBAN"))
+                        sourceFileName = fileName
+                        unstructuredRemittanceInformation = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Ustrd']")
+                        transactionType = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='CdtDbtInd']")
+                        currency = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']/@Ccy")
+                        amount = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']")
+                        status = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Sts']")
+                        bookingDate = 
parseDashedDate(camt53doc.pickString("//*[local-name()='BookgDt']//*[local-name()='Dt']")).millis
+                        nexusUser = extractNexusUser(userId)
+                        counterpartIban = 
camt53doc.pickString("//*[local-name()='${if (this.transactionType == "DBIT") 
"CdtrAcct" else "DbtrAcct"}']//*[local-name()='IBAN']")
+                        counterpartName = 
camt53doc.pickString("//*[local-name()='RltdPties']//*[local-name()='${if 
(this.transactionType == "DBIT") "Cdtr" else "Dbtr"}']//*[local-name()='Nm']")
+                        counterpartBic = 
camt53doc.pickString("//*[local-name()='RltdAgts']//*[local-name()='BIC']")
+                    }
+                }
+            }
+        }
+        is EbicsDownloadBankErrorResult -> {
+            throw NexusError(
+                HttpStatusCode.BadGateway,
+                response.returnCode.errorCode
+                )
+        }
+    }
+}
+
+suspend fun submitPaymentEbics(
+    client: HttpClient,
+    userId: String,
+    transportId: String?,
+    pain001document: String
+) {
+    logger.debug("Uploading PAIN.001: ${pain001document}")
+    doEbicsUploadTransaction(
+        client,
+        getEbicsSubscriberDetails(userId, transportId),
+        "CCT",
+        pain001document.toByteArray(Charsets.UTF_8),
+        EbicsStandardOrderParams()
+    )
+}
 
 
 /**
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt
index aea85b4..ef70927 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/JSON.kt
@@ -1,5 +1,6 @@
 package tech.libeufin.nexus
 
+import com.sun.jdi.connect.Transport
 import tech.libeufin.util.*
 import java.lang.NullPointerException
 import java.time.LocalDate
@@ -137,15 +138,30 @@ data class Transactions(
     val transactions: MutableList<Transaction> = mutableListOf()
 )
 
+/** Specifies the transport to use.  */
+data class Transport(
+    /**
+     * Must match one of the types implemented by nexus:
+     * 'ebics', 'local', possibly 'fints' in the near future!
+     */
+    val type: String,
+    /**
+     * A mnemonic identifier given by the user to one
+     * transport instance.
+     */
+    val name: String
+)
+
 /** Request type of "POST /prepared-payments/submit" */
 data class SubmitPayment(
     val uuid: String,
-    val transport: String?
+    /** Policy to pick the default transport is still work in progress.  */
+    val transport: tech.libeufin.nexus.Transport?
 )
 
 /** Request type of "POST /collected-transactions" */
 data class CollectedTransaction(
-    val transport: String?,
+    val transport: tech.libeufin.nexus.Transport?,
     val start: String?,
     val end: String?
 )
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index c9d185e..d67dc75 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -196,37 +196,27 @@ fun main() {
                     )
                 }
                 val pain001document = createPain001document(preparedPayment)
-                when (body.transport) {
-                    "ebics" -> {
-                        val subscriberDetails = getTransport(body.transport)
-                        logger.debug("Uploading PAIN.001: ${pain001document}")
-                        doEbicsUploadTransaction(
-                            client,
-                            subscriberDetails,
-                            "CCT",
-                            pain001document.toByteArray(Charsets.UTF_8),
-                            EbicsStandardOrderParams()
-                        )
-                        /** mark payment as 'submitted' */
-                        transaction {
-                            val payment = 
PreparedPaymentEntity.findById(body.uuid) ?: throw NexusError(
-                                HttpStatusCode.InternalServerError,
-                                "Severe internal error: could not find payment 
in DB after having submitted it to the bank"
+                if (body.transport != null) {
+                    // type and name aren't null
+                    when (body.transport.type) {
+                        "ebics" -> {
+                            submitPaymentEbics(
+                                client, userId, body.transport.name, 
pain001document
                             )
-                            payment.submitted = true
                         }
-                        call.respondText(
-                            "CCT message submitted to the bank",
-                            ContentType.Text.Plain,
-                            HttpStatusCode.OK
+                        else -> throw NexusError(
+                            HttpStatusCode.NotFound,
+                            "Transport type '${body.transport.type}' not 
implemented"
                         )
-                        preparedPayment.submissionDate = DateTime.now().millis
                     }
-                    else -> throw NexusError(
-                        HttpStatusCode.NotImplemented,
-                        "Bank transport ${body.transport} is not implemented"
+                } else {
+                    // default to ebics and "first" transport from user
+                    submitPaymentEbics(
+                        client, userId, null, pain001document
                     )
                 }
+                preparedPayment.submitted = true
+                call.respondText("Payment ${body.uuid} submitted")
                 return@post
             }
             /**
@@ -282,73 +272,42 @@ fun main() {
             }
             /**
              * Downloads new transactions from the bank.
+             *
+             * NOTE: 'accountid' is not used.  Transaction are asked on
+             * the basis of a transport subscriber (regardless of their
+             * bank account details)
              */
             post("/bank-accounts/{accountid}/collected-transactions") {
                 val userId = 
authenticateRequest(call.request.headers["Authorization"])
                 val body = call.receive<CollectedTransaction>()
-                when (body.transport) {
-                    "ebics" -> {
-                        val orderParams = EbicsStandardOrderParamsJson(
-                            EbicsDateRangeJson(
+                if (body.transport != null) {
+                    when (body.transport.type) {
+                        "ebics" -> {
+                            downloadAndPersistC5xEbics(
+                                "C53",
+                                client,
+                                userId,
                                 body.start,
-                                body.end
+                                body.end,
+                                body.transport.name
                             )
-                        ).toOrderParams()
-                        val subscriberData = 
getSubscriberDetailsFromNexusUserId(userId)
-                        when (val response = 
doEbicsDownloadTransaction(client, subscriberData, "C53", orderParams)) {
-                            is EbicsDownloadSuccessResult -> {
-                                /**
-                                 * The current code is _heavily_ dependent on 
the way GLS returns
-                                 * data.  For example, GLS makes one ZIP entry 
for each "Ntry" element
-                                 * (a bank transfer), but per the 
specifications one bank can choose to
-                                 * return all the "Ntry" elements into one 
single ZIP entry, or even unzipped
-                                 * at all.
-                                 */
-                                response.orderData.unzipWithLambda {
-                                    logger.debug("C53 entry: ${it.second}")
-                                    val fileName = it.first
-                                    val camt53doc = 
XMLUtil.parseStringIntoDom(it.second)
-                                    transaction {
-                                        RawBankTransactionEntity.new {
-                                            bankAccount = 
getBankAccountFromIban(camt53doc.pickString("//*[local-name()='Stmt']/Acct/Id/IBAN"))
-                                            sourceFileName = fileName
-                                            unstructuredRemittanceInformation 
= camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Ustrd']")
-                                            transactionType = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='CdtDbtInd']")
-                                            currency = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']/@Ccy")
-                                            amount = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Amt']")
-                                            status = 
camt53doc.pickString("//*[local-name()='Ntry']//*[local-name()='Sts']")
-                                            bookingDate = 
parseDashedDate(camt53doc.pickString("//*[local-name()='BookgDt']//*[local-name()='Dt']")).millis
-                                            nexusUser = 
extractNexusUser(userId)
-                                            counterpartIban = 
camt53doc.pickString("//*[local-name()='${if (this.transactionType == "DBIT") 
"CdtrAcct" else "DbtrAcct"}']//*[local-name()='IBAN']")
-                                            counterpartName = 
camt53doc.pickString("//*[local-name()='RltdPties']//*[local-name()='${if 
(this.transactionType == "DBIT") "Cdtr" else "Dbtr"}']//*[local-name()='Nm']")
-                                            counterpartBic = 
camt53doc.pickString("//*[local-name()='RltdAgts']//*[local-name()='BIC']")
-                                        }
-                                    }
-                                }
-                                call.respondText(
-                                    "C53 data persisted into the database 
(WIP).",
-                                    ContentType.Text.Plain,
-                                    HttpStatusCode.OK
-                                )
-                            }
-                            is EbicsDownloadBankErrorResult -> {
-                                call.respond(
-                                    HttpStatusCode.BadGateway,
-                                    EbicsErrorJson(
-                                        EbicsErrorDetailJson(
-                                            "bankError",
-                                            response.returnCode.errorCode
-                                        )
-                                    )
-                                )
-                            }
                         }
+                        else -> throw NexusError(
+                            HttpStatusCode.BadRequest,
+                            "Transport type '${body.transport.type}' not 
implemented"
+                        )
                     }
-                    else -> throw NexusError(
-                        HttpStatusCode.NotImplemented,
-                        "Bank transport ${body.transport} is not implemented"
+                } else {
+                    downloadAndPersistC5xEbics(
+                        "C53",
+                        client,
+                        userId,
+                        body.start,
+                        body.end,
+                        null
                     )
                 }
+                call.respondText("Collection performed")
                 return@post
             }
             /**
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt
index f589d76..df00d65 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/MainDeprecated.kt
@@ -572,7 +572,7 @@ fun main() {
                 logger.debug("Uploading PAIN.001: ${painDoc}")
                 doEbicsUploadTransaction(
                     client,
-                    getSubscriberDetailsInternal(subscriber),
+                    getSubscriberDetails(subscriber),
                     "CCT",
                     painDoc.toByteArray(Charsets.UTF_8),
                     EbicsStandardOrderParams()

-- 
To stop receiving notification emails like this one, please contact
address@hidden.



reply via email to

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