libeufin

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

commit 149a0fabab3346f850f4f16b49bc0d3e46ca51d6
parent c1c00b7f5b55ac7b0ddbaee19c72528569e6294b
Author: ms <ms@taler.net>
Date:   Fri, 22 Oct 2021 19:15:00 +0200

Payto.

Parse and build URIs considering only "receiver-name".

Diffstat:
Mnexus/src/main/kotlin/tech/libeufin/nexus/Anastasis.kt | 3+--
Mnexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt | 19+++++++------------
Msandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt | 33++++++++++++++++++---------------
Mutil/src/main/kotlin/Payto.kt | 8++------
Mutil/src/test/kotlin/PaytoTest.kt | 7+++----
5 files changed, 31 insertions(+), 39 deletions(-)

diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Anastasis.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Anastasis.kt @@ -57,7 +57,7 @@ fun anastasisFilter(payment: NexusBankTransactionEntity, txDtls: TransactionDeta subject = txDtls.unstructuredRemittanceInformation timestampMs = System.currentTimeMillis() debtorPaytoUri = buildIbanPaytoUri( - debtorIban, debtorAgent.bic, debtorName, "DBIT" + debtorIban, debtorAgent.bic, debtorName, ) } } @@ -96,7 +96,6 @@ private suspend fun historyIncoming(call: ApplicationCall) { it.payment.bankAccount.iban, it.payment.bankAccount.bankCode, it.payment.bankAccount.accountHolder, - "CRDT" ), debit_account = it.debtorPaytoUri ) diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/Taler.kt @@ -22,7 +22,6 @@ package tech.libeufin.nexus import com.fasterxml.jackson.module.kotlin.jacksonObjectMapper import io.ktor.application.ApplicationCall import io.ktor.application.call -import io.ktor.client.HttpClient import io.ktor.content.TextContent import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode @@ -108,15 +107,13 @@ fun <T : Entity<Long>> SizedIterable<T>.orderTaler(delta: Int): List<T> { } } -/** - * Build an IBAN payto URI. - */ fun buildIbanPaytoUri( - iban: String, bic: String, name: String, direction: String + iban: String, + bic: String, + receiverName: String, ): String { - val nameParam = if (direction == "DBIT") "sender-name" else "receiver-name" - val nameUrlEnc = URLEncoder.encode(name, "utf-8") - return "payto://iban/$bic/$iban?$nameParam=$nameUrlEnc" + val nameUrlEnc = URLEncoder.encode(receiverName, "utf-8") + return "payto://iban/$bic/$iban?receiver-name=$nameUrlEnc" } /** Builds the comparison operator for history entries based on the sign of 'delta' */ @@ -211,7 +208,7 @@ private suspend fun talerTransfer(call: ApplicationCall) { Pain001Data( creditorIban = creditorData.iban, creditorBic = creditorData.bic, - creditorName = creditorData.name ?: throw NexusError( + creditorName = creditorData.receiverName ?: throw NexusError( HttpStatusCode.BadRequest, "Payto did not mention account owner" ), subject = transferRequest.wtid, @@ -309,7 +306,7 @@ fun talerFilter(payment: NexusBankTransactionEntity, txDtls: TransactionDetails) reservePublicKey = reservePub timestampMs = System.currentTimeMillis() debtorPaytoUri = buildIbanPaytoUri( - debtorIban, debtorAgent.bic, debtorName, "DBIT" + debtorIban, debtorAgent.bic, debtorName ) } } @@ -419,7 +416,6 @@ private suspend fun historyOutgoing(call: ApplicationCall) { subscriberBankAccount.iban, subscriberBankAccount.bankCode, subscriberBankAccount.accountHolder, - "DBIT" ), exchange_base_url = "FIXME-to-request-along-subscriber-registration" ) @@ -462,7 +458,6 @@ private suspend fun historyIncoming(call: ApplicationCall) { it.payment.bankAccount.iban, it.payment.bankAccount.bankCode, it.payment.bankAccount.accountHolder, - "CRDT" ), debit_account = it.debtorPaytoUri ) diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Helpers.kt @@ -25,7 +25,6 @@ import org.jetbrains.exposed.sql.SqlExpressionBuilder.eq import org.jetbrains.exposed.sql.and import org.jetbrains.exposed.sql.transactions.transaction import tech.libeufin.util.* -import javax.security.auth.Subject /** * Helps to communicate Camt values without having @@ -87,6 +86,20 @@ fun getHistoryElementFromTransactionRow( } /** + * Get person name from a customer's username. + */ +fun getPersonNameFromCustomer(ownerUsername: String): String { + return if (ownerUsername == "admin") "admin" else { + val ownerCustomer = DemobankCustomerEntity.find( + DemobankCustomersTable.username eq ownerUsername + ).firstOrNull() ?: throw internalServerError( + "Person name of '$ownerUsername' not found" + ) + ownerCustomer.name ?: "Name not given" + } +} + +/** * Book a CRDT and a DBIT transaction and return the unique reference thereof. * * At the moment there is redundancy because all the creditor / debtor details @@ -104,26 +117,16 @@ fun wireTransfer( amount: String, ): String { - fun getOwnerName(ownerUsername: String): String { - return if (creditAccount.owner == "admin") "admin" else { - val creditorCustomer = DemobankCustomerEntity.find( - DemobankCustomersTable.username eq creditAccount.owner - ).firstOrNull() ?: throw internalServerError( - "Owner of bank account '${creditAccount.label}' not found" - ) - creditorCustomer.name ?: "Name not given" - } - } val timeStamp = getUTCnow().toInstant().toEpochMilli() val transactionRef = getRandomString(8) transaction { BankAccountTransactionEntity.new { creditorIban = creditAccount.iban creditorBic = creditAccount.bic - this.creditorName = getOwnerName(creditAccount.owner) + this.creditorName = getPersonNameFromCustomer(creditAccount.owner) debtorIban = debitAccount.iban debtorBic = debitAccount.bic - debtorName = getOwnerName(debitAccount.owner) + debtorName = getPersonNameFromCustomer(debitAccount.owner) this.subject = subject this.amount = amount this.currency = demoBank.currency @@ -135,10 +138,10 @@ fun wireTransfer( BankAccountTransactionEntity.new { creditorIban = creditAccount.iban creditorBic = creditAccount.bic - this.creditorName = getOwnerName(creditAccount.owner) + this.creditorName = getPersonNameFromCustomer(creditAccount.owner) debtorIban = debitAccount.iban debtorBic = debitAccount.bic - debtorName = getOwnerName(debitAccount.owner) + debtorName = getPersonNameFromCustomer(debitAccount.owner) this.subject = subject this.amount = amount this.currency = demoBank.currency diff --git a/util/src/main/kotlin/Payto.kt b/util/src/main/kotlin/Payto.kt @@ -8,7 +8,7 @@ import java.net.URLDecoder */ data class Payto( // represent query param "sender-name" or "receiver-name". - val name: String?, + val receiverName: String?, val iban: String, val bic: String?, // Typically, a wire transfer's subject. @@ -62,15 +62,11 @@ fun parsePayto(paytoLine: String): Payto { } } else null - val receiverName = getQueryParamOrNull("receiver-name", params) - val senderName = getQueryParamOrNull("sender-name", params) - if (receiverName != null && senderName != null) throw InvalidPaytoError("URI had both sender and receiver") - return Payto( iban = iban, bic = bic, amount = getQueryParamOrNull("amount", params), message = getQueryParamOrNull("message", params), - name = listOf(receiverName, senderName).firstNotNullOfOrNull { it } + receiverName = getQueryParamOrNull("receiver-name", params) ) } \ No newline at end of file diff --git a/util/src/test/kotlin/PaytoTest.kt b/util/src/test/kotlin/PaytoTest.kt @@ -1,5 +1,4 @@ import org.junit.Test -import tech.libeufin.util.EbicsProtocolError import tech.libeufin.util.InvalidPaytoError import tech.libeufin.util.parsePayto @@ -44,11 +43,11 @@ class PaytoTest { val withBic = parsePayto("payto://iban/BIC123/IBAN123?receiver-name=The%20Name") assert(withBic.iban == "IBAN123") assert(withBic.bic == "BIC123") - assert(withBic.name == "The Name") + assert(withBic.receiverName == "The Name") val complete = parsePayto("payto://iban/BIC123/IBAN123?sender-name=The%20Name&amount=EUR:1&message=donation") assert(withBic.iban == "IBAN123") assert(withBic.bic == "BIC123") - assert(withBic.name == "The Name") + assert(withBic.receiverName == "The Name") assert(complete.message == "donation") assert(complete.amount == "EUR:1") val withoutOptionals = parsePayto( @@ -56,7 +55,7 @@ class PaytoTest { ) assert(withoutOptionals.bic == null) assert(withoutOptionals.message == null) - assert(withoutOptionals.name == null) + assert(withoutOptionals.receiverName == null) assert(withoutOptionals.amount == null) } } \ No newline at end of file