[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] branch master updated: Separation between bank account and cu
From: |
gnunet |
Subject: |
[libeufin] branch master updated: Separation between bank account and customer accounts. |
Date: |
Tue, 19 Oct 2021 12:56:48 +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 d43df56 Separation between bank account and customer accounts.
d43df56 is described below
commit d43df5630d4d1a1097ba1552d8e950a9056b860d
Author: ms <ms@taler.net>
AuthorDate: Tue Oct 19 12:55:47 2021 +0200
Separation between bank account and customer accounts.
Addressing confuion given by the 'name' field of the BankAccount
type. Choosing 'label' to indicate bank accounts and 'name' for
customers.
---
.../src/main/kotlin/tech/libeufin/sandbox/DB.kt | 18 ++-
.../tech/libeufin/sandbox/EbicsProtocolBackend.kt | 6 +-
.../src/main/kotlin/tech/libeufin/sandbox/JSON.kt | 5 +
.../src/main/kotlin/tech/libeufin/sandbox/Main.kt | 148 ++++++++++++---------
.../kotlin/tech/libeufin/sandbox/bankAccount.kt | 8 +-
5 files changed, 105 insertions(+), 80 deletions(-)
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
index 4186087..2433d48 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/DB.kt
@@ -112,24 +112,20 @@ class DemobankConfigEntity(id: EntityID<Long>) :
LongEntity(id) {
object DemobankCustomersTable : LongIdTable() {
val isPublic = bool("isPublic").default(false)
val demobankConfig = reference("demobankConfig", DemobankConfigsTable)
- val balance = text("balance")
+ val bankAccount = reference("bankAccount", BankAccountsTable)
val username = text("username")
val passwordHash = text("passwordHash")
- val isDebit = bool("isDebit").default(false)
val name = text("name").nullable()
- val iban = text("iban")
}
class DemobankCustomerEntity(id: EntityID<Long>) : LongEntity(id) {
companion object :
LongEntityClass<DemobankCustomerEntity>(DemobankCustomersTable)
var isPublic by DemobankCustomersTable.isPublic
- var demobankConfig by DemobankCustomersTable.demobankConfig
- var balance by DemobankCustomersTable.balance
+ var demobankConfig by DemobankConfigEntity referencedOn
DemobankCustomersTable.demobankConfig
+ var bankAccount by BankAccountEntity referencedOn
DemobankCustomersTable.bankAccount
var username by DemobankCustomersTable.username
var passwordHash by DemobankCustomersTable.passwordHash
- var isDebit by DemobankCustomersTable.isDebit
var name by DemobankCustomersTable.name
- var iban by DemobankCustomersTable.iban
}
/**
@@ -371,10 +367,11 @@ class BankAccountTransactionEntity(id: EntityID<Long>) :
LongEntity(id) {
*/
object BankAccountsTable : IntIdTable() {
val iban = text("iban")
- val bic = text("bic")
- val name = text("name")
+ val bic = text("bic").default("EUSANDBOX")
val label = text("label").uniqueIndex("accountLabelIndex")
val currency = text("currency")
+ val isDebit = bool("isDebit").default(false)
+ val balance = text("balance")
}
class BankAccountEntity(id: EntityID<Int>) : IntEntity(id) {
@@ -382,9 +379,10 @@ class BankAccountEntity(id: EntityID<Int>) : IntEntity(id)
{
var iban by BankAccountsTable.iban
var bic by BankAccountsTable.bic
- var name by BankAccountsTable.name
var label by BankAccountsTable.label
var currency by BankAccountsTable.currency
+ var isDebit by BankAccountsTable.isDebit
+ var balance by BankAccountsTable.balance
}
object BankAccountStatementsTable : IntIdTable() {
diff --git
a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
index 0659c73..7a54d64 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/EbicsProtocolBackend.kt
@@ -972,7 +972,11 @@ private fun makePartnerInfo(subscriber:
EbicsSubscriberEntity): EbicsTypes.Partn
this.accountInfoList = listOf(
EbicsTypes.AccountInfo().apply {
this.id = bankAccount.label
- this.accountHolder = bankAccount.name
+ /**
+ * FIXME:
+ * This value waits to be extracted from the DemobankCustomer
type.
+ */
+ this.accountHolder = "Account Holder"
this.accountNumberList = listOf(
EbicsTypes.GeneralAccountNumber().apply {
this.international = true
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
index 92992e0..7756d98 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/JSON.kt
@@ -67,6 +67,11 @@ data class BankAccountRequest(
val subscriber: EbicsSubscriberElement,
val iban: String,
val bic: String,
+ /**
+ * Obsolete: kept around to allow progressive porting of tests.
+ * This value used to represent a _person_ name, but the new
DemobankCustomer
+ * type is now responsible for that.
+ */
val name: String,
val label: String,
val currency: String
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
index fc53da8..fe6fcac 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/Main.kt
@@ -278,6 +278,11 @@ class Serve : CliktCommand("Run sandbox HTTP server") {
}
}
+private fun getCustomerFromDb(username: String): DemobankCustomerEntity {
+ return transaction { DemobankCustomerEntity.find {
+ DemobankCustomersTable.username eq username
+ }.firstOrNull() } ?: throw notFound("Customer with username '$username'
not found")
+}
private fun getJsonFromDemobankConfig(fromDb: DemobankConfigEntity): Demobank {
return Demobank(
currency = fromDb.currency,
@@ -541,7 +546,6 @@ val sandboxApp: Application.() -> Unit = {
BankAccountEntity.new {
iban = body.iban
bic = body.bic
- name = body.name
label = body.label
currency = body.currency ?: "EUR"
}
@@ -566,7 +570,6 @@ val sandboxApp: Application.() -> Unit = {
val balance = "${bankAccount.currency}:${balance}"
val iban = bankAccount.iban
val bic = bankAccount.bic
- val name = bankAccount.name
val label = bankAccount.label
}
}
@@ -600,7 +603,7 @@ val sandboxApp: Application.() -> Unit = {
tech.libeufin.sandbox.BankAccountTransactionEntity.new {
creditorIban = account.iban
creditorBic = account.bic
- creditorName = account.name
+ creditorName = "Creditor Name" // FIXME: Waits to get this
value from the DemobankCustomer type.
debtorIban = body.debtorIban
debtorBic = reqDebtorBic
debtorName = body.debtorName
@@ -640,7 +643,6 @@ val sandboxApp: Application.() -> Unit = {
subscriber.bankAccount =
tech.libeufin.sandbox.BankAccountEntity.new {
iban = body.iban
bic = body.bic
- name = body.name
label = body.label
currency = body.currency.uppercase(java.util.Locale.ROOT)
}
@@ -658,10 +660,10 @@ val sandboxApp: Application.() -> Unit = {
accounts.add(
BankAccountInfo(
label = it.label,
- name = it.name,
bic = it.bic,
iban = it.iban,
- currency = it.currency
+ currency = it.currency,
+ name = "Bank account owner's name"
)
)
}
@@ -726,7 +728,7 @@ val sandboxApp: Application.() -> Unit = {
tech.libeufin.sandbox.BankAccountTransactionEntity.new {
creditorIban = account.iban
creditorBic = account.bic
- creditorName = account.name
+ creditorName = "Creditor Name"
debtorIban = "DE64500105178797276788"
debtorBic = "DEUTDEBB101"
debtorName = "Max Mustermann"
@@ -746,7 +748,7 @@ val sandboxApp: Application.() -> Unit = {
BankAccountTransactionEntity.new {
debtorIban = account.iban
debtorBic = account.bic
- debtorName = account.name
+ debtorName = "Debitor Name"
creditorIban = "DE64500105178797276788"
creditorBic = "DEUTDEBB101"
creditorName = "Max Mustermann"
@@ -896,49 +898,6 @@ val sandboxApp: Application.() -> Unit = {
return@post
}
- /**
- * Activates a withdraw operation of 1 currency unit with
- * the default exchange, from a designated/constant customer.
- */
- get("/taler") {
- call.request.basicAuth()
- SandboxAssert(
- currencyEnv != null,
- "Currency not found. Logs should have warned"
- )
- // check that the three canonical accounts exist
- val wo = transaction {
- val exchange = BankAccountEntity.find {
- BankAccountsTable.label eq "sandbox-account-exchange"
- }.firstOrNull()
- val customer = BankAccountEntity.find {
- BankAccountsTable.label eq "sandbox-account-customer"
- }.firstOrNull()
- val merchant = BankAccountEntity.find {
- BankAccountsTable.label eq "sandbox-account-merchant"
- }.firstOrNull()
-
- SandboxAssert(exchange != null, "exchange has no bank account")
- SandboxAssert(customer != null, "customer has no bank account")
- SandboxAssert(merchant != null, "merchant has no bank account")
-
- // At this point, the three actors exist and a new withdraw
operation can be created.
- TalerWithdrawalEntity.new {
- // wopid is autogenerated, and momentarily the only column
- }
- }
- val baseUrl = URL(call.request.getBaseUrl())
- val ret = call.url {
- protocol = URLProtocol(
- "taler".plus(if (baseUrl.protocol.lowercase() == "http")
"+http" else ""),
- -1
- )
- pathComponents(baseUrl.path, "api", wo.wopid.toString())
- encodedPath += "/"
- }
- call.respondText(ret)
- return@get
- }
get("/api/config") {
SandboxAssert(
currencyEnv != null,
@@ -1072,26 +1031,80 @@ val sandboxApp: Application.() -> Unit = {
route("/access-api") {
+ post("/accounts/{account_name}/withdrawals") {
+ val username = call.request.basicAuth()
+ ensureDemobank(call.getUriComponent("demobankid"))
+ /**
+ * Check that the three canonical accounts exist. The
names
+ * below match those used in the testing harnesses.
+ */
+ val wo: TalerWithdrawalEntity = transaction {
+ val exchange = BankAccountEntity.find {
+ BankAccountsTable.label eq
"sandbox-account-exchange"
+ }.firstOrNull()
+ val customer = BankAccountEntity.find {
+ BankAccountsTable.label eq
"sandbox-account-customer"
+ }.firstOrNull()
+ val merchant = BankAccountEntity.find {
+ BankAccountsTable.label eq
"sandbox-account-merchant"
+ }.firstOrNull()
+ SandboxAssert(exchange != null, "exchange has no bank
account")
+ SandboxAssert(customer != null, "customer has no bank
account")
+ SandboxAssert(merchant != null, "merchant has no bank
account")
+ // At this point, the three actors exist and a new
withdraw operation can be created.
+ val wo = TalerWithdrawalEntity.new { /* wopid is
autogenerated, and momentarily the only column */ }
+ wo
+ }
+ val baseUrl = URL(call.request.getBaseUrl())
+ val withdrawUri = call.url {
+ protocol = URLProtocol(
+ "taler".plus(if (baseUrl.protocol.lowercase() ==
"http") "+http" else ""),
+ -1
+ )
+ pathComponents(baseUrl.path, "api",
wo.wopid.toString())
+ encodedPath += "/"
+ }
+ call.respond(object {
+ val withdrawal_id = wo.id.value
+ val taler_withdraw_uri = withdrawUri
+ })
+ return@post
+ }
+
+ // Confirm the wire transfer to the exchange. Idempotent
+ post("/accounts/{account_name}/withdrawals/confirm") {
+
+
+ return@post
+ }
get("/accounts/{account_name}") {
val username = call.request.basicAuth()
val accountAccessed = call.getUriComponent("account_name")
- if (username != accountAccessed) {
- throw forbidden("Account '$accountAccessed' not
allowed for '$username'")
- }
- val customer = transaction {
- val res = DemobankCustomerEntity.find {
- DemobankCustomersTable.username eq username
+ val bankAccount = transaction {
+ val res = BankAccountEntity.find {
+ BankAccountsTable.label eq accountAccessed
}.firstOrNull()
res
- } ?: throw internalServerError("Account '$accountAccessed'
not found AFTER authentication!")
- val creditDebitIndicator = if (customer.isDebit) {
+ } ?: throw notFound("Account '$accountAccessed' not found")
+
+ // Check rights.
+ if (WITH_AUTH) {
+ val customer = getCustomerFromDb(username ?: throw
internalServerError(
+ "Optional authentication broken!"
+ ))
+ if (customer.bankAccount.label != accountAccessed)
throw forbidden(
+ "Customer '$username' cannot access bank account
'$accountAccessed'"
+ )
+ }
+
+ val creditDebitIndicator = if (bankAccount.isDebit) {
"debit"
} else {
"credit"
}
call.respond(object {
val balance = {
- val amount = customer.balance
+ val amount = bankAccount.balance
val credit_debit_indicator = creditDebitIndicator
}
})
@@ -1119,8 +1132,8 @@ val sandboxApp: Application.() -> Unit = {
ret.publicAccounts.add(
CustomerInfo(
username = it.username,
- balance = it.balance,
- iban = it.iban,
+ balance = it.bankAccount.balance,
+ iban = it.bankAccount.iban,
name = it.name ?: throw
internalServerError(
"Found name-less public account,
username: ${it.username}"
)
@@ -1155,12 +1168,17 @@ val sandboxApp: Application.() -> Unit = {
// Create new customer.
requireValidResourceName(req.username)
transaction {
- // FIXME: Since we now use IBANs everywhere, maybe the
account should also be assigned an IBAN
+ val bankAccount = BankAccountEntity.new {
+ iban = getIban()
+ label = req.username + "acct" // multiple accounts
per username not allowed.
+ currency = demobank.currency
+ balance = "${demobank.currency}:0"
+ }
DemobankCustomerEntity.new {
username = req.username
passwordHash = CryptoUtil.hashpw(req.password)
- demobankConfig = demobank.id
- iban = getIban()
+ demobankConfig = demobank
+ this.bankAccount = bankAccount
}
}
call.respondText("Registration successful")
diff --git a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
index 3d5236a..151af01 100644
--- a/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
+++ b/sandbox/src/main/kotlin/tech/libeufin/sandbox/bankAccount.kt
@@ -165,10 +165,10 @@ fun wireTransfer(
BankAccountTransactionEntity.new {
creditorIban = credit.iban
creditorBic = credit.bic
- creditorName = credit.name
+ creditorName = "Creditor Name"
debtorIban = debit.iban
debtorBic = debit.bic
- debtorName = debit.name
+ debtorName = "Debitor Name"
subject = subjectArg
this.amount = amountObj.amount.toString()
currency = amountObj.currency
@@ -180,10 +180,10 @@ fun wireTransfer(
BankAccountTransactionEntity.new {
creditorIban = credit.iban
creditorBic = credit.bic
- creditorName = credit.name
+ creditorName = "Creditor Name"
debtorIban = debit.iban
debtorBic = debit.bic
- debtorName = debit.name
+ debtorName = "Debitor Name"
subject = subjectArg
this.amount = amountObj.amount.toString()
currency = amountObj.currency
--
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: Separation between bank account and customer accounts.,
gnunet <=