Skip to content

Commit bdb49f5

Browse files
authored
Merge pull request #5398 from vector-im/bugfix/eric/softlogout-ux-broken
Fixes broken SoftLogout UX for homeservers that support both Password and SSO
2 parents d5b375e + 4cf97d4 commit bdb49f5

37 files changed

+1058
-150
lines changed

changelog.d/5398.bugfix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Adds LoginType to SessionParams to fix soft logout form not showing for SSO and Password type
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/*
2+
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.api.auth
18+
19+
enum class LoginType {
20+
PASSWORD,
21+
SSO,
22+
UNSUPPORTED,
23+
CUSTOM,
24+
DIRECT,
25+
UNKNOWN;
26+
27+
companion object {
28+
29+
fun fromName(name: String) = when (name) {
30+
PASSWORD.name -> PASSWORD
31+
SSO.name -> SSO
32+
UNSUPPORTED.name -> UNSUPPORTED
33+
CUSTOM.name -> CUSTOM
34+
DIRECT.name -> DIRECT
35+
else -> UNKNOWN
36+
}
37+
}
38+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/api/auth/data/SessionParams.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.matrix.android.sdk.api.auth.data
1818

19+
import org.matrix.android.sdk.api.auth.LoginType
20+
1921
/**
2022
* This data class holds necessary data to open a session.
2123
* You don't have to manually instantiate it.
@@ -34,7 +36,12 @@ data class SessionParams(
3436
/**
3537
* Set to false if the current token is not valid anymore. Application should not have to use this info.
3638
*/
37-
val isTokenValid: Boolean
39+
val isTokenValid: Boolean,
40+
41+
/**
42+
* The authentication method that was used to create the session.
43+
*/
44+
val loginType: LoginType,
3845
) {
3946
/*
4047
* Shortcuts. Usually the application should only need to use these shortcuts

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/AuthModule.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,9 @@ internal abstract class AuthModule {
8383
@Binds
8484
abstract fun bindSessionCreator(creator: DefaultSessionCreator): SessionCreator
8585

86+
@Binds
87+
abstract fun bindSessionParamsCreator(creator: DefaultSessionParamsCreator): SessionParamsCreator
88+
8689
@Binds
8790
abstract fun bindDirectLoginTask(task: DefaultDirectLoginTask): DirectLoginTask
8891

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/DefaultAuthenticationService.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import okhttp3.OkHttpClient
2222
import org.matrix.android.sdk.api.MatrixPatterns
2323
import org.matrix.android.sdk.api.MatrixPatterns.getServerName
2424
import org.matrix.android.sdk.api.auth.AuthenticationService
25+
import org.matrix.android.sdk.api.auth.LoginType
2526
import org.matrix.android.sdk.api.auth.data.Credentials
2627
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
2728
import org.matrix.android.sdk.api.auth.data.LoginFlowResult
@@ -361,7 +362,7 @@ internal class DefaultAuthenticationService @Inject constructor(
361362
homeServerConnectionConfig: HomeServerConnectionConfig,
362363
credentials: Credentials
363364
): Session {
364-
return sessionCreator.createSession(credentials, homeServerConnectionConfig)
365+
return sessionCreator.createSession(credentials, homeServerConnectionConfig, LoginType.SSO)
365366
}
366367

367368
override suspend fun getWellKnownData(

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/SessionCreator.kt

Lines changed: 14 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -16,69 +16,41 @@
1616

1717
package org.matrix.android.sdk.internal.auth
1818

19-
import android.net.Uri
19+
import org.matrix.android.sdk.api.auth.LoginType
2020
import org.matrix.android.sdk.api.auth.data.Credentials
2121
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
22-
import org.matrix.android.sdk.api.auth.data.SessionParams
23-
import org.matrix.android.sdk.api.extensions.tryOrNull
2422
import org.matrix.android.sdk.api.session.Session
2523
import org.matrix.android.sdk.internal.SessionManager
26-
import timber.log.Timber
2724
import javax.inject.Inject
2825

2926
internal interface SessionCreator {
30-
suspend fun createSession(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session
27+
28+
suspend fun createSession(
29+
credentials: Credentials,
30+
homeServerConnectionConfig: HomeServerConnectionConfig,
31+
loginType: LoginType,
32+
): Session
3133
}
3234

3335
internal class DefaultSessionCreator @Inject constructor(
3436
private val sessionParamsStore: SessionParamsStore,
3537
private val sessionManager: SessionManager,
3638
private val pendingSessionStore: PendingSessionStore,
37-
private val isValidClientServerApiTask: IsValidClientServerApiTask
39+
private val sessionParamsCreator: SessionParamsCreator,
3840
) : SessionCreator {
3941

4042
/**
4143
* Credentials can affect the homeServerConnectionConfig, override homeserver url and/or
4244
* identity server url if provided in the credentials.
4345
*/
44-
override suspend fun createSession(credentials: Credentials, homeServerConnectionConfig: HomeServerConnectionConfig): Session {
46+
override suspend fun createSession(
47+
credentials: Credentials,
48+
homeServerConnectionConfig: HomeServerConnectionConfig,
49+
loginType: LoginType,
50+
): Session {
4551
// We can cleanup the pending session params
4652
pendingSessionStore.delete()
47-
48-
val overriddenUrl = credentials.discoveryInformation?.homeServer?.baseURL
49-
// remove trailing "/"
50-
?.trim { it == '/' }
51-
?.takeIf { it.isNotBlank() }
52-
// It can be the same value, so in this case, do not check again the validity
53-
?.takeIf { it != homeServerConnectionConfig.homeServerUriBase.toString() }
54-
?.also { Timber.d("Overriding homeserver url to $it (will check if valid)") }
55-
?.let { Uri.parse(it) }
56-
?.takeIf {
57-
// Validate the URL, if the configuration is wrong server side, do not override
58-
tryOrNull {
59-
isValidClientServerApiTask.execute(
60-
IsValidClientServerApiTask.Params(
61-
homeServerConnectionConfig.copy(homeServerUriBase = it)
62-
)
63-
)
64-
.also { Timber.d("Overriding homeserver url: $it") }
65-
} ?: true // In case of other error (no network, etc.), consider it is valid...
66-
}
67-
68-
val sessionParams = SessionParams(
69-
credentials = credentials,
70-
homeServerConnectionConfig = homeServerConnectionConfig.copy(
71-
homeServerUriBase = overriddenUrl ?: homeServerConnectionConfig.homeServerUriBase,
72-
identityServerUri = credentials.discoveryInformation?.identityServer?.baseURL
73-
// remove trailing "/"
74-
?.trim { it == '/' }
75-
?.takeIf { it.isNotBlank() }
76-
?.also { Timber.d("Overriding identity server url to $it") }
77-
?.let { Uri.parse(it) }
78-
?: homeServerConnectionConfig.identityServerUri
79-
),
80-
isTokenValid = true)
81-
53+
val sessionParams = sessionParamsCreator.create(credentials, homeServerConnectionConfig, loginType)
8254
sessionParamsStore.save(sessionParams)
8355
return sessionManager.getOrCreateSession(sessionParams)
8456
}
Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
/*
2+
* Copyright (c) 2022 The Matrix.org Foundation C.I.C.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* http://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.matrix.android.sdk.internal.auth
18+
19+
import android.net.Uri
20+
import org.matrix.android.sdk.api.auth.LoginType
21+
import org.matrix.android.sdk.api.auth.data.Credentials
22+
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
23+
import org.matrix.android.sdk.api.auth.data.SessionParams
24+
import org.matrix.android.sdk.api.extensions.tryOrNull
25+
import timber.log.Timber
26+
import javax.inject.Inject
27+
28+
internal interface SessionParamsCreator {
29+
30+
suspend fun create(
31+
credentials: Credentials,
32+
homeServerConnectionConfig: HomeServerConnectionConfig,
33+
loginType: LoginType,
34+
): SessionParams
35+
}
36+
37+
internal class DefaultSessionParamsCreator @Inject constructor(
38+
private val isValidClientServerApiTask: IsValidClientServerApiTask
39+
) : SessionParamsCreator {
40+
41+
override suspend fun create(
42+
credentials: Credentials,
43+
homeServerConnectionConfig: HomeServerConnectionConfig,
44+
loginType: LoginType,
45+
) = SessionParams(
46+
credentials = credentials,
47+
homeServerConnectionConfig = homeServerConnectionConfig.overrideWithCredentials(credentials),
48+
isTokenValid = true,
49+
loginType = loginType,
50+
)
51+
52+
private suspend fun HomeServerConnectionConfig.overrideWithCredentials(credentials: Credentials) = copy(
53+
homeServerUriBase = credentials.getHomeServerUri(this) ?: homeServerUriBase,
54+
identityServerUri = credentials.getIdentityServerUri() ?: identityServerUri
55+
)
56+
57+
private suspend fun Credentials.getHomeServerUri(homeServerConnectionConfig: HomeServerConnectionConfig) =
58+
discoveryInformation?.homeServer?.baseURL
59+
?.trim { it == '/' }
60+
?.takeIf { it.isNotBlank() }
61+
// It can be the same value, so in this case, do not check again the validity
62+
?.takeIf { it != homeServerConnectionConfig.homeServerUriBase.toString() }
63+
?.also { Timber.d("Overriding homeserver url to $it (will check if valid)") }
64+
?.let { Uri.parse(it) }
65+
?.takeIf { validateUri(it, homeServerConnectionConfig) }
66+
67+
private suspend fun validateUri(uri: Uri, homeServerConnectionConfig: HomeServerConnectionConfig) =
68+
// Validate the URL, if the configuration is wrong server side, do not override
69+
tryOrNull {
70+
performClientServerApiValidation(uri, homeServerConnectionConfig)
71+
} ?: true // In case of other error (no network, etc.), consider it is valid...
72+
73+
private suspend fun performClientServerApiValidation(uri: Uri, homeServerConnectionConfig: HomeServerConnectionConfig) =
74+
isValidClientServerApiTask.execute(
75+
IsValidClientServerApiTask.Params(homeServerConnectionConfig.copy(homeServerUriBase = uri))
76+
).also { Timber.d("Overriding homeserver url: $it") }
77+
78+
private fun Credentials.getIdentityServerUri() = discoveryInformation?.identityServer?.baseURL
79+
?.trim { it == '/' }
80+
?.takeIf { it.isNotBlank() }
81+
?.also { Timber.d("Overriding identity server url to $it") }
82+
?.let { Uri.parse(it) }
83+
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/AuthRealmMigration.kt

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo001
2222
import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo002
2323
import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo003
2424
import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo004
25+
import org.matrix.android.sdk.internal.auth.db.migration.MigrateAuthTo005
2526
import timber.log.Timber
2627
import javax.inject.Inject
2728

@@ -33,7 +34,7 @@ internal class AuthRealmMigration @Inject constructor() : RealmMigration {
3334
override fun equals(other: Any?) = other is AuthRealmMigration
3435
override fun hashCode() = 4000
3536

36-
val schemaVersion = 4L
37+
val schemaVersion = 5L
3738

3839
override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) {
3940
Timber.d("Migrating Auth Realm from $oldVersion to $newVersion")
@@ -42,5 +43,6 @@ internal class AuthRealmMigration @Inject constructor() : RealmMigration {
4243
if (oldVersion < 2) MigrateAuthTo002(realm).perform()
4344
if (oldVersion < 3) MigrateAuthTo003(realm).perform()
4445
if (oldVersion < 4) MigrateAuthTo004(realm).perform()
46+
if (oldVersion < 5) MigrateAuthTo005(realm).perform()
4547
}
4648
}

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/SessionParamsEntity.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,5 +26,6 @@ internal open class SessionParamsEntity(
2626
var homeServerConnectionConfigJson: String = "",
2727
// Set to false when the token is invalid and the user has been soft logged out
2828
// In case of hard logout, this object is deleted from DB
29-
var isTokenValid: Boolean = true
29+
var isTokenValid: Boolean = true,
30+
var loginType: String = "",
3031
) : RealmObject()

matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/auth/db/SessionParamsMapper.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package org.matrix.android.sdk.internal.auth.db
1818

1919
import com.squareup.moshi.Moshi
20+
import org.matrix.android.sdk.api.auth.LoginType
2021
import org.matrix.android.sdk.api.auth.data.Credentials
2122
import org.matrix.android.sdk.api.auth.data.HomeServerConnectionConfig
2223
import org.matrix.android.sdk.api.auth.data.SessionParams
@@ -37,7 +38,7 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
3738
if (credentials == null || homeServerConnectionConfig == null) {
3839
return null
3940
}
40-
return SessionParams(credentials, homeServerConnectionConfig, entity.isTokenValid)
41+
return SessionParams(credentials, homeServerConnectionConfig, entity.isTokenValid, LoginType.fromName(entity.loginType))
4142
}
4243

4344
fun map(sessionParams: SessionParams?): SessionParamsEntity? {
@@ -54,7 +55,8 @@ internal class SessionParamsMapper @Inject constructor(moshi: Moshi) {
5455
sessionParams.userId,
5556
credentialsJson,
5657
homeServerConnectionConfigJson,
57-
sessionParams.isTokenValid
58+
sessionParams.isTokenValid,
59+
sessionParams.loginType.name,
5860
)
5961
}
6062
}

0 commit comments

Comments
 (0)