post rebase fix
This commit is contained in:
parent
49054d8a15
commit
98841bbe3d
|
@ -27,20 +27,20 @@ import org.junit.After
|
||||||
import org.junit.Assert.assertNotNull
|
import org.junit.Assert.assertNotNull
|
||||||
import org.junit.Assert.assertTrue
|
import org.junit.Assert.assertTrue
|
||||||
import org.junit.Before
|
import org.junit.Before
|
||||||
import org.junit.Ignore
|
|
||||||
import org.junit.Rule
|
import org.junit.Rule
|
||||||
import org.junit.Test
|
import org.junit.Test
|
||||||
import org.junit.runner.RunWith
|
import org.junit.runner.RunWith
|
||||||
import org.matrix.android.sdk.InstrumentedTest
|
|
||||||
import org.matrix.android.sdk.TestBuildVersionSdkIntProvider
|
import org.matrix.android.sdk.TestBuildVersionSdkIntProvider
|
||||||
import org.matrix.android.sdk.api.securestorage.SecretStoringUtils
|
import org.matrix.android.sdk.api.securestorage.SecretStoringUtils
|
||||||
import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration
|
import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
|
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
|
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
|
||||||
|
import org.matrix.android.sdk.internal.crypto.store.db.RustMigrationInfoProvider
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
||||||
import org.matrix.android.sdk.internal.database.RealmKeysUtils
|
import org.matrix.android.sdk.internal.database.RealmKeysUtils
|
||||||
import org.matrix.android.sdk.internal.database.TestRealmConfigurationFactory
|
import org.matrix.android.sdk.internal.database.TestRealmConfigurationFactory
|
||||||
import org.matrix.android.sdk.internal.util.time.Clock
|
import org.matrix.android.sdk.internal.util.time.Clock
|
||||||
|
import org.matrix.android.sdk.test.shared.createTimberTestRule
|
||||||
import org.matrix.olm.OlmAccount
|
import org.matrix.olm.OlmAccount
|
||||||
import org.matrix.olm.OlmManager
|
import org.matrix.olm.OlmManager
|
||||||
import org.matrix.rustcomponents.sdk.crypto.OlmMachine
|
import org.matrix.rustcomponents.sdk.crypto.OlmMachine
|
||||||
|
@ -48,10 +48,13 @@ import java.io.File
|
||||||
import java.security.KeyStore
|
import java.security.KeyStore
|
||||||
|
|
||||||
@RunWith(AndroidJUnit4::class)
|
@RunWith(AndroidJUnit4::class)
|
||||||
class DynamicElementAndroidToElementRMigrationTest : InstrumentedTest {
|
class DynamicElementAndroidToElementRMigrationTest {
|
||||||
|
|
||||||
@get:Rule val configurationFactory = TestRealmConfigurationFactory()
|
@get:Rule val configurationFactory = TestRealmConfigurationFactory()
|
||||||
|
|
||||||
|
@Rule
|
||||||
|
fun timberTestRule() = createTimberTestRule()
|
||||||
|
|
||||||
var context: Context = InstrumentationRegistry.getInstrumentation().context
|
var context: Context = InstrumentationRegistry.getInstrumentation().context
|
||||||
var realm: Realm? = null
|
var realm: Realm? = null
|
||||||
|
|
||||||
|
@ -81,25 +84,26 @@ class DynamicElementAndroidToElementRMigrationTest : InstrumentedTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
<<<<<<< feature/bma/crypto_rust_default:matrix-sdk-android/src/androidTestRustCrypto/java/org/matrix/android/sdk/internal/crypto/store/migration/ElementAndroidToElementRMigrationTest.kt
|
|
||||||
fun given_a_valid_crypto_store_realm_file_then_migration_should_be_successful() {
|
fun given_a_valid_crypto_store_realm_file_then_migration_should_be_successful() {
|
||||||
testMigrate(false)
|
testMigrate(false)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore("We don't migrate group session for now, and it makes test suite unstable")
|
|
||||||
fun given_a_valid_crypto_store_realm_file_no_lazy_then_migration_should_be_successful() {
|
fun given_a_valid_crypto_store_realm_file_no_lazy_then_migration_should_be_successful() {
|
||||||
testMigrate(true)
|
testMigrate(true)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun testMigrate(migrateGroupSessions: Boolean) {
|
private fun testMigrate(migrateGroupSessions: Boolean) {
|
||||||
=======
|
|
||||||
fun dynamic_migration_to_rust() {
|
|
||||||
val targetFile = File(configurationFactory.root, "rust-sdk")
|
val targetFile = File(configurationFactory.root, "rust-sdk")
|
||||||
|
|
||||||
>>>>>>> create rust db as a realm migration:matrix-sdk-android/src/androidTestRustCrypto/java/org/matrix/android/sdk/internal/crypto/store/migration/DynamicElementAndroidToElementRMigrationTest.kt
|
|
||||||
val realmName = "crypto_store_migration_16.realm"
|
val realmName = "crypto_store_migration_16.realm"
|
||||||
val migration = RealmCryptoStoreMigration(fakeClock, rustEncryptionConfiguration, targetFile)
|
val infoProvider = RustMigrationInfoProvider(
|
||||||
|
targetFile,
|
||||||
|
rustEncryptionConfiguration
|
||||||
|
).apply {
|
||||||
|
migrateMegolmGroupSessions = migrateGroupSessions
|
||||||
|
}
|
||||||
|
val migration = RealmCryptoStoreMigration(fakeClock, infoProvider)
|
||||||
|
|
||||||
val realmConfiguration = configurationFactory.createConfiguration(
|
val realmConfiguration = configurationFactory.createConfiguration(
|
||||||
realmName,
|
realmName,
|
||||||
|
@ -116,17 +120,7 @@ class DynamicElementAndroidToElementRMigrationTest : InstrumentedTest {
|
||||||
val deviceId = metaData.deviceId!!
|
val deviceId = metaData.deviceId!!
|
||||||
val olmAccount = metaData.getOlmAccount()!!
|
val olmAccount = metaData.getOlmAccount()!!
|
||||||
|
|
||||||
<<<<<<< feature/bma/crypto_rust_default:matrix-sdk-android/src/androidTestRustCrypto/java/org/matrix/android/sdk/internal/crypto/store/migration/ElementAndroidToElementRMigrationTest.kt
|
|
||||||
val extractor = MigrateEAtoEROperation(migrateGroupSessions)
|
|
||||||
|
|
||||||
val targetFile = File(configurationFactory.root, "rust-sdk")
|
|
||||||
|
|
||||||
extractor.execute(realmConfiguration, targetFile, null)
|
|
||||||
|
|
||||||
val machine = OlmMachine(userId, deviceId, targetFile.path, null)
|
|
||||||
=======
|
|
||||||
val machine = OlmMachine(userId, deviceId, targetFile.path, rustEncryptionConfiguration.getDatabasePassphrase())
|
val machine = OlmMachine(userId, deviceId, targetFile.path, rustEncryptionConfiguration.getDatabasePassphrase())
|
||||||
>>>>>>> create rust db as a realm migration:matrix-sdk-android/src/androidTestRustCrypto/java/org/matrix/android/sdk/internal/crypto/store/migration/DynamicElementAndroidToElementRMigrationTest.kt
|
|
||||||
|
|
||||||
assertEquals(olmAccount.identityKeys()[OlmAccount.JSON_KEY_FINGER_PRINT_KEY], machine.identityKeys()["ed25519"])
|
assertEquals(olmAccount.identityKeys()[OlmAccount.JSON_KEY_FINGER_PRINT_KEY], machine.identityKeys()["ed25519"])
|
||||||
assertNotNull(machine.getBackupKeys())
|
assertNotNull(machine.getBackupKeys())
|
||||||
|
@ -135,20 +129,12 @@ class DynamicElementAndroidToElementRMigrationTest : InstrumentedTest {
|
||||||
assertTrue(crossSigningStatus.hasSelfSigning)
|
assertTrue(crossSigningStatus.hasSelfSigning)
|
||||||
assertTrue(crossSigningStatus.hasUserSigning)
|
assertTrue(crossSigningStatus.hasUserSigning)
|
||||||
|
|
||||||
<<<<<<< feature/bma/crypto_rust_default:matrix-sdk-android/src/androidTestRustCrypto/java/org/matrix/android/sdk/internal/crypto/store/migration/ElementAndroidToElementRMigrationTest.kt
|
|
||||||
if (migrateGroupSessions) {
|
if (migrateGroupSessions) {
|
||||||
val inboundGroupSessionEntities = realm!!.where<OlmInboundGroupSessionEntity>().findAll()
|
assertTrue("Some outbound sessions should be migrated", machine.roomKeyCounts().total.toInt() > 0)
|
||||||
assertEquals(inboundGroupSessionEntities.size, machine.roomKeyCounts().total.toInt())
|
assertTrue("There are some backed-up sessions", machine.roomKeyCounts().backedUp.toInt() > 0)
|
||||||
|
} else {
|
||||||
val backedUpInboundGroupSessionEntities = realm!!
|
assertTrue(machine.roomKeyCounts().total.toInt() == 0)
|
||||||
.where<OlmInboundGroupSessionEntity>()
|
assertTrue(machine.roomKeyCounts().backedUp.toInt() == 0)
|
||||||
.equalTo(OlmInboundGroupSessionEntityFields.BACKED_UP, true)
|
|
||||||
.findAll()
|
|
||||||
assertEquals(backedUpInboundGroupSessionEntities.size, machine.roomKeyCounts().backedUp.toInt())
|
|
||||||
}
|
}
|
||||||
=======
|
|
||||||
// How to check that olm sessions have been migrated?
|
|
||||||
// Can see it from logs
|
|
||||||
>>>>>>> create rust db as a realm migration:matrix-sdk-android/src/androidTestRustCrypto/java/org/matrix/android/sdk/internal/crypto/store/migration/DynamicElementAndroidToElementRMigrationTest.kt
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,6 +29,7 @@ import org.matrix.android.sdk.api.securestorage.SecretStoringUtils
|
||||||
import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration
|
import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
|
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreMigration
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
|
import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStoreModule
|
||||||
|
import org.matrix.android.sdk.internal.crypto.store.db.RustMigrationInfoProvider
|
||||||
import org.matrix.android.sdk.internal.util.time.Clock
|
import org.matrix.android.sdk.internal.util.time.Clock
|
||||||
import org.matrix.olm.OlmManager
|
import org.matrix.olm.OlmManager
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
@ -58,12 +59,8 @@ class CryptoSanityMigrationTest {
|
||||||
fun cryptoDatabaseShouldMigrateGracefully() {
|
fun cryptoDatabaseShouldMigrateGracefully() {
|
||||||
val realmName = "crypto_store_20.realm"
|
val realmName = "crypto_store_20.realm"
|
||||||
|
|
||||||
val migration = RealmCryptoStoreMigration(
|
val rustMigrationInfo = RustMigrationInfoProvider(
|
||||||
object : Clock {
|
File(configurationFactory.root, "test_rust"),
|
||||||
override fun epochMillis(): Long {
|
|
||||||
return 0L
|
|
||||||
}
|
|
||||||
},
|
|
||||||
RustEncryptionConfiguration(
|
RustEncryptionConfiguration(
|
||||||
"foo",
|
"foo",
|
||||||
RealmKeysUtils(
|
RealmKeysUtils(
|
||||||
|
@ -71,7 +68,14 @@ class CryptoSanityMigrationTest {
|
||||||
SecretStoringUtils(context, keyStore, TestBuildVersionSdkIntProvider(), false)
|
SecretStoringUtils(context, keyStore, TestBuildVersionSdkIntProvider(), false)
|
||||||
)
|
)
|
||||||
),
|
),
|
||||||
File(configurationFactory.root, "rust-sdk")
|
)
|
||||||
|
val migration = RealmCryptoStoreMigration(
|
||||||
|
object : Clock {
|
||||||
|
override fun epochMillis(): Long {
|
||||||
|
return 0L
|
||||||
|
}
|
||||||
|
},
|
||||||
|
rustMigrationInfo
|
||||||
)
|
)
|
||||||
|
|
||||||
val realmConfiguration = configurationFactory.createConfiguration(
|
val realmConfiguration = configurationFactory.createConfiguration(
|
||||||
|
|
|
@ -17,7 +17,6 @@
|
||||||
package org.matrix.android.sdk.internal.crypto.store.db
|
package org.matrix.android.sdk.internal.crypto.store.db
|
||||||
|
|
||||||
import io.realm.DynamicRealm
|
import io.realm.DynamicRealm
|
||||||
import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo001Legacy
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo001Legacy
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo002Legacy
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo002Legacy
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo003RiotX
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo003RiotX
|
||||||
|
@ -40,10 +39,8 @@ import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo020
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo020
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo021
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo021
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo022
|
import org.matrix.android.sdk.internal.crypto.store.db.migration.MigrateCryptoTo022
|
||||||
import org.matrix.android.sdk.internal.di.SessionRustFilesDirectory
|
|
||||||
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
|
import org.matrix.android.sdk.internal.util.database.MatrixRealmMigration
|
||||||
import org.matrix.android.sdk.internal.util.time.Clock
|
import org.matrix.android.sdk.internal.util.time.Clock
|
||||||
import java.io.File
|
|
||||||
import javax.inject.Inject
|
import javax.inject.Inject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -54,9 +51,7 @@ import javax.inject.Inject
|
||||||
*/
|
*/
|
||||||
internal class RealmCryptoStoreMigration @Inject constructor(
|
internal class RealmCryptoStoreMigration @Inject constructor(
|
||||||
private val clock: Clock,
|
private val clock: Clock,
|
||||||
private val rustEncryptionConfiguration: RustEncryptionConfiguration,
|
private val rustMigrationInfoProvider: RustMigrationInfoProvider,
|
||||||
@SessionRustFilesDirectory
|
|
||||||
private val rustDirectory: File,
|
|
||||||
) : MatrixRealmMigration(
|
) : MatrixRealmMigration(
|
||||||
dbName = "Crypto",
|
dbName = "Crypto",
|
||||||
schemaVersion = 22L,
|
schemaVersion = 22L,
|
||||||
|
@ -90,6 +85,11 @@ internal class RealmCryptoStoreMigration @Inject constructor(
|
||||||
if (oldVersion < 19) MigrateCryptoTo019(realm).perform()
|
if (oldVersion < 19) MigrateCryptoTo019(realm).perform()
|
||||||
if (oldVersion < 20) MigrateCryptoTo020(realm).perform()
|
if (oldVersion < 20) MigrateCryptoTo020(realm).perform()
|
||||||
if (oldVersion < 21) MigrateCryptoTo021(realm).perform()
|
if (oldVersion < 21) MigrateCryptoTo021(realm).perform()
|
||||||
if (oldVersion < 22) MigrateCryptoTo022(realm, rustDirectory, rustEncryptionConfiguration).perform()
|
if (oldVersion < 22) MigrateCryptoTo022(
|
||||||
|
realm,
|
||||||
|
rustMigrationInfoProvider.rustDirectory,
|
||||||
|
rustMigrationInfoProvider.rustEncryptionConfiguration,
|
||||||
|
rustMigrationInfoProvider.migrateMegolmGroupSessions
|
||||||
|
).perform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2023 The Matrix.org Foundation C.I.C.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.matrix.android.sdk.internal.crypto.store.db
|
||||||
|
|
||||||
|
import org.matrix.android.sdk.internal.crypto.RustEncryptionConfiguration
|
||||||
|
import org.matrix.android.sdk.internal.di.SessionRustFilesDirectory
|
||||||
|
import java.io.File
|
||||||
|
import javax.inject.Inject
|
||||||
|
|
||||||
|
internal class RustMigrationInfoProvider @Inject constructor(
|
||||||
|
@SessionRustFilesDirectory
|
||||||
|
val rustDirectory: File,
|
||||||
|
val rustEncryptionConfiguration: RustEncryptionConfiguration
|
||||||
|
) {
|
||||||
|
|
||||||
|
var migrateMegolmGroupSessions: Boolean = false
|
||||||
|
}
|
|
@ -28,14 +28,15 @@ import java.io.File
|
||||||
internal class MigrateCryptoTo022(
|
internal class MigrateCryptoTo022(
|
||||||
realm: DynamicRealm,
|
realm: DynamicRealm,
|
||||||
private val rustDirectory: File,
|
private val rustDirectory: File,
|
||||||
private val rustEncryptionConfiguration: RustEncryptionConfiguration
|
private val rustEncryptionConfiguration: RustEncryptionConfiguration,
|
||||||
|
private val migrateMegolmGroupSessions: Boolean = false
|
||||||
) : RealmMigrator(
|
) : RealmMigrator(
|
||||||
realm,
|
realm,
|
||||||
22
|
22
|
||||||
) {
|
) {
|
||||||
override fun doMigrate(realm: DynamicRealm) {
|
override fun doMigrate(realm: DynamicRealm) {
|
||||||
// Migrate to rust!
|
// Migrate to rust!
|
||||||
val migrateOperation = MigrateEAtoEROperation()
|
val migrateOperation = MigrateEAtoEROperation(migrateMegolmGroupSessions)
|
||||||
migrateOperation.dynamicExecute(realm, rustDirectory, rustEncryptionConfiguration.getDatabasePassphrase())
|
migrateOperation.dynamicExecute(realm, rustDirectory, rustEncryptionConfiguration.getDatabasePassphrase())
|
||||||
|
|
||||||
// wa can't delete all for now, but we can do some cleaning
|
// wa can't delete all for now, but we can do some cleaning
|
||||||
|
|
|
@ -16,4 +16,5 @@
|
||||||
|
|
||||||
package org.matrix.android.sdk.internal.crypto.store.db.migration.rust
|
package org.matrix.android.sdk.internal.crypto.store.db.migration.rust
|
||||||
|
|
||||||
object ExtractMigrationDataFailure : java.lang.RuntimeException("Can't proceed with migration, crypto store is empty or some necessary data is missing.")
|
data class ExtractMigrationDataFailure(override val cause: Throwable) :
|
||||||
|
java.lang.RuntimeException("Can't proceed with migration, crypto store is empty or some necessary data is missing.", cause)
|
||||||
|
|
|
@ -19,29 +19,19 @@ package org.matrix.android.sdk.internal.crypto.store.db.migration.rust
|
||||||
import io.realm.Realm
|
import io.realm.Realm
|
||||||
import io.realm.RealmConfiguration
|
import io.realm.RealmConfiguration
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
import org.matrix.android.sdk.api.extensions.orFalse
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity
|
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity
|
|
||||||
import org.matrix.olm.OlmSession
|
|
||||||
import org.matrix.olm.OlmUtility
|
import org.matrix.olm.OlmUtility
|
||||||
import org.matrix.rustcomponents.sdk.crypto.MigrationData
|
import org.matrix.rustcomponents.sdk.crypto.MigrationData
|
||||||
import org.matrix.rustcomponents.sdk.crypto.PickledInboundGroupSession
|
|
||||||
import org.matrix.rustcomponents.sdk.crypto.PickledSession
|
|
||||||
import timber.log.Timber
|
import timber.log.Timber
|
||||||
import java.nio.charset.Charset
|
|
||||||
import kotlin.system.measureTimeMillis
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
private val charset = Charset.forName("UTF-8")
|
internal class ExtractMigrationDataUseCase(private val migrateGroupSessions: Boolean = false) {
|
||||||
|
|
||||||
internal class ExtractMigrationDataUseCase(val migrateGroupSessions: Boolean = false) {
|
|
||||||
|
|
||||||
fun extractData(realm: RealmToMigrate, importPartial: ((MigrationData) -> Unit)) {
|
fun extractData(realm: RealmToMigrate, importPartial: ((MigrationData) -> Unit)) {
|
||||||
return try {
|
return try {
|
||||||
extract(realm, importPartial)
|
extract(realm, importPartial)
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
throw ExtractMigrationDataFailure
|
throw ExtractMigrationDataFailure(failure)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,75 +78,19 @@ internal class ExtractMigrationDataUseCase(val migrateGroupSessions: Boolean = f
|
||||||
// We are going to do it lazyly when decryption fails
|
// We are going to do it lazyly when decryption fails
|
||||||
if (migrateGroupSessions) {
|
if (migrateGroupSessions) {
|
||||||
var migratedInboundGroupSessionCount = 0
|
var migratedInboundGroupSessionCount = 0
|
||||||
readTime = 0
|
|
||||||
writeTime = 0
|
|
||||||
measureTimeMillis {
|
measureTimeMillis {
|
||||||
realm.where<OlmInboundGroupSessionEntity>()
|
realm.pickledOlmGroupSessions(pickleKey, chunkSize) { pickledSessions ->
|
||||||
.findAll()
|
migratedInboundGroupSessionCount += pickledSessions.size
|
||||||
.chunked(chunkSize) { chunk ->
|
measureTimeMillis {
|
||||||
val export: List<PickledInboundGroupSession>
|
importPartial(
|
||||||
measureTimeMillis {
|
baseExtract.copy(inboundGroupSessions = pickledSessions)
|
||||||
export = chunk.mapNotNull { it.toPickledInboundGroupSession(pickleKey) }
|
)
|
||||||
}.also {
|
}.also { writeTime += it }
|
||||||
readTime += it
|
}
|
||||||
}
|
|
||||||
migratedInboundGroupSessionCount += export.size
|
|
||||||
measureTimeMillis {
|
|
||||||
importPartial(
|
|
||||||
baseExtract.copy(inboundGroupSessions = export)
|
|
||||||
)
|
|
||||||
}.also {
|
|
||||||
writeTime += it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}.also {
|
}.also {
|
||||||
Timber.i("Migration: took $it ms to migrate $migratedInboundGroupSessionCount group sessions")
|
Timber.i("Migration: took $it ms to migrate $migratedInboundGroupSessionCount group sessions")
|
||||||
Timber.i("Migration: extract time $readTime")
|
|
||||||
Timber.i("Migration: rust import time $writeTime")
|
Timber.i("Migration: rust import time $writeTime")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// return baseExtract
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun OlmInboundGroupSessionEntity.toPickledInboundGroupSession(pickleKey: ByteArray): PickledInboundGroupSession? {
|
|
||||||
val senderKey = this.senderKey ?: return null
|
|
||||||
val backedUp = this.backedUp
|
|
||||||
val olmInboundGroupSession = this.getOlmGroupSession() ?: return null.also {
|
|
||||||
Timber.w("Rust db migration: Failed to migrated group session $sessionId")
|
|
||||||
}
|
|
||||||
val data = this.getData() ?: return null.also {
|
|
||||||
Timber.w("Rust db migration: Failed to migrated group session $sessionId, no meta data")
|
|
||||||
}
|
|
||||||
val roomId = data.roomId ?: return null.also {
|
|
||||||
Timber.w("Rust db migration: Failed to migrated group session $sessionId, no roomId")
|
|
||||||
}
|
|
||||||
val pickledInboundGroupSession = olmInboundGroupSession.pickle(pickleKey, StringBuffer()).asString()
|
|
||||||
return PickledInboundGroupSession(
|
|
||||||
pickle = pickledInboundGroupSession,
|
|
||||||
senderKey = senderKey,
|
|
||||||
signingKey = data.keysClaimed.orEmpty(),
|
|
||||||
roomId = roomId,
|
|
||||||
forwardingChains = data.forwardingCurve25519KeyChain.orEmpty(),
|
|
||||||
imported = data.trusted.orFalse().not(),
|
|
||||||
backedUp = backedUp
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun OlmSessionEntity.toPickledSession(pickleKey: ByteArray): PickledSession {
|
|
||||||
val deviceKey = this.deviceKey ?: ""
|
|
||||||
val lastReceivedMessageTs = this.lastReceivedMessageTs
|
|
||||||
val olmSessionStr = this.olmSessionData
|
|
||||||
val olmSession = deserializeFromRealm<OlmSession>(olmSessionStr)!!
|
|
||||||
val pickledOlmSession = olmSession.pickle(pickleKey, StringBuffer()).asString()
|
|
||||||
return PickledSession(
|
|
||||||
pickle = pickledOlmSession,
|
|
||||||
senderKey = deviceKey,
|
|
||||||
createdUsingFallbackKey = false,
|
|
||||||
creationTime = lastReceivedMessageTs.toString(),
|
|
||||||
lastUseTime = lastReceivedMessageTs.toString()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun ByteArray.asString() = String(this, charset)
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,19 +18,27 @@ package org.matrix.android.sdk.internal.crypto.store.db.migration.rust
|
||||||
|
|
||||||
import io.realm.kotlin.where
|
import io.realm.kotlin.where
|
||||||
import okhttp3.internal.toImmutableList
|
import okhttp3.internal.toImmutableList
|
||||||
|
import org.matrix.android.sdk.api.extensions.orFalse
|
||||||
|
import org.matrix.android.sdk.internal.crypto.model.InboundGroupSessionData
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm
|
import org.matrix.android.sdk.internal.crypto.store.db.deserializeFromRealm
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields
|
import org.matrix.android.sdk.internal.crypto.store.db.model.CryptoMetadataEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntity
|
||||||
|
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmInboundGroupSessionEntityFields
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields
|
import org.matrix.android.sdk.internal.crypto.store.db.model.OlmSessionEntityFields
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
|
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntity
|
||||||
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
|
import org.matrix.android.sdk.internal.crypto.store.db.model.UserEntityFields
|
||||||
|
import org.matrix.android.sdk.internal.di.MoshiProvider
|
||||||
import org.matrix.olm.OlmAccount
|
import org.matrix.olm.OlmAccount
|
||||||
|
import org.matrix.olm.OlmInboundGroupSession
|
||||||
import org.matrix.olm.OlmSession
|
import org.matrix.olm.OlmSession
|
||||||
import org.matrix.rustcomponents.sdk.crypto.CrossSigningKeyExport
|
import org.matrix.rustcomponents.sdk.crypto.CrossSigningKeyExport
|
||||||
import org.matrix.rustcomponents.sdk.crypto.MigrationData
|
import org.matrix.rustcomponents.sdk.crypto.MigrationData
|
||||||
import org.matrix.rustcomponents.sdk.crypto.PickledAccount
|
import org.matrix.rustcomponents.sdk.crypto.PickledAccount
|
||||||
|
import org.matrix.rustcomponents.sdk.crypto.PickledInboundGroupSession
|
||||||
import org.matrix.rustcomponents.sdk.crypto.PickledSession
|
import org.matrix.rustcomponents.sdk.crypto.PickledSession
|
||||||
|
import timber.log.Timber
|
||||||
import java.nio.charset.Charset
|
import java.nio.charset.Charset
|
||||||
|
|
||||||
sealed class RealmToMigrate {
|
sealed class RealmToMigrate {
|
||||||
|
@ -225,6 +233,80 @@ fun RealmToMigrate.pickledOlmSessions(pickleKey: ByteArray, chunkSize: Int, onCh
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val sessionDataAdapter = MoshiProvider.providesMoshi()
|
||||||
|
.adapter(InboundGroupSessionData::class.java)
|
||||||
|
fun RealmToMigrate.pickledOlmGroupSessions(pickleKey: ByteArray, chunkSize: Int, onChunk: ((List<PickledInboundGroupSession>) -> Unit)) {
|
||||||
|
when (this) {
|
||||||
|
is RealmToMigrate.ClassicRealm -> {
|
||||||
|
realm.where<OlmInboundGroupSessionEntity>()
|
||||||
|
.findAll()
|
||||||
|
.chunked(chunkSize) { chunk ->
|
||||||
|
val export = chunk.mapNotNull { it.toPickledInboundGroupSession(pickleKey) }
|
||||||
|
onChunk(export)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is RealmToMigrate.DynamicRealm -> {
|
||||||
|
val pickledSessions = mutableListOf<PickledInboundGroupSession>()
|
||||||
|
realm.schema.get("OlmInboundGroupSessionEntity")?.transform {
|
||||||
|
val senderKey = it.getString(OlmInboundGroupSessionEntityFields.SENDER_KEY)
|
||||||
|
val roomId = it.getString(OlmInboundGroupSessionEntityFields.ROOM_ID)
|
||||||
|
val backedUp = it.getBoolean(OlmInboundGroupSessionEntityFields.BACKED_UP)
|
||||||
|
val serializedOlmInboundGroupSession = it.getString(OlmInboundGroupSessionEntityFields.SERIALIZED_OLM_INBOUND_GROUP_SESSION)
|
||||||
|
val inboundSession = deserializeFromRealm<OlmInboundGroupSession>(serializedOlmInboundGroupSession) ?: return@transform Unit.also {
|
||||||
|
Timber.w("Rust db migration: Failed to migrated group session, no meta data")
|
||||||
|
}
|
||||||
|
val sessionData = it.getString(OlmInboundGroupSessionEntityFields.INBOUND_GROUP_SESSION_DATA_JSON).let { json ->
|
||||||
|
sessionDataAdapter.fromJson(json)
|
||||||
|
} ?: return@transform Unit.also {
|
||||||
|
Timber.w("Rust db migration: Failed to migrated group session, no meta data")
|
||||||
|
}
|
||||||
|
val pickle = inboundSession.pickle(pickleKey, StringBuffer()).asString()
|
||||||
|
val pickledSession = PickledInboundGroupSession(
|
||||||
|
pickle = pickle,
|
||||||
|
senderKey = senderKey,
|
||||||
|
signingKey = sessionData.keysClaimed.orEmpty(),
|
||||||
|
roomId = roomId,
|
||||||
|
forwardingChains = sessionData.forwardingCurve25519KeyChain.orEmpty(),
|
||||||
|
imported = sessionData.trusted.orFalse().not(),
|
||||||
|
backedUp = backedUp
|
||||||
|
)
|
||||||
|
// should we check the tracking status?
|
||||||
|
pickledSessions.add(pickledSession)
|
||||||
|
if (pickledSessions.size > chunkSize) {
|
||||||
|
onChunk(pickledSessions.toImmutableList())
|
||||||
|
pickledSessions.clear()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (pickledSessions.isNotEmpty()) {
|
||||||
|
onChunk(pickledSessions)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun OlmInboundGroupSessionEntity.toPickledInboundGroupSession(pickleKey: ByteArray): PickledInboundGroupSession? {
|
||||||
|
val senderKey = this.senderKey ?: return null
|
||||||
|
val backedUp = this.backedUp
|
||||||
|
val olmInboundGroupSession = this.getOlmGroupSession() ?: return null.also {
|
||||||
|
Timber.w("Rust db migration: Failed to migrated group session $sessionId")
|
||||||
|
}
|
||||||
|
val data = this.getData() ?: return null.also {
|
||||||
|
Timber.w("Rust db migration: Failed to migrated group session $sessionId, no meta data")
|
||||||
|
}
|
||||||
|
val roomId = data.roomId ?: return null.also {
|
||||||
|
Timber.w("Rust db migration: Failed to migrated group session $sessionId, no roomId")
|
||||||
|
}
|
||||||
|
val pickledInboundGroupSession = olmInboundGroupSession.pickle(pickleKey, StringBuffer()).asString()
|
||||||
|
return PickledInboundGroupSession(
|
||||||
|
pickle = pickledInboundGroupSession,
|
||||||
|
senderKey = senderKey,
|
||||||
|
signingKey = data.keysClaimed.orEmpty(),
|
||||||
|
roomId = roomId,
|
||||||
|
forwardingChains = data.forwardingCurve25519KeyChain.orEmpty(),
|
||||||
|
imported = data.trusted.orFalse().not(),
|
||||||
|
backedUp = backedUp
|
||||||
|
)
|
||||||
|
}
|
||||||
private fun OlmSessionEntity.toPickledSession(pickleKey: ByteArray): PickledSession {
|
private fun OlmSessionEntity.toPickledSession(pickleKey: ByteArray): PickledSession {
|
||||||
val deviceKey = this.deviceKey ?: ""
|
val deviceKey = this.deviceKey ?: ""
|
||||||
val lastReceivedMessageTs = this.lastReceivedMessageTs
|
val lastReceivedMessageTs = this.lastReceivedMessageTs
|
||||||
|
|
|
@ -59,7 +59,7 @@ class MigrateEAtoEROperation(private val migrateGroupSessions: Boolean = false)
|
||||||
if (!rustFilesDir.exists()) {
|
if (!rustFilesDir.exists()) {
|
||||||
rustFilesDir.mkdir()
|
rustFilesDir.mkdir()
|
||||||
}
|
}
|
||||||
val extractMigrationData = ExtractMigrationDataUseCase()
|
val extractMigrationData = ExtractMigrationDataUseCase(migrateGroupSessions)
|
||||||
|
|
||||||
try {
|
try {
|
||||||
val progressListener = object : ProgressListener {
|
val progressListener = object : ProgressListener {
|
||||||
|
|
Loading…
Reference in New Issue