commit 1bb13f2318f89312542d5cfa723e4049d7afde3e
parent fd6b16355c3c14111a0c23688ee0c6806e51c3a7
Author: Antoine A <>
Date: Thu, 6 Feb 2025 10:25:15 +0100
libeufin-bank: always use legal name in cashout payto
Diffstat:
5 files changed, 29 insertions(+), 21 deletions(-)
diff --git a/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt b/bank/src/main/kotlin/tech/libeufin/bank/db/AccountDAO.kt
@@ -75,7 +75,7 @@ class AccountDAO(private val db: Database) {
setString(1, name)
setString(2, email)
setString(3, phone)
- setString(4, cashoutPayto?.full(name))
+ setString(4, cashoutPayto?.simple())
setString(5, tanChannel?.name)
setBoolean(6, checkPaytoIdempotent)
setString(7, internalPayto.canonical)
@@ -138,7 +138,7 @@ class AccountDAO(private val db: Database) {
setString(3, name)
setString(4, email)
setString(5, phone)
- setString(6, cashoutPayto?.full(name))
+ setString(6, cashoutPayto?.simple())
setString(7, tanChannel?.name)
one { it.getLong("customer_id") }
}
@@ -295,7 +295,7 @@ class AccountDAO(private val db: Database) {
phone = it.getString("phone"),
email = it.getString("email"),
name = it.getString("name"),
- cashoutPayTo = it.getString("cashout_payto"),
+ cashoutPayTo = it.getOptIbanPayto("cashout_payto")?.simple(),
debtLimit = it.getAmount("max_debt", db.bankCurrency),
minCashout = it.getOptAmount("min_cashout", db.bankCurrency),
)
@@ -318,13 +318,13 @@ class AccountDAO(private val db: Database) {
TanChannel.email -> curr.email
null -> null
}
- // Cashout payto with a receiver-name using if receiver-name is missing the new named if present or the current one
- val fullCashoutPayto = cashoutPayto.get()?.full(name ?: curr.name)
+ // Cashout payto without a receiver-name
+ val simpleCashoutPayto = cashoutPayto.get()?.simple()
// Check reconfig rights
if (checkName && name != curr.name)
return@serializableTransaction AccountPatchResult.NonAdminName
- if (checkCashout && fullCashoutPayto != curr.cashoutPayTo)
+ if (checkCashout && simpleCashoutPayto != curr.cashoutPayTo)
return@serializableTransaction AccountPatchResult.NonAdminCashout
if (checkDebtLimit && debtLimit != curr.debtLimit)
return@serializableTransaction AccountPatchResult.NonAdminDebtLimit
@@ -394,7 +394,7 @@ class AccountDAO(private val db: Database) {
},
"WHERE customer_id = ?",
sequence {
- cashoutPayto.some { yield(fullCashoutPayto) }
+ cashoutPayto.some { yield(simpleCashoutPayto) }
phone.some { yield(it) }
email.some { yield(it) }
tan_channel.some { yield(it?.name) }
@@ -561,14 +561,15 @@ class AccountDAO(private val db: Database) {
) {
setString(1, username)
oneOrNull {
+ val name = it.getString("name")
AccountData(
- name = it.getString("name"),
+ name = name,
contact_data = ChallengeContactData(
email = Option.Some(it.getString("email")),
phone = Option.Some(it.getString("phone"))
),
tan_channel = it.getOptEnum<TanChannel>("tan_channel"),
- cashout_payto_uri = it.getString("cashout_payto"),
+ cashout_payto_uri = it.getOptIbanPayto("cashout_payto")?.full(name),
payto_uri = it.getBankPayto("internal_payto", "name", db.ctx),
balance = Balance(
amount = it.getAmount("balance", db.bankCurrency),
diff --git a/bank/src/test/kotlin/CoreBankApiTest.kt b/bank/src/test/kotlin/CoreBankApiTest.kt
@@ -551,17 +551,16 @@ class CoreBankAccountsApiTest {
client.getA("/accounts/cashout_guess").assertOkJson<AccountData> {
assertEquals(payto.full("Mr Guess My Name"), it.cashout_payto_uri)
}
- val full = payto.full("Santa Claus")
client.post("/accounts") {
json {
"username" to "cashout_keep"
"password" to "cashout_keep-password"
"name" to "Mr Keep My Name"
- "cashout_payto_uri" to full
+ "cashout_payto_uri" to payto.full("Santa Claus")
}
}.assertOk()
client.getA("/accounts/cashout_keep").assertOkJson<AccountData> {
- assertEquals(full, it.cashout_payto_uri)
+ assertEquals(payto.full("Mr Keep My Name"), it.cashout_payto_uri)
}
// Check input restrictions
@@ -906,8 +905,8 @@ class CoreBankAccountsApiTest {
for ((cashout, name, expect) in listOf(
Triple(cashout.canonical, null, canonical.full("Mr Cashout Cashout")),
Triple(cashout.canonical, "New name", canonical.full("New name")),
- Triple(cashout.full("Full name"), null, cashout.full("Full name")),
- Triple(cashout.full("Full second name"), "Another name", cashout.full("Full second name"))
+ Triple(cashout.full("Full name"), null, cashout.full("New name")),
+ Triple(cashout.full("Full second name"), "Another name", cashout.full("Another name"))
)) {
client.patchAdmin("/accounts/cashout") {
json {
diff --git a/common/src/main/kotlin/TalerCommon.kt b/common/src/main/kotlin/TalerCommon.kt
@@ -412,11 +412,13 @@ class IbanPayto internal constructor(
val bic: String?,
val iban: IBAN
): Payto() {
-
override fun toString(): String = parsed.toString()
- /** Transform an IBAN payto URI to its full form, using [defaultName] if receiver-name is missing */
- fun full(defaultName: String): String = build(iban.toString(), bic, receiverName ?: defaultName)
+ /** Transform an IBAN payto URI to its simple form without any query */
+ fun simple(): String = build(iban.toString(), bic, null)
+
+ /** Transform an IBAN payto URI to its full form, using [name] as its receiver-name */
+ fun full(name: String): String = build(iban.toString(), bic, name)
internal object Serializer : KSerializer<IbanPayto> {
override val descriptor: SerialDescriptor =
diff --git a/common/src/main/kotlin/db/types.kt b/common/src/main/kotlin/db/types.kt
@@ -1,6 +1,6 @@
/*
* This file is part of LibEuFin.
- * Copyright (C) 2024 Taler Systems S.A.
+ * Copyright (C) 2024-2025 Taler Systems S.A.
*
* LibEuFin is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -61,6 +61,12 @@ fun ResultSet.getBankPayto(payto: String, name: String?, ctx: BankPaytoCtx): Str
, ctx)
}
+fun ResultSet.getOptIbanPayto(payto: String): IbanPayto? {
+ val raw = getString(payto)
+ if (raw == null) return null
+ return Payto.parse(raw).expectIban()
+}
+
fun ResultSet.getIbanPayto(payto: String): IbanPayto {
return Payto.parse(getString(payto)).expectIban()
}
\ No newline at end of file
diff --git a/common/src/test/kotlin/PaytoTest.kt b/common/src/test/kotlin/PaytoTest.kt
@@ -1,6 +1,6 @@
/*
* This file is part of LibEuFin.
- * Copyright (C) 2024 Taler Systems S.A.
+ * Copyright (C) 2024-2025 Taler Systems S.A.
* LibEuFin is free software; you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
@@ -68,8 +68,8 @@ class PaytoTest {
"NotGiven", "Grothoff Hans", null
)
val full = listOf(
- "payto://iban/BIC/CH9300762011623852957?receiver-name=NotGiven",
- "payto://iban/CH9300762011623852957?receiver-name=Grothoff%20Hans",
+ "payto://iban/BIC/CH9300762011623852957?receiver-name=Santa",
+ "payto://iban/CH9300762011623852957?receiver-name=Santa",
"payto://iban/CH9300762011623852957?receiver-name=Santa",
)
for ((i, input) in inputs.withIndex()) {