Skip to content

Commit 1f7a65c

Browse files
authored
Merge pull request #19570 from wordpress-mobile/issue/19501-limit-details-navigation
🤖 Prevent navigation outside the domain details webview
2 parents 44a38b0 + 01aa44d commit 1f7a65c

11 files changed

Lines changed: 130 additions & 41 deletions

WordPress/src/main/AndroidManifest.xml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -804,7 +804,7 @@
804804
android:theme="@style/WordPress.NoActionBar" />
805805

806806
<activity
807-
android:name=".ui.domains.management.DomainManagementDetailsActivity"
807+
android:name=".ui.domains.management.details.DomainManagementDetailsActivity"
808808
android:theme="@style/WordPress.NoActionBar" />
809809
<activity
810810
android:name=".ui.domains.management.purchasedomain.PurchaseDomainActivity"
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,14 @@
11
package org.wordpress.android.ui.blaze.blazecampaigns.campaigndetail
22

3-
import android.net.Uri
3+
import org.wordpress.android.ui.utils.AbstractAllowedUrlsWebViewNavigationDelegate
44

5-
object CampaignDetailWebViewNavigationDelegate {
6-
private val allowedUrls = listOf(
5+
object CampaignDetailWebViewNavigationDelegate : AbstractAllowedUrlsWebViewNavigationDelegate() {
6+
override val allowedUrls = listOf(
77
UrlMatcher(
88
"wordpress.com".toRegex(),
99
listOf(
1010
"/advertising/campaigns/\\d+/[a-zA-Z0-9.-]+\$".toRegex()
1111
)
1212
)
1313
)
14-
15-
fun canNavigateTo(url: Url) = allowedUrls.any { it.matches(url) }
16-
17-
data class UrlMatcher(
18-
private val host: Regex,
19-
private val paths: List<Regex>
20-
) {
21-
private fun matchesHost(url: Url) = url.host.matches(host)
22-
private fun matchesPath(url: Url) = paths.any { url.path.matches(it) }
23-
fun matches(url: Url) = matchesHost(url) && matchesPath(url)
24-
}
25-
26-
data class Url(val host: String, val path: String)
27-
28-
fun Uri.toUrl() = Url(host.orEmpty(), path.orEmpty())
2914
}
Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
11
package org.wordpress.android.ui.domains
22

3-
import android.net.Uri
3+
import org.wordpress.android.ui.utils.AbstractAllowedUrlsWebViewNavigationDelegate
44

5-
object DomainRegistrationCheckoutWebViewNavigationDelegate {
5+
object DomainRegistrationCheckoutWebViewNavigationDelegate : AbstractAllowedUrlsWebViewNavigationDelegate() {
66
private val optionalLanguagePath = "(?:/(?:\\w{2}-)?\\w{2})?".toRegex()
7-
private val allowedUrls = listOf(
7+
8+
override val allowedUrls = listOf(
89
UrlMatcher(
910
".*wordpress.com".toRegex(),
1011
listOf(
@@ -17,19 +18,4 @@ object DomainRegistrationCheckoutWebViewNavigationDelegate {
1718
)
1819
)
1920
)
20-
21-
fun canNavigateTo(url: Url) = allowedUrls.any { it.matches(url) }
22-
23-
data class UrlMatcher(
24-
private val host: Regex,
25-
private val paths: List<Regex>
26-
) {
27-
private fun matchesHost(url: Url) = url.host.matches(host)
28-
private fun matchesPath(url: Url) = paths.any { url.path.matches(it) }
29-
fun matches(url: Url) = matchesHost(url) && matchesPath(url)
30-
}
31-
32-
data class Url(val host: String, val path: String)
33-
34-
fun Uri.toUrl() = Url(host.orEmpty(), path.orEmpty())
3521
}

WordPress/src/main/java/org/wordpress/android/ui/domains/management/DomainManagementActivity.kt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import dagger.hilt.android.AndroidEntryPoint
1010
import kotlinx.coroutines.flow.launchIn
1111
import kotlinx.coroutines.flow.onEach
1212
import org.wordpress.android.ui.ActivityLauncher
13+
import org.wordpress.android.ui.domains.management.details.DomainManagementDetailsActivity
1314
import org.wordpress.android.util.extensions.setContent
1415

1516
@AndroidEntryPoint

WordPress/src/main/java/org/wordpress/android/ui/domains/management/DomainManagementDetailsActivity.kt renamed to WordPress/src/main/java/org/wordpress/android/ui/domains/management/details/DomainManagementDetailsActivity.kt

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
1-
package org.wordpress.android.ui.domains.management
1+
package org.wordpress.android.ui.domains.management.details
22

33
import android.content.Context
44
import android.content.Intent
55
import android.os.Bundle
66
import android.view.Menu
7+
import org.wordpress.android.ui.ActivityLauncher
78
import org.wordpress.android.ui.WPWebViewActivity
89

9-
class DomainManagementDetailsActivity : WPWebViewActivity() {
10+
class DomainManagementDetailsActivity : WPWebViewActivity(),
11+
DomainManagementDetailsWebViewClient.DomainManagementWebViewClientListener {
1012
override fun onCreate(savedInstanceState: Bundle?) {
1113
super.onCreate(savedInstanceState)
1214
toggleNavbarVisibility(false)
@@ -17,6 +19,12 @@ class DomainManagementDetailsActivity : WPWebViewActivity() {
1719
return true
1820
}
1921

22+
override fun createWebViewClient(allowedURL: List<String>?) = DomainManagementDetailsWebViewClient(this)
23+
24+
override fun onRedirectToExternalBrowser(url: String) {
25+
ActivityLauncher.openUrlExternal(this, url)
26+
}
27+
2028
companion object {
2129
fun createIntent(context: Context, domainDetailUrl: String): Intent =
2230
Intent(context, DomainManagementDetailsActivity::class.java).apply {
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.wordpress.android.ui.domains.management.details
2+
3+
import android.webkit.WebResourceRequest
4+
import android.webkit.WebView
5+
import org.wordpress.android.ui.domains.management.details.DomainManagementDetailsWebViewNavigationDelegate.toUrl
6+
import org.wordpress.android.util.ErrorManagedWebViewClient
7+
8+
class DomainManagementDetailsWebViewClient(
9+
private val listener: DomainManagementWebViewClientListener
10+
) : ErrorManagedWebViewClient(listener) {
11+
private val navigationDelegate = DomainManagementDetailsWebViewNavigationDelegate
12+
13+
interface DomainManagementWebViewClientListener : ErrorManagedWebViewClientListener {
14+
fun onRedirectToExternalBrowser(url: String)
15+
}
16+
17+
override fun shouldOverrideUrlLoading(view: WebView, request: WebResourceRequest) : Boolean {
18+
if (navigationDelegate.canNavigateTo(request.url.toUrl())) return false
19+
listener.onRedirectToExternalBrowser(request.url.toString())
20+
return true
21+
}
22+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
package org.wordpress.android.ui.domains.management.details
2+
3+
import org.wordpress.android.ui.utils.AbstractAllowedUrlsWebViewNavigationDelegate
4+
5+
object DomainManagementDetailsWebViewNavigationDelegate: AbstractAllowedUrlsWebViewNavigationDelegate() {
6+
override val allowedUrls = listOf(
7+
UrlMatcher(
8+
"wordpress.com".toRegex(),
9+
listOf("/domains.*".toRegex())
10+
)
11+
)
12+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.wordpress.android.ui.utils
2+
3+
import android.net.Uri
4+
5+
abstract class AbstractAllowedUrlsWebViewNavigationDelegate {
6+
abstract val allowedUrls: List<UrlMatcher>
7+
8+
fun canNavigateTo(url: Url) = allowedUrls.any { it.matches(url) }
9+
10+
data class UrlMatcher(
11+
private val host: Regex,
12+
private val paths: List<Regex>
13+
) {
14+
private fun matchesHost(url: Url) = url.host.matches(host)
15+
private fun matchesPath(url: Url) = paths.any { url.path.matches(it) }
16+
fun matches(url: Url) = matchesHost(url) && matchesPath(url)
17+
}
18+
19+
data class Url(val host: String, val path: String)
20+
21+
fun Uri.toUrl() = Url(host.orEmpty(), path.orEmpty())
22+
}

WordPress/src/test/java/org/wordpress/android/ui/blaze/blazecampaigns/CampaignDetailWebViewNavigationDelegateTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import org.assertj.core.api.Assertions.assertThat
55
import org.junit.Test
66
import org.wordpress.android.BaseUnitTest
77
import org.wordpress.android.ui.blaze.blazecampaigns.campaigndetail.CampaignDetailWebViewNavigationDelegate
8-
import org.wordpress.android.ui.blaze.blazecampaigns.campaigndetail.CampaignDetailWebViewNavigationDelegate.Url
8+
import org.wordpress.android.ui.utils.AbstractAllowedUrlsWebViewNavigationDelegate.Url
99

1010
@ExperimentalCoroutinesApi
1111
class CampaignDetailWebViewNavigationDelegateTest : BaseUnitTest() {

WordPress/src/test/java/org/wordpress/android/ui/domains/DomainRegistrationCheckoutWebViewNavigationDelegateTest.kt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import kotlinx.coroutines.ExperimentalCoroutinesApi
44
import org.assertj.core.api.Assertions.assertThat
55
import org.junit.Test
66
import org.wordpress.android.BaseUnitTest
7-
import org.wordpress.android.ui.domains.DomainRegistrationCheckoutWebViewNavigationDelegate.Url
7+
import org.wordpress.android.ui.utils.AbstractAllowedUrlsWebViewNavigationDelegate.Url
88

99
@ExperimentalCoroutinesApi
1010
class DomainRegistrationCheckoutWebViewNavigationDelegateTest : BaseUnitTest() {

0 commit comments

Comments
 (0)