gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: Cascade-deleting when deleting a user.


From: gnunet
Subject: [libeufin] branch master updated: Cascade-deleting when deleting a user.
Date: Fri, 24 Feb 2023 19:42:15 +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 bb3d2eea Cascade-deleting when deleting a user.
bb3d2eea is described below

commit bb3d2eea0671952b509f16b99f4aba6ef33142fb
Author: MS <ms@taler.net>
AuthorDate: Fri Feb 24 19:39:20 2023 +0100

    Cascade-deleting when deleting a user.
---
 nexus/src/test/kotlin/SandboxCircuitApiTest.kt     | 76 ++++++++++++++++++++--
 .../kotlin/tech/libeufin/sandbox/CircuitApi.kt     | 16 +++--
 .../src/main/kotlin/tech/libeufin/sandbox/DB.kt    | 17 ++++-
 3 files changed, 97 insertions(+), 12 deletions(-)

diff --git a/nexus/src/test/kotlin/SandboxCircuitApiTest.kt 
b/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
index 7d6e3944..350c5e8e 100644
--- a/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
+++ b/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
@@ -11,6 +11,7 @@ import org.junit.Ignore
 import org.junit.Test
 import tech.libeufin.sandbox.*
 import java.io.File
+import java.math.BigDecimal
 import java.util.*
 
 class SandboxCircuitApiTest {
@@ -28,6 +29,10 @@ class SandboxCircuitApiTest {
         }
     }
 
+    /**
+     * Checking that the ordinary user foo doesn't get to access bar's
+     * data, but admin does.
+     */
     @Test
     fun accessAccountsTest() {
         withTestDatabase {
@@ -258,12 +263,12 @@ class SandboxCircuitApiTest {
                     basicAuth("shop", "secret")
                     setBody("""{
                         "amount_debit": "TESTKUDOS:20",
-                        "amount_credit": "KUDOS:19",
+                        "amount_credit": "CHF:19",
                         "tan_channel": "file"
                     }""".trimIndent())
                 }
                 assert(R.status.value == HttpStatusCode.Accepted.value)
-                var operationUuid = 
mapper.readTree(R.readBytes()).get("uuid").asText()
+                val operationUuid = 
mapper.readTree(R.readBytes()).get("uuid").asText()
                 // Check that the operation is found by the bank.
                 R = 
client.get("/demobanks/default/circuit-api/cashouts/${operationUuid}") {
                     // Asking as the Admin but for the 'shop' account.
@@ -290,14 +295,37 @@ class SandboxCircuitApiTest {
                 }
                 respJson = mapper.readTree(R.bodyAsText())
                 assert(respJson.get("balance").get("amount").asText() == 
balanceAfterCashout)
-
+                // Attempt to cash-out with wrong regional currency.
+                R = client.post("/demobanks/default/circuit-api/cashouts") {
+                    contentType(ContentType.Application.Json)
+                    basicAuth("shop", "secret")
+                    setBody("""{
+                        "amount_debit": "NOTFOUND:20",
+                        "amount_credit": "CHF:19",
+                        "tan_channel": "file"
+                    }""".trimIndent())
+                    expectSuccess = false
+                }
+                assert(R.status.value == HttpStatusCode.BadRequest.value)
+                // Attempt to cash-out with wrong fiat currency.
+                R = client.post("/demobanks/default/circuit-api/cashouts") {
+                    contentType(ContentType.Application.Json)
+                    basicAuth("shop", "secret")
+                    setBody("""{
+                        "amount_debit": "TESTKUDOS:20",
+                        "amount_credit": "NOTFOUND:19",
+                        "tan_channel": "file"
+                    }""".trimIndent())
+                    expectSuccess = false
+                }
+                assert(R.status.value == HttpStatusCode.BadRequest.value)
                 // Create a new cash-out and delete it.
                 R = client.post("/demobanks/default/circuit-api/cashouts") {
                     contentType(ContentType.Application.Json)
                     basicAuth("shop", "secret")
                     setBody("""{
                         "amount_debit": "TESTKUDOS:20",
-                        "amount_credit": "KUDOS:19",
+                        "amount_credit": "CHF:19",
                         "tan_channel": "file"
                     }""".trimIndent())
                 }
@@ -451,6 +479,46 @@ class SandboxCircuitApiTest {
         }
     }
 
+    /**
+     * Testing that deleting a user doesn't cause a _different_ user
+     * to lose data.
+     */
+    @Test
+    fun deletionIsolation() {
+        withTestDatabase {
+            prepSandboxDb()
+            transaction {
+                // Admin makes sure foo has balance 100.
+                wireTransfer(
+                    "admin",
+                    "foo",
+                    subject = "set to 100",
+                    amount = "TESTKUDOS:100"
+                )
+                val fooBalance = getBalance("foo")
+                assert(fooBalance == BigDecimal("100"))
+                // Foo pays 3 to bar.
+                wireTransfer(
+                    "foo",
+                    "bar",
+                    subject = "donation",
+                    amount = "TESTKUDOS:3"
+                )
+                val barBalance = getBalance("bar")
+                assert(barBalance == BigDecimal("3"))
+                // Deleting foo from the system.
+                transaction {
+                    val uBankAccount = getBankAccountFromLabel("foo")
+                    val uCustomerProfile = getCustomer("foo")
+                    uBankAccount.delete()
+                    uCustomerProfile.delete()
+                }
+                val barBalanceUpdate = getBalance("bar")
+                assert(barBalance == BigDecimal("3"))
+            }
+        }
+    }
+
     @Test
     fun tanCommandTest() {
         /**
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
index 4fc1ac48..e3903923 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
@@ -33,13 +33,13 @@ data class CircuitCashoutRequest(
      */
     val tan_channel: String?
 )
-
+const val FIAT_CURRENCY = "CHF" // FIXME: make configurable.
 // Configuration response:
 data class ConfigResp(
     val name: String = "circuit",
     val version: String = SANDBOX_VERSION,
     val ratios_and_fees: RatioAndFees,
-    val fiat_currency: String = "CHF" // FIXME: make configurable.
+    val fiat_currency: String = FIAT_CURRENCY
 )
 
 // After fixing #7527, the values held by this
@@ -370,10 +370,16 @@ fun circuitApi(circuitRoute: Route) {
         val amountDebit = parseAmount(req.amount_debit) // amount before rates.
         val amountCredit = parseAmount(req.amount_credit) // amount after 
rates, as expected by the client
         val demobank = ensureDemobank(call)
+        // Currency check of the cash-out's circuit part.
         if (amountDebit.currency != demobank.currency)
-            throw badRequest("The '${req::amount_debit.name}' field has the 
wrong currency")
-        if (amountCredit.currency == demobank.currency)
-            throw badRequest("The '${req::amount_credit.name}' field didn't 
change the currency.")
+            throw badRequest("'${req::amount_debit.name}' 
(${req.amount_debit})" +
+                    " doesn't match the regional currency 
(${demobank.currency})"
+            )
+        // Currency check of the cash-out's fiat part.
+        if (amountCredit.currency != FIAT_CURRENCY)
+            throw badRequest("'${req::amount_credit.name}' 
(${req.amount_credit})" +
+                    " doesn't match the fiat currency ($FIAT_CURRENCY)."
+            )
         // check if TAN is supported.  Default to SMS, if that's missing.
         val tanChannel = req.tan_channel?.uppercase() ?: 
SupportedTanChannels.SMS.name
         if (!isTanChannelSupported(tanChannel))
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt 
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index b6556cb4..3281b67a 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -182,7 +182,11 @@ object EbicsSubscribersTable : IntIdTable() {
     val authenticationKey = reference("authorizationKey", 
EbicsSubscriberPublicKeysTable).nullable()
     val nextOrderID = integer("nextOrderID")
     val state = enumeration("state", SubscriberState::class)
-    val bankAccount = reference("bankAccount", BankAccountsTable).nullable()
+    val bankAccount = reference(
+        "bankAccount",
+        BankAccountsTable,
+        onDelete = ReferenceOption.CASCADE
+    ).nullable()
 }
 
 class EbicsSubscriberEntity(id: EntityID<Int>) : IntEntity(id) {
@@ -297,7 +301,11 @@ class EbicsUploadTransactionChunkEntity(id: 
EntityID<String>) : Entity<String>(i
  * to the main ledger.
  */
 object BankAccountFreshTransactionsTable : LongIdTable() {
-    val transactionRef = reference("transaction", BankAccountTransactionsTable)
+    val transactionRef = reference(
+        "transaction",
+        BankAccountTransactionsTable,
+        onDelete = ReferenceOption.CASCADE
+    )
 }
 class BankAccountFreshTransactionEntity(id: EntityID<Long>) : LongEntity(id) {
     companion object : 
LongEntityClass<BankAccountFreshTransactionEntity>(BankAccountFreshTransactionsTable)
@@ -331,7 +339,10 @@ object BankAccountTransactionsTable : LongIdTable() {
      * Bank account of the party whose 'direction' refers.  This version allows
      * only both parties to be registered at the running Sandbox.
      */
-    val account = reference("account", BankAccountsTable)
+    val account = reference(
+        "account", BankAccountsTable,
+        onDelete = ReferenceOption.CASCADE
+    )
     // Redundantly storing the demobank for query convenience.
     val demobank = reference("demobank", DemobankConfigsTable)
 }

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