Store session data in a secure way (#98)

* Replace SessionData DataStore with an encrypted SQLite DB.

---------

Co-authored-by: Benoit Marty <benoit@matrix.org>
This commit is contained in:
Jorge Martin Espinosa 2023-03-02 16:48:54 +01:00 committed by GitHub
parent 381bd3fd3f
commit 6677f80abe
38 changed files with 600 additions and 199 deletions

View file

@ -22,6 +22,7 @@ import io.element.android.libraries.di.SingleIn
import io.element.android.libraries.matrix.MatrixClient
import io.element.android.libraries.matrix.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.core.SessionId
import io.element.android.libraries.matrix.core.UserId
import kotlinx.coroutines.runBlocking
import timber.log.Timber
import java.util.concurrent.ConcurrentHashMap
@ -57,13 +58,13 @@ class MatrixClientsHolder @Inject constructor(private val authenticationService:
@Suppress("DEPRECATION")
fun restore(savedInstanceState: Bundle?) {
if (savedInstanceState == null || sessionIdsToMatrixClient.isNotEmpty()) return
val sessionIds = savedInstanceState.getSerializable(SAVE_INSTANCE_KEY) as? Array<SessionId>
if (sessionIds.isNullOrEmpty()) return
val userIds = savedInstanceState.getSerializable(SAVE_INSTANCE_KEY) as? Array<UserId>
if (userIds.isNullOrEmpty()) return
// Not ideal but should only happens in case of process recreation. This ensure we restore all the active sessions before restoring the node graphs.
runBlocking {
sessionIds.forEach { sessionId ->
Timber.v("Restore matrix session: $sessionId")
val matrixClient = authenticationService.restoreSession(sessionId)
userIds.forEach { userId ->
Timber.v("Restore matrix session: $userId")
val matrixClient = authenticationService.restoreSession(userId)
if (matrixClient != null) {
add(matrixClient)
}

View file

@ -39,6 +39,7 @@ import io.element.android.libraries.designsystem.theme.components.CircularProgre
import io.element.android.libraries.di.DaggerComponentOwner
import io.element.android.libraries.matrix.auth.MatrixAuthenticationService
import io.element.android.libraries.matrix.core.SessionId
import io.element.android.libraries.matrix.core.UserId
import io.element.android.x.di.MatrixClientsHolder
import io.element.android.x.root.RootPresenter
import io.element.android.x.root.RootView
@ -89,7 +90,7 @@ class RootFlowNode(
}
private fun switchToLoggedInFlow(sessionId: SessionId) {
backstack.safeRoot(NavTarget.LoggedInFlow(sessionId = sessionId))
backstack.safeRoot(NavTarget.LoggedInFlow(sessionId))
}
private fun switchToLogoutFlow() {
@ -98,19 +99,19 @@ class RootFlowNode(
}
private suspend fun tryToRestoreLatestSession(
onSuccess: (SessionId) -> Unit = {},
onSuccess: (UserId) -> Unit = {},
onFailure: () -> Unit = {}
) {
val latestKnownSessionId = authenticationService.getLatestSessionId()
if (latestKnownSessionId == null) {
val latestKnownUserId = authenticationService.getLatestSessionId()
if (latestKnownUserId == null) {
onFailure()
return
}
if (matrixClientsHolder.knowSession(latestKnownSessionId)) {
onSuccess(latestKnownSessionId)
if (matrixClientsHolder.knowSession(latestKnownUserId)) {
onSuccess(latestKnownUserId)
return
}
val matrixClient = authenticationService.restoreSession(latestKnownSessionId)
val matrixClient = authenticationService.restoreSession(UserId(latestKnownUserId.value))
if (matrixClient == null) {
Timber.v("Failed to restore session...")
onFailure()