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 typingRoomMemberIds: List<String> = emptyList(),
val breadcrumbsIndex: Int = NOT_IN_BREADCRUMBS,
// TODO Plug it
val roomEncryptionTrustLevel: RoomEncryptionTrustLevel? = null
) {

View file

@ -15,18 +15,20 @@
*/
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.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.di.SessionDatabase
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.util.MatrixCoroutineDispatchers
import im.vector.matrix.android.internal.util.createBackgroundHandler
import io.realm.Realm
import io.realm.RealmConfiguration
import kotlinx.coroutines.android.asCoroutineDispatcher
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import org.greenrobot.eventbus.EventBus
import org.greenrobot.eventbus.Subscribe
import timber.log.Timber
@ -38,13 +40,13 @@ internal class ShieldTrustUpdater @Inject constructor(
private val eventBus: EventBus,
private val computeTrustTask: ComputeTrustTask,
private val taskExecutor: TaskExecutor,
private val coroutineDispatchers: MatrixCoroutineDispatchers,
@SessionDatabase private val sessionRealmConfiguration: RealmConfiguration,
private val roomSummaryUpdater: RoomSummaryUpdater
) {
companion object {
private val BACKGROUND_HANDLER = createBackgroundHandler("SHIELD_CRYPTO_DB_THREAD")
private val BACKGROUND_HANDLER_DISPATCHER = BACKGROUND_HANDLER.asCoroutineDispatcher()
}
private val backgroundSessionRealm = AtomicReference<Realm>()
@ -76,58 +78,41 @@ internal class ShieldTrustUpdater @Inject constructor(
if (!isStarted.get()) {
return
}
taskExecutor.executorScope.launch(coroutineDispatchers.crypto) {
taskExecutor.executorScope.launch(BACKGROUND_HANDLER_DISPATCHER) {
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(update.userIds))
// We need to send that back to session base
BACKGROUND_HANDLER.post {
backgroundSessionRealm.get()?.executeTransaction { realm ->
roomSummaryUpdater.updateShieldTrust(realm, update.roomId, updatedTrust)
}
}
}
}
@Subscribe
fun onTrustUpdate(update: CryptoToSessionUserTrustChange) {
if (!isStarted.get()) {
return
}
onCryptoDevicesChange(update.userIds)
}
private fun onCryptoDevicesChange(users: List<String>) {
BACKGROUND_HANDLER.post {
val impactedRoomsId = backgroundSessionRealm.get()?.where(RoomMemberSummaryEntity::class.java)
?.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
?.findAll()
?.map { it.roomId }
?.distinct()
val map = HashMap<String, List<String>>()
impactedRoomsId?.forEach { roomId ->
backgroundSessionRealm.get()?.let { realm ->
RoomMemberSummaryEntity.where(realm, roomId)
taskExecutor.executorScope.launch(BACKGROUND_HANDLER_DISPATCHER) {
val realm = backgroundSessionRealm.get() ?: return@launch
val distinctRoomIds = realm.where(RoomMemberSummaryEntity::class.java)
.`in`(RoomMemberSummaryEntityFields.USER_ID, users.toTypedArray())
.distinct(RoomMemberSummaryEntityFields.ROOM_ID)
.findAll()
.let { results ->
map[roomId] = results.map { it.userId }
}
}
}
.map { it.roomId }
map.forEach { entry ->
val roomId = entry.key
val userList = entry.value
taskExecutor.executorScope.launch {
withContext(coroutineDispatchers.crypto) {
distinctRoomIds.forEach { roomId ->
val roomSummary = RoomSummaryEntity.where(realm, roomId).findFirst()
if (roomSummary?.isEncrypted.orFalse()) {
val allActiveRoomMembers = RoomMemberHelper(realm, roomId).getActiveRoomMemberIds()
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)
}
val updatedTrust = computeTrustTask.execute(ComputeTrustTask.Params(allActiveRoomMembers))
realm.executeTransaction {
roomSummaryUpdater.updateShieldTrust(it, roomId, updatedTrust)
}
} catch (failure: Throwable) {
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) {
val otherRoomMembers = RoomMemberHelper(realm, roomId)
.queryRoomMembersEvent()
.queryActiveRoomMembersEvent()
.notEqualTo(RoomMemberSummaryEntityFields.USER_ID, userId)
.findAll()
.asSequence()