Changing where we insert UnableToDecryptEventEntity in DB

This commit is contained in:
Maxime NATUREL 2022-12-21 16:35:27 +01:00 committed by Maxime NATUREL
parent a29d4399a5
commit 7e1016da7e
4 changed files with 65 additions and 9 deletions

View file

@ -62,7 +62,9 @@ import org.matrix.android.sdk.internal.crypto.store.db.RealmCryptoStore
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.tasks.ClaimOneTimeKeysForUsersDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.CreateUnableToDecryptEventEntityTask
import org.matrix.android.sdk.internal.crypto.tasks.DefaultClaimOneTimeKeysForUsersDevice
import org.matrix.android.sdk.internal.crypto.tasks.DefaultCreateUnableToDecryptEventEntityTask
import org.matrix.android.sdk.internal.crypto.tasks.DefaultDeleteDeviceTask
import org.matrix.android.sdk.internal.crypto.tasks.DefaultDownloadKeysForUsers
import org.matrix.android.sdk.internal.crypto.tasks.DefaultEncryptEventTask
@ -253,4 +255,7 @@ internal abstract class CryptoModule {
@Binds
abstract fun bindSendEventTask(task: DefaultSendEventTask): SendEventTask
@Binds
abstract fun bindCreateUnableToDecryptEventEntityTask(task: DefaultCreateUnableToDecryptEventEntityTask): CreateUnableToDecryptEventEntityTask
}

View file

@ -38,6 +38,7 @@ import org.matrix.android.sdk.api.session.events.model.toModel
import org.matrix.android.sdk.internal.crypto.actions.EnsureOlmSessionsForDevicesAction
import org.matrix.android.sdk.internal.crypto.actions.MessageEncrypter
import org.matrix.android.sdk.internal.crypto.store.IMXCryptoStore
import org.matrix.android.sdk.internal.crypto.tasks.CreateUnableToDecryptEventEntityTask
import org.matrix.android.sdk.internal.crypto.tasks.SendToDeviceTask
import org.matrix.android.sdk.internal.extensions.foldToCallback
import org.matrix.android.sdk.internal.session.SessionScope
@ -59,7 +60,8 @@ internal class EventDecryptor @Inject constructor(
private val sendToDeviceTask: SendToDeviceTask,
private val deviceListManager: DeviceListManager,
private val ensureOlmSessionsForDevicesAction: EnsureOlmSessionsForDevicesAction,
private val cryptoStore: IMXCryptoStore
private val cryptoStore: IMXCryptoStore,
private val createUnableToDecryptEventEntityTask: CreateUnableToDecryptEventEntityTask,
) {
/**
@ -136,6 +138,7 @@ internal class EventDecryptor @Inject constructor(
val eventContent = event.content
if (eventContent == null) {
Timber.tag(loggerTag.value).e("decryptEvent : empty event content")
createUnableToDecryptEventEntity(event.eventId)
throw MXCryptoError.Base(MXCryptoError.ErrorType.BAD_ENCRYPTED_MESSAGE, MXCryptoError.BAD_ENCRYPTED_MESSAGE_REASON)
} else if (event.isRedacted()) {
// we shouldn't attempt to decrypt a redacted event because the content is cleared and decryption will fail because of null algorithm
@ -153,6 +156,7 @@ internal class EventDecryptor @Inject constructor(
if (alg == null) {
val reason = String.format(MXCryptoError.UNABLE_TO_DECRYPT_REASON, event.eventId, algorithm)
Timber.tag(loggerTag.value).e("decryptEvent() : $reason")
createUnableToDecryptEventEntity(event.eventId)
throw MXCryptoError.Base(MXCryptoError.ErrorType.UNABLE_TO_DECRYPT, reason)
} else {
try {
@ -171,12 +175,20 @@ internal class EventDecryptor @Inject constructor(
}
}
}
createUnableToDecryptEventEntity(event.eventId)
throw mxCryptoError
}
}
}
}
private suspend fun createUnableToDecryptEventEntity(eventId: String?) {
eventId?.let {
val params = CreateUnableToDecryptEventEntityTask.Params(eventId = it)
createUnableToDecryptEventEntityTask.execute(params)
}
}
private suspend fun markOlmSessionForUnwedging(senderId: String, senderKey: String) {
wedgedMutex.withLock {
val info = WedgedDeviceInfo(senderId, senderKey)

View file

@ -0,0 +1,46 @@
/*
* Copyright (c) 2022 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.tasks
import io.realm.RealmConfiguration
import org.matrix.android.sdk.internal.crypto.store.db.doRealmTransactionAsync
import org.matrix.android.sdk.internal.database.model.UnableToDecryptEventEntity
import org.matrix.android.sdk.internal.di.SessionDatabase
import org.matrix.android.sdk.internal.task.Task
import javax.inject.Inject
/**
* This task create a dedicated entity for UTD events so that it can be processed later.
*/
internal interface CreateUnableToDecryptEventEntityTask : Task<CreateUnableToDecryptEventEntityTask.Params, Unit> {
data class Params(
val eventId: String,
)
}
// TODO add unit tests
internal class DefaultCreateUnableToDecryptEventEntityTask @Inject constructor(
@SessionDatabase val realmConfiguration: RealmConfiguration,
) : CreateUnableToDecryptEventEntityTask {
override suspend fun execute(params: CreateUnableToDecryptEventEntityTask.Params) {
val utdEventEntity = UnableToDecryptEventEntity(eventId = params.eventId)
doRealmTransactionAsync(realmConfiguration) { realm ->
realm.insert(utdEventEntity)
}
}
}

View file

@ -25,7 +25,6 @@ import org.matrix.android.sdk.internal.database.model.EventEntity
import org.matrix.android.sdk.internal.database.model.EventEntityFields
import org.matrix.android.sdk.internal.database.model.EventInsertEntity
import org.matrix.android.sdk.internal.database.model.EventInsertType
import org.matrix.android.sdk.internal.database.model.UnableToDecryptEventEntity
internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInsertType): EventEntity {
val eventEntity = realm.where<EventEntity>()
@ -33,17 +32,11 @@ internal fun EventEntity.copyToRealmOrIgnore(realm: Realm, insertType: EventInse
.equalTo(EventEntityFields.ROOM_ID, roomId)
.findFirst()
return if (eventEntity == null) {
val isEncrypted = type == EventType.ENCRYPTED && decryptionResultJson == null
val canBeProcessed = isEncrypted.not()
val canBeProcessed = type != EventType.ENCRYPTED || decryptionResultJson != null
val insertEntity = EventInsertEntity(eventId = eventId, eventType = type, canBeProcessed = canBeProcessed).apply {
this.insertType = insertType
}
realm.insert(insertEntity)
// TODO check with others if it is the right spot to detect UTD events
if (isEncrypted) {
val utdEventEntity = UnableToDecryptEventEntity(eventId = eventId)
realm.insert(utdEventEntity)
}
// copy this event entity and return it
realm.copyToRealm(this)
} else {