mirror of
https://github.com/bitwarden/android.git
synced 2024-12-18 07:11:51 +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? =
|
||||
this
|
||||
.toUriOrNull()
|
||||
?.addSchemeToUriIfNecessary()
|
||||
?.parseDomainOrNull(resourceCacheManager = resourceCacheManager)
|
||||
|
||||
/**
|
||||
|
@ -63,7 +64,10 @@ fun String.getDomainOrNull(resourceCacheManager: ResourceCacheManager): String?
|
|||
*/
|
||||
@OmitFromCoverage
|
||||
fun String.hasPort(): Boolean {
|
||||
val uri = this.toUriOrNull() ?: return false
|
||||
val uri = this
|
||||
.toUriOrNull()
|
||||
?.addSchemeToUriIfNecessary()
|
||||
?: return false
|
||||
return uri.port != -1
|
||||
}
|
||||
|
||||
|
@ -71,14 +75,19 @@ fun String.hasPort(): Boolean {
|
|||
* Extract the host from this [String] if possible, otherwise return null.
|
||||
*/
|
||||
@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.
|
||||
*/
|
||||
@OmitFromCoverage
|
||||
fun String.getHostWithPortOrNull(): String? {
|
||||
val uri = this.toUriOrNull() ?: return null
|
||||
val uri = this
|
||||
.toUriOrNull()
|
||||
?.addSchemeToUriIfNecessary()
|
||||
?: return null
|
||||
return uri.host?.let { host ->
|
||||
val port = uri.port
|
||||
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
|
||||
* 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.util.findLastSubstringIndicesOrNull
|
||||
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.hasHttpProtocol
|
||||
import com.x8bit.bitwarden.data.platform.util.hasPort
|
||||
import com.x8bit.bitwarden.data.platform.util.isAndroidApp
|
||||
import com.x8bit.bitwarden.data.platform.util.parseDomainOrNull
|
||||
import com.x8bit.bitwarden.data.platform.util.toUriOrNull
|
||||
|
@ -154,4 +157,71 @@ class StringExtensionsTest {
|
|||
// Verify
|
||||
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.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.parseDomainOrNull
|
||||
import io.mockk.every
|
||||
|
@ -321,4 +322,38 @@ class UriExtensionsTest {
|
|||
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…
Reference in a new issue