Skip to content

Commit 5e191a1

Browse files
@W-20161958: [MSDK 13.1][Android] Cannot login GUS using Welcome endpoint (Final Code Review Of LoginViewModel, Restore CodeCov P.O.C. Of isSwitchFromSalesforceWelcomeDiscoveryToDefaultLoginˆ)
1 parent 8b20336 commit 5e191a1

File tree

4 files changed

+78
-23
lines changed

4 files changed

+78
-23
lines changed

libs/SalesforceSDK/src/com/salesforce/androidsdk/ui/LoginActivity.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1663,13 +1663,13 @@ open class LoginActivity : FragmentActivity() {
16631663
// Guard against observing a pending login server already provided by the intent data, such as a Salesforce Welcome Discovery mobile URL.
16641664
val pendingServerUri = value.toUri()
16651665
if (activity.intent.data?.host == pendingServerUri.host || activity.intent.getStringExtra(EXTRA_KEY_LOGIN_HOST) == pendingServerUri.host) {
1666-
activity.viewModel.previousPendingLoginServer = value
1666+
activity.viewModel.previousPendingServer = value
16671667
return
16681668
}
16691669

16701670
// Use the URL to switch between default or Salesforce Welcome Discovery log in, if applicable.
16711671
if (activity.switchDefaultOrSalesforceWelcomeDiscoveryLogin(pendingServerUri)) {
1672-
activity.viewModel.previousPendingLoginServer = value
1672+
activity.viewModel.previousPendingServer = value
16731673
return
16741674
}
16751675

libs/SalesforceSDK/src/com/salesforce/androidsdk/ui/LoginViewModel.kt

Lines changed: 65 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -121,10 +121,10 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
121121
/** The login server that has been selected by the login server manager, has an authentication configuration and is ready for use */
122122
val selectedServer = MediatorLiveData<String>()
123123

124-
/** The selected login server's OAuth authorization URL */
124+
/** The selected login server's OAuth authorization URL for use in the web view when browser-based authentication is inactive */
125125
val loginUrl = MediatorLiveData<String>()
126126

127-
/** The URL to be displayed in the activity's browser custom tab activity. This is used for browser-based authentication requires loading the OAuth authorization URL outside the app's web view */
127+
/** The selected login server's OAuth authorization URL for use in the external browser custom tab when browser-based authentication is active. This provides the login flow with the requirements for advanced authentication, such as client certificates */
128128
val browserCustomTabUrl = MediatorLiveData<String>()
129129

130130
var showServerPicker = mutableStateOf(false)
@@ -136,12 +136,12 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
136136
@VisibleForTesting
137137
internal var authenticationConfigurationFetchJob: Job? = null
138138

139-
/** The login server that is pending authentication configuration before becoming the selected login server */
139+
/** The login server that has been selected by the login server manager and is pending authentication configuration before becoming the selected login server */
140140
internal val pendingServer = MediatorLiveData<String>()
141141

142142
/** The previously observed pending login server for use in switching between default and Salesforce Welcome Discovery log in */
143143
@VisibleForTesting
144-
internal var previousPendingLoginServer: String? = null
144+
internal var previousPendingServer: String? = null
145145

146146
internal val authFinished = mutableStateOf(false)
147147
internal val isIDPLoginFlowEnabled = derivedStateOf {
@@ -257,7 +257,7 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
257257
// Update loginUrl when selectedServer updates so webview automatically reloads
258258
loginUrl.addSource(selectedServer, LoginUrlSource())
259259

260-
// Update the browser custom tab URL to match the OAuth authorization URL when browser-based authentication is active.
260+
// When selecting a login server, update the browser custom tab URL to match the OAuth authorization URL when browser-based authentication is active.
261261
browserCustomTabUrl.addSource(selectedServer, BrowserCustomTabUrlSource())
262262
}
263263

@@ -314,11 +314,11 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
314314

315315
/**
316316
* Applies a new pending login server. The decision to authenticate in a
317-
* web browser-custom tab will be made, which may require fetching the
317+
* web browser custom tab will be made, which may require fetching the
318318
* authentication configuration. The selected server and login URL (OAuth
319319
* authorization URL) will set to continue the flow.
320320
* @param sdkManager The Salesforce SDK manager. This parameter is intended
321-
* for testing purposes only. Defaults to the shared instance.
321+
* for testing purposes only. Defaults to the shared instance
322322
* @param pendingLoginServer The new pending login server value
323323
*/
324324
internal fun applyPendingServer(
@@ -328,7 +328,7 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
328328
val pendingLoginServerUnwrapped: String = pendingLoginServer ?: return
329329

330330
// Recall this pending login server for reference by future updates.
331-
previousPendingLoginServer = pendingLoginServerUnwrapped
331+
previousPendingServer = pendingLoginServerUnwrapped
332332

333333
// When authorization via a single-server, custom tab activity is requested skip fetching the authorization configuration and immediately set the selected login server to generate the OAuth authorization URL.
334334
if (singleServerCustomTabActivity) {
@@ -415,6 +415,14 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
415415
}
416416
}
417417

418+
/**
419+
* Generates an OAuth authorization URL for the provided server.
420+
* @param server The login server URL
421+
* @param sdkManager The Salesforce SDK manager. This parameter is intended
422+
* for testing purposes only. Defaults to the shared instance
423+
* @param scope The Coroutine scope. This parameter is intended for testing
424+
* purposes only. Defaults to the IO scope
425+
*/
418426
@VisibleForTesting
419427
internal suspend fun getAuthorizationUrl(
420428
server: String,
@@ -505,10 +513,31 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
505513
* @return Boolean true if the provided pending login server URL is a
506514
* switch from Salesforce Welcome Discovery back to the default log in,
507515
* false otherwise.
508-
* */
516+
*/
509517
internal fun isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(
510518
pendingLoginServerUri: Uri
511-
) = (previousPendingLoginServer?.toUri()?.let { isSalesforceWelcomeDiscoveryUrlPath(it) } ?: false).and(!isSalesforceWelcomeDiscoveryUrlPath(pendingLoginServerUri))
519+
): Boolean {
520+
// TODO: Re-compress this logic after CodeCov P.O.C. ECJ20251210
521+
val pPLS = previousPendingServer
522+
if (pPLS == null) {
523+
Log.i("WSC", "0")
524+
return false
525+
}
526+
val a = isSalesforceWelcomeDiscoveryUrlPath(pPLS.toUri())
527+
val b = !isSalesforceWelcomeDiscoveryUrlPath(pendingLoginServerUri)
528+
529+
if ((!a).and(!b)) {
530+
Log.i("WSC", "1")
531+
} else if (a.and(!b)) {
532+
Log.i("WSC", "2")
533+
} else if (!a) {
534+
Log.i("WSC", "3")
535+
} else {
536+
Log.i("WSC", "4")
537+
}
538+
539+
return a && b
540+
}
512541

513542
// endregion
514543

@@ -539,6 +568,16 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
539568
val onClick: () -> Unit
540569
)
541570

571+
/**
572+
* An observer used to set the web view's OAuth authorization URL from the
573+
* selected login server.
574+
* @param sdkManager The Salesforce SDK manager. This parameter is intended
575+
* for testing purposes only. Defaults to the shared instance
576+
* @param viewModel The login activity view model. This parameter is
577+
* intended for testing purposes only. Defaults to this inner class receiver
578+
* @param scope The Coroutine scope. This parameter is intended for testing
579+
* purposes only. Defaults to the IO scope
580+
*/
542581
@VisibleForTesting
543582
inner class LoginUrlSource(
544583
private val sdkManager: SalesforceSDKManager = SalesforceSDKManager.getInstance(),
@@ -557,6 +596,12 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
557596
}
558597
}
559598

599+
/**
600+
* An observer used to set the pending login server from the login server
601+
* manager's selected login server.
602+
* @param viewModel The login activity view model. This parameter is
603+
* intended for testing purposes only. Defaults to this inner class receiver
604+
*/
560605
@VisibleForTesting
561606
inner class PendingServerSource(
562607
private val viewModel: LoginViewModel = this@LoginViewModel,
@@ -571,6 +616,16 @@ open class LoginViewModel(val bootConfig: BootConfig) : ViewModel() {
571616
}
572617
}
573618

619+
/**
620+
* An observer used to set the external browser custom tab's OAuth
621+
* authorization URL from the selected login server.
622+
* @param sdkManager The Salesforce SDK manager. This parameter is intended
623+
* for testing purposes only. Defaults to the shared instance
624+
* @param viewModel The login activity view model. This parameter is
625+
* intended for testing purposes only. Defaults to this inner class receiver
626+
* @param scope The Coroutine scope. This parameter is intended for testing
627+
* purposes only. Defaults to the IO scope
628+
*/
574629
@VisibleForTesting
575630
inner class BrowserCustomTabUrlSource(
576631
private val sdkManager: SalesforceSDKManager = SalesforceSDKManager.getInstance(),

libs/test/SalesforceSDKTest/src/com/salesforce/androidsdk/auth/LoginViewModelTest.kt

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -669,7 +669,7 @@ class LoginViewModelTest {
669669
val sdkManager = mockk<SalesforceSDKManager>(relaxed = true)
670670

671671
viewModel.applyPendingServer(sdkManager = sdkManager, pendingLoginServer = null)
672-
assert(viewModel.previousPendingLoginServer == null)
672+
assert(viewModel.previousPendingServer == null)
673673
verify(exactly = 0) { sdkManager.fetchAuthenticationConfiguration(any(), any()) }
674674
}
675675

@@ -685,7 +685,7 @@ class LoginViewModelTest {
685685

686686
viewModel.applyPendingServer(sdkManager = sdkManager, pendingLoginServer = exampleUrl)
687687

688-
assert(viewModel.previousPendingLoginServer == exampleUrl)
688+
assert(viewModel.previousPendingServer == exampleUrl)
689689
assert(viewModel.selectedServer.value == exampleUrl)
690690
verify(exactly = 0) { sdkManager.fetchAuthenticationConfiguration(any(), any()) }
691691
}
@@ -705,7 +705,7 @@ class LoginViewModelTest {
705705
viewModel.authenticationConfigurationFetchJob = job
706706
viewModel.applyPendingServer(sdkManager = sdkManager, pendingLoginServer = exampleUrl)
707707

708-
assert(viewModel.previousPendingLoginServer == exampleUrl)
708+
assert(viewModel.previousPendingServer == exampleUrl)
709709
assert(viewModel.selectedServer.value == exampleUrl)
710710
verify(exactly = 1) { sdkManager.fetchAuthenticationConfiguration(any(), any()) }
711711
verify(exactly = 1) { job.cancel() }
@@ -716,7 +716,7 @@ class LoginViewModelTest {
716716

717717
val exampleUrl = "https://www.example.com" // IETF-Reserved Test Domain
718718

719-
viewModel.previousPendingLoginServer = null
719+
viewModel.previousPendingServer = null
720720
assertFalse(viewModel.isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(exampleUrl.toUri()))
721721
}
722722

@@ -725,7 +725,7 @@ class LoginViewModelTest {
725725

726726
val exampleUrl = "https://www.example.com" // IETF-Reserved Test Domain
727727

728-
viewModel.previousPendingLoginServer = "_invalid_uri_"
728+
viewModel.previousPendingServer = "_invalid_uri_"
729729
assertFalse(viewModel.isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(exampleUrl.toUri()))
730730
}
731731

@@ -734,7 +734,7 @@ class LoginViewModelTest {
734734

735735
val exampleUrl = "https://www.example.com" // IETF-Reserved Test Domain
736736

737-
viewModel.previousPendingLoginServer = WELCOME_LOGIN_URL
737+
viewModel.previousPendingServer = WELCOME_LOGIN_URL
738738
assertTrue(viewModel.isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(exampleUrl.toUri()))
739739
}
740740

@@ -743,7 +743,7 @@ class LoginViewModelTest {
743743

744744
val exampleUrl = "https://www.example.com" // IETF-Reserved Test Domain
745745

746-
viewModel.previousPendingLoginServer = exampleUrl
746+
viewModel.previousPendingServer = exampleUrl
747747
assertFalse(viewModel.isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(WELCOME_LOGIN_URL.toUri()))
748748
}
749749

@@ -752,14 +752,14 @@ class LoginViewModelTest {
752752

753753
val exampleUrl = "https://www.example.com" // IETF-Reserved Test Domain
754754

755-
viewModel.previousPendingLoginServer = "https://other.example.com" // IETF-Reserved Test Domain
755+
viewModel.previousPendingServer = "https://other.example.com" // IETF-Reserved Test Domain
756756
assertFalse(viewModel.isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(exampleUrl.toUri()))
757757
}
758758

759759
@Test
760760
fun loginViewModel_isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin_returnsFalseSwitchBetweenWelcomeLoginUrls() {
761761

762-
viewModel.previousPendingLoginServer = WELCOME_LOGIN_URL
762+
viewModel.previousPendingServer = WELCOME_LOGIN_URL
763763
assertFalse(viewModel.isSwitchFromSalesforceWelcomeDiscoveryToDefaultLogin(WELCOME_LOGIN_URL.toUri()))
764764
}
765765

libs/test/SalesforceSDKTest/src/com/salesforce/androidsdk/ui/LoginActivityScenarioTest.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -385,10 +385,10 @@ class LoginActivityScenarioTest {
385385

386386
activityScenario.onActivity { activity ->
387387

388-
activity.viewModel.previousPendingLoginServer = PRODUCTION_LOGIN_URL
388+
activity.viewModel.previousPendingServer = PRODUCTION_LOGIN_URL
389389
assertTrue(activity.switchDefaultOrSalesforceWelcomeDiscoveryLogin(WELCOME_LOGIN_URL.toUri()))
390390

391-
activity.viewModel.previousPendingLoginServer = WELCOME_LOGIN_URL
391+
activity.viewModel.previousPendingServer = WELCOME_LOGIN_URL
392392
assertTrue(activity.switchDefaultOrSalesforceWelcomeDiscoveryLogin(PRODUCTION_LOGIN_URL.toUri()))
393393
}
394394
}

0 commit comments

Comments
 (0)