ShieldTrust: use only active members

This commit is contained in:
ganfra 2020-04-28 11:00:41 +02:00
parent 21912c290a
commit fc86e7e1f6
3 changed files with 27 additions and 44 deletions

View file

@ -49,7 +49,6 @@ data class RoomSummary constructor(
val inviterId: String? = null, val inviterId: String? = null,
val typingRoomMemberIds: List<String> = emptyList(), val typingRoomMemberIds: List<String> = emptyList(),
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS, val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
// TODO Plug it
val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
) { ) {

View file

@ -15,18 +15,20 @@
*/ */
package im.vector.matrix.android.internal.crypto.crosssigning package im.vector.matrix.android.internal.crypto.crosssigning
import im.vector.matrix.android.api.extensions.orFalse
import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntity import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntity
import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields import im.vector.matrix.android.internal.database.model.RoomMemberSummaryEntityFields
import im.vector.matrix.android.internal.database.model.RoomSummaryEntity
import im.vector.matrix.android.internal.database.query.where import im.vector.matrix.android.internal.database.query.where
import im.vector.matrix.android.internal.di.SessionDatabase import im.vector.matrix.android.internal.di.SessionDatabase
import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater import im.vector.matrix.android.internal.session.room.RoomSummaryUpdater
import im.vector.matrix.android.internal.session.room.membership.RoomMemberHelper
import im.vector.matrix.android.internal.task.TaskExecutor import im.vector.matrix.android.internal.task.TaskExecutor
import im.vector.matrix.android.internal.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.createBackgroundHandler import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.Realm import io.realm.Realm
import io.realm.RealmConfiguration import io.realm.RealmConfiguration
import kotlinx.coroutines.android.asCoroutineDispatcher
import kotlinx.coroutines.launch import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe import org.greenrobot.eventbus.Subscribe
import timber.log.Timber import timber.log.Timber
@ -38,13 +40,13 @@ internal class ShieldTrustUpdater @Inject constructor(
private val eventBus: EventBus, private val eventBus: EventBus,
private val computeTrustTask: ComputeTrustTask, private val computeTrustTask: ComputeTrustTask,
private val taskExecutor: TaskExecutor, private val taskExecutor: TaskExecutor,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration, @SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
private val roomSummaryUpdater: RoomSummaryUpdater private val roomSummaryUpdater: RoomSummaryUpdater
) { ) {
companion object { companion object {
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD") private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
private val BACKGROUND_HANDLER_DISPATCHER = BACKGROUND_HANDLER.asCoroutineDispatcher()
} }
private val backgroundSessionRealm = AtomicReference<Realm>() private val backgroundSessionRealm = AtomicReference<Realm>()
@ -76,14 +78,11 @@ internal class ShieldTrustUpdater @Inject constructor(
if (!isStarted.get()) { if (!isStarted.get()) {
return return
} }
taskExecutor.executorScope.launch(coroutineDispatchers.crypto) { taskExecutor.executorScope.launch(BACKGROUND_HANDLER_DISPATCHER) {
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds)) val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds))
// We need to send that back to session base // We need to send that back to session base
backgroundSessionRealm.get()?.executeTransaction { realm ->
BACKGROUND_HANDLER.post { roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
backgroundSessionRealm.get()?.executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
}
} }
} }
} }
@ -93,45 +92,30 @@ internal class ShieldTrustUpdater @Inject constructor(
if (!isStarted.get()) { if (!isStarted.get()) {
return return
} }
onCryptoDevicesChange(update.userIds) onCryptoDevicesChange(update.userIds)
} }
private fun onCryptoDevicesChange(users: List<String>) { private fun onCryptoDevicesChange(users: List<String>) {
BACKGROUND_HANDLER.post { taskExecutor.executorScope.launch(BACKGROUND_HANDLER_DISPATCHER) {
val impactedRoomsId = backgroundSessionRealm.get()?.where(RoomMemberSummaryEntity::class.java) val realm = backgroundSessionRealm.get() ?: return@launch
?.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray()) val distinctRoomIds = realm.where(RoomMemberSummaryEntity::class.java)
?.findAll() .`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
?.map { it.roomId } .distinct(RoomMemberSummaryEntityFields.ROOM_ID)
?.distinct() .findAll()
.map { it.roomId }
val map = HashMap<String, List<String>>() distinctRoomIds.forEach { roomId ->
impactedRoomsId?.forEach { roomId -> val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
backgroundSessionRealm.get()?.let { realm -> if (roomSummary?.isEncrypted.orFalse()) {
RoomMemberSummaryEntity.where(realm, roomId) val allActiveRoomMembers = RoomMemberHelper(realm, roomId).getActiveRoomMemberIds()
.findAll() try {
.let { results -> // Can throw if the crypto database has been closed in between, in this case log and ignore?
map[roomId] = results.map { it.userId } val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(allActiveRoomMembers))
} realm.executeTransaction {
} roomSummaryUpdater.updateShieldTrust(it, roomId, updatedTrust)
}
map.forEach { entry ->
val roomId = entry.key
val userList = entry.value
taskExecutor.executorScope.launch {
withContext(coroutineDispatchers.crypto) {
try {
// Can throw if the crypto database has been closed in between, in this case log and ignore?
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList))
BACKGROUND_HANDLER.post {
backgroundSessionRealm.get()?.executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust)
}
}
} catch (failure: Throwable) {
Timber.e(failure)
} }
} catch (failure: Throwable) {
Timber.e(failure)
} }
} }
} }

View file

@ -152,7 +152,7 @@ internal class RoomSummaryUpdater @Inject constructor(
if (updateMembers) { if (updateMembers) {
val otherRoomMembers = RoomMemberHelper(realm, roomId) val otherRoomMembers = RoomMemberHelper(realm, roomId)
.queryRoomMembersEvent() .queryActiveRoomMembersEvent()
.notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId) .notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId)
.findAll() .findAll()
.asSequence() .asSequence()