libeufin

Integration and sandbox testing for FinTech APIs and data formats
Log | Files | Refs | Submodules | README | LICENSE

commit e3e48333e03826fc58aaa5ca0f7312e936daeec3
parent d8438142db43975ea348f00bdf51106ecef67d69
Author: MS <ms@taler.net>
Date:   Wed, 21 Dec 2022 10:00:00 +0100

link admin to bank's account

Diffstat:
Msandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt | 4+---
Msandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt | 44+++++++++++++++-----------------------------
Msandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt | 30+++++++++++++++---------------
Msandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt | 31++++++-------------------------
4 files changed, 37 insertions(+), 72 deletions(-)

diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt @@ -749,9 +749,7 @@ private fun handleCct(paymentRequest: String, accountServicerReference = "sandboxref-${getRandomString(16)}" direction = "DBIT" } - val maybeLocalCreditor = BankAccountEntity.find( - BankAccountsTable.iban eq parseResult.creditorIban - ).firstOrNull() + val maybeLocalCreditor = BankAccountEntity.find(BankAccountsTable.iban eq parseResult.creditorIban).firstOrNull() if (maybeLocalCreditor != null) { BankAccountTransactionEntity.new { account = maybeLocalCreditor diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt @@ -227,21 +227,19 @@ fun getBankAccountFromIban(iban: String): BankAccountEntity { ) } -fun getBankAccountFromLabel(label: String, demobankName: String): BankAccountEntity { - return transaction { - val demobank: DemobankConfigEntity = DemobankConfigEntity.find { - DemobankConfigsTable.name eq demobankName - }.firstOrNull() ?: throw notFound("Demobank ${demobankName} not found") - getBankAccountFromLabel(label, demobank) - } -} -fun getBankAccountFromLabel(label: String, demobank: DemobankConfigEntity): BankAccountEntity { +fun getBankAccountFromLabel(label: String, + demobank: DemobankConfigEntity +): BankAccountEntity { + var labelCheck = label; + /** + * Admin is the only exception to the "username == bank account label" rule. + * Consider calling the default demobank's bank account directly "admin"? + */ + if (label == "admin") labelCheck = "bank" return transaction { - BankAccountEntity.find( - BankAccountsTable.label eq label and (BankAccountsTable.demoBank eq demobank.id) - ).firstOrNull() ?: throw SandboxError( + BankAccountEntity.find(BankAccountsTable.label eq labelCheck and (BankAccountsTable.demoBank eq demobank.id)).firstOrNull() ?: throw SandboxError( HttpStatusCode.NotFound, - "Did not find a bank account for label ${label}" + "Did not find a bank account for label $label" ) } } @@ -269,7 +267,7 @@ fun ensureDemobank(call: ApplicationCall): DemobankConfigEntity { return ensureDemobank(call.getUriComponent("demobankid")) } -private fun ensureDemobank(name: String): DemobankConfigEntity { +fun ensureDemobank(name: String): DemobankConfigEntity { return transaction { DemobankConfigEntity.find { DemobankConfigsTable.name eq name @@ -311,21 +309,9 @@ fun getBankAccountWithAuth(call: ApplicationCall): BankAccountEntity { val username = call.request.basicAuth() val accountAccessed = call.getUriComponent("account_name") val demobank = ensureDemobank(call) - val bankAccount = transaction { - val res = BankAccountEntity.find { - (BankAccountsTable.label eq accountAccessed).and( - BankAccountsTable.demoBank eq demobank.id - ) - }.firstOrNull() - res - } ?: throw notFound("Account '$accountAccessed' not found") - // Check rights. - if ( - WITH_AUTH - && (bankAccount.owner != username && username != "admin") - ) throw forbidden( - "Customer '$username' cannot access bank account '$accountAccessed'" - ) + val bankAccount = getBankAccountFromLabel(accountAccessed, demobank) + if (WITH_AUTH && (bankAccount.owner != username && username != "admin")) + throw forbidden("Customer '$username' cannot access bank account '$accountAccessed'") return bankAccount } diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt @@ -151,9 +151,7 @@ class Config : CliktCommand( execThrowableOrTerminate { dbCreateTables(dbConnString) transaction { - val maybeDemobank = BankAccountEntity.find( - BankAccountsTable.label eq "bank" - ).firstOrNull() + val maybeDemobank = BankAccountEntity.find(BankAccountsTable.label eq "bank").firstOrNull() if (showOption) { if (maybeDemobank != null) { val ret = ObjectMapper() @@ -634,6 +632,9 @@ val sandboxApp: Application.() -> Unit = { throw unauthorized("User '$username' has no rights over" + " bank account '${body.label}'" ) + if (body.label == "admin" || body.label == "bank") throw forbidden( + "Requested bank account label '${body.label}' not allowed." + ) transaction { val maybeBankAccount = BankAccountEntity.find { BankAccountsTable.label eq body.label @@ -743,6 +744,10 @@ val sandboxApp: Application.() -> Unit = { if (subscriber.bankAccount != null) throw conflict("subscriber has already a bank account: ${subscriber.bankAccount?.label}") val demobank = getDefaultDemobank() + // Forbid institutional names for bank account. + if (body.label == "admin" || body.label == "bank") throw forbidden( + "Requested bank account label '${body.label}' not allowed." + ) /** * Checking that the default demobank doesn't have already the * requested IBAN and bank account label. @@ -778,9 +783,8 @@ val sandboxApp: Application.() -> Unit = { val accounts = mutableListOf<BankAccountInfo>() transaction { val demobank = getDefaultDemobank() - BankAccountEntity.find { - BankAccountsTable.demoBank eq demobank.id - }.forEach { + // Finds all the accounts of this demobank. + BankAccountEntity.find { BankAccountsTable.demoBank eq demobank.id }.forEach { accounts.add( BankAccountInfo( label = it.label, @@ -1270,7 +1274,10 @@ val sandboxApp: Application.() -> Unit = { * after the /confirm call. Username == null case is handled above. */ val pendingBalance = getBalance(username!!, withPending = true) - if ((pendingBalance - amount.amount).abs() > BigDecimal.valueOf(demobank.usersDebtLimit.toLong())) { + val maxDebt = if (username == "admin") { + demobank.bankDebtLimit + } else demobank.usersDebtLimit + if ((pendingBalance - amount.amount).abs() > BigDecimal.valueOf(maxDebt.toLong())) { logger.info("User $username would surpass user debit " + "threshold of ${demobank.usersDebtLimit}. Rollback Taler withdrawal" ) @@ -1372,14 +1379,7 @@ val sandboxApp: Application.() -> Unit = { val username = call.request.basicAuth() val accountAccessed = call.getUriComponent("account_name") val demobank = ensureDemobank(call) - val bankAccount = transaction { - val res = BankAccountEntity.find { - (BankAccountsTable.label eq accountAccessed).and( - BankAccountsTable.demoBank eq demobank.id - ) - }.firstOrNull() - res - } ?: throw notFound("Account '$accountAccessed' not found") + val bankAccount = getBankAccountFromLabel(accountAccessed, demobank) // Check rights. if ( WITH_AUTH diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt @@ -55,10 +55,8 @@ fun getBalance( // Wrapper offering to get bank accounts from a string. fun getBalance(accountLabel: String, withPending: Boolean = false): BigDecimal { - val account = transaction { - BankAccountEntity.find { BankAccountsTable.label.eq(accountLabel) }.firstOrNull() - } - if (account == null) throw notFound("Bank account $accountLabel not found") + val defaultDemobank = getDefaultDemobank() + val account = getBankAccountFromLabel(accountLabel, defaultDemobank) return getBalance(account, withPending) } @@ -71,28 +69,11 @@ fun wireTransfer( pmtInfId: String? = null ): String { val args: Triple<BankAccountEntity, BankAccountEntity, DemobankConfigEntity> = transaction { - val debitAccountDb = BankAccountEntity.find { - BankAccountsTable.label eq debitAccount - }.firstOrNull() ?: throw SandboxError( - HttpStatusCode.NotFound, - "Debit account '$debitAccount' not found" - ) - val creditAccountDb = BankAccountEntity.find { - BankAccountsTable.label eq creditAccount - }.firstOrNull() ?: throw SandboxError( - HttpStatusCode.NotFound, - "Credit account '$creditAccount' not found" - ) - val demoBank = DemobankConfigEntity.find { - DemobankConfigsTable.name eq demobank - }.firstOrNull() ?: throw SandboxError( - HttpStatusCode.NotFound, - "Demobank '$demobank' not found" - ) - - Triple(debitAccountDb, creditAccountDb, demoBank) + val demobankDb = ensureDemobank(demobank) + val debitAccountDb = getBankAccountFromLabel(debitAccount, demobankDb) + val creditAccountDb = getBankAccountFromLabel(creditAccount, demobankDb) + Triple(debitAccountDb, creditAccountDb, demobankDb) } - return wireTransfer( debitAccount = args.first, creditAccount = args.second,