gnunet-svn
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[taler-wallet-kotlin] branch master updated: Upgrade Taler URI to new fo


From: gnunet
Subject: [taler-wallet-kotlin] branch master updated: Upgrade Taler URI to new format
Date: Wed, 29 Jul 2020 22:58:36 +0200

This is an automated email from the git hooks/post-receive script.

torsten-grote pushed a commit to branch master
in repository wallet-kotlin.

The following commit(s) were added to refs/heads/master by this push:
     new 479f801  Upgrade Taler URI to new format
479f801 is described below

commit 479f8015f8663507fd318aa29e863dac35683c64
Author: Torsten Grote <t@grobox.de>
AuthorDate: Wed Jul 29 17:24:27 2020 -0300

    Upgrade Taler URI to new format
---
 .../kotlin/net/taler/wallet/kotlin/TalerUri.kt     | 37 ++++++++++++++++------
 .../net/taler/wallet/kotlin/operations/Withdraw.kt |  9 +++---
 .../kotlin/net/taler/wallet/kotlin/TalerUriTest.kt | 34 ++++++++++++--------
 .../kotlin/net/taler/wallet/kotlin/TestUtils.kt    |  4 +--
 .../taler/wallet/kotlin/operations/WithdrawTest.kt |  6 ++--
 5 files changed, 58 insertions(+), 32 deletions(-)

diff --git a/src/commonMain/kotlin/net/taler/wallet/kotlin/TalerUri.kt 
b/src/commonMain/kotlin/net/taler/wallet/kotlin/TalerUri.kt
index f64f738..c489d71 100644
--- a/src/commonMain/kotlin/net/taler/wallet/kotlin/TalerUri.kt
+++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/TalerUri.kt
@@ -19,23 +19,42 @@ package net.taler.wallet.kotlin
 internal object TalerUri {
 
     private const val SCHEME = "taler://"
+    private const val SCHEME_INSECURE = "taler+http://";
     private const val AUTHORITY_PAY = "pay"
     private const val AUTHORITY_WITHDRAW = "withdraw"
     private const val AUTHORITY_REFUND = "refund"
     private const val AUTHORITY_TIP = "tip"
 
+    data class WithdrawUriResult(
+        val bankIntegrationApiBaseUrl: String,
+        val withdrawalOperationId: String
+    )
+
     /**
      * Parses a withdraw URI and returns a bank status URL or null if the URI 
was invalid.
      */
-    fun parseWithdrawUri(uri: String): String? {
-        val prefix = "${SCHEME}${AUTHORITY_WITHDRAW}"
-        if (!uri.startsWith(prefix, ignoreCase = true)) return null
-        val parts = uri.substring(prefix.length + 1).split('/')
-        if (parts.size != 3) return null
-        val (host, query, withdrawId) = parts
-        // TODO clarify what query is and if it can include '/' (docs seem out 
of date)
-        val urlQuery = if (query == "-") "api/withdraw-operation" else query
-        return "https://${host.toLowerCase()}/$urlQuery/$withdrawId"
+    fun parseWithdrawUri(uri: String): WithdrawUriResult? {
+        val (resultScheme, prefix) = when {
+            uri.startsWith(SCHEME, ignoreCase = true) -> {
+                Pair("https://";, "${SCHEME}${AUTHORITY_WITHDRAW}/")
+            }
+            uri.startsWith(SCHEME_INSECURE, ignoreCase = true) -> {
+                Pair("http://";, "${SCHEME_INSECURE}${AUTHORITY_WITHDRAW}/")
+            }
+            else -> return null
+        }
+        if (!uri.startsWith(prefix)) return null
+        val parts = uri.let {
+            (if (it.endsWith("/")) it.dropLast(1) else 
it).substring(prefix.length).split('/')
+        }
+        if (parts.size < 2) return null
+        val host = parts[0].toLowerCase()
+        val pathSegments = parts.slice(1 until parts.size - 
1).joinToString("/")
+        val withdrawId = parts.last()
+        if (withdrawId.isBlank()) return null
+        val url = "${resultScheme}${host}/${pathSegments}"
+
+        return WithdrawUriResult(url, withdrawId)
     }
 
 }
diff --git 
a/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt 
b/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt
index 1fa2822..1173140 100644
--- a/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt
+++ b/src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt
@@ -52,7 +52,7 @@ internal class Withdraw(
         val amount: Amount,
         val selectionDone: Boolean,
         val transferDone: Boolean,
-        val senderWire: String?,
+        val senderPaytoUri: String?,
         val suggestedExchange: String?,
         val confirmTransferUrl: String?,
         val wireTypes: List<String>,
@@ -69,7 +69,7 @@ internal class Withdraw(
         @SerialName("wire_types")
         val wireTypes: List<String>,
         @SerialName("sender_wire")
-        val senderWire: String?,
+        val senderPaytoUri: String?,
         @SerialName("suggested_exchange")
         val suggestedExchange: String?,
         @SerialName("confirm_transfer_url")
@@ -80,7 +80,7 @@ internal class Withdraw(
             confirmTransferUrl = confirmTransferUrl,
             extractedStatusUrl = extractedStatusUrl,
             selectionDone = selectionDone,
-            senderWire = senderWire,
+            senderPaytoUri = senderPaytoUri,
             suggestedExchange = suggestedExchange,
             transferDone = transferDone,
             wireTypes = wireTypes
@@ -88,7 +88,8 @@ internal class Withdraw(
     }
 
     suspend fun getBankInfo(talerWithdrawUri: String): BankDetails {
-        val url = parseWithdrawUri(talerWithdrawUri) ?: throw Error("Can't 
parse URI $talerWithdrawUri")
+        val uriResult = parseWithdrawUri(talerWithdrawUri) ?: throw 
Error("Can't parse URI $talerWithdrawUri")
+        val url = 
"${uriResult.bankIntegrationApiBaseUrl}api/withdraw-operation/${uriResult.withdrawalOperationId}"
         val response: Response = httpClient.get(url)
         return response.toBankDetails(url)
     }
diff --git a/src/commonTest/kotlin/net/taler/wallet/kotlin/TalerUriTest.kt 
b/src/commonTest/kotlin/net/taler/wallet/kotlin/TalerUriTest.kt
index c35d155..cfcc8bd 100644
--- a/src/commonTest/kotlin/net/taler/wallet/kotlin/TalerUriTest.kt
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/TalerUriTest.kt
@@ -16,6 +16,7 @@
 
 package net.taler.wallet.kotlin
 
+import net.taler.wallet.kotlin.TalerUri.WithdrawUriResult
 import net.taler.wallet.kotlin.TalerUri.parseWithdrawUri
 import kotlin.test.Test
 import kotlin.test.assertEquals
@@ -26,31 +27,38 @@ class TalerUriTest {
     @Test
     fun testParseWithdrawUri() {
         // correct parsing
-        var uri = "taler://withdraw/bank.example.com/-/12345"
-        assertEquals("https://bank.example.com/api/withdraw-operation/12345";, 
parseWithdrawUri(uri))
+        var uri = "taler://withdraw/bank.example.com/12345"
+        var expected = WithdrawUriResult("https://bank.example.com/";, "12345")
+        assertEquals(expected, parseWithdrawUri(uri))
 
-        // correct parsing with custom query
-        uri = "taler://withdraw/bank.example.com/foo/12345"
-        assertEquals("https://bank.example.com/foo/12345";, 
parseWithdrawUri(uri))
+        // correct parsing with insecure http
+        uri = "taler+http://withdraw/bank.example.org/foo";
+        expected = WithdrawUriResult("http://bank.example.org/";, "foo")
+        assertEquals(expected, parseWithdrawUri(uri))
+
+        // correct parsing with long path
+        uri = "taler://withdraw/bank.example.com/foo/bar/23/42/1337/1234567890"
+        expected = 
WithdrawUriResult("https://bank.example.com/foo/bar/23/42/1337";, "1234567890")
+        assertEquals(expected, parseWithdrawUri(uri))
 
         // rejects incorrect scheme
-        uri = "talerx://withdraw/bank.example.com/-/12345"
+        uri = "talerx://withdraw/bank.example.com/12345"
         assertNull(parseWithdrawUri(uri))
 
         // rejects incorrect authority
-        uri = "taler://withdrawx/bank.example.com/-/12345"
+        uri = "taler://withdrawx/bank.example.com/12345"
         assertNull(parseWithdrawUri(uri))
 
-        // rejects incorrect authority
-        uri = "taler://withdrawx/bank.example.com/-/12345"
+        // rejects incorrect authority with insecure http
+        uri = "taler+http://withdrawx/bank.example.com/12345";
         assertNull(parseWithdrawUri(uri))
 
-        // rejects too few parts
-        uri = "taler://withdraw/bank.example.com/foo"
+        // rejects empty withdrawalId
+        uri = "taler://withdraw/bank.example.com//"
         assertNull(parseWithdrawUri(uri))
 
-        // rejects too many parts
-        uri = "taler://withdraw/bank.example.com/-/12345/foo"
+        // rejects empty path and withdrawalId
+        uri = "taler://withdraw/bank.example.com////"
         assertNull(parseWithdrawUri(uri))
     }
 
diff --git a/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt 
b/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt
index 4b04ebf..42f297a 100644
--- a/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt
@@ -20,11 +20,9 @@ import io.ktor.client.HttpClient
 import io.ktor.client.engine.mock.MockEngine
 import io.ktor.client.engine.mock.MockEngineConfig
 import io.ktor.client.engine.mock.respond
-import io.ktor.client.engine.mock.respondError
 import io.ktor.client.features.json.JsonFeature
 import io.ktor.client.features.json.serializer.KotlinxSerializer
 import io.ktor.http.ContentType.Application
-import io.ktor.http.HttpStatusCode.Companion.InternalServerError
 import io.ktor.http.Url
 import io.ktor.http.fullPath
 import io.ktor.http.headersOf
@@ -63,7 +61,7 @@ fun HttpClient.giveJsonResponse(url: String, jsonProducer: () 
-> String) {
             val headers = headersOf("Content-Type" to 
listOf(Application.Json.toString()))
             respond(jsonProducer(), headers = headers)
         } else {
-            respondError(InternalServerError, "Unexpected URL: 
${request.url.fullUrl}")
+            error("Unexpected URL: ${request.url.fullUrl}")
         }
     }
 }
diff --git 
a/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt 
b/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt
index 413deef..541f24f 100644
--- a/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt
+++ b/src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt
@@ -59,7 +59,7 @@ internal class WithdrawTest {
             confirmTransferUrl = 
"https://bank.test.taler.net/confirm-withdrawal/9b51c1dd-db41-4b5f-97d9-1071d5dd8091";,
             extractedStatusUrl = 
"https://bank.test.taler.net/api/withdraw-operation/9b51c1dd-db41-4b5f-97d9-1071d5dd8091";,
             selectionDone = false,
-            senderWire = "payto://x-taler-bank/bank.test.taler.net/test",
+            senderPaytoUri = "payto://x-taler-bank/bank.test.taler.net/test",
             suggestedExchange = "https://exchange.test.taler.net/";,
             transferDone = false,
             wireTypes = listOf("x-taler-bank")
@@ -70,14 +70,14 @@ internal class WithdrawTest {
                 "transfer_done": ${bankDetails.transferDone},
                 "amount": "${bankDetails.amount.toJSONString()}",
                 "wire_types": ["${bankDetails.wireTypes[0]}"],
-                "sender_wire": "${bankDetails.senderWire}",
+                "sender_wire": "${bankDetails.senderPaytoUri}",
                 "suggested_exchange": "${bankDetails.suggestedExchange}",
                 "confirm_transfer_url": "${bankDetails.confirmTransferUrl}"
             }""".trimIndent()
         }
         runCoroutine {
             val details =
-                
withdraw.getBankInfo("taler://withdraw/bank.test.taler.net/-/9b51c1dd-db41-4b5f-97d9-1071d5dd8091")
+                
withdraw.getBankInfo("taler://withdraw/bank.test.taler.net/9b51c1dd-db41-4b5f-97d9-1071d5dd8091")
             assertEquals(bankDetails, details)
         }
     }

-- 
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.



reply via email to

[Prev in Thread] Current Thread [Next in Thread]