From 1bfd78753a825d8739b98fb0030eeb3fa705d567 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Mon, 1 Mar 2021 17:52:56 +0100 Subject: [PATCH] Ensure we do not edit an Event from another room --- .../database/helper/ChunkEntityHelper.kt | 2 +- .../EventAnnotationsSummaryEntityQuery.kt | 18 ++++--------- .../EventRelationsAggregationProcessor.kt | 25 ++++++++----------- .../room/relation/DefaultRelationService.kt | 4 +-- .../relation/FindReactionEventForUndoTask.kt | 8 +++--- .../room/relation/UpdateQuickReactionTask.kt | 14 +++++------ 6 files changed, 30 insertions(+), 41 deletions(-) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt index b4935cfdcc..c2b729e593 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/helper/ChunkEntityHelper.kt @@ -97,7 +97,7 @@ internal fun ChunkEntity.addTimelineEvent(roomId: String, this.root = eventEntity this.eventId = eventId this.roomId = roomId - this.annotations = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() + this.annotations = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst() this.readReceipts = readReceiptsSummaryEntity this.displayIndex = displayIndex val roomMemberContent = roomMemberContentsByUser[senderId] diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt index b96fc54a42..c3cae3d268 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/database/query/EventAnnotationsSummaryEntityQuery.kt @@ -23,18 +23,10 @@ import io.realm.Realm import io.realm.RealmQuery import io.realm.kotlin.where -internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, eventId: String): RealmQuery { - val query = realm.where() - query.equalTo(EventAnnotationsSummaryEntityFields.EVENT_ID, eventId) - return query -} - -internal fun EventAnnotationsSummaryEntity.Companion.whereInRoom(realm: Realm, roomId: String?): RealmQuery { - val query = realm.where() - if (roomId != null) { - query.equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId) - } - return query +internal fun EventAnnotationsSummaryEntity.Companion.where(realm: Realm, roomId: String, eventId: String): RealmQuery { + return realm.where() + .equalTo(EventAnnotationsSummaryEntityFields.ROOM_ID, roomId) + .equalTo(EventAnnotationsSummaryEntityFields.EVENT_ID, eventId) } internal fun EventAnnotationsSummaryEntity.Companion.create(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity { @@ -49,6 +41,6 @@ internal fun EventAnnotationsSummaryEntity.Companion.create(realm: Realm, roomId } internal fun EventAnnotationsSummaryEntity.Companion.getOrCreate(realm: Realm, roomId: String, eventId: String): EventAnnotationsSummaryEntity { - return EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() + return EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst() ?: EventAnnotationsSummaryEntity.create(realm, roomId, eventId) } diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt index dd6b16de59..c274ccb244 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/EventRelationsAggregationProcessor.kt @@ -93,13 +93,11 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr Timber.v("###REACTION Agreggation in room $roomId for event ${event.eventId}") handleInitialAggregatedRelations(event, roomId, event.unsignedData.relations.annotations, realm) - EventAnnotationsSummaryEntity.where(realm, event.eventId - ?: "").findFirst()?.let { - TimelineEventEntity.where(realm, roomId = roomId, eventId = event.eventId - ?: "").findFirst()?.let { tet -> - tet.annotations = it - } - } + EventAnnotationsSummaryEntity.where(realm, roomId, event.eventId ?: "").findFirst() + ?.let { + TimelineEventEntity.where(realm, roomId = roomId, eventId = event.eventId ?: "").findFirst() + ?.let { tet -> tet.annotations = it } + } } val content: MessageContent? = event.content.toModel() @@ -281,7 +279,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr val eventTimestamp = event.originServerTs ?: return // ok, this is a poll response - var existing = EventAnnotationsSummaryEntity.where(realm, targetEventId).findFirst() + var existing = EventAnnotationsSummaryEntity.where(realm, roomId, targetEventId).findFirst() if (existing == null) { Timber.v("## POLL creating new relation summary for $targetEventId") existing = EventAnnotationsSummaryEntity.create(realm, roomId, targetEventId) @@ -361,7 +359,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr aggregation.chunk?.forEach { if (it.type == EventType.REACTION) { val eventId = event.eventId ?: "" - val existing = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() + val existing = EventAnnotationsSummaryEntity.where(realm, roomId, eventId).findFirst() if (existing == null) { val eventSummary = EventAnnotationsSummaryEntity.create(realm, roomId, eventId) val sum = realm.createObject(ReactionAggregatedSummaryEntity::class.java) @@ -445,7 +443,7 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr */ private fun handleRedactionOfReplace(redacted: EventEntity, relatedEventId: String, realm: Realm) { Timber.d("Handle redaction of m.replace") - val eventSummary = EventAnnotationsSummaryEntity.where(realm, relatedEventId).findFirst() + val eventSummary = EventAnnotationsSummaryEntity.where(realm, redacted.roomId, relatedEventId).findFirst() if (eventSummary == null) { Timber.w("Redaction of a replace targeting an unknown event $relatedEventId") return @@ -475,16 +473,15 @@ internal class EventRelationsAggregationProcessor @Inject constructor(@UserId pr } } - fun handleReactionRedact(eventToPrune: EventEntity, realm: Realm, userId: String) { + private fun handleReactionRedact(eventToPrune: EventEntity, realm: Realm, userId: String) { Timber.v("REDACTION of reaction ${eventToPrune.eventId}") // delete a reaction, need to update the annotation summary if any - val reactionContent: ReactionContent = EventMapper.map(eventToPrune).content.toModel() - ?: return + val reactionContent: ReactionContent = EventMapper.map(eventToPrune).content.toModel() ?: return val eventThatWasReacted = reactionContent.relatesTo?.eventId ?: return val reactionKey = reactionContent.relatesTo.key Timber.v("REMOVE reaction for key $reactionKey") - val summary = EventAnnotationsSummaryEntity.where(realm, eventThatWasReacted).findFirst() + val summary = EventAnnotationsSummaryEntity.where(realm, eventToPrune.roomId, eventThatWasReacted).findFirst() if (summary != null) { summary.reactionsSummary.where() .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reactionKey) diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt index b7caf62865..bbcad3a4fe 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/DefaultRelationService.kt @@ -159,7 +159,7 @@ internal class DefaultRelationService @AssistedInject constructor( override fun getEventAnnotationsSummary(eventId: String): EventAnnotationsSummary? { return monarchy.fetchCopyMap( - { EventAnnotationsSummaryEntity.where(it, eventId).findFirst() }, + { EventAnnotationsSummaryEntity.where(it, roomId, eventId).findFirst() }, { entity, _ -> entity.asDomain() } @@ -168,7 +168,7 @@ internal class DefaultRelationService @AssistedInject constructor( override fun getEventAnnotationsSummaryLive(eventId: String): LiveData> { val liveData = monarchy.findAllMappedWithChanges( - { EventAnnotationsSummaryEntity.where(it, eventId) }, + { EventAnnotationsSummaryEntity.where(it, roomId, eventId) }, { it.asDomain() } ) return Transformations.map(liveData) { results -> diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt index fa6db2ee37..863ae4f5ce 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/FindReactionEventForUndoTask.kt @@ -45,16 +45,16 @@ internal class DefaultFindReactionEventForUndoTask @Inject constructor( override suspend fun execute(params: FindReactionEventForUndoTask.Params): FindReactionEventForUndoTask.Result { val eventId = Realm.getInstance(monarchy.realmConfiguration).use { realm -> - getReactionToRedact(realm, params.reaction, params.eventId)?.eventId + getReactionToRedact(realm, params)?.eventId } return FindReactionEventForUndoTask.Result(eventId) } - private fun getReactionToRedact(realm: Realm, reaction: String, eventId: String): EventEntity? { - val summary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() ?: return null + private fun getReactionToRedact(realm: Realm, params: FindReactionEventForUndoTask.Params): EventEntity? { + val summary = EventAnnotationsSummaryEntity.where(realm, params.roomId, params.eventId).findFirst() ?: return null val rase = summary.reactionsSummary.where() - .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reaction) + .equalTo(ReactionAggregatedSummaryEntityFields.KEY, params.reaction) .findFirst() ?: return null // want to find the event originated by me! diff --git a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt index 1f68a700ad..32d6c5aa7e 100644 --- a/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt +++ b/matrix-sdk-android/src/main/java/org/matrix/android/sdk/internal/session/room/relation/UpdateQuickReactionTask.kt @@ -47,22 +47,22 @@ internal class DefaultUpdateQuickReactionTask @Inject constructor(@SessionDataba override suspend fun execute(params: UpdateQuickReactionTask.Params): UpdateQuickReactionTask.Result { var res: Pair?>? = null monarchy.doWithRealm { realm -> - res = updateQuickReaction(realm, params.reaction, params.oppositeReaction, params.eventId) + res = updateQuickReaction(realm, params) } return UpdateQuickReactionTask.Result(res?.first, res?.second.orEmpty()) } - private fun updateQuickReaction(realm: Realm, reaction: String, oppositeReaction: String, eventId: String): Pair?> { + private fun updateQuickReaction(realm: Realm, params: UpdateQuickReactionTask.Params): Pair?> { // the emoji reaction has been selected, we need to check if we have reacted it or not - val existingSummary = EventAnnotationsSummaryEntity.where(realm, eventId).findFirst() - ?: return Pair(reaction, null) + val existingSummary = EventAnnotationsSummaryEntity.where(realm, params.roomId, params.eventId).findFirst() + ?: return Pair(params.reaction, null) // Ok there is already reactions on this event, have we reacted to it val aggregationForReaction = existingSummary.reactionsSummary.where() - .equalTo(ReactionAggregatedSummaryEntityFields.KEY, reaction) + .equalTo(ReactionAggregatedSummaryEntityFields.KEY, params.reaction) .findFirst() val aggregationForOppositeReaction = existingSummary.reactionsSummary.where() - .equalTo(ReactionAggregatedSummaryEntityFields.KEY, oppositeReaction) + .equalTo(ReactionAggregatedSummaryEntityFields.KEY, params.oppositeReaction) .findFirst() if (aggregationForReaction == null || !aggregationForReaction.addedByMe) { @@ -72,7 +72,7 @@ internal class DefaultUpdateQuickReactionTask @Inject constructor(@SessionDataba val entity = EventEntity.where(realm, it).findFirst() if (entity?.sender == userId) entity.eventId else null } - return Pair(reaction, toRedact) + return Pair(params.reaction, toRedact) } else { // I already added it, so i need to undo it (like a toggle) // find all m.redaction coming from me to readact them