gnunet-svn
[Top][All Lists]
Advanced

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

[libeufin] 03/06: Nexus tests.


From: gnunet
Subject: [libeufin] 03/06: Nexus tests.
Date: Wed, 23 Nov 2022 20:06:19 +0100

This is an automated email from the git hooks/post-receive script.

ms pushed a commit to branch master
in repository libeufin.

commit 0b14b8f09c2009138dd6dbe89e3174ab949afa3c
Author: MS <ms@taler.net>
AuthorDate: Wed Nov 23 20:00:20 2022 +0100

    Nexus tests.
    
    Implement test server to respond arbitrary
    1-segment-long data along EBICS init and transfer
    phases.
---
 nexus/src/test/kotlin/MakeEnv.kt          | 171 ++++++++++++++++++++++++++++++
 nexus/src/test/kotlin/SchedulingTest.kt   | 137 ++++++++++++++++++++++++
 nexus/src/test/resources/logback-test.xml |  28 +++++
 3 files changed, 336 insertions(+)

diff --git a/nexus/src/test/kotlin/MakeEnv.kt b/nexus/src/test/kotlin/MakeEnv.kt
new file mode 100644
index 00000000..5161650e
--- /dev/null
+++ b/nexus/src/test/kotlin/MakeEnv.kt
@@ -0,0 +1,171 @@
+import org.jetbrains.exposed.sql.Database
+import org.jetbrains.exposed.sql.statements.api.ExposedBlob
+import org.jetbrains.exposed.sql.transactions.transaction
+import tech.libeufin.nexus.*
+import tech.libeufin.nexus.dbCreateTables
+import tech.libeufin.nexus.dbDropTables
+import tech.libeufin.sandbox.*
+import tech.libeufin.util.CryptoUtil
+import tech.libeufin.util.EbicsInitState
+import java.io.File
+import tech.libeufin.util.getIban
+
+data class EbicsKeys(
+    val auth: CryptoUtil.RsaCrtKeyPair,
+    val enc: CryptoUtil.RsaCrtKeyPair,
+    val sig: CryptoUtil.RsaCrtKeyPair
+)
+const val TEST_DB_FILE = "/tmp/nexus-test.sqlite3"
+const val TEST_DB_CONN = "jdbc:sqlite:$TEST_DB_FILE"
+val BANK_IBAN = getIban()
+val USER_IBAN = getIban()
+
+val bankKeys = EbicsKeys(
+    auth = CryptoUtil.generateRsaKeyPair(2048),
+    enc = CryptoUtil.generateRsaKeyPair(2048),
+    sig = CryptoUtil.generateRsaKeyPair(2048)
+)
+val userKeys = EbicsKeys(
+    auth = CryptoUtil.generateRsaKeyPair(2048),
+    enc = CryptoUtil.generateRsaKeyPair(2048),
+    sig = CryptoUtil.generateRsaKeyPair(2048)
+)
+/**
+ * Run a block after connecting to the test database.
+ * Cleans up the DB file afterwards.
+ */
+fun withTestDatabase(f: () -> Unit) {
+    val dbfile = TEST_DB_CONN
+    File(dbfile).also {
+        if (it.exists()) {
+            it.delete()
+        }
+    }
+    Database.connect("jdbc:sqlite:$dbfile")
+    dbDropTables(dbfile)
+    tech.libeufin.sandbox.dbDropTables(TEST_DB_CONN)
+    try {
+        f()
+    }
+    finally {
+        File(dbfile).also {
+            if (it.exists()) {
+                it.delete()
+            }
+        }
+    }
+}
+
+fun prepNexusDb() {
+    dbCreateTables(TEST_DB_CONN)
+    transaction {
+        val u = NexusUserEntity.new {
+            username = "foo"
+            passwordHash = "foo"
+            superuser = false
+        }
+        val c = NexusBankConnectionEntity.new {
+            connectionId = "foo"
+            owner = u
+            type = "ebics"
+        }
+        tech.libeufin.nexus.EbicsSubscriberEntity.new {
+            ebicsURL = "http://localhost:5000/ebicsweb";
+            hostID = "eufinSandbox"
+            partnerID = "foo"
+            userID = "foo"
+            systemID = "foo"
+            signaturePrivateKey = ExposedBlob(userKeys.sig.private.encoded)
+            encryptionPrivateKey = ExposedBlob(userKeys.enc.private.encoded)
+            authenticationPrivateKey = 
ExposedBlob(userKeys.auth.private.encoded)
+            nexusBankConnection = c
+            ebicsIniState = EbicsInitState.NOT_SENT
+            ebicsHiaState = EbicsInitState.NOT_SENT
+            bankEncryptionPublicKey = ExposedBlob(bankKeys.enc.public.encoded)
+            bankAuthenticationPublicKey = 
ExposedBlob(bankKeys.auth.public.encoded)
+        }
+        val a = NexusBankAccountEntity.new {
+            bankAccountName = "mock-bank-account"
+            iban = USER_IBAN
+            bankCode = "SANDBOXX"
+            defaultBankConnection = c
+            highestSeenBankMessageSerialId = 0
+            accountHolder = "foo"
+        }
+    }
+}
+
+fun prepSandboxDb() {
+    tech.libeufin.sandbox.dbCreateTables(TEST_DB_CONN)
+    transaction {
+        val demoBank = DemobankConfigEntity.new {
+            currency = "TESTKUDOS"
+            bankDebtLimit = 10000
+            usersDebtLimit = 1000
+            allowRegistrations = true
+            name = "default"
+            this.withSignupBonus = false
+            captchaUrl = "http://example.com/"; // unused
+        }
+        BankAccountEntity.new {
+            iban = BANK_IBAN
+            label = "bank" // used by the wire helper
+            owner = "bank" // used by the person name finder
+            // For now, the model assumes always one demobank
+            this.demoBank = demoBank
+        }
+        EbicsHostEntity.new {
+            this.ebicsVersion = "3.0"
+            this.hostId = "eufinSandbox"
+            this.authenticationPrivateKey = 
ExposedBlob(bankKeys.auth.private.encoded)
+            this.encryptionPrivateKey = 
ExposedBlob(bankKeys.enc.private.encoded)
+            this.signaturePrivateKey = 
ExposedBlob(bankKeys.sig.private.encoded)
+        }
+        val bankAccount = BankAccountEntity.new {
+            iban = USER_IBAN
+            /**
+             * For now, keep same semantics of Pybank: a username
+             * is AS WELL a bank account label.  In other words, it
+             * identifies a customer AND a bank account.
+             */
+            label = "foo"
+            owner = "foo"
+            this.demoBank = demoBank
+            isPublic = false
+        }
+        tech.libeufin.sandbox.EbicsSubscriberEntity.new {
+            hostId = "eufinSandbox"
+            partnerId = "foo"
+            userId = "foo"
+            systemId = "foo"
+            signatureKey = EbicsSubscriberPublicKeyEntity.new {
+                rsaPublicKey = ExposedBlob(userKeys.sig.public.encoded)
+                state = KeyState.RELEASED
+            }
+            encryptionKey = EbicsSubscriberPublicKeyEntity.new {
+                rsaPublicKey = ExposedBlob(userKeys.enc.public.encoded)
+                state = KeyState.RELEASED
+            }
+            authenticationKey = EbicsSubscriberPublicKeyEntity.new {
+                rsaPublicKey = ExposedBlob(userKeys.auth.public.encoded)
+                state = KeyState.RELEASED
+            }
+            state = SubscriberState.INITIALIZED
+            nextOrderID = 1
+            this.bankAccount = bankAccount
+        }
+        DemobankCustomerEntity.new {
+            username = "foo"
+            passwordHash = "foo"
+            name = "Foo"
+        }
+    }
+}
+
+fun withNexusAndSandboxUser(f: () -> Unit) {
+    withTestDatabase {
+        prepNexusDb()
+        prepSandboxDb()
+        f()
+    }
+}
\ No newline at end of file
diff --git a/nexus/src/test/kotlin/SchedulingTest.kt 
b/nexus/src/test/kotlin/SchedulingTest.kt
new file mode 100644
index 00000000..767ddbd2
--- /dev/null
+++ b/nexus/src/test/kotlin/SchedulingTest.kt
@@ -0,0 +1,137 @@
+import io.ktor.application.*
+import io.ktor.features.*
+import io.ktor.http.*
+import io.ktor.request.*
+import io.ktor.response.*
+import io.ktor.routing.*
+import io.ktor.server.testing.*
+import kotlinx.coroutines.runBlocking
+import org.junit.Ignore
+import org.junit.Test
+import org.w3c.dom.Document
+import tech.libeufin.nexus.*
+import tech.libeufin.sandbox.*
+import tech.libeufin.util.*
+import tech.libeufin.util.ebics_h004.EbicsRequest
+import tech.libeufin.util.ebics_h004.EbicsResponse
+import tech.libeufin.util.ebics_h004.EbicsTypes
+
+
+/**
+ * Data to make the test server return for EBICS
+ * phases.  Currently only init is supported.
+ */
+data class EbicsResponses(
+    val init: String,
+    val download: String? = null,
+    val receipt: String? = null
+)
+
+/**
+ * Minimal server responding always the 'init' field of a EbicsResponses
+ * object along a download EBICS message.  Suitable to set arbitrary data
+ * in said response.  Signs the response assuming the client is the one
+ * created a MakeEnv.kt.
+ */
+fun getCustomEbicsServer(r: EbicsResponses, endpoint: String = "/ebicsweb"): 
Application.() -> Unit {
+    val ret: Application.() -> Unit = {
+        install(ContentNegotiation) {
+            register(ContentType.Text.Xml, XMLEbicsConverter())
+            register(ContentType.Text.Plain, XMLEbicsConverter())
+        }
+        routing {
+            post(endpoint) {
+                val requestDocument = this.call.receive<Document>()
+                val req = requestDocument.toObject<EbicsRequest>()
+                val clientKey = 
CryptoUtil.loadRsaPublicKey(userKeys.enc.public.encoded)
+                val msgId = EbicsOrderUtil.generateTransactionId()
+                val resp: EbicsResponse = if (
+                    req.header.mutable.transactionPhase == 
EbicsTypes.TransactionPhaseType.INITIALISATION
+                ) {
+                    val payload = prepareEbicsPayload(r.init, clientKey)
+                    EbicsResponse.createForDownloadInitializationPhase(
+                        msgId,
+                        1,
+                        4096,
+                        payload.second, // for key material
+                        payload.first // actual payload
+                    )
+                } else {
+                    // msgId doesn't have to match the one used for the init 
phase.
+                    EbicsResponse.createForDownloadReceiptPhase(msgId, true)
+                }
+                val sigEbics = XMLUtil.signEbicsResponse(
+                    resp,
+                    CryptoUtil.loadRsaPrivateKey(bankKeys.auth.private.encoded)
+                )
+                call.respond(sigEbics)
+            }
+        }
+    }
+    return ret
+}
+
+@Ignore
+class SchedulingTest {
+    /**
+     * Instruct the server to return invalid CAMT content.
+     */
+    @Test
+    fun inject() {
+        withNexusAndSandboxUser {
+            val payload = """
+                Invalid Camt Document
+            """.trimIndent()
+            withTestApplication(
+                getCustomEbicsServer(EbicsResponses(payload))
+            ) {
+                runBlocking {
+                    runTask(
+                        client,
+                        TaskSchedule(
+                            0L,
+                            "test-schedule",
+                            "fetch",
+                            "bank-account",
+                            "mock-bank-account",
+                            params = 
"{\"level\":\"report\",\"rangeType\":\"all\"}"
+                        )
+                    )
+                }
+            }
+        }
+    }
+    /**
+     * Create two payments and asks for C52.
+     */
+    @Test
+    fun ordinary() {
+        withNexusAndSandboxUser { // DB prep
+            for (t in 1 .. 2) {
+                wireTransfer(
+                    "bank",
+                    "foo",
+                    "default",
+                    "1HJX78AH7WAGBDJTCXJ4JKX022DBCHERA051KH7D3EC48X09G4RG",
+                    "TESTKUDOS:5",
+                    "xxx"
+                )
+            }
+            withTestApplication(sandboxApp) {
+                runBlocking {
+                    runTask(
+                        client,
+                        TaskSchedule(
+                            0L,
+                            "test-schedule",
+                            "fetch",
+                            "bank-account",
+                            "mock-bank-account",
+                            params = 
"{\"level\":\"report\",\"rangeType\":\"all\"}"
+                        )
+                    )
+                }
+            }
+        }
+    }
+}
\ No newline at end of file
diff --git a/nexus/src/test/resources/logback-test.xml 
b/nexus/src/test/resources/logback-test.xml
new file mode 100644
index 00000000..cbd96f5f
--- /dev/null
+++ b/nexus/src/test/resources/logback-test.xml
@@ -0,0 +1,28 @@
+<!-- configuration scan="true" -->
+<configuration>
+    <appender name="STDERR" class="ch.qos.logback.core.ConsoleAppender">
+       <target>System.err</target>
+        <encoder>
+            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - 
%msg%n</pattern>
+        </encoder>
+    </appender>
+
+    <logger name="tech.libeufin.nexus" level="ALL"  additivity="false">
+        <appender-ref ref="STDERR" />
+    </logger>
+
+    <logger name="tech.libeufin.sandbox" level="ALL"  additivity="false">
+        <appender-ref ref="STDERR" />
+    </logger>
+
+    <logger name="io.netty" level="WARN"/>
+    <logger name="ktor" level="WARN"/>
+    <logger name="Exposed" level="WARN"/>
+    <logger name="tech.libeufin.util" level="DEBUG"/>
+    <logger name="ch.qos" level="WARN"/>
+
+    <root level="WARN">
+        <appender-ref ref="STDERR"/>
+    </root>
+
+</configuration>

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