summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTorsten Grote <t@grobox.de>2020-07-29 17:24:27 -0300
committerTorsten Grote <t@grobox.de>2020-07-29 17:25:41 -0300
commit479f8015f8663507fd318aa29e863dac35683c64 (patch)
tree3d65de0c8af74cf4f2ba37e65624d01a8eb8af60 /src
parent9befa8db8317758ad9e5dad5e7698efff76f1a71 (diff)
downloadwallet-kotlin-479f8015f8663507fd318aa29e863dac35683c64.tar.gz
wallet-kotlin-479f8015f8663507fd318aa29e863dac35683c64.tar.bz2
wallet-kotlin-479f8015f8663507fd318aa29e863dac35683c64.zip
Upgrade Taler URI to new format
Diffstat (limited to 'src')
-rw-r--r--src/commonMain/kotlin/net/taler/wallet/kotlin/TalerUri.kt37
-rw-r--r--src/commonMain/kotlin/net/taler/wallet/kotlin/operations/Withdraw.kt9
-rw-r--r--src/commonTest/kotlin/net/taler/wallet/kotlin/TalerUriTest.kt34
-rw-r--r--src/commonTest/kotlin/net/taler/wallet/kotlin/TestUtils.kt4
-rw-r--r--src/commonTest/kotlin/net/taler/wallet/kotlin/operations/WithdrawTest.kt6
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)
}
}