gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: Snack-machine demo changes.


From: gnunet
Subject: [libeufin] branch master updated: Snack-machine demo changes.
Date: Wed, 04 May 2022 10:49:15 +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 e9cc8a8e Snack-machine demo changes.
e9cc8a8e is described below

commit e9cc8a8e44b6ad1269a53056500b45d564dc091b
Author: ms <ms@taler.net>
AuthorDate: Wed May 4 10:46:47 2022 +0200

    Snack-machine demo changes.
    
    - set creditor name
    - make signup bonus optional
    - make currency mandatory on the CLI (simulate-incoming-transaction 
subcommand)
---
 cli/bin/libeufin-cli                               | 14 ++++++++--
 .../src/main/kotlin/tech/libeufin/sandbox/DB.kt    |  2 ++
 .../main/kotlin/tech/libeufin/sandbox/Helpers.kt   | 10 +++++--
 .../src/main/kotlin/tech/libeufin/sandbox/JSON.kt  |  4 ++-
 .../src/main/kotlin/tech/libeufin/sandbox/Main.kt  | 32 ++++++++++++++--------
 util/src/main/kotlin/amounts.kt                    | 15 ++++++++++
 6 files changed, 58 insertions(+), 19 deletions(-)

diff --git a/cli/bin/libeufin-cli b/cli/bin/libeufin-cli
index 956859ff..e40c8f1a 100755
--- a/cli/bin/libeufin-cli
+++ b/cli/bin/libeufin-cli
@@ -1273,13 +1273,21 @@ def sandbox_demobank_info(obj, bank_account):
     default=False,
     help="Decides whether a bank account is public.",
 )
+@click.option(
+    "--name",
+    default=False,
+    help="Person name",
+)
 @click.pass_obj
-def sandbox_demobank_register(obj, public):
+def sandbox_demobank_register(obj, public, name):
     url = obj.access_api_url ("/testing/register")
+    req = dict(username=obj.username, password=obj.password, isPublic=public)
+    if name:
+        req.update(name=name)
     try:
         resp = post(
             url,
-            json=dict(username=obj.username, password=obj.password, 
isPublic=public),
+            json=req,
         )
     except Exception as e:
         print(e)
@@ -1386,7 +1394,7 @@ def bankaccount_generate_transactions(obj, account_label):
 @click.option(
     "--debtor-name", help="name of the person who is sending the payment", 
prompt=True
 )
-@click.option("--amount", help="amount, no currency", prompt=True)
+@click.option("--amount", help="amount with currency (currency:x.y)", 
prompt=True)
 @click.option("--subject", help="payment subject", prompt=True)
 @click.pass_obj
 def simulate_incoming_transaction(
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index caf82ad5..c2dd5662 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -92,6 +92,7 @@ enum class KeyState {
 object DemobankConfigsTable : LongIdTable() {
     val currency = text("currency")
     val allowRegistrations = bool("allowRegistrations")
+    val withSignupBonus = bool("withSignupBonus")
     val bankDebtLimit = integer("bankDebtLimit")
     val usersDebtLimit = integer("usersDebtLimit")
     val name = text("hostname")
@@ -103,6 +104,7 @@ class DemobankConfigEntity(id: EntityID<Long>) : 
LongEntity(id) {
     companion object : 
LongEntityClass<DemobankConfigEntity>(DemobankConfigsTable)
     var currency by DemobankConfigsTable.currency
     var allowRegistrations by DemobankConfigsTable.allowRegistrations
+    var withSignupBonus by DemobankConfigsTable.withSignupBonus
     var bankDebtLimit by DemobankConfigsTable.bankDebtLimit
     var usersDebtLimit by DemobankConfigsTable.usersDebtLimit
     var name by DemobankConfigsTable.name
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
index 372fc9cc..b02307f9 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
@@ -136,7 +136,10 @@ fun getCustomer(username: String): DemobankCustomerEntity {
 /**
  * Get person name from a customer's username.
  */
-fun getPersonNameFromCustomer(ownerUsername: String): String {
+fun getPersonNameFromCustomer(ownerUsername: String?): String {
+    if (ownerUsername == null) {
+        return "Name unknown"
+    }
     return when (ownerUsername) {
         "admin" -> "admin" // Could be changed to Admin, or some different 
value.
         "bank" -> "The Bank"
@@ -146,7 +149,7 @@ fun getPersonNameFromCustomer(ownerUsername: String): 
String {
             ).firstOrNull() ?: throw internalServerError(
                 "Person name of '$ownerUsername' not found"
             )
-            ownerCustomer.name ?: "Unknown"
+            ownerCustomer.name ?: "Name unknown"
         }
     }
 }
@@ -170,7 +173,7 @@ fun getDefaultDemobank(): DemobankConfigEntity {
     )
 }
 
-fun maybeCreateDefaultDemobank() {
+fun maybeCreateDefaultDemobank(withSignupBonus: Boolean = false) {
     transaction {
         if (DemobankConfigEntity.all().empty()) {
             DemobankConfigEntity.new {
@@ -179,6 +182,7 @@ fun maybeCreateDefaultDemobank() {
                 usersDebtLimit = 10000
                 allowRegistrations = true
                 name = "default"
+                this.withSignupBonus = withSignupBonus
             }
             // Give one demobank a own bank account, mainly to award
             // customer upon registration.
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
index 33cc8531..4636850f 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
@@ -95,7 +95,9 @@ data class CustomerRegistration(
     val password: String,
     val isPublic: Boolean = false,
     // When missing, it's autogenerated.
-    val iban: String?
+    val iban: String?,
+    // When missing, stays null in the DB.
+    val name: String?
 )
 
 // Could be used as a general bank account info container.
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index 142b6ed2..2cae0f34 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -295,6 +295,10 @@ class Serve : CliktCommand("Run sandbox HTTP server") {
         help = "Bind the Sandbox to the Unix domain socket at PATH.  
Overrides" +
                 " --port, when both are given", metavar = "PATH"
     )
+    private val withSignupBonus by option(
+        "--with-signup-bonus",
+        help = "Award new customers with 100 units of currency!"
+    ).flag("--without-signup-bonus", default = false)
 
     override fun run() {
         WITH_AUTH = auth
@@ -305,7 +309,7 @@ class Serve : CliktCommand("Run sandbox HTTP server") {
             exitProcess(1)
         }
         execThrowableOrTerminate { 
dbCreateTables(getDbConnFromEnv(SANDBOX_DB_ENV_VAR_NAME)) }
-        maybeCreateDefaultDemobank()
+        maybeCreateDefaultDemobank(withSignupBonus)
         if (withUnixSocket != null) {
             startServer(
                 withUnixSocket ?: throw Exception("Could not use the Unix 
domain socket path value!"),
@@ -590,16 +594,10 @@ val sandboxApp: Application.() -> Unit = {
         // Book one incoming payment for the requesting account.
         // The debtor is not required to have an account at this Sandbox.
         post("/admin/bank-accounts/{label}/simulate-incoming-transaction") {
-            call.request.basicAuth()
+            val username = call.request.basicAuth()
             val body = call.receiveJson<IncomingPaymentInfo>()
             // FIXME: generate nicer UUID!
             val accountLabel = ensureNonNull(call.parameters["label"])
-            if (!validatePlainAmount(body.amount)) {
-                throw SandboxError(
-                    HttpStatusCode.BadRequest,
-                    "invalid amount (should be plain amount without currency)"
-                )
-            }
             val reqDebtorBic = body.debtorBic
             if (reqDebtorBic != null && !validateBic(reqDebtorBic)) {
                 throw SandboxError(
@@ -607,8 +605,16 @@ val sandboxApp: Application.() -> Unit = {
                     "invalid BIC"
                 )
             }
+            val (amount, currency) = parseAmountAsString(body.amount)
             transaction {
                 val demobank = getDefaultDemobank()
+                /**
+                 * This API needs compatibility with the currency-less format.
+                 */
+                if (currency != null) {
+                    if (currency != demobank.currency)
+                        throw SandboxError(HttpStatusCode.BadRequest, 
"Currency ${currency} not supported.")
+                }
                 val account = getBankAccountFromLabel(
                     accountLabel, demobank
                 )
@@ -616,18 +622,18 @@ val sandboxApp: Application.() -> Unit = {
                 BankAccountTransactionEntity.new {
                     creditorIban = account.iban
                     creditorBic = account.bic
-                    creditorName = "Creditor Name" // FIXME: Waits to get this 
value from the DemobankCustomer type.
+                    creditorName = getPersonNameFromCustomer(username)
                     debtorIban = body.debtorIban
                     debtorBic = reqDebtorBic
                     debtorName = body.debtorName
                     subject = body.subject
-                    amount = body.amount
+                    this.amount = amount
                     date = getUTCnow().toInstant().toEpochMilli()
                     accountServicerReference = "sandbox-$randId"
                     this.account = account
                     direction = "CRDT"
                     this.demobank = demobank
-                    currency = demobank.currency
+                    this.currency = demobank.currency
                 }
             }
             call.respond(object {})
@@ -1436,8 +1442,10 @@ val sandboxApp: Application.() -> Unit = {
                         DemobankCustomerEntity.new {
                             username = req.username
                             passwordHash = CryptoUtil.hashpw(req.password)
+                            name = req.name // nullable
                         }
-                        bankAccount.bonus("${demobank.currency}:100")
+                        if (demobank.withSignupBonus)
+                            bankAccount.bonus("${demobank.currency}:100")
                         bankAccount
                     }
                     val balance = balanceForAccount(bankAccount)
diff --git a/util/src/main/kotlin/amounts.kt b/util/src/main/kotlin/amounts.kt
index 327bcbd4..5528a35b 100644
--- a/util/src/main/kotlin/amounts.kt
+++ b/util/src/main/kotlin/amounts.kt
@@ -28,6 +28,21 @@ fun validatePlainAmount(plainAmount: String): Boolean {
     return re.matches(plainAmount)
 }
 
+/**
+ * Parse an "amount" where the currency is optional.  It returns
+ * a pair where the first item is always the amount, and the second
+ * is the currency or null (when this one wasn't given in the input)
+ */
+fun parseAmountAsString(amount: String): Pair<String, String?> {
+    val match = Regex("^([A-Z]+:)?([0-9]+(\\.[0-9]+)?)$").find(amount) ?: throw
+    UtilError(HttpStatusCode.BadRequest, "invalid amount: $amount")
+    var (currency, number) = match.destructured
+    // Currency given, need to strip the ":".
+    if (currency.isNotEmpty())
+        currency = currency.dropLast(1)
+    return Pair(number, if (currency.isEmpty()) null else currency)
+}
+
 fun parseAmount(amount: String): AmountWithCurrency {
     val match = Regex("([A-Z]+):([0-9]+(\\.[0-9]+)?)").find(amount) ?: throw
     UtilError(HttpStatusCode.BadRequest, "invalid amount: $amount")

-- 
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]