Skip to content

Commit 0b4b63a

Browse files
authored
Merge pull request #5371 from element-hq/feature/bma/cleanMatrixAuthenticationService
Clean MatrixAuthenticationService and SessionStore API
2 parents 95ce404 + 92b8be9 commit 0b4b63a

File tree

15 files changed

+70
-67
lines changed

15 files changed

+70
-67
lines changed

appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -46,13 +46,13 @@ import io.element.android.libraries.architecture.waitForChildAttached
4646
import io.element.android.libraries.core.uri.ensureProtocol
4747
import io.element.android.libraries.deeplink.api.DeeplinkData
4848
import io.element.android.libraries.designsystem.theme.components.CircularProgressIndicator
49-
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
5049
import io.element.android.libraries.matrix.api.core.SessionId
5150
import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias
5251
import io.element.android.libraries.matrix.api.permalink.PermalinkData
5352
import io.element.android.libraries.oidc.api.OidcAction
5453
import io.element.android.libraries.oidc.api.OidcActionFlow
5554
import io.element.android.libraries.sessionstorage.api.LoggedInState
55+
import io.element.android.libraries.sessionstorage.api.SessionStore
5656
import kotlinx.coroutines.flow.distinctUntilChanged
5757
import kotlinx.coroutines.flow.launchIn
5858
import kotlinx.coroutines.flow.onEach
@@ -64,7 +64,7 @@ import timber.log.Timber
6464
class RootFlowNode(
6565
@Assisted val buildContext: BuildContext,
6666
@Assisted plugins: List<Plugin>,
67-
private val authenticationService: MatrixAuthenticationService,
67+
private val sessionStore: SessionStore,
6868
private val accountProviderAccessControl: AccountProviderAccessControl,
6969
private val navStateFlowFactory: RootNavStateFlowFactory,
7070
private val matrixSessionCache: MatrixSessionCache,
@@ -152,7 +152,7 @@ class RootFlowNode(
152152
onSuccess: (SessionId) -> Unit,
153153
onFailure: () -> Unit
154154
) {
155-
val latestSessionId = authenticationService.getLatestSessionId()
155+
val latestSessionId = sessionStore.getLatestSessionId()
156156
if (latestSessionId == null) {
157157
onFailure()
158158
return
@@ -268,7 +268,7 @@ class RootFlowNode(
268268

269269
private suspend fun onLoginLink(params: LoginParams) {
270270
// Is there a session already?
271-
val latestSessionId = authenticationService.getLatestSessionId()
271+
val latestSessionId = sessionStore.getLatestSessionId()
272272
if (latestSessionId == null) {
273273
// No session, open login
274274
if (accountProviderAccessControl.isAllowedToConnectToAccountProvider(params.accountProvider.ensureProtocol())) {
@@ -285,7 +285,7 @@ class RootFlowNode(
285285

286286
private suspend fun onIncomingShare(intent: Intent) {
287287
// Is there a session already?
288-
val latestSessionId = authenticationService.getLatestSessionId()
288+
val latestSessionId = sessionStore.getLatestSessionId()
289289
if (latestSessionId == null) {
290290
// No session, open login
291291
switchToNotLoggedInFlow(null)
@@ -342,3 +342,5 @@ class RootFlowNode(
342342
.attachSession()
343343
}
344344
}
345+
346+
private suspend fun SessionStore.getLatestSessionId() = getLatestSession()?.userId?.let(::SessionId)

appnav/src/main/kotlin/io/element/android/appnav/root/RootNavStateFlowFactory.kt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,9 +12,9 @@ import com.bumble.appyx.core.state.SavedStateMap
1212
import dev.zacsweers.metro.Inject
1313
import io.element.android.appnav.di.MatrixSessionCache
1414
import io.element.android.features.preferences.api.CacheService
15-
import io.element.android.libraries.matrix.api.auth.MatrixAuthenticationService
1615
import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder
1716
import io.element.android.libraries.preferences.api.store.SessionPreferencesStoreFactory
17+
import io.element.android.libraries.sessionstorage.api.SessionStore
1818
import kotlinx.coroutines.flow.Flow
1919
import kotlinx.coroutines.flow.combine
2020
import kotlinx.coroutines.flow.flow
@@ -28,7 +28,7 @@ private const val SAVE_INSTANCE_KEY = "io.element.android.x.RootNavStateFlowFact
2828
*/
2929
@Inject
3030
class RootNavStateFlowFactory(
31-
private val authenticationService: MatrixAuthenticationService,
31+
private val sessionStore: SessionStore,
3232
private val cacheService: CacheService,
3333
private val matrixSessionCache: MatrixSessionCache,
3434
private val imageLoaderHolder: ImageLoaderHolder,
@@ -39,7 +39,7 @@ class RootNavStateFlowFactory(
3939
fun create(savedStateMap: SavedStateMap?): Flow<RootNavState> {
4040
return combine(
4141
cacheIndexFlow(savedStateMap),
42-
authenticationService.loggedInStateFlow(),
42+
sessionStore.loggedInStateFlow(),
4343
) { cacheIndex, loggedInState ->
4444
RootNavState(
4545
cacheIndex = cacheIndex,

libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/MatrixAuthenticationService.kt

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,9 @@ import io.element.android.libraries.matrix.api.auth.external.ExternalSession
1313
import io.element.android.libraries.matrix.api.auth.qrlogin.MatrixQrCodeLoginData
1414
import io.element.android.libraries.matrix.api.auth.qrlogin.QrCodeLoginStep
1515
import io.element.android.libraries.matrix.api.core.SessionId
16-
import io.element.android.libraries.sessionstorage.api.LoggedInState
17-
import kotlinx.coroutines.flow.Flow
1816
import kotlinx.coroutines.flow.StateFlow
1917

2018
interface MatrixAuthenticationService {
21-
fun loggedInStateFlow(): Flow<LoggedInState>
22-
suspend fun getLatestSessionId(): SessionId?
23-
2419
/**
2520
* Restore a session from a [sessionId].
2621
* Do not restore anything it the access token is not valid anymore.

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

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,11 +33,9 @@ import io.element.android.libraries.matrix.impl.keys.PassphraseGenerator
3333
import io.element.android.libraries.matrix.impl.mapper.toSessionData
3434
import io.element.android.libraries.matrix.impl.paths.SessionPaths
3535
import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory
36-
import io.element.android.libraries.sessionstorage.api.LoggedInState
3736
import io.element.android.libraries.sessionstorage.api.LoginType
3837
import io.element.android.libraries.sessionstorage.api.SessionStore
3938
import kotlinx.coroutines.CancellationException
40-
import kotlinx.coroutines.flow.Flow
4139
import kotlinx.coroutines.flow.MutableStateFlow
4240
import kotlinx.coroutines.flow.StateFlow
4341
import kotlinx.coroutines.withContext
@@ -83,14 +81,6 @@ class RustMatrixAuthenticationService(
8381
.also { sessionPaths = it }
8482
}
8583

86-
override fun loggedInStateFlow(): Flow<LoggedInState> {
87-
return sessionStore.isLoggedIn()
88-
}
89-
90-
override suspend fun getLatestSessionId(): SessionId? = withContext(coroutineDispatchers.io) {
91-
sessionStore.getLatestSession()?.userId?.let { SessionId(it) }
92-
}
93-
9484
override suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient> = withContext(coroutineDispatchers.io) {
9585
runCatchingExceptions {
9686
val sessionData = sessionStore.getSession(sessionId.value)
@@ -158,7 +148,7 @@ class RustMatrixAuthenticationService(
158148
)
159149
val matrixClient = rustMatrixClientFactory.create(client)
160150
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
161-
sessionStore.storeData(sessionData)
151+
sessionStore.addSession(sessionData)
162152

163153
// Clean up the strong reference held here since it's no longer necessary
164154
currentClient = null
@@ -182,7 +172,7 @@ class RustMatrixAuthenticationService(
182172
sessionPaths = currentSessionPaths,
183173
)
184174
clear()
185-
sessionStore.storeData(sessionData)
175+
sessionStore.addSession(sessionData)
186176
SessionId(sessionData.userId)
187177
}
188178
}
@@ -250,7 +240,7 @@ class RustMatrixAuthenticationService(
250240

251241
val matrixClient = rustMatrixClientFactory.create(client)
252242
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
253-
sessionStore.storeData(sessionData)
243+
sessionStore.addSession(sessionData)
254244

255245
// Clean up the strong reference held here since it's no longer necessary
256246
currentClient = null
@@ -295,7 +285,7 @@ class RustMatrixAuthenticationService(
295285
)
296286
val matrixClient = rustMatrixClientFactory.create(client)
297287
newMatrixClientObservers.forEach { it.invoke(matrixClient) }
298-
sessionStore.storeData(sessionData)
288+
sessionStore.addSession(sessionData)
299289

300290
// Clean up the strong reference held here since it's no longer necessary
301291
currentClient = null

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/FakeClientBuilderProvider.kt

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ package io.element.android.libraries.matrix.impl
1010
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClientBuilder
1111
import org.matrix.rustcomponents.sdk.ClientBuilder
1212

13-
class FakeClientBuilderProvider : ClientBuilderProvider {
13+
class FakeClientBuilderProvider(
14+
private val provideResult: () -> ClientBuilder = { FakeFfiClientBuilder() }
15+
) : ClientBuilderProvider {
1416
override fun provide(): ClientBuilder {
15-
return FakeFfiClientBuilder()
17+
return provideResult()
1618
}
1719
}

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/RustMatrixClientFactoryTest.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ fun TestScope.createRustMatrixClientFactory(
3939
baseDirectory: File = File("/base"),
4040
cacheDirectory: File = File("/cache"),
4141
sessionStore: SessionStore = InMemorySessionStore(),
42+
clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(),
4243
) = RustMatrixClientFactory(
4344
baseDirectory = baseDirectory,
4445
cacheDirectory = cacheDirectory,
@@ -52,5 +53,5 @@ fun TestScope.createRustMatrixClientFactory(
5253
analyticsService = FakeAnalyticsService(),
5354
featureFlagService = FakeFeatureFlagService(),
5455
timelineEventTypeFilterFactory = FakeTimelineEventTypeFilterFactory(),
55-
clientBuilderProvider = FakeClientBuilderProvider(),
56+
clientBuilderProvider = clientBuilderProvider,
5657
)

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/auth/RustMatrixAuthenticationServiceTest.kt

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,17 @@
88
package io.element.android.libraries.matrix.impl.auth
99

1010
import com.google.common.truth.Truth.assertThat
11-
import io.element.android.libraries.matrix.api.core.SessionId
11+
import io.element.android.libraries.matrix.impl.ClientBuilderProvider
12+
import io.element.android.libraries.matrix.impl.FakeClientBuilderProvider
1213
import io.element.android.libraries.matrix.impl.createRustMatrixClientFactory
14+
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClient
15+
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiClientBuilder
16+
import io.element.android.libraries.matrix.impl.fixtures.fakes.FakeFfiHomeserverLoginDetails
1317
import io.element.android.libraries.matrix.impl.paths.SessionPathsFactory
1418
import io.element.android.libraries.matrix.test.auth.FakeOidcRedirectUrlProvider
1519
import io.element.android.libraries.matrix.test.core.aBuildMeta
1620
import io.element.android.libraries.sessionstorage.api.SessionStore
1721
import io.element.android.libraries.sessionstorage.test.InMemorySessionStore
18-
import io.element.android.libraries.sessionstorage.test.aSessionData
1922
import io.element.android.tests.testutils.testCoroutineDispatchers
2023
import kotlinx.coroutines.test.TestScope
2124
import kotlinx.coroutines.test.runTest
@@ -24,25 +27,36 @@ import java.io.File
2427

2528
class RustMatrixAuthenticationServiceTest {
2629
@Test
27-
fun `getLatestSessionId should return the value from the store`() = runTest {
28-
val sessionStore = InMemorySessionStore()
30+
fun `setHomeserver is successful`() = runTest {
2931
val sut = createRustMatrixAuthenticationService(
30-
sessionStore = sessionStore,
32+
clientBuilderProvider = FakeClientBuilderProvider(
33+
provideResult = {
34+
FakeFfiClientBuilder(
35+
buildResult = {
36+
FakeFfiClient(
37+
homeserverLoginDetailsResult = {
38+
FakeFfiHomeserverLoginDetails()
39+
}
40+
)
41+
}
42+
)
43+
}
44+
),
3145
)
32-
assertThat(sut.getLatestSessionId()).isNull()
33-
sessionStore.storeData(aSessionData(sessionId = "@alice:server.org"))
34-
assertThat(sut.getLatestSessionId()).isEqualTo(SessionId("@alice:server.org"))
46+
assertThat(sut.setHomeserver("matrix.org").isSuccess).isTrue()
3547
}
3648

3749
private fun TestScope.createRustMatrixAuthenticationService(
3850
sessionStore: SessionStore = InMemorySessionStore(),
51+
clientBuilderProvider: ClientBuilderProvider = FakeClientBuilderProvider(),
3952
): RustMatrixAuthenticationService {
4053
val baseDirectory = File("/base")
4154
val cacheDirectory = File("/cache")
4255
val rustMatrixClientFactory = createRustMatrixClientFactory(
4356
baseDirectory = baseDirectory,
4457
cacheDirectory = cacheDirectory,
4558
sessionStore = sessionStore,
59+
clientBuilderProvider = clientBuilderProvider,
4660
)
4761
return RustMatrixAuthenticationService(
4862
sessionPathsFactory = SessionPathsFactory(baseDirectory, cacheDirectory),

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClient.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@ import io.element.android.tests.testutils.simulateLongTask
1515
import org.matrix.rustcomponents.sdk.Client
1616
import org.matrix.rustcomponents.sdk.ClientDelegate
1717
import org.matrix.rustcomponents.sdk.Encryption
18+
import org.matrix.rustcomponents.sdk.HomeserverLoginDetails
1819
import org.matrix.rustcomponents.sdk.IgnoredUsersListener
1920
import org.matrix.rustcomponents.sdk.NoPointer
2021
import org.matrix.rustcomponents.sdk.NotificationClient
@@ -41,6 +42,7 @@ class FakeFfiClient(
4142
private val session: Session = aRustSession(),
4243
private val clearCachesResult: () -> Unit = { lambdaError() },
4344
private val withUtdHook: (UnableToDecryptDelegate) -> Unit = { lambdaError() },
45+
private val homeserverLoginDetailsResult: () -> HomeserverLoginDetails = { lambdaError() },
4446
private val closeResult: () -> Unit = {},
4547
) : Client(NoPointer) {
4648
override fun userId(): String = userId
@@ -71,12 +73,18 @@ class FakeFfiClient(
7173
override suspend fun ignoredUsers(): List<String> {
7274
return emptyList()
7375
}
76+
7477
override fun subscribeToIgnoredUsers(listener: IgnoredUsersListener): TaskHandle {
7578
return FakeFfiTaskHandle()
7679
}
7780

7881
override suspend fun getProfile(userId: String): UserProfile {
7982
return UserProfile(userId = userId, displayName = null, avatarUrl = null)
8083
}
84+
85+
override suspend fun homeserverLoginDetails(): HomeserverLoginDetails {
86+
return homeserverLoginDetailsResult()
87+
}
88+
8189
override fun close() = closeResult()
8290
}

libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/fakes/FakeFfiClientBuilder.kt

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@ import uniffi.matrix_sdk.BackupDownloadStrategy
1717
import uniffi.matrix_sdk_crypto.CollectStrategy
1818
import uniffi.matrix_sdk_crypto.DecryptionSettings
1919

20-
class FakeFfiClientBuilder : ClientBuilder(NoPointer) {
20+
class FakeFfiClientBuilder(
21+
val buildResult: () -> Client = { FakeFfiClient(withUtdHook = {}) }
22+
) : ClientBuilder(NoPointer) {
2123
override fun addRootCertificates(certificates: List<ByteArray>) = this
2224
override fun autoEnableBackups(autoEnableBackups: Boolean) = this
2325
override fun autoEnableCrossSigning(autoEnableCrossSigning: Boolean) = this
@@ -41,7 +43,5 @@ class FakeFfiClientBuilder : ClientBuilder(NoPointer) {
4143
override fun enableShareHistoryOnInvite(enableShareHistoryOnInvite: Boolean): ClientBuilder = this
4244
override fun threadsEnabled(enabled: Boolean, threadSubscriptions: Boolean): ClientBuilder = this
4345

44-
override suspend fun build(): Client {
45-
return FakeFfiClient(withUtdHook = {})
46-
}
46+
override suspend fun build() = buildResult()
4747
}

libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/auth/FakeMatrixAuthenticationService.kt

Lines changed: 0 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -19,14 +19,11 @@ import io.element.android.libraries.matrix.api.core.SessionId
1919
import io.element.android.libraries.matrix.test.A_SESSION_ID
2020
import io.element.android.libraries.matrix.test.A_USER_ID
2121
import io.element.android.libraries.matrix.test.FakeMatrixClient
22-
import io.element.android.libraries.sessionstorage.api.LoggedInState
2322
import io.element.android.tests.testutils.lambda.lambdaError
2423
import io.element.android.tests.testutils.lambda.lambdaRecorder
2524
import io.element.android.tests.testutils.simulateLongTask
26-
import kotlinx.coroutines.flow.Flow
2725
import kotlinx.coroutines.flow.MutableStateFlow
2826
import kotlinx.coroutines.flow.StateFlow
29-
import kotlinx.coroutines.flow.flowOf
3027

3128
val A_OIDC_DATA = OidcDetails(url = "a-url")
3229

@@ -44,14 +41,6 @@ class FakeMatrixAuthenticationService(
4441
private var matrixClient: MatrixClient? = null
4542
private var onAuthenticationListener: ((MatrixClient) -> Unit)? = null
4643

47-
var getLatestSessionIdLambda: (() -> SessionId?) = { null }
48-
49-
override fun loggedInStateFlow(): Flow<LoggedInState> {
50-
return flowOf(LoggedInState.NotLoggedIn)
51-
}
52-
53-
override suspend fun getLatestSessionId(): SessionId? = getLatestSessionIdLambda()
54-
5544
override suspend fun restoreSession(sessionId: SessionId): Result<MatrixClient> {
5645
matrixClientResult?.let {
5746
return it.invoke(sessionId)

0 commit comments

Comments
 (0)