mirror of
https://github.com/bitwarden/android.git
synced 2025-02-16 11:59:57 +03:00
PM-13848 Handle URIs with ports and host matching (#4203)
This commit is contained in:
parent
8f9585e4bc
commit
202b4de5ca
4 changed files with 138 additions and 3 deletions
|
@ -56,6 +56,7 @@ fun String.getWebHostFromAndroidUriOrNull(): String? =
|
||||||
fun String.getDomainOrNull(resourceCacheManager: ResourceCacheManager): String? =
|
fun String.getDomainOrNull(resourceCacheManager: ResourceCacheManager): String? =
|
||||||
this
|
this
|
||||||
.toUriOrNull()
|
.toUriOrNull()
|
||||||
|
?.addSchemeToUriIfNecessary()
|
||||||
?.parseDomainOrNull(resourceCacheManager = resourceCacheManager)
|
?.parseDomainOrNull(resourceCacheManager = resourceCacheManager)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -63,7 +64,10 @@ fun String.getDomainOrNull(resourceCacheManager: ResourceCacheManager): String?
|
||||||
*/
|
*/
|
||||||
@OmitFromCoverage
|
@OmitFromCoverage
|
||||||
fun String.hasPort(): Boolean {
|
fun String.hasPort(): Boolean {
|
||||||
val uri = this.toUriOrNull() ?: return false
|
val uri = this
|
||||||
|
.toUriOrNull()
|
||||||
|
?.addSchemeToUriIfNecessary()
|
||||||
|
?: return false
|
||||||
return uri.port != -1
|
return uri.port != -1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,14 +75,19 @@ fun String.hasPort(): Boolean {
|
||||||
* Extract the host from this [String] if possible, otherwise return null.
|
* Extract the host from this [String] if possible, otherwise return null.
|
||||||
*/
|
*/
|
||||||
@OmitFromCoverage
|
@OmitFromCoverage
|
||||||
fun String.getHostOrNull(): String? = this.toUriOrNull()?.host
|
fun String.getHostOrNull(): String? = this.toUriOrNull()
|
||||||
|
?.addSchemeToUriIfNecessary()
|
||||||
|
?.host
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extract the host with optional port from this [String] if possible, otherwise return null.
|
* Extract the host with optional port from this [String] if possible, otherwise return null.
|
||||||
*/
|
*/
|
||||||
@OmitFromCoverage
|
@OmitFromCoverage
|
||||||
fun String.getHostWithPortOrNull(): String? {
|
fun String.getHostWithPortOrNull(): String? {
|
||||||
val uri = this.toUriOrNull() ?: return null
|
val uri = this
|
||||||
|
.toUriOrNull()
|
||||||
|
?.addSchemeToUriIfNecessary()
|
||||||
|
?: return null
|
||||||
return uri.host?.let { host ->
|
return uri.host?.let { host ->
|
||||||
val port = uri.port
|
val port = uri.port
|
||||||
if (port != -1) {
|
if (port != -1) {
|
||||||
|
|
|
@ -45,6 +45,27 @@ fun URI.parseDomainNameOrNull(resourceCacheManager: ResourceCacheManager): Domai
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds and HTTPS scheme to a valid URI if that URI has a valid host in the raw string but
|
||||||
|
* the standard parsing of `URI("foo.com")` is not able to determine a valid host.
|
||||||
|
* (i.e. val uri = URI("foo.bar:1090") -> uri.host == null)
|
||||||
|
*/
|
||||||
|
fun URI.addSchemeToUriIfNecessary(): URI {
|
||||||
|
val uriString = this.toString()
|
||||||
|
return if (
|
||||||
|
// see if the string contains a host pattern
|
||||||
|
uriString.contains(".") &&
|
||||||
|
// if it does but the URI's host is null, add an https scheme
|
||||||
|
this.host == null &&
|
||||||
|
// provided that scheme does not exist already.
|
||||||
|
!uriString.hasHttpProtocol()
|
||||||
|
) {
|
||||||
|
URI("https://$uriString")
|
||||||
|
} else {
|
||||||
|
this
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The internal implementation of [parseDomainNameOrNull]. This doesn't extend URI and has a
|
* The internal implementation of [parseDomainNameOrNull]. This doesn't extend URI and has a
|
||||||
* non-null [host] parameter. Technically, URI.host could be null and we want to avoid issues with
|
* non-null [host] parameter. Technically, URI.host could be null and we want to avoid issues with
|
||||||
|
|
|
@ -3,8 +3,11 @@ package com.x8bit.bitwarden.data.util
|
||||||
import com.x8bit.bitwarden.data.platform.manager.ResourceCacheManager
|
import com.x8bit.bitwarden.data.platform.manager.ResourceCacheManager
|
||||||
import com.x8bit.bitwarden.data.platform.util.findLastSubstringIndicesOrNull
|
import com.x8bit.bitwarden.data.platform.util.findLastSubstringIndicesOrNull
|
||||||
import com.x8bit.bitwarden.data.platform.util.getDomainOrNull
|
import com.x8bit.bitwarden.data.platform.util.getDomainOrNull
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.getHostOrNull
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.getHostWithPortOrNull
|
||||||
import com.x8bit.bitwarden.data.platform.util.getWebHostFromAndroidUriOrNull
|
import com.x8bit.bitwarden.data.platform.util.getWebHostFromAndroidUriOrNull
|
||||||
import com.x8bit.bitwarden.data.platform.util.hasHttpProtocol
|
import com.x8bit.bitwarden.data.platform.util.hasHttpProtocol
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.hasPort
|
||||||
import com.x8bit.bitwarden.data.platform.util.isAndroidApp
|
import com.x8bit.bitwarden.data.platform.util.isAndroidApp
|
||||||
import com.x8bit.bitwarden.data.platform.util.parseDomainOrNull
|
import com.x8bit.bitwarden.data.platform.util.parseDomainOrNull
|
||||||
import com.x8bit.bitwarden.data.platform.util.toUriOrNull
|
import com.x8bit.bitwarden.data.platform.util.toUriOrNull
|
||||||
|
@ -154,4 +157,71 @@ class StringExtensionsTest {
|
||||||
// Verify
|
// Verify
|
||||||
assertEquals(expected, actual)
|
assertEquals(expected, actual)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getHostOrNull should return host when one is present`() {
|
||||||
|
val expectedHost = "www.google.com"
|
||||||
|
assertEquals(expectedHost, expectedHost.getHostOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getHostOrNull should return null when no host is present`() {
|
||||||
|
assertNull("boo".getHostOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getHostOrNull should return host from URI string when present and custom URI scheme`() {
|
||||||
|
val expectedHost = "www.google.com"
|
||||||
|
val hostWithScheme = "androidapp://$expectedHost"
|
||||||
|
assertEquals(expectedHost, hostWithScheme.getHostOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `getHostOrNull should return host from URI string when present and has port but no scheme`() {
|
||||||
|
val expectedHost = "www.google.com"
|
||||||
|
val hostWithPort = "$expectedHost:8080"
|
||||||
|
assertEquals(expectedHost, hostWithPort.getHostOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `hasPort returns true when port is present`() {
|
||||||
|
val uriString = "www.google.com:8080"
|
||||||
|
assertTrue("www.google.com:8080".hasPort())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `hasPort returns false when port is not present`() {
|
||||||
|
assertFalse("www.google.com".hasPort())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `hasPort return true when port is present and custom scheme is present`() {
|
||||||
|
val uriString = "androidapp://www.google.com:8080"
|
||||||
|
assertTrue(uriString.hasPort())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getHostWithPortOrNull should return host with port when present`() {
|
||||||
|
val uriString = "www.google.com:8080"
|
||||||
|
assertEquals("www.google.com:8080", uriString.getHostWithPortOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getHostWithPortOrNull should return host when no port is present`() {
|
||||||
|
val uriString = "www.google.com"
|
||||||
|
assertEquals("www.google.com", uriString.getHostWithPortOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `getHostWithPortOrNull should return null when no host is present`() {
|
||||||
|
assertNull("boo".getHostWithPortOrNull())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `getHostWithPortOrNull should return host with port when present and custom scheme is present`() {
|
||||||
|
val uriString = "androidapp://www.google.com:8080"
|
||||||
|
assertEquals("www.google.com:8080", uriString.getHostWithPortOrNull())
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,6 +2,7 @@ package com.x8bit.bitwarden.data.util
|
||||||
|
|
||||||
import com.x8bit.bitwarden.data.platform.manager.ResourceCacheManager
|
import com.x8bit.bitwarden.data.platform.manager.ResourceCacheManager
|
||||||
import com.x8bit.bitwarden.data.platform.manager.model.DomainName
|
import com.x8bit.bitwarden.data.platform.manager.model.DomainName
|
||||||
|
import com.x8bit.bitwarden.data.platform.util.addSchemeToUriIfNecessary
|
||||||
import com.x8bit.bitwarden.data.platform.util.parseDomainNameOrNull
|
import com.x8bit.bitwarden.data.platform.util.parseDomainNameOrNull
|
||||||
import com.x8bit.bitwarden.data.platform.util.parseDomainOrNull
|
import com.x8bit.bitwarden.data.platform.util.parseDomainOrNull
|
||||||
import io.mockk.every
|
import io.mockk.every
|
||||||
|
@ -321,4 +322,38 @@ class UriExtensionsTest {
|
||||||
assertEquals(expected[index], actual)
|
assertEquals(expected[index], actual)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `addSchemeToUriIfNecessary should add https when missing`() {
|
||||||
|
val uriWithNoScheme = URI("example.com")
|
||||||
|
assertEquals(URI("https://example.com"), uriWithNoScheme.addSchemeToUriIfNecessary())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("MaxLineLength")
|
||||||
|
@Test
|
||||||
|
fun `addSchemeToUriIfNecessary should add https when https scheme is missing and a port is present`() {
|
||||||
|
val uriWithPort = URI("example.com:8080")
|
||||||
|
assertEquals(URI("https://example.com:8080"), uriWithPort.addSchemeToUriIfNecessary())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `addSchemeToUriIfNecessary should not add https when http scheme is present`() {
|
||||||
|
val uriWithHttpScheme = URI("http://example.com")
|
||||||
|
assertEquals(URI("http://example.com"), uriWithHttpScheme.addSchemeToUriIfNecessary())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `addSchemeToUriIfNecessary should not add https when https scheme is present`() {
|
||||||
|
val uriWithHttpsScheme = URI("https://example.com")
|
||||||
|
assertEquals(URI("https://example.com"), uriWithHttpsScheme.addSchemeToUriIfNecessary())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun `addSchemeToUriIfNecessary should not add https when custom scheme is already present`() {
|
||||||
|
val uriWithCustomScheme = URI("bitwarden://example.com")
|
||||||
|
assertEquals(
|
||||||
|
URI("bitwarden://example.com"),
|
||||||
|
uriWithCustomScheme.addSchemeToUriIfNecessary(),
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue