Skip to content

Commit 1dfd215

Browse files
committed
fix: update OIDC handling to use custom tabs
1 parent 4e10c44 commit 1dfd215

File tree

3 files changed

+41
-13
lines changed

3 files changed

+41
-13
lines changed

build.gradle

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ android {
475475
dependencies {
476476
implementation fileTree(dir: 'libs', include: ['*.jar'])
477477
implementation platform('org.jetbrains.kotlin:kotlin-bom:1.9.24')
478+
implementation 'androidx.browser:browser:1.8.0'
478479
implementation 'androidx.core:core:1.13.1'
479480
implementation 'androidx.activity:activity:1.9.0'
480481
implementation 'androidx.fragment:fragment:1.7.1'

src/main/java/org/medicmobile/webapp/mobile/UrlHandler.java

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,8 @@
1717
import android.webkit.WebView;
1818
import android.webkit.WebViewClient;
1919

20+
import androidx.browser.customtabs.CustomTabsIntent;
21+
2022
public class UrlHandler extends WebViewClient {
2123
EmbeddedBrowserActivity parentActivity;
2224
SettingsStore settings;
@@ -31,10 +33,14 @@ public UrlHandler(EmbeddedBrowserActivity parentActivity, SettingsStore settings
3133
@Override
3234
public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request) {
3335
Uri uri = request.getUrl();
34-
if (isUrlRelated(this.settings.getAppUrl(), uri) || isOidcProviderUrl(uri)) {
36+
if (isUrlRelated(this.settings.getAppUrl(), uri)) {
3537
// Load all related URLs in the WebView
3638
return false;
3739
}
40+
if (isOidcProviderUrl(uri)) {
41+
launchCustomTab(uri);
42+
return true;
43+
}
3844

3945
// Let Android decide what to do with unrelated URLs
4046
// unrelated URLs include `tel:` and `sms:` uri schemes
@@ -43,6 +49,11 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request
4349
return true;
4450
}
4551

52+
private void launchCustomTab(Uri uri) {
53+
CustomTabsIntent customTabsIntent = new CustomTabsIntent.Builder().build();
54+
customTabsIntent.launchUrl(this.parentActivity, uri);
55+
}
56+
4657
/**
4758
* Support OIDC login flow by allowing any URL that contains the current app_url as the redirect_uri.
4859
*/

src/test/java/org/medicmobile/webapp/mobile/UrlHandlerTest.java

Lines changed: 28 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package org.medicmobile.webapp.mobile;
22

3+
import static org.junit.Assert.assertEquals;
34
import static org.junit.Assert.assertFalse;
45
import static org.junit.Assert.assertTrue;
56
import static org.mockito.ArgumentMatchers.any;
67
import static org.mockito.Mockito.doNothing;
78
import static org.mockito.Mockito.mock;
9+
import static org.mockito.Mockito.mockConstruction;
810
import static org.mockito.Mockito.times;
911
import static org.mockito.Mockito.verify;
1012
import static org.mockito.Mockito.when;
@@ -14,14 +16,18 @@
1416
import android.webkit.WebResourceRequest;
1517
import android.webkit.WebView;
1618

19+
import androidx.browser.customtabs.CustomTabsIntent;
20+
1721
import org.junit.Before;
1822
import org.junit.Test;
1923
import org.junit.runner.RunWith;
24+
import org.mockito.MockedConstruction;
2025
import org.robolectric.RobolectricTestRunner;
2126

2227
@RunWith(RobolectricTestRunner.class)
2328
public class UrlHandlerTest {
2429
private static final String APP_URL = "https://project-abc.medic.org";
30+
private EmbeddedBrowserActivity parentActivity;
2531
private SettingsStore settingsStore;
2632
private WebView webView;
2733
private WebResourceRequest webResourceRequest;
@@ -30,6 +36,7 @@ public class UrlHandlerTest {
3036

3137
@Before
3238
public void setup() {
39+
parentActivity = mock(EmbeddedBrowserActivity.class);
3340
settingsStore = mock(SettingsStore.class);
3441
when(settingsStore.getAppUrl()).thenReturn(APP_URL);
3542
webView = mock(WebView.class);
@@ -38,7 +45,7 @@ public void setup() {
3845
doNothing().when(context).startActivity(any());
3946
webResourceRequest = mock(WebResourceRequest.class);
4047

41-
handler = new UrlHandler(null, settingsStore);
48+
handler = new UrlHandler(parentActivity, settingsStore);
4249
}
4350

4451
@Test
@@ -69,17 +76,26 @@ public void shouldOverrideUrlLoading_withExternalUrl() {
6976

7077
@Test
7178
public void shouldOverrideUrlLoading_withExternalOidcProviderUrl() {
72-
when(webResourceRequest.getUrl()).thenReturn(
73-
Uri.parse("some-external-url.com?redirect_uri=" + Uri.encode(APP_URL + "/medic/login/oidc"))
74-
);
75-
76-
boolean result = handler.shouldOverrideUrlLoading(webView, webResourceRequest);
77-
78-
assertFalse(result);
79-
verify(settingsStore, times(2)).getAppUrl();
80-
verify(webResourceRequest).getUrl();
81-
verify(webView, times(0)).getContext();
82-
verify(context, times(0)).startActivity(any());
79+
CustomTabsIntent intent = mock(CustomTabsIntent.class);
80+
Uri expectedUri = Uri.parse("some-external-url.com?redirect_uri=" + Uri.encode(APP_URL + "/medic/login/oidc"));
81+
try (MockedConstruction<CustomTabsIntent.Builder> mocked = mockConstruction(
82+
CustomTabsIntent.Builder.class,
83+
(mock, context) -> when(mock.build()).thenReturn(intent)
84+
)) {
85+
doNothing().when(intent).launchUrl(any(), any());
86+
when(webResourceRequest.getUrl()).thenReturn(expectedUri);
87+
88+
boolean result = handler.shouldOverrideUrlLoading(webView, webResourceRequest);
89+
90+
assertTrue(result);
91+
verify(settingsStore, times(2)).getAppUrl();
92+
verify(webResourceRequest).getUrl();
93+
verify(webView, times(0)).getContext();
94+
verify(context, times(0)).startActivity(any());
95+
assertEquals(1, mocked.constructed().size());
96+
verify(mocked.constructed().get(0), times(1)).build();
97+
verify(intent, times(1)).launchUrl(parentActivity, expectedUri);
98+
}
8399
}
84100

85101
@Test

0 commit comments

Comments
 (0)