gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: Separation between bank account and cu


From: gnunet
Subject: [libeufin] branch master updated: Separation between bank account and customer accounts.
Date: Tue, 19 Oct 2021 12:56:48 +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 d43df56  Separation between bank account and customer accounts.
d43df56 is described below

commit d43df5630d4d1a1097ba1552d8e950a9056b860d
Author: ms <ms@taler.net>
AuthorDate: Tue Oct 19 12:55:47 2021 +0200

    Separation between bank account and customer accounts.
    
    Addressing confuion given by the 'name' field of the BankAccount
    type.  Choosing 'label' to indicate bank accounts and 'name' for
    customers.
---
 .../src/main/kotlin/tech/libeufin/sandbox/DB.kt    |  18 ++-
 .../tech/libeufin/sandbox/EbicsProtocolBackend.kt  |   6 +-
 .../src/main/kotlin/tech/libeufin/sandbox/JSON.kt  |   5 +
 .../src/main/kotlin/tech/libeufin/sandbox/Main.kt  | 148 ++++++++++++---------
 .../kotlin/tech/libeufin/sandbox/bankAccount.kt    |   8 +-
 5 files changed, 105 insertions(+), 80 deletions(-)

diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index 4186087..2433d48 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -112,24 +112,20 @@ class DemobankConfigEntity(id: EntityID<Long>) : 
LongEntity(id) {
 object DemobankCustomersTable : LongIdTable() {
     val isPublic = bool("isPublic").default(false)
     val demobankConfig = reference("demobankConfig", DemobankConfigsTable)
-    val balance = text("balance")
+    val bankAccount = reference("bankAccount", BankAccountsTable)
     val username = text("username")
     val passwordHash = text("passwordHash")
-    val isDebit = bool("isDebit").default(false)
     val name = text("name").nullable()
-    val iban = text("iban")
 }
 
 class DemobankCustomerEntity(id: EntityID<Long>) : LongEntity(id) {
     companion object : 
LongEntityClass<DemobankCustomerEntity>(DemobankCustomersTable)
     var isPublic by DemobankCustomersTable.isPublic
-    var demobankConfig by DemobankCustomersTable.demobankConfig
-    var balance by DemobankCustomersTable.balance
+    var demobankConfig by DemobankConfigEntity referencedOn 
DemobankCustomersTable.demobankConfig
+    var bankAccount by BankAccountEntity referencedOn 
DemobankCustomersTable.bankAccount
     var username by DemobankCustomersTable.username
     var passwordHash by DemobankCustomersTable.passwordHash
-    var isDebit by DemobankCustomersTable.isDebit
     var name by DemobankCustomersTable.name
-    var iban by DemobankCustomersTable.iban
 }
 
 /**
@@ -371,10 +367,11 @@ class BankAccountTransactionEntity(id: EntityID<Long>) : 
LongEntity(id) {
  */
 object BankAccountsTable : IntIdTable() {
     val iban = text("iban")
-    val bic = text("bic")
-    val name = text("name")
+    val bic = text("bic").default("EUSANDBOX")
     val label = text("label").uniqueIndex("accountLabelIndex")
     val currency = text("currency")
+    val isDebit = bool("isDebit").default(false)
+    val balance = text("balance")
 }
 
 class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) {
@@ -382,9 +379,10 @@ class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) 
{
 
     var iban by BankAccountsTable.iban
     var bic by BankAccountsTable.bic
-    var name by BankAccountsTable.name
     var label by BankAccountsTable.label
     var currency by BankAccountsTable.currency
+    var isDebit by BankAccountsTable.isDebit
+    var balance by BankAccountsTable.balance
 }
 
 object BankAccountStatementsTable : IntIdTable() {
diff --git 
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 0659c73..7a54d64 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -972,7 +972,11 @@ private fun makePartnerInfo(subscriber: 
EbicsSubscriberEntity): EbicsTypes.Partn
         this.accountInfoList = listOf(
             EbicsTypes.AccountInfo().apply {
                 this.id = bankAccount.label
-                this.accountHolder = bankAccount.name
+                /**
+                 * FIXME:
+                 * This value waits to be extracted from the DemobankCustomer 
type.
+                 */
+                this.accountHolder = "Account Holder"
                 this.accountNumberList = listOf(
                     EbicsTypes.GeneralAccountNumber().apply {
                         this.international = true
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
index 92992e0..7756d98 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
@@ -67,6 +67,11 @@ data class BankAccountRequest(
     val subscriber: EbicsSubscriberElement,
     val iban: String,
     val bic: String,
+    /**
+     * Obsolete: kept around to allow progressive porting of tests.
+     * This value used to represent a _person_ name, but the new 
DemobankCustomer
+     * type is now responsible for that.
+     */
     val name: String,
     val label: String,
     val currency: String
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index fc53da8..fe6fcac 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -278,6 +278,11 @@ class Serve : CliktCommand("Run sandbox HTTP server") {
     }
 }
 
+private fun getCustomerFromDb(username: String): DemobankCustomerEntity {
+    return transaction { DemobankCustomerEntity.find {
+        DemobankCustomersTable.username eq username
+    }.firstOrNull() } ?: throw notFound("Customer with username '$username' 
not found")
+}
 private fun getJsonFromDemobankConfig(fromDb: DemobankConfigEntity): Demobank {
     return Demobank(
         currency = fromDb.currency,
@@ -541,7 +546,6 @@ val sandboxApp: Application.() -> Unit = {
                 BankAccountEntity.new {
                     iban = body.iban
                     bic = body.bic
-                    name = body.name
                     label = body.label
                     currency = body.currency ?: "EUR"
                 }
@@ -566,7 +570,6 @@ val sandboxApp: Application.() -> Unit = {
                     val balance = "${bankAccount.currency}:${balance}"
                     val iban = bankAccount.iban
                     val bic = bankAccount.bic
-                    val name = bankAccount.name
                     val label = bankAccount.label
                 }
             }
@@ -600,7 +603,7 @@ val sandboxApp: Application.() -> Unit = {
                 tech.libeufin.sandbox.BankAccountTransactionEntity.new {
                     creditorIban = account.iban
                     creditorBic = account.bic
-                    creditorName = account.name
+                    creditorName = "Creditor Name" // FIXME: Waits to get this 
value from the DemobankCustomer type.
                     debtorIban = body.debtorIban
                     debtorBic = reqDebtorBic
                     debtorName = body.debtorName
@@ -640,7 +643,6 @@ val sandboxApp: Application.() -> Unit = {
                 subscriber.bankAccount = 
tech.libeufin.sandbox.BankAccountEntity.new {
                     iban = body.iban
                     bic = body.bic
-                    name = body.name
                     label = body.label
                     currency = body.currency.uppercase(java.util.Locale.ROOT)
                 }
@@ -658,10 +660,10 @@ val sandboxApp: Application.() -> Unit = {
                     accounts.add(
                         BankAccountInfo(
                             label = it.label,
-                            name = it.name,
                             bic = it.bic,
                             iban = it.iban,
-                            currency = it.currency
+                            currency = it.currency,
+                            name = "Bank account owner's name"
                         )
                     )
                 }
@@ -726,7 +728,7 @@ val sandboxApp: Application.() -> Unit = {
                     tech.libeufin.sandbox.BankAccountTransactionEntity.new {
                         creditorIban = account.iban
                         creditorBic = account.bic
-                        creditorName = account.name
+                        creditorName = "Creditor Name"
                         debtorIban = "DE64500105178797276788"
                         debtorBic = "DEUTDEBB101"
                         debtorName = "Max Mustermann"
@@ -746,7 +748,7 @@ val sandboxApp: Application.() -> Unit = {
                     BankAccountTransactionEntity.new {
                         debtorIban = account.iban
                         debtorBic = account.bic
-                        debtorName = account.name
+                        debtorName = "Debitor Name"
                         creditorIban = "DE64500105178797276788"
                         creditorBic = "DEUTDEBB101"
                         creditorName = "Max Mustermann"
@@ -896,49 +898,6 @@ val sandboxApp: Application.() -> Unit = {
             return@post
         }
 
-        /**
-         * Activates a withdraw operation of 1 currency unit with
-         * the default exchange, from a designated/constant customer.
-         */
-        get("/taler") {
-            call.request.basicAuth()
-            SandboxAssert(
-                currencyEnv != null,
-                "Currency not found.  Logs should have warned"
-            )
-            // check that the three canonical accounts exist
-            val wo = transaction {
-                val exchange = BankAccountEntity.find {
-                    BankAccountsTable.label eq "sandbox-account-exchange"
-                }.firstOrNull()
-                val customer = BankAccountEntity.find {
-                    BankAccountsTable.label eq "sandbox-account-customer"
-                }.firstOrNull()
-                val merchant = BankAccountEntity.find {
-                    BankAccountsTable.label eq "sandbox-account-merchant"
-                }.firstOrNull()
-
-                SandboxAssert(exchange != null, "exchange has no bank account")
-                SandboxAssert(customer != null, "customer has no bank account")
-                SandboxAssert(merchant != null, "merchant has no bank account")
-
-                // At this point, the three actors exist and a new withdraw 
operation can be created.
-                TalerWithdrawalEntity.new {
-                    // wopid is autogenerated, and momentarily the only column
-                }
-            }
-            val baseUrl = URL(call.request.getBaseUrl())
-            val ret = call.url {
-                protocol = URLProtocol(
-                    "taler".plus(if (baseUrl.protocol.lowercase() == "http") 
"+http" else ""),
-                    -1
-                )
-                pathComponents(baseUrl.path, "api", wo.wopid.toString())
-                encodedPath += "/"
-            }
-            call.respondText(ret)
-            return@get
-        }
         get("/api/config") {
             SandboxAssert(
                 currencyEnv != null,
@@ -1072,26 +1031,80 @@ val sandboxApp: Application.() -> Unit = {
 
             route("/access-api") {
 
+                post("/accounts/{account_name}/withdrawals") {
+                    val username = call.request.basicAuth()
+                    ensureDemobank(call.getUriComponent("demobankid"))
+                    /**
+                     * Check that the three canonical accounts exist.  The 
names
+                     * below match those used in the testing harnesses.
+                     */
+                    val wo: TalerWithdrawalEntity = transaction {
+                        val exchange = BankAccountEntity.find {
+                            BankAccountsTable.label eq 
"sandbox-account-exchange"
+                        }.firstOrNull()
+                        val customer = BankAccountEntity.find {
+                            BankAccountsTable.label eq 
"sandbox-account-customer"
+                        }.firstOrNull()
+                        val merchant = BankAccountEntity.find {
+                            BankAccountsTable.label eq 
"sandbox-account-merchant"
+                        }.firstOrNull()
+                        SandboxAssert(exchange != null, "exchange has no bank 
account")
+                        SandboxAssert(customer != null, "customer has no bank 
account")
+                        SandboxAssert(merchant != null, "merchant has no bank 
account")
+                        // At this point, the three actors exist and a new 
withdraw operation can be created.
+                        val wo = TalerWithdrawalEntity.new { /* wopid is 
autogenerated, and momentarily the only column */ }
+                        wo
+                    }
+                    val baseUrl = URL(call.request.getBaseUrl())
+                    val withdrawUri = call.url {
+                        protocol = URLProtocol(
+                            "taler".plus(if (baseUrl.protocol.lowercase() == 
"http") "+http" else ""),
+                            -1
+                        )
+                        pathComponents(baseUrl.path, "api", 
wo.wopid.toString())
+                        encodedPath += "/"
+                    }
+                    call.respond(object {
+                        val withdrawal_id = wo.id.value
+                        val taler_withdraw_uri = withdrawUri
+                    })
+                    return@post
+                }
+
+                // Confirm the wire transfer to the exchange.  Idempotent
+                post("/accounts/{account_name}/withdrawals/confirm") {
+
+
+                    return@post
+                }
                 get("/accounts/{account_name}") {
                     val username = call.request.basicAuth()
                     val accountAccessed = call.getUriComponent("account_name")
-                    if (username != accountAccessed) {
-                        throw forbidden("Account '$accountAccessed' not 
allowed for '$username'")
-                    }
-                    val customer = transaction {
-                        val res = DemobankCustomerEntity.find {
-                            DemobankCustomersTable.username eq username
+                    val bankAccount = transaction {
+                        val res = BankAccountEntity.find {
+                            BankAccountsTable.label eq accountAccessed
                         }.firstOrNull()
                         res
-                    } ?: throw internalServerError("Account '$accountAccessed' 
not found AFTER authentication!")
-                    val creditDebitIndicator = if (customer.isDebit) {
+                    } ?: throw notFound("Account '$accountAccessed' not found")
+
+                    // Check rights.
+                    if (WITH_AUTH) {
+                        val customer = getCustomerFromDb(username ?: throw 
internalServerError(
+                            "Optional authentication broken!"
+                        ))
+                        if (customer.bankAccount.label != accountAccessed) 
throw forbidden(
+                            "Customer '$username' cannot access bank account 
'$accountAccessed'"
+                        )
+                    }
+
+                    val creditDebitIndicator = if (bankAccount.isDebit) {
                         "debit"
                     } else {
                         "credit"
                     }
                     call.respond(object {
                         val balance = {
-                            val amount = customer.balance
+                            val amount = bankAccount.balance
                             val credit_debit_indicator = creditDebitIndicator
                         }
                     })
@@ -1119,8 +1132,8 @@ val sandboxApp: Application.() -> Unit = {
                             ret.publicAccounts.add(
                                 CustomerInfo(
                                     username = it.username,
-                                    balance = it.balance,
-                                    iban = it.iban,
+                                    balance = it.bankAccount.balance,
+                                    iban = it.bankAccount.iban,
                                     name = it.name ?: throw 
internalServerError(
                                         "Found name-less public account, 
username: ${it.username}"
                                     )
@@ -1155,12 +1168,17 @@ val sandboxApp: Application.() -> Unit = {
                     // Create new customer.
                     requireValidResourceName(req.username)
                     transaction {
-                        // FIXME: Since we now use IBANs everywhere, maybe the 
account should also be assigned an IBAN
+                        val bankAccount = BankAccountEntity.new {
+                            iban = getIban()
+                            label = req.username + "acct" // multiple accounts 
per username not allowed.
+                            currency = demobank.currency
+                            balance = "${demobank.currency}:0"
+                        }
                         DemobankCustomerEntity.new {
                             username = req.username
                             passwordHash = CryptoUtil.hashpw(req.password)
-                            demobankConfig = demobank.id
-                            iban = getIban()
+                            demobankConfig = demobank
+                            this.bankAccount = bankAccount
                         }
                     }
                     call.respondText("Registration successful")
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
index 3d5236a..151af01 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
@@ -165,10 +165,10 @@ fun wireTransfer(
         BankAccountTransactionEntity.new {
             creditorIban = credit.iban
             creditorBic = credit.bic
-            creditorName = credit.name
+            creditorName = "Creditor Name"
             debtorIban = debit.iban
             debtorBic = debit.bic
-            debtorName = debit.name
+            debtorName = "Debitor Name"
             subject = subjectArg
             this.amount = amountObj.amount.toString()
             currency = amountObj.currency
@@ -180,10 +180,10 @@ fun wireTransfer(
         BankAccountTransactionEntity.new {
             creditorIban = credit.iban
             creditorBic = credit.bic
-            creditorName = credit.name
+            creditorName = "Creditor Name"
             debtorIban = debit.iban
             debtorBic = debit.bic
-            debtorName = debit.name
+            debtorName = "Debitor Name"
             subject = subjectArg
             this.amount = amountObj.amount.toString()
             currency = amountObj.currency

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