gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: TWG.


From: gnunet
Subject: [libeufin] branch master updated: TWG.
Date: Thu, 28 May 2020 17:03:03 +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 1179c26  TWG.
1179c26 is described below

commit 1179c26313c1a11df9c1f9f56f684f0f90b77b28
Author: MS <ms@taler.net>
AuthorDate: Thu May 28 17:01:30 2020 +0200

    TWG.
    
    Isolating any API handler in a simple function.
    This gives more flexibility with regard to changes
    in the URL structure, and to test/move the code.
---
 nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt  |   4 +-
 nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt | 470 +++++++++------------
 2 files changed, 201 insertions(+), 273 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index b41292f..aa984ba 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -50,9 +50,7 @@ import io.ktor.jackson.jackson
 import io.ktor.request.*
 import io.ktor.response.respond
 import io.ktor.response.respondText
-import io.ktor.routing.get
-import io.ktor.routing.post
-import io.ktor.routing.routing
+import io.ktor.routing.*
 import io.ktor.server.engine.embeddedServer
 import io.ktor.server.netty.Netty
 import io.ktor.utils.io.ByteReadChannel
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
index a5e4a49..5611510 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/taler.kt
@@ -1,6 +1,7 @@
 package tech.libeufin.nexus
 
 import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper
+import io.ktor.application.ApplicationCall
 import io.ktor.application.call
 import io.ktor.content.TextContent
 import io.ktor.http.ContentType
@@ -211,160 +212,140 @@ fun paymentFailed(entry: RawBankTransactionEntity): 
Boolean {
     return false
 }
 
-class Taler(app: Route) {
-
-    /** Attach Taler endpoints to the main Web server */
-
-    init {
-        app.get("/taler") {
-            call.respondText("Taler Gateway Hello\n", ContentType.Text.Plain, 
HttpStatusCode.OK)
-            return@get
-        }
-        app.post("/{fcid}/taler/transfer") {
-            val exchangeUser = authenticateRequest(call.request)
-            val transferRequest = call.receive<TalerTransferRequest>()
-            val amountObj = parseAmount(transferRequest.amount)
-            val creditorObj = parsePayto(transferRequest.credit_account)
-            val opaque_row_id = transaction {
-                val creditorData = parsePayto(transferRequest.credit_account)
-                /** Checking the UID has the desired characteristics */
-                TalerRequestedPaymentEntity.find {
-                    TalerRequestedPayments.requestUId eq 
transferRequest.request_uid
-                }.forEach {
-                    if (
-                        (it.amount != transferRequest.amount) or
-                        (it.creditAccount != 
transferRequest.exchange_base_url) or
-                        (it.wtid != transferRequest.wtid)
-                    ) {
-                        throw NexusError(
-                            HttpStatusCode.Conflict,
-                            "This uid (${transferRequest.request_uid}) belongs 
to a different payment already"
-                        )
-                    }
-                }
-                val pain001 = addPreparedPayment(
-                    Pain001Data(
-                        creditorIban = creditorData.iban,
-                        creditorBic = creditorData.bic,
-                        creditorName = creditorData.name,
-                        subject = transferRequest.wtid,
-                        sum = amountObj.amount,
-                        currency = amountObj.currency
-                    ),
-                    NexusBankAccountEntity.new { /* FIXME; exchange should 
communicate this value */ }
+suspend fun talerTransfer(call: ApplicationCall): Unit {
+    val exchangeUser = authenticateRequest(call.request)
+    val transferRequest = call.receive<TalerTransferRequest>()
+    val amountObj = parseAmount(transferRequest.amount)
+    val creditorObj = parsePayto(transferRequest.credit_account)
+    val opaque_row_id = transaction {
+        val creditorData = parsePayto(transferRequest.credit_account)
+        /** Checking the UID has the desired characteristics */
+        TalerRequestedPaymentEntity.find {
+            TalerRequestedPayments.requestUId eq transferRequest.request_uid
+        }.forEach {
+            if (
+                (it.amount != transferRequest.amount) or
+                (it.creditAccount != transferRequest.exchange_base_url) or
+                (it.wtid != transferRequest.wtid)
+            ) {
+                throw NexusError(
+                    HttpStatusCode.Conflict,
+                    "This uid (${transferRequest.request_uid}) belongs to a 
different payment already"
                 )
-                val rawEbics = if (!isProduction()) {
-                    RawBankTransactionEntity.new {
-                        unstructuredRemittanceInformation = 
transferRequest.wtid
-                        transactionType = "DBIT"
-                        currency = amountObj.currency
-                        this.amount = amountObj.amount.toPlainString()
-                        counterpartBic = creditorObj.bic
-                        counterpartIban = creditorObj.iban
-                        counterpartName = creditorObj.name
-                        bankAccount = NexusBankAccountEntity.new { /* FIXME; 
exchange should communicate this value */ }
-                        bookingDate = DateTime.now().millis
-                        status = "BOOK"
-                    }
-                } else null
-
-                val row = TalerRequestedPaymentEntity.new {
-                    preparedPayment = pain001 // not really used/needed, just 
here to silence warnings
-                    exchangeBaseUrl = transferRequest.exchange_base_url
-                    requestUId = transferRequest.request_uid
-                    amount = transferRequest.amount
-                    wtid = transferRequest.wtid
-                    creditAccount = transferRequest.credit_account
-                    rawConfirmed = rawEbics
-                }
-
-                row.id.value
             }
-            call.respond(
-                HttpStatusCode.OK,
-                TextContent(
-                    customConverter(
-                        TalerTransferResponse(
-                            /**
-                             * Normally should point to the next round where 
the background
-                             * routine will send new PAIN.001 data to the 
bank; work in progress..
-                             */
-                            timestamp = GnunetTimestamp(DateTime.now().millis),
-                            row_id = opaque_row_id
-                        )
-                    ),
-                    ContentType.Application.Json
-                )
-            )
-            return@post
         }
-        /** Test-API that creates one new payment addressed to the exchange.  
*/
-        app.post("/{fcid}/taler/admin/add-incoming") {
-            val exchangeUser = authenticateRequest(call.request)
-            val addIncomingData = call.receive<TalerAdminAddIncoming>()
-            val debtor = parsePayto(addIncomingData.debit_account)
-            val amount = parseAmount(addIncomingData.amount)
-            val (bookingDate, opaque_row_id) = transaction {
-                val rawPayment = RawBankTransactionEntity.new {
-                    unstructuredRemittanceInformation = 
addIncomingData.reserve_pub
-                    transactionType = "CRDT"
-                    currency = amount.currency
-                    this.amount = amount.amount.toPlainString()
-                    counterpartBic = debtor.bic
-                    counterpartName = debtor.name
-                    counterpartIban = debtor.iban
-                    bookingDate = DateTime.now().millis
-                    status = "BOOK"
-                    bankAccount = NexusBankAccountEntity.new { /* FIXME; 
exchange should communicate this value */ }
-                }
-                /** This payment is "valid by default" and will be returned
-                 * as soon as the exchange will ask for new payments.  */
-                val row = TalerIncomingPaymentEntity.new {
-                    payment = rawPayment
-                    valid = true
-                }
-                Pair(rawPayment.bookingDate, row.id.value)
+        val pain001 = addPreparedPayment(
+            Pain001Data(
+                creditorIban = creditorData.iban,
+                creditorBic = creditorData.bic,
+                creditorName = creditorData.name,
+                subject = transferRequest.wtid,
+                sum = amountObj.amount,
+                currency = amountObj.currency
+            ),
+            NexusBankAccountEntity.new { /* FIXME; exchange should communicate 
this value */ }
+        )
+        val rawEbics = if (!isProduction()) {
+            RawBankTransactionEntity.new {
+                unstructuredRemittanceInformation = transferRequest.wtid
+                transactionType = "DBIT"
+                currency = amountObj.currency
+                this.amount = amountObj.amount.toPlainString()
+                counterpartBic = creditorObj.bic
+                counterpartIban = creditorObj.iban
+                counterpartName = creditorObj.name
+                bankAccount = NexusBankAccountEntity.new { /* FIXME; exchange 
should communicate this value */ }
+                bookingDate = DateTime.now().millis
+                status = "BOOK"
             }
-            call.respond(
-                TextContent(
-                    customConverter(
-                        TalerAddIncomingResponse(
-                            timestamp = GnunetTimestamp(bookingDate/ 1000),
-                            row_id = opaque_row_id
-                        )
-                    ),
-                ContentType.Application.Json
+        } else null
+
+        val row = TalerRequestedPaymentEntity.new {
+            preparedPayment = pain001 // not really used/needed, just here to 
silence warnings
+            exchangeBaseUrl = transferRequest.exchange_base_url
+            requestUId = transferRequest.request_uid
+            amount = transferRequest.amount
+            wtid = transferRequest.wtid
+            creditAccount = transferRequest.credit_account
+            rawConfirmed = rawEbics
+        }
+
+        row.id.value
+    }
+    return call.respond(
+        HttpStatusCode.OK,
+        TextContent(
+            customConverter(
+                TalerTransferResponse(
+                    /**
+                     * Normally should point to the next round where the 
background
+                     * routine will send new PAIN.001 data to the bank; work 
in progress..
+                     */
+                    timestamp = GnunetTimestamp(DateTime.now().millis),
+                    row_id = opaque_row_id
                 )
-            )
-            return@post
+            ),
+            ContentType.Application.Json
+        )
+    )
+}
+
+suspend fun talerAddIncoming(call: ApplicationCall): Unit {
+    val exchangeUser = authenticateRequest(call.request)
+    val addIncomingData = call.receive<TalerAdminAddIncoming>()
+    val debtor = parsePayto(addIncomingData.debit_account)
+    val amount = parseAmount(addIncomingData.amount)
+    val (bookingDate, opaque_row_id) = transaction {
+        val rawPayment = RawBankTransactionEntity.new {
+            unstructuredRemittanceInformation = addIncomingData.reserve_pub
+            transactionType = "CRDT"
+            currency = amount.currency
+            this.amount = amount.amount.toPlainString()
+            counterpartBic = debtor.bic
+            counterpartName = debtor.name
+            counterpartIban = debtor.iban
+            bookingDate = DateTime.now().millis
+            status = "BOOK"
+            bankAccount = NexusBankAccountEntity.new { /* FIXME; exchange 
should communicate this value */ }
         }
+        /** This payment is "valid by default" and will be returned
+         * as soon as the exchange will ask for new payments.  */
+        val row = TalerIncomingPaymentEntity.new {
+            payment = rawPayment
+            valid = true
+        }
+        Pair(rawPayment.bookingDate, row.id.value)
+    }
+    return call.respond(
+        TextContent(
+            customConverter(
+                TalerAddIncomingResponse(
+                    timestamp = GnunetTimestamp(bookingDate/ 1000),
+                    row_id = opaque_row_id
+                )
+            ),
+            ContentType.Application.Json
+        )
+    )
+}
 
-        /** This endpoint triggers the examination of raw incoming payments 
aimed
-         * at separating the good payments (those that will lead to a new 
reserve
-         * being created), from the invalid payments (those with a invalid 
subject
-         * that will soon be refunded.)  Recently, the examination of raw 
OUTGOING
-         * payment was added as well.
+fun ingestTransactions() {
+    transaction {
+        val subscriberAccount = NexusBankAccountEntity.new { /* FIXME; 
exchange should communicate this value */ }
+        /**
+         * Search for fresh incoming payments in the raw table, and making 
pointers
+         * from the Taler incoming payments table to the found fresh (and 
valid!) payments.
          */
-        app.post("/{fcid}/taler/crunch-raw-transactions") {
-            val id = ensureNonNull(call.parameters["id"])
-            // first find highest ID value of already processed rows.
-            transaction {
-                val subscriberAccount = NexusBankAccountEntity.new { /* FIXME; 
exchange should communicate this value */ }
-                /**
-                 * Search for fresh incoming payments in the raw table, and 
making pointers
-                 * from the Taler incoming payments table to the found fresh 
(and valid!) payments.
-                 */
-                val latestIncomingPaymentId: Long = 
TalerIncomingPaymentEntity.getLast()
-                RawBankTransactionEntity.find {
-                    /** Those with exchange bank account involved */
-                    RawBankTransactionsTable.bankAccount eq 
subscriberAccount.id.value and
-                            /** Those that are incoming */
-                            (RawBankTransactionsTable.transactionType eq 
"CRDT") and
-                            /** Those that are booked */
-                            (RawBankTransactionsTable.status eq "BOOK") and
-                            /** Those that came later than the latest 
processed payment */
-                            
(RawBankTransactionsTable.id.greater(latestIncomingPaymentId))
-
+        val latestIncomingPaymentId: Long = 
TalerIncomingPaymentEntity.getLast()
+        RawBankTransactionEntity.find {
+            /** Those with exchange bank account involved */
+            RawBankTransactionsTable.bankAccount eq subscriberAccount.id.value 
and
+                    /** Those that are incoming */
+                    (RawBankTransactionsTable.transactionType eq "CRDT") and
+                    /** Those that are booked */
+                    (RawBankTransactionsTable.status eq "BOOK") and
+                    /** Those that came later than the latest processed 
payment */
+                    
(RawBankTransactionsTable.id.greater(latestIncomingPaymentId))
                 }.forEach {
                     if (duplicatePayment(it)) {
                         logger.warn("Incoming payment already seen")
@@ -373,140 +354,89 @@ class Taler(app: Route) {
                             "Incoming payment already seen"
                         )
                     }
-                    if 
(CryptoUtil.checkValidEddsaPublicKey(it.unstructuredRemittanceInformation)) {
-                        TalerIncomingPaymentEntity.new {
-                            payment = it
-                            valid = true
-                        }
-                    } else {
-                        TalerIncomingPaymentEntity.new {
-                            payment = it
-                            valid = false
-                        }
-                    }
+            if 
(CryptoUtil.checkValidEddsaPublicKey(it.unstructuredRemittanceInformation)) {
+                TalerIncomingPaymentEntity.new {
+                    payment = it
+                    valid = true
                 }
-                /**
-                 * Search for fresh OUTGOING transactions acknowledged by the 
bank.  As well
-                 * searching only for BOOKed transactions, even though status 
changes should
-                 * be really unexpected here.
-                 */
-                val latestOutgoingPaymentId = 
TalerRequestedPaymentEntity.getLast()
-                RawBankTransactionEntity.find {
-                    /** Those that came after the last processed payment */
-                    RawBankTransactionsTable.id greater 
latestOutgoingPaymentId and
-                            /** Those involving the exchange bank account */
-                            (RawBankTransactionsTable.bankAccount eq 
subscriberAccount.id.value) and
-                            /** Those that are outgoing */
-                            (RawBankTransactionsTable.transactionType eq 
"DBIT")
-                }.forEach {
-                    if (paymentFailed(it)) {
-                        logger.error("Bank didn't accept one payment from the 
exchange")
-                        throw NexusError(
-                            HttpStatusCode.InternalServerError,
-                            "Bank didn't accept one payment from the exchange"
-                        )
-                    }
-                    if (duplicatePayment(it)) {
-                        logger.warn("Incomint payment already seen")
-                        throw NexusError(
-                            HttpStatusCode.InternalServerError,
-                            "Outgoing payment already seen"
-                        )
-                    }
-                    var talerRequested = TalerRequestedPaymentEntity.find {
-                        TalerRequestedPayments.wtid eq 
it.unstructuredRemittanceInformation
-                    }.firstOrNull() ?: throw NexusError(
-                        HttpStatusCode.InternalServerError,
-                        "Unrecognized fresh outgoing payment met (subject: 
${it.unstructuredRemittanceInformation})."
-                    )
-                    talerRequested.rawConfirmed = it
+            } else {
+                TalerIncomingPaymentEntity.new {
+                    payment = it
+                    valid = false
                 }
             }
-
-            call.respondText (
-                "New raw payments Taler-processed",
-                ContentType.Text.Plain,
-                HttpStatusCode.OK
-            )
-            return@post
         }
-        /** Responds only with the payments that the EXCHANGE made.  Typically 
to
-         * merchants but possibly to refund invalid incoming payments.  A 
payment is
-         * counted only if was once confirmed by the bank.
+        /**
+         * Search for fresh OUTGOING transactions acknowledged by the bank.  
As well
+         * searching only for BOOKed transactions, even though status changes 
should
+         * be really unexpected here.
          */
-        app.get("/{fcid}/taler/history/outgoing") {
-            /* sanitize URL arguments */
-            val subscriberId = authenticateRequest(call.request)
-            val delta: Int = expectInt(call.expectUrlParameter("delta"))
-            val start: Long = 
handleStartArgument(call.request.queryParameters["start"], delta)
-            val startCmpOp = getComparisonOperator(delta, start, 
TalerRequestedPayments)
-            /* retrieve database elements */
-            val history = TalerOutgoingHistory()
-            transaction {
-                /** Retrieve all the outgoing payments from the _clean Taler 
outgoing table_ */
-                val subscriberBankAccount = NexusBankAccountEntity.new { /* 
FIXME; exchange should communicate this value */ }
-                val reqPayments = TalerRequestedPaymentEntity.find {
-                    TalerRequestedPayments.rawConfirmed.isNotNull() and 
startCmpOp
-                }.orderTaler(delta)
-                if (reqPayments.isNotEmpty()) {
-                    reqPayments.subList(0, min(abs(delta), 
reqPayments.size)).forEach {
-                        history.outgoing_transactions.add(
-                            TalerOutgoingBankTransaction(
-                                row_id = it.id.value,
-                                amount = it.amount,
-                                wtid = it.wtid,
-                                date = 
GnunetTimestamp(it.rawConfirmed?.bookingDate?.div(1000) ?: throw NexusError(
-                                    HttpStatusCode.InternalServerError, "Null 
value met after check, VERY strange.")),
-                                credit_account = it.creditAccount,
-                                debit_account = 
buildPaytoUri(subscriberBankAccount.iban, subscriberBankAccount.bankCode),
-                                exchange_base_url = 
"FIXME-to-request-along-subscriber-registration"
-                            )
-                        )
-                    }
-                }
+        val latestOutgoingPaymentId = TalerRequestedPaymentEntity.getLast()
+        RawBankTransactionEntity.find {
+            /** Those that came after the last processed payment */
+            RawBankTransactionsTable.id greater latestOutgoingPaymentId and
+                    /** Those involving the exchange bank account */
+                    (RawBankTransactionsTable.bankAccount eq 
subscriberAccount.id.value) and
+                    /** Those that are outgoing */
+                    (RawBankTransactionsTable.transactionType eq "DBIT")
+        }.forEach {
+            if (paymentFailed(it)) {
+                logger.error("Bank didn't accept one payment from the 
exchange")
+                throw NexusError(
+                    HttpStatusCode.InternalServerError,
+                    "Bank didn't accept one payment from the exchange"
+                )
+            }
+            if (duplicatePayment(it)) {
+                logger.warn("Incoming payment already seen")
+                throw NexusError(
+                    HttpStatusCode.InternalServerError,
+                    "Outgoing payment already seen"
+                )
             }
-            call.respond(
-                HttpStatusCode.OK,
-                TextContent(customConverter(history), 
ContentType.Application.Json)
+            var talerRequested = TalerRequestedPaymentEntity.find {
+                TalerRequestedPayments.wtid eq 
it.unstructuredRemittanceInformation
+            }.firstOrNull() ?: throw NexusError(
+                HttpStatusCode.InternalServerError,
+                "Unrecognized fresh outgoing payment met (subject: 
${it.unstructuredRemittanceInformation})."
             )
-            return@get
+            talerRequested.rawConfirmed = it
         }
-        /** Responds only with the valid incoming payments */
-        app.get("/{fcid}/taler/history/incoming") {
-            val exchangeUser = authenticateRequest(call.request)
-            val delta: Int = expectInt(call.expectUrlParameter("delta"))
-            val start: Long = 
handleStartArgument(call.request.queryParameters["start"], delta)
-            val history = TalerIncomingHistory()
-            val startCmpOp = getComparisonOperator(delta, start, 
TalerIncomingPayments)
-            transaction {
-                val orderedPayments = TalerIncomingPaymentEntity.find {
-                    TalerIncomingPayments.valid eq true and startCmpOp
-                }.orderTaler(delta)
-                if (orderedPayments.isNotEmpty()) {
-                    orderedPayments.subList(0, min(abs(delta), 
orderedPayments.size)).forEach {
-                        history.incoming_transactions.add(
-                            TalerIncomingBankTransaction(
-                                date = GnunetTimestamp(it.payment.bookingDate 
/ 1000),
-                                row_id = it.id.value,
-                                amount = 
"${it.payment.currency}:${it.payment.amount}",
-                                reserve_pub = 
it.payment.unstructuredRemittanceInformation,
-                                credit_account = buildPaytoUri(
-                                    it.payment.bankAccount.accountHolder,
-                                    it.payment.bankAccount.iban,
-                                    it.payment.bankAccount.bankCode
-                                ),
-                                debit_account = buildPaytoUri(
-                                    it.payment.counterpartName,
-                                    it.payment.counterpartIban,
-                                    it.payment.counterpartBic
-                                )
-                            )
+    }
+}
+
+suspend fun historyIncoming(call: ApplicationCall): Unit {
+    val exchangeUser = authenticateRequest(call.request)
+    val delta: Int = expectInt(call.expectUrlParameter("delta"))
+    val start: Long = 
handleStartArgument(call.request.queryParameters["start"], delta)
+    val history = TalerIncomingHistory()
+    val startCmpOp = getComparisonOperator(delta, start, TalerIncomingPayments)
+    transaction {
+        val orderedPayments = TalerIncomingPaymentEntity.find {
+            TalerIncomingPayments.valid eq true and startCmpOp
+        }.orderTaler(delta)
+        if (orderedPayments.isNotEmpty()) {
+            orderedPayments.subList(0, min(abs(delta), 
orderedPayments.size)).forEach {
+                history.incoming_transactions.add(
+                    TalerIncomingBankTransaction(
+                        date = GnunetTimestamp(it.payment.bookingDate / 1000),
+                        row_id = it.id.value,
+                        amount = "${it.payment.currency}:${it.payment.amount}",
+                        reserve_pub = 
it.payment.unstructuredRemittanceInformation,
+                        credit_account = buildPaytoUri(
+                            it.payment.bankAccount.accountHolder,
+                            it.payment.bankAccount.iban,
+                            it.payment.bankAccount.bankCode
+                        ),
+                        debit_account = buildPaytoUri(
+                            it.payment.counterpartName,
+                            it.payment.counterpartIban,
+                            it.payment.counterpartBic
                         )
-                    }
-                }
+                    )
+                )
             }
-            call.respond(TextContent(customConverter(history), 
ContentType.Application.Json))
-            return@get
         }
     }
+    return call.respond(TextContent(customConverter(history), 
ContentType.Application.Json))
 }
\ 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]