Skip to content

Commit 702159b

Browse files
authored
Merge pull request #2447 from brandonpage/enhanced-domain
Optionally support use custom domain button in webview.
2 parents 09fdd34 + 8be650d commit 702159b

File tree

2 files changed

+73
-4
lines changed

2 files changed

+73
-4
lines changed

libs/SalesforceSDK/src/com/salesforce/androidsdk/app/SalesforceSDKManager.java

+27
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@
4848
import android.webkit.CookieManager;
4949

5050
import androidx.annotation.NonNull;
51+
import androidx.annotation.Nullable;
5152
import androidx.lifecycle.Lifecycle;
5253
import androidx.lifecycle.LifecycleObserver;
5354
import androidx.lifecycle.OnLifecycleEvent;
@@ -100,6 +101,7 @@
100101
import java.util.SortedSet;
101102
import java.util.UUID;
102103
import java.util.concurrent.ConcurrentSkipListSet;
104+
import java.util.regex.Pattern;
103105

104106
/**
105107
* This class serves as an interface to the various
@@ -181,6 +183,9 @@ public class SalesforceSDKManager implements LifecycleObserver {
181183
private boolean useWebServerAuthentication = true; // web server flow ON by default - but app can opt out by calling setUseWebServerAuthentication(false)
182184

183185
private boolean useHybridAuthentication = true; // hybrid authentication flows ON by default - but app can opt out by calling setUseHybridAuthentication(false)
186+
187+
private Pattern customDomainInferencePattern;
188+
184189
private Theme theme = Theme.SYSTEM_DEFAULT;
185190
private String appName;
186191

@@ -672,6 +677,28 @@ public synchronized void setUseHybridAuthentication(boolean useHybridAuthenticat
672677
this.useHybridAuthentication = useHybridAuthentication;
673678
}
674679

680+
/**
681+
* Returns the pattern used to detect the use of "Use Custom Domain" input from login web view.
682+
*
683+
* @return pattern if set or null
684+
*/
685+
public synchronized Pattern getCustomDomainInferencePattern() {
686+
return customDomainInferencePattern;
687+
}
688+
689+
/**
690+
* Detect use of "Use Custom Domain" input from login web view using the given regex.
691+
* Example for a specific org:
692+
* "^https:\\/\\/mobilesdk\\.my\\.salesforce\\.com\\/\\?startURL=%2Fsetup%2Fsecur%2FRemoteAccessAuthorizationPage\\.apexp"
693+
* For any my domain:
694+
* "^https:\\/\\/[a-zA-Z0-9]+\\.my\\.salesforce\\.com/\\?startURL=%2Fsetup%2Fsecur%2FRemoteAccessAuthorizationPage\\.apexp"
695+
*
696+
* @param pattern regex to use when detecting use of custom domain on login
697+
*/
698+
public synchronized void setCustomDomainInferencePattern(@Nullable Pattern pattern) {
699+
this.customDomainInferencePattern = pattern;
700+
}
701+
675702
/**
676703
* Returns whether the IDP login flow is enabled.
677704
*

libs/SalesforceSDK/src/com/salesforce/androidsdk/ui/OAuthWebviewHelper.java

+46-4
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@
8080
import com.salesforce.androidsdk.security.BiometricAuthenticationManager;
8181
import com.salesforce.androidsdk.security.SalesforceKeyGenerator;
8282
import com.salesforce.androidsdk.security.ScreenLockManager;
83+
import com.salesforce.androidsdk.util.AuthConfigTask;
8384
import com.salesforce.androidsdk.util.EventsObservable;
8485
import com.salesforce.androidsdk.util.EventsObservable.EventType;
8586
import com.salesforce.androidsdk.util.MapUtil;
@@ -99,6 +100,7 @@
99100
import java.util.Map;
100101
import java.util.concurrent.ExecutorService;
101102
import java.util.concurrent.Executors;
103+
import java.util.regex.Pattern;
102104

103105
import okhttp3.Request;
104106
import okhttp3.Response;
@@ -473,7 +475,7 @@ protected String getLoginUrl() {
473475
* WebViewClient which intercepts the redirect to the oauth callback url.
474476
* That redirect marks the end of the user facing portion of the authentication flow.
475477
*/
476-
protected class AuthWebViewClient extends WebViewClient {
478+
protected class AuthWebViewClient extends WebViewClient implements AuthConfigTask.AuthConfigCallbackInterface {
477479

478480
@Override
479481
public void onPageFinished(WebView view, String url) {
@@ -500,6 +502,7 @@ public void onPageFinished(WebView view, String url) {
500502
}
501503
}
502504
}
505+
503506
EventsObservable.get().notifyEvent(EventType.AuthWebViewPageFinished, url);
504507
super.onPageFinished(view, url);
505508
}
@@ -522,8 +525,37 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request
522525
return true;
523526
}
524527

525-
boolean isDone = uri.toString().replace("///", "/").toLowerCase(Locale.US).startsWith(loginOptions.getOauthCallbackUrl().replace("///", "/").toLowerCase(Locale.US));
526-
if (isDone) {
528+
// Check if user entered a custom domain
529+
String host = uri.getHost();
530+
Pattern customDomainPattern = SalesforceSDKManager.getInstance().getCustomDomainInferencePattern();
531+
if (host != null && !getLoginUrl().contains(host) && customDomainPattern != null
532+
&& customDomainPattern.matcher(uri.toString()).find()) {
533+
try {
534+
String baseUrl = "https://" + uri.getHost();
535+
LoginServerManager serverManager = SalesforceSDKManager.getInstance().getLoginServerManager();
536+
LoginServerManager.LoginServer loginServer = serverManager.getLoginServerFromURL(baseUrl);
537+
538+
// Check if url is already in server list
539+
if (loginServer == null) {
540+
// Add also sets as selected
541+
serverManager.addCustomLoginServer("Custom Domain", baseUrl);
542+
} else {
543+
serverManager.setSelectedLoginServer(loginServer);
544+
}
545+
546+
// Set title to new login url
547+
loginOptions.setLoginUrl(baseUrl);
548+
// Checks the config for the selected login server
549+
(new AuthConfigTask(this)).execute();
550+
} catch (Exception e) {
551+
SalesforceSDKLogger.e(TAG, "Unable to retrieve auth config.");
552+
}
553+
}
554+
555+
String formattedUrl = uri.toString().replace("///", "/").toLowerCase(Locale.US);
556+
String callbackUrl = loginOptions.getOauthCallbackUrl().replace("///", "/").toLowerCase(Locale.US);
557+
boolean authFlowFinished = formattedUrl.startsWith(callbackUrl);
558+
if (authFlowFinished) {
527559
Map<String, String> params = UriFragmentParser.parse(uri);
528560
String error = params.get("error");
529561
// Did we fail?
@@ -542,7 +574,8 @@ public boolean shouldOverrideUrlLoading(WebView view, WebResourceRequest request
542574
}
543575
}
544576
}
545-
return isDone;
577+
578+
return authFlowFinished;
546579
}
547580

548581
@Override
@@ -570,6 +603,15 @@ public void onReceivedClientCertRequest(WebView view, ClientCertRequest request)
570603
SalesforceSDKLogger.d(TAG, "Received client certificate request from server");
571604
request.proceed(key, certChain);
572605
}
606+
607+
@Override
608+
public void onAuthConfigFetched() {
609+
SalesforceSDKManager manager = SalesforceSDKManager.getInstance();
610+
if (manager.isBrowserLoginEnabled()) {
611+
// This load will trigger advanced auth and do all necessary setup.
612+
doLoadPage();
613+
}
614+
}
573615
}
574616

575617
/**

0 commit comments

Comments
 (0)