Batch insertion of user data after downloading keys.

This commit is contained in:
Benoit Marty 2023-01-03 15:57:39 +01:00
parent f26178fc21
commit 4c4ef0d73e
4 changed files with 165 additions and 112 deletions

View File

@ -30,6 +30,7 @@ import org.matrix.android.sdk.api.session.crypto.model.MXUsersDevicesMap
import org.matrix.android.sdk.internal.crypto.model.CryptoInfoMapper
import org.matrix.android.sdk.internal.crypto.model.rest.KeysQueryResponse
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.store.UserDataToStore
import org.matrix.android.sdk.internal.crypto.tasks.DownloadKeysForUsersTask
import org.matrix.android.sdk.internal.session.SessionScope
import org.matrix.android.sdk.internal.session.sync.SyncTokenStore
@ -371,6 +372,8 @@ internal class DeviceListManager @Inject constructor(
Timber.v("## CRYPTO | doKeyDownloadForUsers() : Got keys for " + filteredUsers.size + " users")
}
val userDataToStore = UserDataToStore()
for (userId in filteredUsers) {
// al devices =
val models = response.deviceKeys?.get(userId)?.mapValues { entry -> CryptoInfoMapper.map(entry.value) }
@ -404,7 +407,7 @@ internal class DeviceListManager @Inject constructor(
}
// Update the store
// Note that devices which aren't in the response will be removed from the stores
cryptoStore.storeUserDevices(userId, workingCopy)
userDataToStore.userDevices[userId] = workingCopy
}
val masterKey = response.masterKeys?.get(userId)?.toCryptoModel().also {
@ -416,14 +419,11 @@ internal class DeviceListManager @Inject constructor(
val userSigningKey = response.userSigningKeys?.get(userId)?.toCryptoModel()?.also {
Timber.v("## CRYPTO | CrossSigning : Got keys for $userId : USK ${it.unpaddedBase64PublicKey}")
}
cryptoStore.storeUserCrossSigningKeys(
userId,
masterKey,
selfSigningKey,
userSigningKey
)
userDataToStore.userCrossSigningKeys[userId] = Triple(masterKey, selfSigningKey, userSigningKey)
}
cryptoStore.storeUserDataToStore(userDataToStore)
// Update devices trust for these users
// dispatchDeviceChange(downloadUsers)

View File

@ -583,4 +583,6 @@ internal interface IMXCryptoStore {
fun areDeviceKeysUploaded(): Boolean
fun tidyUpDataBase()
fun getOutgoingRoomKeyRequests(inStates: Set<OutgoingRoomKeyRequestState>): List<OutgoingKeyRequest>
fun storeUserDataToStore(userDataToStore: UserDataToStore)
}

View File

@ -0,0 +1,25 @@
/*
* Copyright (c) 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
import org.matrix.android.sdk.api.session.crypto.crosssigning.CryptoCrossSigningKey
import org.matrix.android.sdk.api.session.crypto.model.CryptoDeviceInfo
internal data class UserDataToStore(
val userDevices: MutableMap<String, Map<String, CryptoDeviceInfo>> = mutableMapOf(),
val userCrossSigningKeys: MutableMap<String, Triple<CryptoCrossSigningKey?, CryptoCrossSigningKey?, CryptoCrossSigningKey?>> = mutableMapOf(),
)

View File

@ -55,6 +55,7 @@ import org.matrix.android.sdk.internal.crypto.model.MXInboundMegolmSessionWrappe
import org.matrix.android.sdk.internal.crypto.model.OlmSessionWrapper
import org.matrix.android.sdk.internal.crypto.model.OutboundGroupSessionWrapper
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.store.UserDataToStore
import org.matrix.android.sdk.internal.crypto.store.db.mapper.CrossSigningKeysMapper
import org.matrix.android.sdk.internal.crypto.store.db.mapper.MyDeviceLastSeenInfoEntityMapper
import org.matrix.android.sdk.internal.crypto.store.db.model.AuditTrailEntity
@ -289,6 +290,11 @@ internal class RealmCryptoStore @Inject constructor(
override fun storeUserDevices(userId: String, devices: Map<String, CryptoDeviceInfo>?) {
doRealmTransaction("storeUserDevices", realmConfiguration) { realm ->
storeUserDevices(realm, userId, devices)
}
}
private fun storeUserDevices(realm: Realm, userId: String, devices: Map<String, CryptoDeviceInfo>?) {
if (devices == null) {
Timber.d("Remove user $userId")
// Remove the user
@ -323,7 +329,6 @@ internal class RealmCryptoStore @Inject constructor(
}
}
}
}
override fun storeUserCrossSigningKeys(
userId: String,
@ -332,6 +337,17 @@ internal class RealmCryptoStore @Inject constructor(
userSigningKey: CryptoCrossSigningKey?
) {
doRealmTransaction("storeUserCrossSigningKeys", realmConfiguration) { realm ->
storeUserCrossSigningKeys(realm, userId, masterKey, selfSigningKey, userSigningKey)
}
}
private fun storeUserCrossSigningKeys(
realm: Realm,
userId: String,
masterKey: CryptoCrossSigningKey?,
selfSigningKey: CryptoCrossSigningKey?,
userSigningKey: CryptoCrossSigningKey?
) {
UserEntity.getOrCreate(realm, userId)
.let { userEntity ->
if (masterKey == null || selfSigningKey == null) {
@ -411,7 +427,6 @@ internal class RealmCryptoStore @Inject constructor(
}
}
}
}
override fun getCrossSigningPrivateKeys(): PrivateKeysInfo? {
return doWithRealm(realmConfiguration) { realm ->
@ -1831,13 +1846,24 @@ internal class RealmCryptoStore @Inject constructor(
}
doRealmTransaction("onSyncCompleted", realmConfiguration) { realm ->
// setShouldShareHistory
aggregator.setShouldShareHistoryData.map {
aggregator.setShouldShareHistoryData.forEach {
CryptoRoomEntity.getOrCreate(realm, it.key).shouldShareHistory = it.value
}
// setShouldEncryptForInvitedMembers
aggregator.setShouldEncryptForInvitedMembersData.map {
aggregator.setShouldEncryptForInvitedMembersData.forEach {
CryptoRoomEntity.getOrCreate(realm, it.key).shouldEncryptForInvitedMembers = it.value
}
}
}
override fun storeUserDataToStore(userDataToStore: UserDataToStore) {
doRealmTransaction("storeUserDataToStore", realmConfiguration) { realm ->
userDataToStore.userDevices.forEach {
storeUserDevices(realm, it.key, it.value)
}
userDataToStore.userCrossSigningKeys.forEach {
storeUserCrossSigningKeys(realm, it.key, it.value.first, it.value.second, it.value.third)
}
}
}
}