From cee8ae3af4ff0cbd0122ee0f267b3a8b7e90426e Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 May 2020 14:43:53 +0200 Subject: [PATCH 1/3] Fix #1329 + migration to remove duplicate --- .../internal/crypto/DefaultCryptoService.kt | 2 +- .../actions/SetDeviceVerificationAction.kt | 2 +- .../internal/crypto/store/IMXCryptoStore.kt | 10 +------ .../crypto/store/db/RealmCryptoStore.kt | 27 ++----------------- .../store/db/RealmCryptoStoreMigration.kt | 22 ++++++++++++++- 5 files changed, 26 insertions(+), 37 deletions(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt index 1d3c0f4dcd..d529cf4ae5 100755 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/DefaultCryptoService.kt @@ -446,7 +446,7 @@ internal class DefaultCryptoService @Inject constructor( } override fun getCryptoDeviceInfo(userId: String): List { - return cryptoStore.getUserDevices(userId)?.map { it.value }?.sortedBy { it.deviceId } ?: emptyList() + return cryptoStore.getUserDeviceList(userId) ?: emptyList() } override fun getLiveCryptoDeviceInfo(): LiveData> { diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt index d6538f041d..d9fa8d5955 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/actions/SetDeviceVerificationAction.kt @@ -48,7 +48,7 @@ internal class SetDeviceVerificationAction @Inject constructor( if (device.trustLevel != trustLevel) { device.trustLevel = trustLevel - cryptoStore.storeUserDevice(userId, device) + cryptoStore.setDeviceTrust(userId, deviceId, trustLevel.crossSigningVerified, trustLevel.locallyVerified) } } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt index 888e436ea0..69f0985391 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/IMXCryptoStore.kt @@ -164,14 +164,6 @@ internal interface IMXCryptoStore { */ fun saveOlmAccount() - /** - * Store a device for a user. - * - * @param userId the user's id. - * @param device the device to store. - */ - fun storeUserDevice(userId: String?, deviceInfo: CryptoDeviceInfo?) - /** * Retrieve a device for a user. * @@ -415,7 +407,7 @@ internal interface IMXCryptoStore { fun getKeyBackupRecoveryKeyInfo() : SavedKeyBackupKeyInfo? fun setUserKeysAsTrusted(userId: String, trusted: Boolean = true) - fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean) + fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean?) fun clearOtherUserTrust() diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt index ac7f00b531..17f049512c 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStore.kt @@ -233,29 +233,6 @@ internal class RealmCryptoStore @Inject constructor( return olmAccount!! } - override fun storeUserDevice(userId: String?, deviceInfo: CryptoDeviceInfo?) { - if (userId == null || deviceInfo == null) { - return - } - - doRealmTransaction(realmConfiguration) { realm -> - val user = UserEntity.getOrCreate(realm, userId) - - // Create device info - val deviceInfoEntity = CryptoMapper.mapToEntity(deviceInfo) - realm.insertOrUpdate(deviceInfoEntity) -// val deviceInfoEntity = DeviceInfoEntity.getOrCreate(it, userId, deviceInfo.deviceId).apply { -// deviceId = deviceInfo.deviceId -// identityKey = deviceInfo.identityKey() -// putDeviceInfo(deviceInfo) -// } - - if (!user.devices.contains(deviceInfoEntity)) { - user.devices.add(deviceInfoEntity) - } - } - } - override fun getUserDevice(userId: String, deviceId: String): CryptoDeviceInfo? { return doWithRealm(realmConfiguration) { it.where() @@ -1276,7 +1253,7 @@ internal class RealmCryptoStore @Inject constructor( } } - override fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean) { + override fun setDeviceTrust(userId: String, deviceId: String, crossSignedVerified: Boolean, locallyVerified: Boolean?) { doRealmTransaction(realmConfiguration) { realm -> realm.where(DeviceInfoEntity::class.java) .equalTo(DeviceInfoEntityFields.PRIMARY_KEY, DeviceInfoEntity.createPrimaryKey(userId, deviceId)) @@ -1289,7 +1266,7 @@ internal class RealmCryptoStore @Inject constructor( deviceInfoEntity.trustLevelEntity = it } } else { - trustEntity.locallyVerified = locallyVerified + locallyVerified?.let { trustEntity.locallyVerified = it } trustEntity.crossSignedVerified = crossSignedVerified } } diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt index c604250be7..2a55fa2f6d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt @@ -26,6 +26,7 @@ import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrap import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntityFields import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMetadataEntityFields +import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntity import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntityFields import im.vector.matrix.android.internal.crypto.store.db.model.GossipingEventEntityFields import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields @@ -45,7 +46,7 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi // Version 1L added Cross Signing info persistence companion object { - const val CRYPTO_STORE_SCHEMA_VERSION = 5L + const val CRYPTO_STORE_SCHEMA_VERSION = 6L } override fun migrate(realm: DynamicRealm, oldVersion: Long, newVersion: Long) { @@ -56,6 +57,7 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi if (oldVersion <= 2) migrateTo3(realm) if (oldVersion <= 3) migrateTo4(realm) if (oldVersion <= 4) migrateTo5(realm) + if (oldVersion <= 5) migrateTo6(realm) } private fun migrateTo1(realm: DynamicRealm) { @@ -255,4 +257,22 @@ internal class RealmCryptoStoreMigration @Inject constructor(private val crossSi } } } + + // Fixes duplicate devices in UserEntity#devices + private fun migrateTo6(realm: DynamicRealm) { + val userEntities = realm.where("UserEntity").findAll() + userEntities.forEach { + try { + val deviceList = it.getList(UserEntityFields.DEVICES.`$`) + ?: return@forEach + val distinct = deviceList.distinctBy { it.getString(DeviceInfoEntityFields.DEVICE_ID) } + if (distinct.size != deviceList.size) { + deviceList.clear() + deviceList.addAll(distinct) + } + } catch (failure: Throwable) { + Timber.w(failure, "Crypto Data base migration error for migrateTo6") + } + } + } } From 583139d51e1158054f815dce83581ba417625a11 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 May 2020 15:06:34 +0200 Subject: [PATCH 2/3] klint --- .../internal/crypto/store/db/RealmCryptoStoreMigration.kt | 1 - 1 file changed, 1 deletion(-) diff --git a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt index 2a55fa2f6d..885abb776d 100644 --- a/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt +++ b/matrix-sdk-android/src/main/java/im/vector/matrix/android/internal/crypto/store/db/RealmCryptoStoreMigration.kt @@ -26,7 +26,6 @@ import im.vector.matrix.android.internal.crypto.model.OlmInboundGroupSessionWrap import im.vector.matrix.android.internal.crypto.store.db.mapper.CrossSigningKeysMapper import im.vector.matrix.android.internal.crypto.store.db.model.CrossSigningInfoEntityFields import im.vector.matrix.android.internal.crypto.store.db.model.CryptoMetadataEntityFields -import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntity import im.vector.matrix.android.internal.crypto.store.db.model.DeviceInfoEntityFields import im.vector.matrix.android.internal.crypto.store.db.model.GossipingEventEntityFields import im.vector.matrix.android.internal.crypto.store.db.model.IncomingGossipingRequestEntityFields From 0afa7a706afe810f5031d8be3cc70837026996a5 Mon Sep 17 00:00:00 2001 From: Valere Date: Wed, 6 May 2020 18:20:43 +0200 Subject: [PATCH 3/3] Update change log --- CHANGES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGES.md b/CHANGES.md index f0cf30af2d..8bdd42636d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,7 +8,7 @@ Improvements 🙌: - Bugfix 🐛: - - + - Sometimes the same device appears twice in the list of devices of a user (#1329) Translations 🗣: -