Skip to content

Commit 58548e7

Browse files
committed
fix: removed session usage from WebAuthenticationProvider class
1 parent 7a03c23 commit 58548e7

File tree

5 files changed

+130
-118
lines changed

5 files changed

+130
-118
lines changed

app/src/main/java/com/sap/cdc/bitsnbytes/feature/auth/AuthenticationFlowDelegate.kt

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -166,6 +166,11 @@ class AuthenticationFlowDelegate(context: Context) {
166166
aliases = listOf("google", "googleplus"),
167167
provider = GoogleAuthenticationProvider()
168168
)
169+
170+
registerAuthenticationProvider("linkedIn", WebAuthenticationProvider(
171+
"linked",
172+
siteConfig = authenticationService.siteConfig,
173+
))
169174
}
170175

171176
init {
@@ -636,7 +641,6 @@ class AuthenticationFlowDelegate(context: Context) {
636641
return WebAuthenticationProvider(
637642
name,
638643
siteConfig,
639-
authenticationService.session().getSession()
640644
)
641645
}
642646
return authenticationProviderMap[name]

app/src/main/java/com/sap/cdc/bitsnbytes/ui/activity/MainActivity.kt

Lines changed: 7 additions & 83 deletions
Original file line numberDiff line numberDiff line change
@@ -13,31 +13,28 @@ import androidx.fragment.app.FragmentActivity
1313
import androidx.lifecycle.Lifecycle
1414
import androidx.lifecycle.lifecycleScope
1515
import androidx.lifecycle.repeatOnLifecycle
16-
import com.sap.cdc.android.sdk.CDCDebuggable
17-
import com.sap.cdc.android.sdk.events.CDCEventBusProvider
18-
import com.sap.cdc.android.sdk.events.SessionEvent
19-
import com.sap.cdc.android.sdk.events.subscribeToSessionEvents
2016
import com.sap.cdc.bitsnbytes.BuildConfig
2117
import com.sap.cdc.bitsnbytes.apptheme.AppTheme
2218
import com.sap.cdc.bitsnbytes.navigation.AppStateManager
2319
import com.sap.cdc.bitsnbytes.navigation.NavigationCoordinator
24-
import com.sap.cdc.bitsnbytes.navigation.ProfileScreenRoute
2520
import com.sap.cdc.bitsnbytes.ui.view.screens.HomeScaffoldView
2621
import kotlinx.coroutines.launch
2722

2823
/**
29-
* Main Activity with proper lifecycle management and memory leak prevention.
24+
* Main Activity with proper lifecycle management and MVVM architecture.
3025
*
31-
* - Proper event bus lifecycle management to prevent memory leaks
26+
* Responsibilities:
3227
* - Conditional WebView debugging (debug builds only)
3328
* - Lifecycle-aware splash screen handling
34-
* - Proper cleanup in onDestroy
35-
* - Lifecycle-aware navigation calls
36-
* - Integrated with MainActivityViewModel for proper MVVM architecture
29+
* - UI composition with Jetpack Compose
30+
* - Navigation coordinator setup
31+
*
32+
* Session event handling is delegated to MainActivityViewModel for proper MVVM architecture.
3733
*/
3834
class MainActivity : FragmentActivity() {
3935

4036
// ViewModel integration for proper MVVM architecture
37+
// ViewModel handles all session events and business logic
4138
private val viewModel: MainActivityViewModel by viewModels()
4239

4340
// AppStateManager for navigation
@@ -58,9 +55,6 @@ class MainActivity : FragmentActivity() {
5855
// Proper splash screen lifecycle management
5956
configureSplashScreen(splashScreen)
6057

61-
// ViewModel is now available for authentication state access
62-
// viewModel.initializeApp() - method removed to avoid compilation errors
63-
6458
// Connect NavigationCoordinator with AppStateManager
6559
NavigationCoordinator.INSTANCE.setAppStateManager(appStateManager)
6660

@@ -75,9 +69,6 @@ class MainActivity : FragmentActivity() {
7569
}
7670
}
7771
}
78-
79-
// Setup session event handling with proper lifecycle awareness
80-
setupSessionEventHandling()
8172
}
8273

8374
/**
@@ -95,71 +86,4 @@ class MainActivity : FragmentActivity() {
9586
}
9687
}
9788
}
98-
99-
/**
100-
* Setup session event handling with proper lifecycle management
101-
*/
102-
private fun setupSessionEventHandling() {
103-
if (!CDCEventBusProvider.isInitialized()) {
104-
CDCEventBusProvider.initialize()
105-
}
106-
// Subscribe to session events with lifecycle awareness
107-
subscribeToSessionEvents { event ->
108-
when (event) {
109-
is SessionEvent.SessionExpired -> handleSessionExpired()
110-
is SessionEvent.VerifySession -> handleSessionVerification()
111-
is SessionEvent.SessionRefreshed -> handleSessionRefreshed()
112-
else -> {
113-
/* No action needed for other events */
114-
}
115-
}
116-
}
117-
}
118-
119-
/**
120-
* Handle session expiration with lifecycle awareness
121-
*/
122-
private fun handleSessionExpired() {
123-
CDCDebuggable.log("MainActivity", "Session expired - navigating to welcome")
124-
// Only handle if activity is in proper state
125-
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
126-
// ViewModel method removed to avoid compilation errors
127-
// viewModel.handleSessionExpired()
128-
129-
// Navigate to welcome screen
130-
NavigationCoordinator.INSTANCE.popToRootAndNavigate(
131-
toRoute = ProfileScreenRoute.Welcome.route,
132-
rootRoute = ProfileScreenRoute.Welcome.route
133-
)
134-
}
135-
}
136-
137-
/**
138-
* Handle session refreshed
139-
*/
140-
private fun handleSessionRefreshed() {
141-
CDCDebuggable.log("MainActivity", "Session refreshed")
142-
}
143-
144-
/**
145-
* Handle session verification
146-
*/
147-
private fun handleSessionVerification() {
148-
CDCDebuggable.log("MainActivity", "Session verification requested")
149-
// Only handle if activity is in proper state
150-
if (lifecycle.currentState.isAtLeast(Lifecycle.State.STARTED)) {
151-
// ViewModel method removed to avoid compilation errors
152-
// viewModel.handleSessionVerification()
153-
}
154-
}
155-
156-
override fun onDestroy() {
157-
// Proper cleanup to prevent memory leaks
158-
// Only dispose the global event bus if this is the last activity
159-
if (isFinishing) {
160-
// Dispose any global resources if needed
161-
}
162-
163-
super.onDestroy()
164-
}
16589
}
Lines changed: 113 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
package com.sap.cdc.bitsnbytes.ui.activity
22

33
import androidx.lifecycle.ViewModel
4+
import com.sap.cdc.android.sdk.CDCDebuggable
5+
import com.sap.cdc.android.sdk.events.CDCEventBusProvider
6+
import com.sap.cdc.android.sdk.events.EventSubscription
7+
import com.sap.cdc.android.sdk.events.SessionEvent
8+
import com.sap.cdc.android.sdk.events.subscribeToSessionEventsManual
49
import com.sap.cdc.bitsnbytes.feature.auth.AuthenticationFlowDelegate
10+
import com.sap.cdc.bitsnbytes.navigation.NavigationCoordinator
11+
import com.sap.cdc.bitsnbytes.navigation.ProfileScreenRoute
512

613
/**
7-
* ViewModel for MainActivity demonstrating AuthenticationDelegate injection.
14+
* ViewModel for MainActivity with proper session event handling.
815
*
9-
* UPDATED: Now uses the shared AuthenticationDelegate pattern.
10-
* This ViewModel receives the shared delegate instance to ensure single CDC SDK connection.
16+
* Responsibilities:
17+
* - Session event subscription and handling (proper MVVM architecture)
18+
* - Delegates authentication operations to AuthenticationFlowDelegate
19+
* - Coordinates navigation on session events
20+
* - Proper cleanup in onCleared()
1121
*/
1222
class MainActivityViewModel(
1323
private val authenticationFlowDelegate: AuthenticationFlowDelegate
@@ -23,8 +33,103 @@ class MainActivityViewModel(
2333
// Direct access to CDC SDK components
2434
val authenticationService = authenticationFlowDelegate.authenticationService
2535

26-
// Example methods would go here - implementation details removed to avoid compilation errors
27-
// fun initializeApp() { /* implementation */ }
28-
// fun handleSessionExpired() { /* implementation */ }
29-
// fun handleSessionVerification() { /* implementation */ }
30-
}
36+
// Event subscription handle for manual cleanup
37+
private var sessionEventSubscription: EventSubscription? = null
38+
39+
init {
40+
setupSessionEventHandling()
41+
}
42+
43+
/**
44+
* Setup session event handling with manual subscription.
45+
* ViewModels use manual subscription since they're not LifecycleOwners.
46+
*/
47+
private fun setupSessionEventHandling() {
48+
// Initialize event bus if not already initialized
49+
if (!CDCEventBusProvider.isInitialized()) {
50+
CDCEventBusProvider.initialize()
51+
}
52+
53+
// Subscribe to session events with manual lifecycle management
54+
sessionEventSubscription = subscribeToSessionEventsManual { event ->
55+
when (event) {
56+
is SessionEvent.SessionExpired -> handleSessionExpired()
57+
is SessionEvent.VerifySession -> handleSessionVerification()
58+
is SessionEvent.SessionRefreshed -> handleSessionRefreshed()
59+
is SessionEvent.ValidationStarted -> handleValidationStarted()
60+
is SessionEvent.ValidationSucceeded -> handleValidationSucceeded()
61+
is SessionEvent.ValidationFailed -> handleValidationFailed(event.reason)
62+
}
63+
}
64+
}
65+
66+
/**
67+
* Handle session expiration.
68+
* Clears authentication state and navigates to welcome screen.
69+
*/
70+
private fun handleSessionExpired() {
71+
CDCDebuggable.log("MainActivityViewModel", "Session expired - clearing state")
72+
73+
// Clear authentication state via delegate
74+
authenticationFlowDelegate.handleSessionExpired()
75+
76+
// Navigate to welcome screen
77+
NavigationCoordinator.INSTANCE.popToRootAndNavigate(
78+
toRoute = ProfileScreenRoute.Welcome.route,
79+
rootRoute = ProfileScreenRoute.Welcome.route
80+
)
81+
}
82+
83+
/**
84+
* Handle session verification request.
85+
*/
86+
private fun handleSessionVerification() {
87+
CDCDebuggable.log("MainActivityViewModel", "Session verification requested")
88+
// Session verification logic can be added here if needed
89+
}
90+
91+
/**
92+
* Handle session refresh.
93+
*/
94+
private fun handleSessionRefreshed() {
95+
CDCDebuggable.log("MainActivityViewModel", "Session refreshed")
96+
// Session refresh handling can be added here if needed
97+
}
98+
99+
/**
100+
* Handle session validation started.
101+
* Only fires if session validation is enabled via registerForSessionValidation().
102+
*/
103+
private fun handleValidationStarted() {
104+
CDCDebuggable.log("MainActivityViewModel", "Session validation started")
105+
}
106+
107+
/**
108+
* Handle successful session validation.
109+
* Only fires if session validation is enabled via registerForSessionValidation().
110+
*/
111+
private fun handleValidationSucceeded() {
112+
CDCDebuggable.log("MainActivityViewModel", "Session validation succeeded")
113+
}
114+
115+
/**
116+
* Handle failed session validation.
117+
* Only fires if session validation is enabled via registerForSessionValidation().
118+
*
119+
* @param reason The reason for validation failure
120+
*/
121+
private fun handleValidationFailed(reason: String) {
122+
CDCDebuggable.log("MainActivityViewModel", "Session validation failed: $reason")
123+
// Could trigger re-authentication flow if needed
124+
}
125+
126+
/**
127+
* Clean up resources when ViewModel is cleared.
128+
* Unsubscribes from event bus to prevent memory leaks.
129+
*/
130+
override fun onCleared() {
131+
sessionEventSubscription?.unsubscribe()
132+
sessionEventSubscription = null
133+
super.onCleared()
134+
}
135+
}

library/src/main/java/com/sap/cdc/android/sdk/feature/provider/web/WebAuthenticationProvider.kt

Lines changed: 5 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,6 @@ import androidx.activity.result.contract.ActivityResultContract
1010
import com.sap.cdc.android.sdk.CDCDebuggable
1111
import com.sap.cdc.android.sdk.core.SiteConfig
1212
import com.sap.cdc.android.sdk.core.api.model.CDCError
13-
import com.sap.cdc.android.sdk.core.api.utils.AndroidBase64Encoder
14-
import com.sap.cdc.android.sdk.core.api.utils.Signing
15-
import com.sap.cdc.android.sdk.core.api.utils.SigningSpec
1613
import com.sap.cdc.android.sdk.core.api.utils.toEncodedQuery
1714
import com.sap.cdc.android.sdk.extensions.getEncryptedPreferences
1815
import com.sap.cdc.android.sdk.feature.AuthEndpoints
@@ -23,34 +20,31 @@ import com.sap.cdc.android.sdk.feature.provider.ProviderException
2320
import com.sap.cdc.android.sdk.feature.provider.ProviderExceptionType
2421
import com.sap.cdc.android.sdk.feature.provider.ProviderType
2522
import com.sap.cdc.android.sdk.feature.session.Session
26-
import io.ktor.http.HttpMethod
2723
import io.ktor.util.generateNonce
2824
import kotlin.coroutines.resume
2925
import kotlin.coroutines.resumeWithException
3026
import kotlin.coroutines.suspendCoroutine
3127

3228
/**
3329
* Web-based social authentication provider.
34-
*
30+
*
3531
* Implements social login using WebView for providers that don't have native SDK support.
3632
* Handles OAuth 1.0a flow with the CDC socialize.login endpoint.
37-
*
33+
*
3834
* @property socialProvider Social provider identifier (e.g., "twitter", "linkedin")
3935
* @property siteConfig CDC site configuration
40-
* @property session Optional existing session for authenticated requests
41-
*
36+
*
4237
* @author Tal Mirmelshtein
4338
* @since 10/06/2024
44-
*
39+
*
4540
* Copyright: SAP LTD.
46-
*
41+
*
4742
* @see IAuthenticationProvider
4843
* @see WebLoginActivity
4944
*/
5045
class WebAuthenticationProvider(
5146
private val socialProvider: String,
5247
private val siteConfig: SiteConfig,
53-
private val session: Session?,
5448
) :
5549
IAuthenticationProvider {
5650

@@ -176,20 +170,6 @@ class WebAuthenticationProvider(
176170
"nonce" to generateNonce()
177171
)
178172

179-
// Check session state to apply authentication parameters.
180-
if (session != null) {
181-
uriParameters["oauth_token"] = session.token
182-
uriParameters["timestamp"] = siteConfig.getServerTimestamp()
183-
Signing(base64Encoder = AndroidBase64Encoder()).newSignature(
184-
SigningSpec(
185-
session.secret,
186-
AuthEndpoints.Companion.EP_SOCIALIZE_LOGIN,
187-
HttpMethod.Companion.Get.value,
188-
uriParameters
189-
)
190-
)
191-
}
192-
193173
return String.format(
194174
"%s://%s.%s/%s?%s", "https", "socialize", siteConfig.domain,
195175
AuthEndpoints.Companion.EP_SOCIALIZE_LOGIN, uriParameters.toEncodedQuery()

library/src/main/java/com/sap/cdc/android/sdk/feature/screensets/WebBridgeJSApiService.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -297,7 +297,6 @@ class WebBridgeJSApiService(
297297
authProvider = WebAuthenticationProvider(
298298
socialProvider = provider,
299299
siteConfig = authenticationService.siteConfig,
300-
session = authenticationService.session().getSession()
301300
)
302301
}
303302

0 commit comments

Comments
 (0)