[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Implementing GET /accounts
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Implementing GET /accounts |
Date: |
Mon, 02 Oct 2023 09:25:26 +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 44f2a6c1 Implementing GET /accounts
44f2a6c1 is described below
commit 44f2a6c1236f6cb3f557afba572ccc5ae2381b78
Author: MS <ms@taler.net>
AuthorDate: Mon Oct 2 09:25:07 2023 +0200
Implementing GET /accounts
---
.../main/kotlin/tech/libeufin/bank/BankMessages.kt | 8 +++
.../tech/libeufin/bank/CorebankApiHandlers.kt | 24 +++++++++
.../src/main/kotlin/tech/libeufin/bank/Database.kt | 4 +-
bank/src/test/kotlin/LibeuFinApiTest.kt | 62 ++++++++++++++++++++++
4 files changed, 97 insertions(+), 1 deletion(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
b/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
index 7142ba38..787a99a5 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/BankMessages.kt
@@ -379,6 +379,14 @@ data class AccountMinimalData(
val debit_threshold: TalerAmount
)
+/**
+ * Response type of GET /accounts.
+ */
+@Serializable
+data class ListBankAccountsResponse(
+ val accounts: MutableList<AccountMinimalData> = mutableListOf()
+)
+
/**
* GET /accounts/$USERNAME response.
*/
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
index a55f5328..b9a53fab 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/CorebankApiHandlers.kt
@@ -199,6 +199,30 @@ fun Routing.accountsMgmtHandlers(db: Database, ctx:
BankApplicationContext) {
return@post
}
+ get("/accounts") {
+ val c = call.authenticateBankRequest(db, TokenScope.readonly) ?: throw
unauthorized()
+ if (c.login != "admin") throw forbidden("Only admin allowed.")
+ // Get optional param.
+ val maybeFilter: String? = call.request.queryParameters["filter_name"]
+ logger.debug("Filtering on '${maybeFilter}'")
+ val queryParam = if (maybeFilter != null) {
+ "%${maybeFilter}%"
+ } else "%"
+ val dbRes = db.accountsGetForAdmin(queryParam)
+ if (dbRes.isEmpty()) {
+ call.respond(HttpStatusCode.NoContent)
+ return@get
+ }
+ call.respond(
+ ListBankAccountsResponse().apply {
+ dbRes.forEach { element ->
+ this.accounts.add(element)
+ }
+ }
+ )
+ return@get
+ }
+
get("/accounts/{USERNAME}") {
val c = call.authenticateBankRequest(db, TokenScope.readonly) ?: throw
unauthorized("Login failed")
val resourceName = call.maybeUriComponent("USERNAME") ?: throw
badRequest(
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
index fd467600..717239de 100644
--- a/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
+++ b/bank/src/main/kotlin/tech/libeufin/bank/Database.kt
@@ -362,7 +362,9 @@ class Database(private val dbConfig: String, private val
bankCurrency: String) {
/**
* Gets a minimal set of account data, as outlined in the GET /accounts
- * endpoint.
+ * endpoint. The nameFilter parameter will be passed AS IS to the SQL
+ * LIKE operator. If it's null, it defaults to the "%" wildcard, meaning
+ * that it returns ALL the existing accounts.
*/
fun accountsGetForAdmin(nameFilter: String = "%"):
List<AccountMinimalData> {
reconnect()
diff --git a/bank/src/test/kotlin/LibeuFinApiTest.kt
b/bank/src/test/kotlin/LibeuFinApiTest.kt
index eb44f06b..107d277c 100644
--- a/bank/src/test/kotlin/LibeuFinApiTest.kt
+++ b/bank/src/test/kotlin/LibeuFinApiTest.kt
@@ -516,4 +516,66 @@ class LibeuFinApiTest {
assert(resp.status == HttpStatusCode.Created)
}
}
+
+ /**
+ * Tests the GET /accounts endpoint.
+ */
+ @Test
+ fun getAccountsList() {
+ val db = initDb()
+ val ctx = getTestContext()
+ val adminCustomer = Customer(
+ "admin",
+ CryptoUtil.hashpw("pass"),
+ "CFO"
+ )
+ assert(db.customerCreate(adminCustomer) != null)
+ testApplication {
+ application {
+ corebankWebApp(db, ctx)
+ }
+ // No users registered, expect no data.
+ client.get("/accounts") {
+ basicAuth("admin", "pass")
+ expectSuccess = true
+ }.apply {
+ assert(this.status == HttpStatusCode.NoContent)
+ }
+ // foo account
+ db.customerCreate(customerFoo).apply {
+ assert(this != null)
+ db.bankAccountCreate(genBankAccount(this!!)) != null
+ }
+ // bar account
+ db.customerCreate(customerBar).apply {
+ assert(this != null)
+ db.bankAccountCreate(genBankAccount(this!!)) != null
+ }
+ // Two users registered, requesting all of them.
+ client.get("/accounts") {
+ basicAuth("admin", "pass")
+ expectSuccess = true
+ }.apply {
+ println(this.bodyAsText())
+ assert(this.status == HttpStatusCode.OK)
+ val obj =
Json.decodeFromString<ListBankAccountsResponse>(this.bodyAsText())
+ assert(obj.accounts.size == 2)
+ // Order unreliable, just checking they're different.
+ assert(obj.accounts[0].username != obj.accounts[1].username)
+ }
+ // Filtering on bar.
+ client.get("/accounts?filter_name=ar") {
+ basicAuth("admin", "pass")
+ expectSuccess = true
+ }.apply {
+ assert(this.status == HttpStatusCode.OK)
+ val obj =
Json.decodeFromString<ListBankAccountsResponse>(this.bodyAsText())
+ assert(obj.accounts.size == 1) {
+ println("Wrong size of filtered query:
${obj.accounts.size}")
+ }
+ assert(obj.accounts[0].username == "bar")
+ }
+ }
+ }
+
}
--
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: Implementing GET /accounts,
gnunet <=