Skip to content

Commit 316ebc4

Browse files
committed
fix: sso login flow and other fixes
1 parent 2207571 commit 316ebc4

File tree

8 files changed

+58
-61
lines changed

8 files changed

+58
-61
lines changed

app/schemas/org.openedx.app.room.AppDatabase/4.json

Lines changed: 3 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
"formatVersion": 1,
33
"database": {
44
"version": 4,
5-
"identityHash": "ad2d11c09b3d243a97daf995a50b761f",
5+
"identityHash": "488bd2b78e977fef626afb28014c80f2",
66
"entities": [
77
{
88
"tableName": "course_discovery_table",
@@ -748,7 +748,7 @@
748748
},
749749
{
750750
"tableName": "course_enrollment_details_table",
751-
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `courseUpdates` TEXT NOT NULL, `courseHandouts` TEXT NOT NULL, `discussionUrl` TEXT NOT NULL, `hasUnmetPrerequisites` INTEGER NOT NULL, `isTooEarly` INTEGER NOT NULL, `isStaff` INTEGER NOT NULL, `auditAccessExpires` TEXT, `hasAccess` INTEGER, `errorCode` TEXT, `developerMessage` TEXT, `userMessage` TEXT, `additionalContextUserMessage` TEXT, `userFragment` TEXT, `certificateURL` TEXT, `created` TEXT, `mode` TEXT, `isActive` INTEGER NOT NULL, `upgradeDeadline` TEXT, `name` TEXT NOT NULL, `number` TEXT NOT NULL, `org` TEXT NOT NULL, `startDisplay` TEXT NOT NULL, `startType` TEXT NOT NULL, `isSelfPaced` INTEGER NOT NULL, `courseAbout` TEXT NOT NULL, `fastTime` INTEGER, `cdate` TEXT, `fastTime` INTEGER, `cdate` TEXT, `bannerImage` TEXT, `courseImage` TEXT, `courseVideo` TEXT, `image` TEXT, `facebook` TEXT NOT NULL, `twitter` TEXT NOT NULL, PRIMARY KEY(`id`))",
751+
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`id` TEXT NOT NULL, `courseUpdates` TEXT NOT NULL, `courseHandouts` TEXT NOT NULL, `discussionUrl` TEXT NOT NULL, `hasUnmetPrerequisites` INTEGER NOT NULL, `isTooEarly` INTEGER NOT NULL, `isStaff` INTEGER NOT NULL, `auditAccessExpires` TEXT, `hasAccess` INTEGER, `errorCode` TEXT, `developerMessage` TEXT, `userMessage` TEXT, `additionalContextUserMessage` TEXT, `userFragment` TEXT, `certificateURL` TEXT, `created` TEXT, `mode` TEXT, `isActive` INTEGER NOT NULL, `upgradeDeadline` TEXT, `name` TEXT NOT NULL, `number` TEXT NOT NULL, `org` TEXT NOT NULL, `startDisplay` TEXT NOT NULL, `startType` TEXT NOT NULL, `isSelfPaced` INTEGER NOT NULL, `courseAbout` TEXT NOT NULL, `bannerImage` TEXT, `courseImage` TEXT, `courseVideo` TEXT, `image` TEXT, `facebook` TEXT NOT NULL, `twitter` TEXT NOT NULL, PRIMARY KEY(`id`))",
752752
"fields": [
753753
{
754754
"fieldPath": "id",
@@ -895,26 +895,6 @@
895895
"affinity": "TEXT",
896896
"notNull": true
897897
},
898-
{
899-
"fieldPath": "courseInfoOverview.start.fastTime",
900-
"columnName": "fastTime",
901-
"affinity": "INTEGER"
902-
},
903-
{
904-
"fieldPath": "courseInfoOverview.start.cdate",
905-
"columnName": "cdate",
906-
"affinity": "TEXT"
907-
},
908-
{
909-
"fieldPath": "courseInfoOverview.end.fastTime",
910-
"columnName": "fastTime",
911-
"affinity": "INTEGER"
912-
},
913-
{
914-
"fieldPath": "courseInfoOverview.end.cdate",
915-
"columnName": "cdate",
916-
"affinity": "TEXT"
917-
},
918898
{
919899
"fieldPath": "courseInfoOverview.media.bannerImage",
920900
"columnName": "bannerImage",
@@ -1158,7 +1138,7 @@
11581138
],
11591139
"setupQueries": [
11601140
"CREATE TABLE IF NOT EXISTS room_master_table (id INTEGER PRIMARY KEY,identity_hash TEXT)",
1161-
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, 'ad2d11c09b3d243a97daf995a50b761f')"
1141+
"INSERT OR REPLACE INTO room_master_table (id,identity_hash) VALUES(42, '488bd2b78e977fef626afb28014c80f2')"
11621142
]
11631143
}
11641144
}

auth/src/main/java/org/openedx/auth/data/repository/AuthRepository.kt

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,8 @@ class AuthRepository(
3434
suspend fun ssoLogin(
3535
jwtToken: String
3636
) {
37-
if (preferencesManager.accessToken.isBlank() ||
38-
preferencesManager.refreshToken.isBlank()){
37+
if (preferencesManager.accessToken.isBlank()){
3938
preferencesManager.accessToken = jwtToken
40-
preferencesManager.refreshToken = jwtToken
4139
}
4240
val user = api.getProfile()
4341
preferencesManager.user = user

auth/src/main/java/org/openedx/auth/presentation/signin/SignInFragment.kt

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package org.openedx.auth.presentation.signin
22

33
import android.os.Bundle
44
import android.view.LayoutInflater
5+
import android.view.View
56
import android.view.ViewGroup
67
import androidx.compose.runtime.LaunchedEffect
78
import androidx.compose.runtime.collectAsState
@@ -44,9 +45,7 @@ class SignInFragment : Fragment() {
4445
val appUpgradeEvent by viewModel.appUpgradeEvent.observeAsState(null)
4546

4647
if (appUpgradeEvent == null) {
47-
setFragmentResultListener("requestKey") { requestKey, bundle ->
48-
viewModel.ssoLogin(token = requestKey)
49-
}
48+
5049
LoginScreen(
5150
windowSize = windowSize,
5251
state = state,
@@ -94,6 +93,13 @@ class SignInFragment : Fragment() {
9493
}
9594
}
9695

96+
override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
97+
super.onViewCreated(view, savedInstanceState)
98+
setFragmentResultListener("requestKey") { _, bundle ->
99+
val token = bundle.getString("bundleKey")
100+
viewModel.ssoLogin(token = "$token")
101+
}
102+
}
97103
companion object {
98104
private const val ARG_COURSE_ID = "courseId"
99105
private const val ARG_INFO_TYPE = "info_type"

auth/src/main/java/org/openedx/auth/presentation/signin/SignInViewModel.kt

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ class SignInViewModel(
6767
SignInUIState(
6868
isLoginRegistrationFormEnabled = config.isLoginRegistrationEnabled(),
6969
isSSOLoginEnabled = config.isSSOLoginEnabled(),
70-
ssoButtonTitle = currentLang,
70+
ssoButtonTitle = config.getSSOButtonTitle(currentLang, "Login"),
7171
isSSODefaultLoginButton = config.isSSODefaultLoginButton(),
7272
isFacebookAuthEnabled = config.getFacebookConfig().isEnabled(),
7373
isGoogleAuthEnabled = config.getGoogleConfig().isEnabled(),
@@ -157,19 +157,10 @@ class SignInViewModel(
157157
_uiState.update { it.copy(showProgress = true) }
158158
viewModelScope.launch {
159159
try {
160-
interactor.ssoLogin("JWT $token")
160+
interactor.ssoLogin(token)
161161
_uiState.update { it.copy(loginSuccess = true) }
162-
163162
setUserId()
164-
logEvent(
165-
AuthAnalyticsEvent.SIGN_IN_SUCCESS,
166-
buildMap {
167-
put(
168-
AuthAnalyticsKey.METHOD.key,
169-
AuthType.PASSWORD.methodName.lowercase()
170-
)
171-
}
172-
)
163+
173164
} catch (e: Exception) {
174165
if (e is EdxError.InvalidGrantException) {
175166
_uiMessage.value =

auth/src/main/java/org/openedx/auth/presentation/signin/compose/SignInView.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -337,7 +337,7 @@ private fun AuthForm(
337337
}
338338
if (state.isSSOLoginEnabled) {
339339
Spacer(modifier = Modifier.height(18.dp))
340-
if (state.isLoginRegistrationFormEnabled) {
340+
if (!state.isLoginRegistrationFormEnabled) {
341341
Text(
342342
modifier =
343343
Modifier
@@ -396,7 +396,7 @@ private fun AuthForm(
396396
buttonWidth
397397
.testTag("btn_sso")
398398
.fillMaxWidth(),
399-
text = stringResource(id = coreR.string.core_sso_sign_in),
399+
text = state.ssoButtonTitle,
400400
borderColor = MaterialTheme.appColors.primary,
401401
textColor = MaterialTheme.appColors.textPrimary,
402402
onClick = { onEvent(AuthEvent.SsoSignIn(jwtToken = "")) },

core/src/main/java/org/openedx/core/config/Config.kt

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ class Config(context: Context) {
3232
return getString(SSO_URL, "")
3333
}
3434

35+
fun getSSOFinishedURL(): String {
36+
return getString(SSO_FINISHED_URL, "")
37+
}
3538
fun getUriScheme(): String {
3639
return getString(URI_SCHEME)
3740
}
@@ -125,8 +128,10 @@ class Config(context: Context) {
125128
}
126129

127130
fun getSSOButtonTitle(key: String, defaultValue: String): String {
131+
print("getSSOButtonTitle")
128132
val element = getObject(SSO_BUTTON_TITLE)
129-
return element?.asJsonObject?.get(key)?.asString ?: defaultValue
133+
print("element: $element, key: ${key.uppercase()}")
134+
return element?.asJsonObject?.get(key.uppercase())?.asString ?: defaultValue
130135
}
131136

132137
fun getCourseUIConfig(): UIConfig {

core/src/main/java/org/openedx/core/presentation/global/webview/SSOWebContentFragment.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import androidx.core.os.bundleOf
99
import androidx.fragment.app.Fragment
1010
import androidx.fragment.app.setFragmentResult
1111
import org.koin.android.ext.android.inject
12+
import org.koin.androidx.viewmodel.ext.android.viewModel
1213
import org.openedx.core.config.Config
1314
import org.openedx.core.ui.SSOWebContentScreen
1415
import org.openedx.foundation.presentation.rememberWindowSize
@@ -32,6 +33,7 @@ class SSOWebContentFragment : Fragment() {
3233
url = config.getSSOURL(),
3334
uriScheme = requireArguments().getString(ARG_TITLE, ""),
3435
title = "",
36+
ssoFinishedUrl = config.getSSOFinishedURL().toString(),
3537
onBackClick = {
3638
// use it to close the webView
3739
requireActivity().supportFragmentManager.popBackStack()
@@ -44,7 +46,6 @@ class SSOWebContentFragment : Fragment() {
4446
setFragmentResult("requestKey", bundleOf("bundleKey" to token))
4547
requireActivity().supportFragmentManager.popBackStack()
4648
}
47-
4849
})
4950
}
5051
}

core/src/main/java/org/openedx/core/ui/SSOWebContentScreen.kt

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -40,13 +40,15 @@ fun SSOWebContentScreen(
4040
url: String,
4141
uriScheme: String,
4242
title: String,
43+
ssoFinishedUrl: String,
4344
onBackClick: () -> Unit,
4445
onWebPageLoaded: () -> Unit,
4546
onWebPageUpdated: (String) -> Unit = {},
4647
){
4748
val webView = SSOWebView(
4849
url = url,
4950
uriScheme = uriScheme,
51+
ssoFinishedUrl = ssoFinishedUrl,
5052
onWebPageLoaded = onWebPageLoaded,
5153
onWebPageUpdated = onWebPageUpdated
5254
)
@@ -111,6 +113,7 @@ fun SSOWebContentScreen(
111113
fun SSOWebView(
112114
url: String,
113115
uriScheme: String,
116+
ssoFinishedUrl: String,
114117
onWebPageLoaded: () -> Unit,
115118
onWebPageUpdated: (String) -> Unit = {},
116119
): WebView {
@@ -119,11 +122,21 @@ fun SSOWebView(
119122
return remember {
120123
WebView(context).apply {
121124
webViewClient = object : WebViewClient() {
122-
override fun onPageFinished(view: WebView?, url: String?) {
123-
super.onPageFinished(view, url)
124-
url?.let {
125-
val jwtToken = getCookie(url, "edx-jwt-cookie-header-payload") + getCookie(url, "edx-jwt-cookie-signature")
126-
onWebPageUpdated(jwtToken)
125+
override fun onPageFinished(view: WebView?, pageUrl: String?) {
126+
super.onPageFinished(view, pageUrl)
127+
128+
if (pageUrl == null) return
129+
130+
if (pageUrl.contains(ssoFinishedUrl)) {
131+
132+
val header = getCookie(pageUrl, "edx-jwt-cookie-header-payload") ?: ""
133+
val signature = getCookie(pageUrl, "edx-jwt-cookie-signature") ?: ""
134+
135+
val token = "$header.$signature"
136+
137+
if (token.isNotEmpty()) {
138+
onWebPageUpdated(token)
139+
}
127140
}
128141
}
129142

@@ -170,18 +183,21 @@ fun SSOWebView(
170183

171184
fun getCookie(siteName: String?, cookieName: String?): String? {
172185
var cookieValue: String? = ""
173-
174-
val cookieManager = CookieManager.getInstance()
175-
val cookies = cookieManager.getCookie(siteName)
176-
val temp = cookies.split(";".toRegex()).dropLastWhile { it.isEmpty() }
177-
.toTypedArray()
178-
for (ar1 in temp) {
179-
if (ar1.contains(cookieName!!)) {
180-
val temp1 = ar1.split("=".toRegex()).dropLastWhile { it.isEmpty() }
181-
.toTypedArray()
182-
cookieValue = temp1[1]
183-
break
186+
if (siteName != null && cookieName != null) {
187+
val cookieManager = CookieManager.getInstance()
188+
val cookies = cookieManager.getCookie(siteName)
189+
val temp = cookies.split(";".toRegex()).dropLastWhile { it.isEmpty() }
190+
.toTypedArray()
191+
for (ar1 in temp) {
192+
if (ar1.contains(cookieName)) {
193+
val temp1 = ar1.split("=".toRegex()).dropLastWhile { it.isEmpty() }
194+
.toTypedArray()
195+
cookieValue = temp1[1]
196+
break
197+
}
184198
}
199+
return cookieValue
185200
}
201+
186202
return cookieValue
187203
}

0 commit comments

Comments
 (0)