Skip to content

Commit 683f26c

Browse files
committed
Ensure sessionPath is not reused for different homeserver.
1 parent 498f843 commit 683f26c

File tree

1 file changed

+24
-10
lines changed

1 file changed

+24
-10
lines changed

libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationService.kt

Lines changed: 24 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ import javax.inject.Inject
6060
@ContributesBinding(AppScope::class)
6161
@SingleIn(AppScope::class)
6262
class RustMatrixAuthenticationService @Inject constructor(
63-
baseDirectory: File,
63+
private val baseDirectory: File,
6464
private val coroutineDispatchers: CoroutineDispatchers,
6565
private val sessionStore: SessionStore,
6666
private val rustMatrixClientFactory: RustMatrixClientFactory,
@@ -70,10 +70,18 @@ class RustMatrixAuthenticationService @Inject constructor(
7070
// Passphrase which will be used for new sessions. Existing sessions will use the passphrase
7171
// stored in the SessionData.
7272
private val pendingPassphrase = getDatabasePassphrase()
73-
private val sessionPath = File(baseDirectory, UUID.randomUUID().toString()).absolutePath
73+
// Need to keep a copy of the current session path to delete it.
74+
// Ideally it would be possible to get the sessionPath from the Client to avoid doing this.
75+
private var sessionPath: File? = null
7476
private var currentClient: Client? = null
7577
private var currentHomeserver = MutableStateFlow<MatrixHomeServerDetails?>(null)
7678

79+
private fun rotateSessionPath(): File {
80+
sessionPath?.deleteRecursively()
81+
return File(baseDirectory, UUID.randomUUID().toString())
82+
.also { sessionPath = it }
83+
}
84+
7785
override fun loggedInStateFlow(): Flow<LoggedInState> {
7886
return sessionStore.isLoggedIn()
7987
}
@@ -117,8 +125,9 @@ class RustMatrixAuthenticationService @Inject constructor(
117125

118126
override suspend fun setHomeserver(homeserver: String): Result<Unit> =
119127
withContext(coroutineDispatchers.io) {
128+
val emptySessionPath = rotateSessionPath()
120129
runCatching {
121-
val client = getBaseClientBuilder()
130+
val client = getBaseClientBuilder(emptySessionPath)
122131
.serverNameOrHomeserverUrl(homeserver)
123132
.build()
124133
currentClient = client
@@ -135,13 +144,14 @@ class RustMatrixAuthenticationService @Inject constructor(
135144
withContext(coroutineDispatchers.io) {
136145
runCatching {
137146
val client = currentClient ?: error("You need to call `setHomeserver()` first")
147+
val currentSessionPath = sessionPath ?: error("You need to call `setHomeserver()` first")
138148
client.login(username, password, "Element X Android", null)
139149
val sessionData = client.session()
140150
.toSessionData(
141151
isTokenValid = true,
142152
loginType = LoginType.PASSWORD,
143153
passphrase = pendingPassphrase,
144-
sessionPath = sessionPath,
154+
sessionPath = currentSessionPath.absolutePath,
145155
)
146156
clear()
147157
sessionStore.storeData(sessionData)
@@ -185,13 +195,14 @@ class RustMatrixAuthenticationService @Inject constructor(
185195
return withContext(coroutineDispatchers.io) {
186196
runCatching {
187197
val client = currentClient ?: error("You need to call `setHomeserver()` first")
198+
val currentSessionPath = sessionPath ?: error("You need to call `setHomeserver()` first")
188199
val urlForOidcLogin = pendingOidcAuthorizationData ?: error("You need to call `getOidcUrl()` first")
189200
client.loginWithOidcCallback(urlForOidcLogin, callbackUrl)
190201
val sessionData = client.session().toSessionData(
191202
isTokenValid = true,
192203
loginType = LoginType.OIDC,
193204
passphrase = pendingPassphrase,
194-
sessionPath = sessionPath,
205+
sessionPath = currentSessionPath.absolutePath,
195206
)
196207
clear()
197208
pendingOidcAuthorizationData?.close()
@@ -206,9 +217,10 @@ class RustMatrixAuthenticationService @Inject constructor(
206217

207218
override suspend fun loginWithQrCode(qrCodeData: MatrixQrCodeLoginData, progress: (QrCodeLoginStep) -> Unit) =
208219
withContext(coroutineDispatchers.io) {
220+
val emptySessionPath = rotateSessionPath()
209221
runCatching {
210222
val client = rustMatrixClientFactory.getBaseClientBuilder(
211-
sessionPath = sessionPath,
223+
sessionPath = emptySessionPath.absolutePath,
212224
passphrase = pendingPassphrase,
213225
slidingSyncProxy = AuthenticationConfig.SLIDING_SYNC_PROXY_URL,
214226
slidingSync = ClientBuilderSlidingSync.Discovered,
@@ -229,7 +241,7 @@ class RustMatrixAuthenticationService @Inject constructor(
229241
isTokenValid = true,
230242
loginType = LoginType.QR,
231243
passphrase = pendingPassphrase,
232-
sessionPath = sessionPath,
244+
sessionPath = emptySessionPath.absolutePath,
233245
)
234246
sessionStore.storeData(sessionData)
235247
SessionId(sessionData.userId)
@@ -246,11 +258,13 @@ class RustMatrixAuthenticationService @Inject constructor(
246258
}
247259
Timber.e(throwable, "Failed to login with QR code")
248260
}
249-
}
261+
}
250262

251-
private fun getBaseClientBuilder() = rustMatrixClientFactory
263+
private fun getBaseClientBuilder(
264+
sessionPath: File,
265+
) = rustMatrixClientFactory
252266
.getBaseClientBuilder(
253-
sessionPath = sessionPath,
267+
sessionPath = sessionPath.absolutePath,
254268
passphrase = pendingPassphrase,
255269
slidingSyncProxy = AuthenticationConfig.SLIDING_SYNC_PROXY_URL,
256270
slidingSync = ClientBuilderSlidingSync.Discovered,

0 commit comments

Comments
 (0)