Merge commit from fork
* Check validity of Element Call url host. * Prepare release 25.04.2
This commit is contained in:
@@ -12,25 +12,26 @@ import javax.inject.Inject
|
||||
|
||||
class CallIntentDataParser @Inject constructor() {
|
||||
private val validHttpSchemes = sequenceOf("https")
|
||||
private val knownHosts = sequenceOf(
|
||||
"call.element.io",
|
||||
)
|
||||
|
||||
fun parse(data: String?): String? {
|
||||
val parsedUrl = data?.let { Uri.parse(data) } ?: return null
|
||||
val scheme = parsedUrl.scheme
|
||||
return when {
|
||||
scheme in validHttpSchemes && parsedUrl.host == "call.element.io" -> parsedUrl
|
||||
scheme in validHttpSchemes -> parsedUrl
|
||||
scheme == "element" && parsedUrl.host == "call" -> {
|
||||
// We use this custom scheme to load arbitrary URLs for other instances of Element Call,
|
||||
// so we can only verify it's an HTTP/HTTPs URL with a non-empty host
|
||||
parsedUrl.getUrlParameter()
|
||||
}
|
||||
scheme == "io.element.call" && parsedUrl.host == null -> {
|
||||
// We use this custom scheme to load arbitrary URLs for other instances of Element Call,
|
||||
// so we can only verify it's an HTTP/HTTPs URL with a non-empty host
|
||||
parsedUrl.getUrlParameter()
|
||||
}
|
||||
// This should never be possible, but we still need to take into account the possibility
|
||||
else -> null
|
||||
}?.withCustomParameters()
|
||||
}
|
||||
?.takeIf { it.host in knownHosts }
|
||||
?.withCustomParameters()
|
||||
}
|
||||
|
||||
private fun Uri.getUrlParameter(): Uri? {
|
||||
|
||||
@@ -45,6 +45,17 @@ class CallIntentDataParserTest {
|
||||
doTest("http://call.element.io/some-actual-call?with=parameters", null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Element Call urls with unknown host returns null`() {
|
||||
// Check valid host first, should not return null
|
||||
doTest("https://call.element.io", "https://call.element.io#?appPrompt=false&confineToRoom=true")
|
||||
// Unknown host should return null
|
||||
doTest("https://unknown.io", null)
|
||||
doTest("https://call.unknown.io", null)
|
||||
doTest("https://call.element.com", null)
|
||||
doTest("https://call.element.io.tld", null)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun `Element Call urls will be returned as is`() {
|
||||
doTest(
|
||||
@@ -64,7 +75,7 @@ class CallIntentDataParserTest {
|
||||
@Test
|
||||
fun `HTTP and HTTPS urls that don't come from EC return null`() {
|
||||
doTest("http://app.element.io", null)
|
||||
doTest("https://app.element.io", null, testEmbedded = false)
|
||||
doTest("https://app.element.io", null)
|
||||
doTest("http://", null)
|
||||
doTest("https://", null)
|
||||
}
|
||||
@@ -193,20 +204,18 @@ class CallIntentDataParserTest {
|
||||
)
|
||||
}
|
||||
|
||||
private fun doTest(url: String, expectedResult: String?, testEmbedded: Boolean = true) {
|
||||
private fun doTest(url: String, expectedResult: String?) {
|
||||
// Test direct parsing
|
||||
assertThat(callIntentDataParser.parse(url)).isEqualTo(expectedResult)
|
||||
|
||||
if (testEmbedded) {
|
||||
// Test embedded url, scheme 1
|
||||
val encodedUrl = URLEncoder.encode(url, "utf-8")
|
||||
val urlScheme1 = "element://call?url=$encodedUrl"
|
||||
assertThat(callIntentDataParser.parse(urlScheme1)).isEqualTo(expectedResult)
|
||||
// Test embedded url, scheme 1
|
||||
val encodedUrl = URLEncoder.encode(url, "utf-8")
|
||||
val urlScheme1 = "element://call?url=$encodedUrl"
|
||||
assertThat(callIntentDataParser.parse(urlScheme1)).isEqualTo(expectedResult)
|
||||
|
||||
// Test embedded url, scheme 2
|
||||
val urlScheme2 = "io.element.call:/?url=$encodedUrl"
|
||||
assertThat(callIntentDataParser.parse(urlScheme2)).isEqualTo(expectedResult)
|
||||
}
|
||||
// Test embedded url, scheme 2
|
||||
val urlScheme2 = "io.element.call:/?url=$encodedUrl"
|
||||
assertThat(callIntentDataParser.parse(urlScheme2)).isEqualTo(expectedResult)
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
||||
Reference in New Issue
Block a user