commit 9d15c7304e3eaea5c98373c8ed465c824203e56d
parent c553a2991ec6aeb910351658092cef1762e413d2
Author: MS <ms@taler.net>
Date: Fri, 17 Nov 2023 17:37:49 +0100
nexus fetch: removing noise around payment subject
Diffstat:
3 files changed, 65 insertions(+), 17 deletions(-)
diff --git a/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt b/nexus/src/main/kotlin/tech/libeufin/nexus/EbicsFetch.kt
@@ -329,6 +329,10 @@ data class OutgoingPaymentWithLink(
val initiatedPaymentLink: String
)
+/**
+ * Collects incoming and outgoing payments which are
+ * the result of parsing one camt.054 notification.
+ */
data class Camt054Result(
val incoming: MutableList<IncomingPayment> = mutableListOf(),
val outgoing: MutableList<OutgoingPaymentWithLink> = mutableListOf()
@@ -403,6 +407,21 @@ fun isReservePub(maybeReservePub: String): ByteArray? {
}
return dec
}
+
+/**
+ * Extract the part of the subject that might represent a
+ * valid Taler reserve public key. That addresses some bank
+ * policies of adding extra information around the payment
+ * subject.
+ *
+ * @param subject raw subject as read from the bank.
+ */
+fun removeSubjectNoise(subject: String): String? {
+ val re = "\\b[a-z0-9A-Z]{52}\\b".toRegex()
+ val result = re.find(subject.replace("[\n]+".toRegex(), "")) ?: return null
+ return result.value
+}
+
/**
* Checks the two conditions that may invalidate one incoming
* payment: subject validity and availability.
@@ -416,8 +435,10 @@ suspend fun getTalerReservePub(
db: Database,
payment: IncomingPayment
): ByteArray? {
+ // Removing noise around the potential reserve public key.
+ val maybeReservePub = removeSubjectNoise(payment.wireTransferSubject) ?: return null
// Checking validity first.
- val dec = isReservePub(payment.wireTransferSubject) ?: return null
+ val dec = isReservePub(maybeReservePub) ?: return null
// Now checking availability.
val maybeUnavailable = db.isReservePubFound(dec)
if (maybeUnavailable) {
diff --git a/nexus/src/test/kotlin/Parsing.kt b/nexus/src/test/kotlin/Parsing.kt
@@ -1,9 +1,6 @@
import org.junit.Test
import org.junit.jupiter.api.assertThrows
-import tech.libeufin.nexus.TalerAmount
-import tech.libeufin.nexus.getAmountNoCurrency
-import tech.libeufin.nexus.getTalerAmount
-import tech.libeufin.nexus.isReservePub
+import tech.libeufin.nexus.*
import tech.libeufin.util.parseBookDate
import tech.libeufin.util.parseCamtTime
import java.lang.StringBuilder
@@ -24,6 +21,48 @@ class Parsing {
@Test
fun bookDateTest() {
parseBookDate("1970-01-01")
+ assertThrows<Exception> { parseBookDate("1970-01-01T00:00:01Z") }
+ }
+
+ @Test
+ fun reservePublicKey() {
+ assertNull(removeSubjectNoise("does not contain any reserve"))
+ // 4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0
+ assertNotNull(removeSubjectNoise("4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0"))
+ assertEquals(
+ "4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0",
+ removeSubjectNoise(
+ "noise 4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0 noise"
+ )
+ )
+ assertEquals(
+ "4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0",
+ removeSubjectNoise(
+ "4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0 noise to the right"
+ )
+ )
+ assertEquals(
+ "4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0",
+ removeSubjectNoise(
+ "noise to the left 4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0"
+ )
+ )
+ assertEquals(
+ "4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0",
+ removeSubjectNoise(
+ " 4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0 "
+ )
+ )
+ assertEquals(
+ "4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0",
+ removeSubjectNoise("""
+ noise
+ 4MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0
+ noise
+ """)
+ )
+ // Got the first char removed.
+ assertNull(removeSubjectNoise("MZT6RS3RVB3B0E2RDMYW0YRA3Y0VPHYV0CYDE6XBB0YMPFXCEG0"))
}
@Test // Could be moved in a dedicated Amounts.kt test module.
diff --git a/util/src/main/kotlin/strings.kt b/util/src/main/kotlin/strings.kt
@@ -83,15 +83,3 @@ fun getQueryParam(uriQueryString: String, param: String): String? {
return null
}
-fun extractReservePubFromSubject(rawSubject: String): String? {
- val re = "\\b[a-z0-9A-Z]{52}\\b".toRegex()
- val result = re.find(rawSubject.replace("[\n]+".toRegex(), "")) ?: return null
- try {
- Base32Crockford.decode(result.value)
- } catch (e: Exception) {
- logger.debug("Not containing a reserve pub: $rawSubject")
- return null
- }
- return result.value.uppercase()
-}
-