[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Addressing #7788
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Addressing #7788 |
Date: |
Fri, 07 Apr 2023 17:14:58 +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 101fa06f Addressing #7788
101fa06f is described below
commit 101fa06fd5fa863a90eb4cbc0b4fcd2e28fda583
Author: MS <ms@taler.net>
AuthorDate: Fri Apr 7 17:14:50 2023 +0200
Addressing #7788
---
cli/tests/launch_services.sh | 6 +-
nexus/src/test/kotlin/MakeEnv.kt | 18 +++++-
nexus/src/test/kotlin/SandboxCircuitApiTest.kt | 66 ++++++++++++++++++++++
nexus/src/test/kotlin/SandboxLegacyApiTest.kt | 1 -
.../kotlin/tech/libeufin/sandbox/CircuitApi.kt | 36 ++++++++----
.../main/kotlin/tech/libeufin/sandbox/Helpers.kt | 2 +-
.../kotlin/tech/libeufin/sandbox/bankAccount.kt | 14 ++++-
7 files changed, 124 insertions(+), 19 deletions(-)
diff --git a/cli/tests/launch_services.sh b/cli/tests/launch_services.sh
index f085fb26..2a5e10c5 100755
--- a/cli/tests/launch_services.sh
+++ b/cli/tests/launch_services.sh
@@ -4,8 +4,8 @@
# connected through x-libeufin-bank.
set -eu
-WITH_TASKS=1
-# WITH_TASKS=0
+# WITH_TASKS=1
+WITH_TASKS=0
function exit_cleanup()
{
echo "Running exit-cleanup"
@@ -41,7 +41,7 @@ libeufin-sandbox \
echo DONE
echo -n Start the bank...
export LIBEUFIN_SANDBOX_ADMIN_PASSWORD=foo
-libeufin-sandbox serve &> sandbox.log &
+libeufin-sandbox serve > sandbox.log 2>&1 &
SANDBOX_PID=$!
echo DONE
echo -n Wait for the bank...
diff --git a/nexus/src/test/kotlin/MakeEnv.kt b/nexus/src/test/kotlin/MakeEnv.kt
index 596b2c95..b3c2e221 100644
--- a/nexus/src/test/kotlin/MakeEnv.kt
+++ b/nexus/src/test/kotlin/MakeEnv.kt
@@ -278,11 +278,23 @@ fun prepSandboxDb(usersDebtLimit: Int = 1000) {
name = "Bar"
cashout_address = "payto://iban/FIAT"
}
+ // Note: exchange doesn't have the cash-out address.
DemobankCustomerEntity.new {
- username = "baz"
+ username = "exchange-0"
passwordHash = CryptoUtil.hashpw("foo")
- name = "Baz"
- cashout_address = "payto://iban/OTHERBANK"
+ name = "Exchange"
+ }
+ BankAccountEntity.new {
+ iban = "AT561936082973364859"
+ /**
+ * 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 = "exchange-0"
+ owner = "exchange-0"
+ this.demoBank = demoBank
+ isPublic = false
}
}
}
diff --git a/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
b/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
index d9ff3d51..8ac0d1dc 100644
--- a/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
+++ b/nexus/src/test/kotlin/SandboxCircuitApiTest.kt
@@ -11,12 +11,78 @@ import org.jetbrains.exposed.sql.transactions.transaction
import org.junit.Ignore
import org.junit.Test
import tech.libeufin.sandbox.*
+import tech.libeufin.util.getIban
import tech.libeufin.util.parseAmount
import java.io.File
import java.math.BigDecimal
import java.util.*
class SandboxCircuitApiTest {
+
+ /**
+ * Testing that the admin is able to conduct ordinary
+ * account operations even on non-circuit accounts. Recall:
+ * such accounts are just those without the cash-out address.
+ */
+ @Test
+ fun opOnNonCircuitAccounts() {
+ withTestDatabase {
+ testApplication {
+ prepSandboxDb()
+ testApplication {
+ application(sandboxApp)
+ // Only testing that this doesn't except.
+ client.get("/demobanks/default/circuit-api/accounts") {
+ expectSuccess = true
+ basicAuth("admin", "foo")
+ }
+ // Trying to PATCH non circuit account
+
client.patch("/demobanks/default/circuit-api/accounts/exchange-0") {
+ expectSuccess = true
+ basicAuth("admin", "foo")
+ contentType(ContentType.Application.Json)
+ setBody("""
+ {"name": "Exchange 0",
+ "contact_data": {},
+ "cashout_address":
"payto://iban/SANDBOXX/${getIban()}"
+ }
+ """.trimIndent())
+ }
+ // PATCH it again passing a null name and cashout-address.
+
client.patch("/demobanks/default/circuit-api/accounts/exchange-0") {
+ expectSuccess = true
+ basicAuth("admin", "foo")
+ contentType(ContentType.Application.Json)
+ setBody("{ \"contact_data\": {} }")
+ }
+ // PATCH the password.
+
client.patch("/demobanks/default/circuit-api/accounts/exchange-0/auth") {
+ expectSuccess = true
+ basicAuth("admin", "foo")
+ contentType(ContentType.Application.Json)
+ setBody("{ \"new_password\": \"secret\" }")
+ }
+ // Check that PATCHing worked.
+
client.get("/demobanks/default/access-api/accounts/exchange-0") {
+ expectSuccess = true
+ basicAuth("exchange-0", "secret")
+ contentType(ContentType.Application.Json)
+ }
+ // Deleting the account.
+
client.delete("/demobanks/default/circuit-api/accounts/exchange-0") {
+ expectSuccess = true
+ basicAuth("admin", "foo")
+ }
+ // Checking actual deletion.
+ val R =
client.get("/demobanks/default/circuit-api/accounts/exchange-0") {
+ expectSuccess = false
+ basicAuth("admin", "foo")
+ }
+ assert(R.status.value == HttpStatusCode.NotFound.value)
+ }
+ }
+ }
+ }
// Get /config, fails if != 200.
@Test
fun config() {
diff --git a/nexus/src/test/kotlin/SandboxLegacyApiTest.kt
b/nexus/src/test/kotlin/SandboxLegacyApiTest.kt
index bd8b0248..76ee405d 100644
--- a/nexus/src/test/kotlin/SandboxLegacyApiTest.kt
+++ b/nexus/src/test/kotlin/SandboxLegacyApiTest.kt
@@ -111,7 +111,6 @@ class SandboxLegacyApiTest {
val label = "baz"
})
client.post("/admin/ebics/bank-accounts") {
- expectSuccess = true
expectSuccess = true
contentType(ContentType.Application.Json)
basicAuth("admin", "foo")
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
index d9008fb6..d63dac33 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/CircuitApi.kt
@@ -6,6 +6,8 @@ import io.ktor.http.*
import io.ktor.server.request.*
import io.ktor.server.response.*
import io.ktor.server.routing.*
+import org.jetbrains.exposed.sql.*
+import org.jetbrains.exposed.sql.SqlExpressionBuilder.like
import org.jetbrains.exposed.sql.transactions.transaction
import tech.libeufin.sandbox.CashoutOperationsTable.uuid
import tech.libeufin.util.*
@@ -79,7 +81,7 @@ data class CircuitContactData(
data class CircuitAccountReconfiguration(
val contact_data: CircuitContactData,
- val cashout_address: String,
+ val cashout_address: String?,
val name: String? = null
)
@@ -96,7 +98,7 @@ data class CircuitAccountInfo(
val iban: String,
val contact_data: CircuitContactData,
val name: String,
- val cashout_address: String
+ val cashout_address: String?
)
data class CashoutOperationInfo(
@@ -631,11 +633,12 @@ fun circuitApi(circuitRoute: Route) {
* that the customer was indeed added via the Circuit API, as opposed
* to the Access API.
*/
- val maybeError = "$resourceName not managed by the Circuit API."
call.respond(CircuitAccountInfo(
username = customer.username,
- name = customer.name ?: throw notFound(maybeError),
- cashout_address = customer.cashout_address ?: throw
notFound(maybeError),
+ name = customer.name ?: throw internalServerError(
+ "Account '$resourceName' was found without owner's name."
+ ),
+ cashout_address = customer.cashout_address,
contact_data = CircuitContactData(
email = customer.email,
phone = customer.phone
@@ -659,10 +662,22 @@ fun circuitApi(circuitRoute: Route) {
val customers = mutableListOf<Any>()
val demobank = ensureDemobank(call)
transaction {
- DemobankCustomerEntity.find{
- // like() is case insensitive.
- DemobankCustomersTable.name.like(filter)
- }.forEach {
+ /**
+ * This block builds the DB query so that IF the %-wildcard was
+ * given, then BOTH name and name-less accounts are returned.
+ */
+ val query: Op<Boolean> = SqlExpressionBuilder.run {
+ val like = DemobankCustomersTable.name.like(filter)
+ /**
+ * This IF statement is needed because Postgres would NOT
+ * match a null column even with the %-wildcard.
+ */
+ if (filter == "%") {
+ return@run like.or(DemobankCustomersTable.name.isNull())
+ }
+ return@run like
+ }
+ DemobankCustomerEntity.find { query }.forEach {
customers.add(object {
val username = it.username
val name = it.name
@@ -676,6 +691,7 @@ fun circuitApi(circuitRoute: Route) {
)
})
}
+ StdOutSqlLogger
}
if (customers.size == 0) {
call.respond(HttpStatusCode.NoContent)
@@ -727,7 +743,7 @@ fun circuitApi(circuitRoute: Route) {
throw badRequest("Invalid e-mail address:
${req.contact_data.email}")
if ((req.contact_data.phone != null) &&
(!checkPhoneNumber(req.contact_data.phone)))
throw badRequest("Invalid phone number: ${req.contact_data.phone}")
- try { parsePayto(req.cashout_address) }
+ try { if (req.cashout_address != null) parsePayto(req.cashout_address)
}
catch (e: InvalidPaytoError) {
throw badRequest("Invalid cash-out address:
${req.cashout_address}")
}
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
index 5d492914..54519bbb 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt
@@ -80,7 +80,7 @@ data class AccountPair(
)
fun insertNewAccount(username: String,
password: String,
- name: String? = null, // tests do not usually give one.
+ name: String? = null, // tests and access API may not
give one.
iban: String? = null,
demobank: String = "default",
isPublic: Boolean = false): AccountPair {
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
index 2ebe5fc2..e6559897 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
@@ -111,7 +111,19 @@ fun getBalance(accountLabel: String,
HttpStatusCode.InternalServerError,
"Demobank '$demobankName' not found"
)
- val account = getBankAccountFromLabel(accountLabel, demobank)
+
+ /**
+ * Setting withBankFault to true for the following reason:
+ * when asking for a balance, the bank should have made sure
+ * that the user has a bank account (together with a customer profile).
+ * If that's not the case, it's bank's fault, since it didn't check
+ * earlier.
+ */
+ val account = getBankAccountFromLabel(
+ accountLabel,
+ demobank,
+ withBankFault = true
+ )
return getBalance(account, withPending)
}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [libeufin] branch master updated: Addressing #7788,
gnunet <=