mirror of
https://github.com/SchildiChat/SchildiChat-android.git
synced 2025-03-18 04:08:44 +03:00
Better algorithm to update user devices
Should fix the problem of too many TrustLevelEntity objects
This commit is contained in:
parent
5eb794f8af
commit
b4e7f10019
3 changed files with 49 additions and 34 deletions
|
@ -77,7 +77,3 @@ data class CryptoDeviceInfo(
|
|||
internal fun CryptoDeviceInfo.toRest(): DeviceKeys {
|
||||
return CryptoInfoMapper.map(this)
|
||||
}
|
||||
|
||||
internal fun CryptoDeviceInfo.toEntity(): DeviceInfoEntity {
|
||||
return CryptoMapper.mapToEntity(this)
|
||||
}
|
||||
|
|
|
@ -51,7 +51,6 @@ import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper
|
|||
import org.matrix.android.sdk.internal.crypto.model.event.RoomKeyWithHeldContent
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.DeviceInfo
|
||||
import org.matrix.android.sdk.internal.crypto.model.rest.RoomKeyRequestBody
|
||||
import org.matrix.android.sdk.internal.crypto.model.toEntity
|
||||
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
|
||||
import org.matrix.android.sdk.internal.crypto.store.PrivateKeysInfo
|
||||
import org.matrix.android.sdk.internal.crypto.store.SavedKeyBackupKeyInfo
|
||||
|
@ -280,23 +279,34 @@ internal class RealmCryptoStore @Inject constructor(
|
|||
override fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?) {
|
||||
doRealmTransaction(realmConfiguration) { realm ->
|
||||
if (devices == null) {
|
||||
Timber.d("Remove user $userId")
|
||||
// Remove the user
|
||||
UserEntity.delete(realm, userId)
|
||||
} else {
|
||||
val userEntity = UserEntity.getOrCreate(realm, userId)
|
||||
// Add the devices
|
||||
val currentDevices = userEntity.devices.toList()
|
||||
val newDevices = devices.values.map { cryptoDeviceInfo -> cryptoDeviceInfo.toEntity() }
|
||||
newDevices.forEach { deviceInfoEntity ->
|
||||
// Maintain first time seen
|
||||
val existing = currentDevices
|
||||
.firstOrNull { it.deviceId == deviceInfoEntity.deviceId && it.identityKey == deviceInfoEntity.identityKey }
|
||||
deviceInfoEntity.firstTimeSeenLocalTs = existing?.firstTimeSeenLocalTs ?: System.currentTimeMillis()
|
||||
realm.insertOrUpdate(deviceInfoEntity)
|
||||
// First delete the removed devices
|
||||
val deviceIds = devices.keys
|
||||
userEntity.devices.iterator().forEach { deviceInfoEntity ->
|
||||
if (deviceInfoEntity.deviceId !in deviceIds) {
|
||||
Timber.d("Remove device ${deviceInfoEntity.deviceId} of user $userId")
|
||||
deviceInfoEntity.deleteOnCascade()
|
||||
}
|
||||
}
|
||||
// Then update existing devices or add new one
|
||||
devices.values.forEach { cryptoDeviceInfo ->
|
||||
val existingDeviceInfoEntity = userEntity.devices.firstOrNull { it.deviceId == cryptoDeviceInfo.deviceId }
|
||||
if (existingDeviceInfoEntity == null) {
|
||||
// Add the device
|
||||
Timber.d("Add device ${cryptoDeviceInfo.deviceId} of user $userId")
|
||||
val newEntity = CryptoMapper.mapToEntity(cryptoDeviceInfo)
|
||||
newEntity.firstTimeSeenLocalTs = System.currentTimeMillis()
|
||||
userEntity.devices.add(newEntity)
|
||||
} else {
|
||||
// Update the device
|
||||
Timber.d("Update device ${cryptoDeviceInfo.deviceId} of user $userId")
|
||||
CryptoMapper.updateDeviceInfoEntity(existingDeviceInfoEntity, cryptoDeviceInfo)
|
||||
}
|
||||
}
|
||||
// Ensure all other devices are deleted
|
||||
userEntity.devices.clearWith { it.deleteOnCascade() }
|
||||
userEntity.devices.addAll(newDevices)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -44,23 +44,32 @@ object CryptoMapper {
|
|||
))
|
||||
|
||||
internal fun mapToEntity(deviceInfo: CryptoDeviceInfo): DeviceInfoEntity {
|
||||
return DeviceInfoEntity(
|
||||
primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId),
|
||||
userId = deviceInfo.userId,
|
||||
deviceId = deviceInfo.deviceId,
|
||||
algorithmListJson = listMigrationAdapter.toJson(deviceInfo.algorithms),
|
||||
keysMapJson = mapMigrationAdapter.toJson(deviceInfo.keys),
|
||||
signatureMapJson = mapMigrationAdapter.toJson(deviceInfo.signatures),
|
||||
isBlocked = deviceInfo.isBlocked,
|
||||
trustLevelEntity = deviceInfo.trustLevel?.let {
|
||||
TrustLevelEntity(
|
||||
crossSignedVerified = it.crossSigningVerified,
|
||||
locallyVerified = it.locallyVerified
|
||||
)
|
||||
},
|
||||
// We store the device name if present now
|
||||
unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName
|
||||
)
|
||||
return DeviceInfoEntity(primaryKey = DeviceInfoEntity.createPrimaryKey(deviceInfo.userId, deviceInfo.deviceId))
|
||||
.also { updateDeviceInfoEntity(it, deviceInfo) }
|
||||
}
|
||||
|
||||
internal fun updateDeviceInfoEntity(entity: DeviceInfoEntity, deviceInfo: CryptoDeviceInfo) {
|
||||
entity.userId = deviceInfo.userId
|
||||
entity.deviceId = deviceInfo.deviceId
|
||||
entity.algorithmListJson = listMigrationAdapter.toJson(deviceInfo.algorithms)
|
||||
entity.keysMapJson = mapMigrationAdapter.toJson(deviceInfo.keys)
|
||||
entity.signatureMapJson = mapMigrationAdapter.toJson(deviceInfo.signatures)
|
||||
entity.isBlocked = deviceInfo.isBlocked
|
||||
val deviceInfoTrustLevel = deviceInfo.trustLevel
|
||||
if (deviceInfoTrustLevel == null) {
|
||||
entity.trustLevelEntity?.deleteFromRealm()
|
||||
entity.trustLevelEntity = null
|
||||
} else {
|
||||
if (entity.trustLevelEntity == null) {
|
||||
// Create a new TrustLevelEntity object
|
||||
entity.trustLevelEntity = TrustLevelEntity()
|
||||
}
|
||||
// Update the existing TrustLevelEntity object
|
||||
entity.trustLevelEntity?.crossSignedVerified = deviceInfoTrustLevel.crossSigningVerified
|
||||
entity.trustLevelEntity?.locallyVerified = deviceInfoTrustLevel.locallyVerified
|
||||
}
|
||||
// We store the device name if present now
|
||||
entity.unsignedMapJson = deviceInfo.unsigned?.deviceDisplayName
|
||||
}
|
||||
|
||||
internal fun mapToModel(deviceInfoEntity: DeviceInfoEntity): CryptoDeviceInfo {
|
||||
|
|
Loading…
Add table
Reference in a new issue