[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[libeufin] 01/02: nexus ebics-setup
From: |
gnunet |
Subject: |
[libeufin] 01/02: nexus ebics-setup |
Date: |
Fri, 27 Oct 2023 12:51:05 +0200 |
This is an automated email from the git hooks/post-receive script.
ms pushed a commit to branch master
in repository libeufin.
commit 83451e306b83615b70b5d5e541fdcb965862ef0e
Author: MS <ms@taler.net>
AuthorDate: Fri Oct 27 12:47:53 2023 +0200
nexus ebics-setup
only relying to the account metadata found in the
configuration, as per last DD 50 version.
---
.../main/kotlin/tech/libeufin/nexus/EbicsSetup.kt | 100 ++++-----------------
nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt | 31 ++-----
.../kotlin/tech/libeufin/nexus/ebics/Ebics2.kt | 25 ++++++
nexus/src/test/kotlin/PostFinance.kt | 20 ++++-
4 files changed, 66 insertions(+), 110 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt
index f14ee558..c2385304 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsSetup.kt
@@ -346,57 +346,6 @@ private fun makePdf(privs: ClientPrivateKeysFile, cfg:
EbicsSetupConfig) {
println("PDF file with keys hex encoding created at: $pdfFile")
}
-/**
- * Extracts bank account information and stores it to the bank account
- * metadata file that's found in the configuration. It returns void in
- * case of success, or fails the whole process upon errors.
- *
- * @param cfg configuration handle.
- * @param bankAccounts bank response to EBICS HTD request.
- * @param showAssociatedAccounts if true, the function only shows the
- * users account, without persisting anything to disk.
- */
-fun extractBankAccountMetadata(
- cfg: EbicsSetupConfig,
- bankAccounts: HTDResponseOrderData,
- showAssociatedAccounts: Boolean
-) {
- // Now trying to extract whatever IBAN & BIC pair the bank gave in the
response.
- val foundIban: String? = findIban(bankAccounts.partnerInfo.accountInfoList)
- val foundBic: String? = findBic(bankAccounts.partnerInfo.accountInfoList)
- // _some_ IBAN & BIC _might_ have been found, compare it with the config.
- if (foundIban == null)
- logger.warn("Bank seems NOT to show any IBAN for our account.")
- if (foundBic == null)
- logger.warn("Bank seems NOT to show any BIC for our account.")
- // Warn the user if instead one IBAN was found but that differs from the
config.
- if (foundIban != null && foundIban != cfg.accountNumber) {
- logger.error("Bank has another IBAN for us: $foundIban, while config
has: ${cfg.accountNumber}")
- exitProcess(1)
- }
- // Users wants to only _see_ the accounts, NOT checking values and
returning here.
- if (showAssociatedAccounts) {
- println("Bank associates this account to the EBICS user
${cfg.ebicsUserId}: IBAN: $foundIban, BIC: $foundBic, Name:
${bankAccounts.userInfo.name}")
- return
- }
- // No divergences were found, either because the config was right
- // _or_ the bank didn't give any information. Setting the account
- // metadata accordingly.
- val accountMetaData = BankAccountMetadataFile(
- account_holder_name = bankAccounts.userInfo.name ?: "Account holder
name not given",
- account_holder_iban = foundIban ?: run iban@ {
- logger.warn("Bank did not show any IBAN for us, defaulting to the
one we configured.")
- return@iban cfg.accountNumber },
- bank_code = foundBic ?: run bic@ {
- logger.warn("Bank did not show any BIC for us, setting it as
null.")
- return@bic null }
- )
- if (!syncJsonToDisk(accountMetaData, cfg.bankAccountMetadataFilename)) {
- logger.error("Failed to persist bank account meta-data at:
${cfg.bankAccountMetadataFilename}")
- exitProcess(1)
- }
-}
-
/**
* CLI class implementing the "ebics-setup" subcommand.
*/
@@ -481,7 +430,7 @@ class EbicsSetup: CliktCommand("Set up the EBICS
subscriber") {
if (keysNotSub || generateRegistrationPdf) makePdf(privs, cfg)
// Checking if the bank keys exist on disk.
val bankKeysFile = File(cfg.bankPublicKeysFilename)
- if (!bankKeysFile.exists()) { // FIXME: should this also check the
content validity?
+ if (!bankKeysFile.exists()) {
val areKeysOnDisk = runBlocking {
doKeysRequestAndUpdateState(
cfg,
@@ -502,43 +451,24 @@ class EbicsSetup: CliktCommand("Set up the EBICS
subscriber") {
logger.error("Although previous checks, could not load the bank
keys file from: ${cfg.bankPublicKeysFilename}")
exitProcess(1)
}
- /**
- * The following block potentially updates the bank keys state
- * on disk, if that's the first time that they become accepted.
- * If so, finally reloads the bank keys file from disk.
- */
- val bankKeys = if (!bankKeysMaybe.accepted) {
-
- if (autoAcceptKeys) bankKeysMaybe.accepted = true
- else bankKeysMaybe.accepted = askUserToAcceptKeys(bankKeysMaybe)
-
- if (!bankKeysMaybe.accepted) {
- logger.error("Cannot continue without accepting the bank
keys.")
- exitProcess(1)
- }
+ val printOk = { println("setup ready") }
- if (!syncJsonToDisk(bankKeysMaybe, cfg.bankPublicKeysFilename)) {
- logger.error("Could not set bank keys as accepted on disk.")
- exitProcess(1)
- }
- // Reloading after the disk write above.
- loadBankKeys(cfg.bankPublicKeysFilename) ?: kotlin.run {
- logger.error("Could not reload bank keys after disk write.")
- exitProcess(1)
- }
- } else
- bankKeysMaybe // keys were already accepted.
+ if (bankKeysMaybe.accepted) {
+ printOk()
+ return
+ }
+ // Finishing the setup by accepting the bank keys.
+ if (autoAcceptKeys) bankKeysMaybe.accepted = true
+ else bankKeysMaybe.accepted = askUserToAcceptKeys(bankKeysMaybe)
- // Downloading the list of owned bank account(s).
- val bankAccounts = runBlocking {
- fetchBankAccounts(cfg, privs, bankKeys, httpClient)
+ if (!bankKeysMaybe.accepted) {
+ logger.error("Cannot successfully finish the setup without
accepting the bank keys.")
+ exitProcess(1)
}
- if (bankAccounts == null) {
- logger.error("Could not obtain the list of bank accounts from the
bank.")
+ if (!syncJsonToDisk(bankKeysMaybe, cfg.bankPublicKeysFilename)) {
+ logger.error("Could not set bank keys as accepted on disk.")
exitProcess(1)
}
- logger.info("Subscriber's bank accounts fetched.")
- extractBankAccountMetadata(cfg, bankAccounts, showAssociatedAccounts)
- println("setup ready")
+ printOk()
}
}
\ No newline at end of file
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
index c00c13b3..cf6a0c02 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/Main.kt
@@ -101,10 +101,14 @@ class EbicsSetupConfig(val config: TalerConfig) {
*/
val ebicsSystemId = ebicsSetupRequireString("system_id")
/**
- * Bank account name, as given by the bank. It
- * can be an IBAN or even any alphanumeric value.
+ * Bank account metadata.
*/
- val accountNumber = ebicsSetupRequireString("account_number")
+ val accountNumber: IbanPayto =
ebicsSetupRequireString("account_number").run {
+ val maybeAccount = parsePayto(this)
+ if (maybeAccount?.bic == null) throw Exception("ACCOUNT_NUMBER lacks
the BIC")
+ if (maybeAccount.receiverName == null) throw Exception("ACCOUNT_NUMBER
lacks the name")
+ return@run maybeAccount
+ }
/**
* Filename where we store the bank public keys.
*/
@@ -113,10 +117,6 @@ class EbicsSetupConfig(val config: TalerConfig) {
* Filename where we store our private keys.
*/
val clientPrivateKeysFilename =
ebicsSetupRequireString("client_private_keys_file")
- /**
- * Filename where we store the bank account main information.
- */
- val bankAccountMetadataFilename =
ebicsSetupRequireString("account_meta_data_file")
/**
* A name that identifies the EBICS and ISO20022 flavour
* that Nexus should honor in the communication with the
@@ -200,23 +200,6 @@ data class BankPublicKeysFile(
var accepted: Boolean
)
-/**
- * Gets the bank account metadata file, according to the
- * location found in the configuration. The caller may still
- * have to handle the exception, in case the found file doesn't
- * parse to the wanted JSON type.
- *
- * @param cfg configuration handle.
- * @return [BankAccountMetadataFile] or null, if the file wasn't found.
- */
-fun loadBankAccountFile(cfg: EbicsSetupConfig): BankAccountMetadataFile? {
- val f = File(cfg.bankAccountMetadataFilename)
- if (!f.exists()) {
- logger.error("Bank account metadata file not found in
${cfg.bankAccountMetadataFilename}")
- return null
- }
- return myJson.decodeFromString(f.readText())
-}
/**
* Load the bank keys file from disk.
*
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
index 361bdd95..2c4cf45b 100644
--- a/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
+++ b/nexus/src/main/kotlin/tech/libeufin/nexus/ebics/Ebics2.kt
@@ -34,6 +34,30 @@ import java.time.ZoneId
import java.util.*
import javax.xml.datatype.DatatypeFactory
+/**
+ * Convenience function to download via EBICS with a
+ * customer message type.
+ *
+ * @param messageType EBICS 2.x message type. Defaults
+ * to HTD, to get general information about the EBICS
+ * subscriber.
+ * @param cfg configuration handle
+ * @param clientKeys client EBICS keys.
+ * @param bankKeys bank EBICS keys.
+ * @param client HTTP client handle.
+ * @return raw XML response, or null upon errors.
+ */
+suspend fun doEbicsCustomDownload(
+ messageType: String = "HTD",
+ cfg: EbicsSetupConfig,
+ clientKeys: ClientPrivateKeysFile,
+ bankKeys: BankPublicKeysFile,
+ client: HttpClient
+): String? {
+ val xmlReq = createEbics25DownloadInit(cfg, clientKeys, bankKeys,
messageType)
+ return doEbicsDownload(client, cfg, clientKeys, bankKeys, xmlReq, false)
+}
+
/**
* Request EBICS (2.x) HTD to the bank. This message type
* gets the list of bank accounts that are owned by the EBICS
@@ -59,6 +83,7 @@ suspend fun fetchBankAccounts(
return null
}
return try {
+ logger.debug("Fetched accounts: $xmlResp")
XMLUtil.convertStringToJaxb<HTDResponseOrderData>(xmlResp).value
} catch (e: Exception) {
logger.error("Could not parse the HTD payload, detail: ${e.message}")
diff --git a/nexus/src/test/kotlin/PostFinance.kt
b/nexus/src/test/kotlin/PostFinance.kt
index b1b5469d..d439ae79 100644
--- a/nexus/src/test/kotlin/PostFinance.kt
+++ b/nexus/src/test/kotlin/PostFinance.kt
@@ -3,6 +3,7 @@ import kotlinx.coroutines.runBlocking
import org.junit.Ignore
import org.junit.Test
import tech.libeufin.nexus.*
+import tech.libeufin.nexus.ebics.doEbicsCustomDownload
import tech.libeufin.nexus.ebics.fetchBankAccounts
import tech.libeufin.nexus.ebics.submitPayment
import tech.libeufin.util.IbanPayto
@@ -50,7 +51,7 @@ class Iso20022 {
}
}
-@Ignore
+// @Ignore
class PostFinance {
// Tests sending client keys to the PostFinance test platform.
@Test
@@ -83,6 +84,23 @@ class PostFinance {
}
}
+ @Test
+ fun customDownload() {
+ val cfg = prep()
+ val clientKeys = loadPrivateKeysFromDisk(cfg.clientPrivateKeysFilename)
+ val bankKeys = loadBankKeys(cfg.bankPublicKeysFilename)
+ runBlocking {
+ val xml = doEbicsCustomDownload(
+ messageType = "HTD",
+ cfg = cfg,
+ bankKeys = bankKeys!!,
+ clientKeys = clientKeys!!,
+ client = HttpClient()
+ )
+ println(xml)
+ }
+ }
+
// Tests the HTD message type.
@Test
fun fetchAccounts() {
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.