gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] branch master updated: addressing #7738


From: gnunet
Subject: [libeufin] branch master updated: addressing #7738
Date: Fri, 21 Apr 2023 21:39:21 +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 bb96fd4f addressing #7738
bb96fd4f is described below

commit bb96fd4f635cd9b760363acc7aacb9f7d890cf89
Author: MS <ms@taler.net>
AuthorDate: Fri Apr 21 21:39:03 2023 +0200

    addressing #7738
---
 .../tech/libeufin/nexus/server/NexusServer.kt      | 29 ++++++++++---
 nexus/src/test/kotlin/NexusApiTest.kt              | 47 ++++++++++++++++++++++
 2 files changed, 70 insertions(+), 6 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt 
b/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
index 542f2d4f..5b9a0bd7 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/server/NexusServer.kt
@@ -1036,7 +1036,7 @@ val nexusApp: Application.() -> Unit = {
         }
 
         post("/facades") {
-            requireSuperuser(call.request)
+            val user = requireSuperuser(call.request)
             val body = call.receive<FacadeInfo>()
             requireValidResourceName(body.name)
             if (!listOf("taler-wire-gateway", "anastasis").contains(body.type))
@@ -1044,9 +1044,29 @@ val nexusApp: Application.() -> Unit = {
                     HttpStatusCode.NotImplemented,
                     "Facade type '${body.type}' is not implemented"
                 )
-            try {
+            // Check if the facade exists already.
+            val createNewFacade = transaction {
+                val maybeFacade = FacadeEntity.findByName(body.name)
+                // Facade exists, check all the values for idempotence.
+                if (maybeFacade != null) {
+                    // First get the associated config.
+                    val facadeConfig = getFacadeState(maybeFacade.facadeName)
+                    if (maybeFacade.type != body.type
+                        || maybeFacade.creator.username != user.username
+                        || facadeConfig.bankAccount != body.config.bankAccount
+                        || facadeConfig.bankConnection != 
body.config.bankConnection
+                        || facadeConfig.reserveTransferLevel != 
body.config.reserveTransferLevel
+                        || facadeConfig.currency != body.config.currency) {
+                        throw conflict("Facade ${body.name} exists but its 
state differs from the request.")
+                    }
+                    // Facade exists and has exact same values, inhibit 
creation.
+                    else return@transaction false
+                }
+                // Facade does not exist, trigger creation.
+                true
+            }
+            if (createNewFacade) {
                 transaction {
-                    val user = authenticateRequest(call.request)
                     val newFacade = FacadeEntity.new {
                         facadeName = body.name
                         type = body.type
@@ -1060,9 +1080,6 @@ val nexusApp: Application.() -> Unit = {
                         currency = body.config.currency
                     }
                 }
-            } catch (e: Exception) {
-                logger.error(e.stackTraceToString())
-                throw internalServerError("Could not create facade")
             }
             call.respond(HttpStatusCode.OK)
             return@post
diff --git a/nexus/src/test/kotlin/NexusApiTest.kt 
b/nexus/src/test/kotlin/NexusApiTest.kt
index d1ccad47..ab6dcb34 100644
--- a/nexus/src/test/kotlin/NexusApiTest.kt
+++ b/nexus/src/test/kotlin/NexusApiTest.kt
@@ -67,6 +67,53 @@ class NexusApiTest {
             }
         }
     }
+    @Test
+    fun facadeIdempotence() {
+        val facadeData = """{
+          "name": "foo-facade",
+          "type": "taler-wire-gateway",
+          "config": {
+            "bankAccount": "foo",
+            "bankConnection": "foo",
+            "reserveTransferLevel": "report",
+            "currency": "TESTKUDOS"
+          }
+        }""".trimIndent()
+        withTestDatabase {
+            prepNexusDb()
+            testApplication {
+                application(nexusApp)
+                client.post("/facades") {
+                    expectSuccess = true
+                    basicAuth("foo", "foo")
+                    contentType(ContentType.Application.Json)
+                    setBody(facadeData)
+                }
+                // Changing one detail, and expecting 409 Conflict.
+                var resp = client.post("/facades") {
+                    expectSuccess = false
+                    basicAuth("foo", "foo")
+                    contentType(ContentType.Application.Json)
+                    setBody(facadeData.replace(
+                        "taler-wire-gateway",
+                        "anastasis"
+                    ))
+                }
+                assert(resp.status.value == HttpStatusCode.Conflict.value)
+                // Changing a value deeper in the request object.
+                resp = client.post("/facades") {
+                    expectSuccess = false
+                    basicAuth("foo", "foo")
+                    contentType(ContentType.Application.Json)
+                    setBody(facadeData.replace(
+                        "report",
+                        "statement"
+                    ))
+                }
+                assert(resp.status.value == HttpStatusCode.Conflict.value)
+            }
+        }
+    }
     // Testing basic operations on facades.
     @Test
     fun facades() {

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