feat(matrix): add SecretStorage API and implementation
Adds SecretStorage interface and RustSecretStorage implementation for accessing Matrix SSSS (Secure Secret Storage and Sharing). This enables storing and retrieving encrypted secrets using the user's recovery key. Also fixes SDK compatibility issues: - Remove deprecated Sentry configuration from TracingService - Make analytics SDK enableSentryLogging a no-op Requires updated Rust SDK with SecretStoreWrapper FFI.
This commit is contained in:
parent
f56f124a39
commit
86d6686aee
6 changed files with 122 additions and 17 deletions
|
|
@ -49,6 +49,7 @@ import io.element.android.libraries.matrix.api.sync.SyncState
|
|||
import io.element.android.libraries.matrix.api.user.MatrixSearchUserResults
|
||||
import io.element.android.libraries.matrix.api.user.MatrixUser
|
||||
import io.element.android.libraries.matrix.impl.encryption.RustEncryptionService
|
||||
import io.element.android.libraries.matrix.impl.secretstorage.RustSecretStorage
|
||||
import io.element.android.libraries.matrix.impl.exception.mapClientException
|
||||
import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkDesktopHandler
|
||||
import io.element.android.libraries.matrix.impl.linknewdevice.RustLinkMobileHandler
|
||||
|
|
@ -178,6 +179,8 @@ class RustMatrixClient(
|
|||
dispatchers = dispatchers,
|
||||
)
|
||||
|
||||
override val secretStorage = RustSecretStorage(innerClient, dispatchers)
|
||||
|
||||
override val roomDirectoryService = RustRoomDirectoryService(
|
||||
client = innerClient,
|
||||
sessionDispatcher = sessionDispatcher,
|
||||
|
|
|
|||
|
|
@ -11,12 +11,12 @@ import dev.zacsweers.metro.AppScope
|
|||
import dev.zacsweers.metro.ContributesBinding
|
||||
import io.element.android.services.analytics.api.AnalyticsSdkManager
|
||||
import io.element.android.services.analytics.api.AnalyticsSdkSpan
|
||||
import org.matrix.rustcomponents.sdk.enableSentryLogging
|
||||
|
||||
@ContributesBinding(AppScope::class)
|
||||
class RustAnalyticsSdkManager : AnalyticsSdkManager {
|
||||
override fun enableSdkAnalytics(enabled: Boolean) {
|
||||
enableSentryLogging(enabled)
|
||||
// Sentry logging was removed from the Rust SDK
|
||||
// This is now a no-op
|
||||
}
|
||||
|
||||
override fun startSpan(name: String, parentTraceId: String?): AnalyticsSdkSpan {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* Copyright (c) 2026 Sulkta Coop.
|
||||
*
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package io.element.android.libraries.matrix.impl.secretstorage
|
||||
|
||||
import io.element.android.libraries.core.coroutine.CoroutineDispatchers
|
||||
import io.element.android.libraries.matrix.api.secretstorage.SecretStorage
|
||||
import io.element.android.libraries.matrix.api.secretstorage.SecretStore
|
||||
import kotlinx.coroutines.withContext
|
||||
import org.matrix.rustcomponents.sdk.Client
|
||||
import org.matrix.rustcomponents.sdk.SecretStoreWrapper
|
||||
|
||||
/**
|
||||
* Implementation of [SecretStorage] backed by the Rust SDK.
|
||||
*/
|
||||
class RustSecretStorage(
|
||||
private val client: Client,
|
||||
private val dispatchers: CoroutineDispatchers,
|
||||
) : SecretStorage {
|
||||
|
||||
override suspend fun openSecretStore(recoveryKey: String): SecretStore? =
|
||||
withContext(dispatchers.io) {
|
||||
client.openSecretStore(recoveryKey)?.let { RustSecretStore(it, dispatchers) }
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Implementation of [SecretStore] backed by the Rust SDK SecretStoreWrapper.
|
||||
*/
|
||||
class RustSecretStore(
|
||||
private val inner: SecretStoreWrapper,
|
||||
private val dispatchers: CoroutineDispatchers,
|
||||
) : SecretStore {
|
||||
|
||||
override suspend fun putSecret(secretName: String, secret: String): Result<Unit> =
|
||||
withContext(dispatchers.io) {
|
||||
runCatching { inner.putSecret(secretName, secret) }
|
||||
}
|
||||
|
||||
override suspend fun getSecret(secretName: String): Result<String?> =
|
||||
withContext(dispatchers.io) {
|
||||
runCatching { inner.getSecret(secretName) }
|
||||
}
|
||||
|
||||
override fun exportRecoveryKey(): String = inner.exportRecoveryKey()
|
||||
}
|
||||
|
|
@ -17,7 +17,6 @@ import io.element.android.libraries.matrix.api.tracing.LogLevel
|
|||
import io.element.android.libraries.matrix.api.tracing.TracingConfiguration
|
||||
import io.element.android.libraries.matrix.api.tracing.TracingService
|
||||
import io.element.android.libraries.matrix.api.tracing.WriteToFilesConfiguration
|
||||
import org.matrix.rustcomponents.sdk.SentryConfig
|
||||
import org.matrix.rustcomponents.sdk.TracingFileConfiguration
|
||||
import org.matrix.rustcomponents.sdk.reloadTracingFileWriter
|
||||
import timber.log.Timber
|
||||
|
|
@ -60,17 +59,14 @@ private fun WriteToFilesConfiguration.toTracingFileConfiguration(): TracingFileC
|
|||
}
|
||||
}
|
||||
|
||||
fun TracingConfiguration.map(buildMeta: BuildMeta): org.matrix.rustcomponents.sdk.TracingConfiguration = org.matrix.rustcomponents.sdk.TracingConfiguration(
|
||||
writeToStdoutOrSystem = writesToLogcat,
|
||||
logLevel = logLevel.toRustLogLevel(),
|
||||
extraTargets = extraTargets,
|
||||
traceLogPacks = traceLogPacks.map(),
|
||||
writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(),
|
||||
sentryConfig = sdkSentryDsn?.let {
|
||||
SentryConfig(
|
||||
dsn = it,
|
||||
appVersion = buildMeta.versionName,
|
||||
appPlatform = "Android",
|
||||
)
|
||||
}
|
||||
)
|
||||
@Suppress("UNUSED_PARAMETER")
|
||||
fun TracingConfiguration.map(buildMeta: BuildMeta): org.matrix.rustcomponents.sdk.TracingConfiguration {
|
||||
// Note: sdkSentryDsn is no longer supported by the Rust SDK
|
||||
return org.matrix.rustcomponents.sdk.TracingConfiguration(
|
||||
writeToStdoutOrSystem = writesToLogcat,
|
||||
logLevel = logLevel.toRustLogLevel(),
|
||||
extraTargets = extraTargets,
|
||||
traceLogPacks = traceLogPacks.map(),
|
||||
writeToFiles = writesToFilesConfiguration.toTracingFileConfiguration(),
|
||||
)
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue