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,58 +78,41 @@ 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
BACKGROUND_HANDLER.post {
backgroundSessionRealm.get()?.executeTransaction { realm -> backgroundSessionRealm.get()?.executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust) roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
} }
} }
} }
}
@Subscribe @Subscribe
fun onTrustUpdate(update: CryptoToSessionUserTrustChange) { fun onTrustUpdate(update: CryptoToSessionUserTrustChange) {
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()
val map = HashMap<String, List<String>>()
impactedRoomsId?.forEach { roomId ->
backgroundSessionRealm.get()?.let { realm ->
RoomMemberSummaryEntity.where(realm, roomId)
.findAll() .findAll()
.let { results -> .map { it.roomId }
map[roomId] = results.map { it.userId }
}
}
}
map.forEach { entry -> distinctRoomIds.forEach { roomId ->
val roomId = entry.key val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
val userList = entry.value if (roomSummary?.isEncrypted.orFalse()) {
taskExecutor.executorScope.launch { val allActiveRoomMembers = RoomMemberHelper(realm, roomId).getActiveRoomMemberIds()
withContext(coroutineDispatchers.crypto) {
try { try {
// Can throw if the crypto database has been closed in between, in this case log and ignore? // Can throw if the crypto database has been closed in between, in this case log and ignore?
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(userList)) val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(allActiveRoomMembers))
BACKGROUND_HANDLER.post { realm.executeTransaction {
backgroundSessionRealm.get()?.executeTransaction { realm -> roomSummaryUpdater.updateShieldTrust(it, roomId, updatedTrust)
roomSummaryUpdater.updateShieldTrust(realm, roomId, updatedTrust)
}
} }
} catch (failure: Throwable) { } catch (failure: Throwable) {
Timber.e(failure) Timber.e(failure)
@ -137,4 +122,3 @@ internal class ShieldTrustUpdater @Inject constructor(
} }
} }
} }
}

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()