2018-11-09 08:43:12 +00:00
|
|
|
package im.vector.matrix.android.internal.session.events.prune
|
|
|
|
|
|
|
|
import android.content.Context
|
|
|
|
import androidx.work.Worker
|
|
|
|
import androidx.work.WorkerParameters
|
|
|
|
import arrow.core.Option
|
2018-11-09 13:06:23 +00:00
|
|
|
import com.squareup.moshi.JsonClass
|
2018-11-09 08:43:12 +00:00
|
|
|
import im.vector.matrix.android.api.session.events.model.Event
|
|
|
|
import im.vector.matrix.android.api.session.events.model.EventType
|
2018-11-26 16:09:49 +00:00
|
|
|
import im.vector.matrix.android.internal.database.DatabaseInstances
|
2018-11-09 08:43:12 +00:00
|
|
|
import im.vector.matrix.android.internal.database.mapper.asDomain
|
2018-11-13 09:48:05 +00:00
|
|
|
import im.vector.matrix.android.internal.database.mapper.asEntity
|
2018-11-09 08:43:12 +00:00
|
|
|
import im.vector.matrix.android.internal.database.model.EventEntity
|
|
|
|
import im.vector.matrix.android.internal.database.query.where
|
2018-11-09 13:06:23 +00:00
|
|
|
import im.vector.matrix.android.internal.util.WorkerParamsFactory
|
2018-11-09 08:43:12 +00:00
|
|
|
import im.vector.matrix.android.internal.util.tryTransactionAsync
|
|
|
|
import io.realm.Realm
|
|
|
|
import org.koin.standalone.KoinComponent
|
|
|
|
import org.koin.standalone.inject
|
|
|
|
|
|
|
|
internal class PruneEventWorker(context: Context,
|
|
|
|
workerParameters: WorkerParameters
|
|
|
|
) : Worker(context, workerParameters), KoinComponent {
|
|
|
|
|
2018-11-09 13:06:23 +00:00
|
|
|
@JsonClass(generateAdapter = true)
|
|
|
|
internal data class Params(
|
|
|
|
val redactionEvents: List<Event>,
|
|
|
|
val updateIndexes: List<Int>,
|
|
|
|
val deletionIndexes: List<Int>
|
|
|
|
)
|
|
|
|
|
2018-11-26 16:09:49 +00:00
|
|
|
private val dbInstances by inject<DatabaseInstances>()
|
2018-11-09 08:43:12 +00:00
|
|
|
|
|
|
|
override fun doWork(): Result {
|
2018-11-09 13:06:23 +00:00
|
|
|
val params = WorkerParamsFactory.fromData<Params>(inputData)
|
2018-11-26 16:09:49 +00:00
|
|
|
?: return Result.FAILURE
|
2018-11-09 13:06:23 +00:00
|
|
|
|
2018-11-26 16:09:49 +00:00
|
|
|
val result = dbInstances.disk.tryTransactionAsync { realm ->
|
2018-11-09 08:43:12 +00:00
|
|
|
params.updateIndexes.forEach { index ->
|
|
|
|
val data = params.redactionEvents[index]
|
|
|
|
pruneEvent(realm, data)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return result.fold({ Result.RETRY }, { Result.SUCCESS })
|
|
|
|
}
|
|
|
|
|
|
|
|
private fun pruneEvent(realm: Realm, redactionEvent: Event?) {
|
|
|
|
if (redactionEvent == null || redactionEvent.redacts.isNullOrEmpty()) {
|
|
|
|
return
|
|
|
|
}
|
2018-11-13 09:48:05 +00:00
|
|
|
val eventToPrune = EventEntity.where(realm, eventId = redactionEvent.redacts).findFirst()?.asDomain()
|
2018-11-26 16:09:49 +00:00
|
|
|
?: return
|
2018-11-09 08:43:12 +00:00
|
|
|
|
|
|
|
val allowedKeys = computeAllowedKeys(eventToPrune.type)
|
|
|
|
val prunedContent = allowedKeys.fold(
|
|
|
|
{ eventToPrune.content },
|
|
|
|
{ eventToPrune.content?.filterKeys { key -> it.contains(key) } }
|
|
|
|
)
|
2018-11-13 09:48:05 +00:00
|
|
|
val eventToPruneEntity = eventToPrune.copy(content = prunedContent).asEntity()
|
|
|
|
realm.insertOrUpdate(eventToPruneEntity)
|
2018-11-09 08:43:12 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
private fun computeAllowedKeys(type: String): Option<List<String>> {
|
|
|
|
// Add filtered content, allowed keys in content depends on the event type
|
|
|
|
val result = when (type) {
|
2018-11-26 16:09:49 +00:00
|
|
|
EventType.STATE_ROOM_MEMBER -> listOf("membership")
|
|
|
|
EventType.STATE_ROOM_CREATE -> listOf("creator")
|
|
|
|
EventType.STATE_ROOM_JOIN_RULES -> listOf("join_rule")
|
2018-11-09 08:43:12 +00:00
|
|
|
EventType.STATE_ROOM_POWER_LEVELS -> listOf("users",
|
2018-11-26 16:09:49 +00:00
|
|
|
"users_default",
|
|
|
|
"events",
|
|
|
|
"events_default",
|
|
|
|
"state_default",
|
|
|
|
"ban",
|
|
|
|
"kick",
|
|
|
|
"redact",
|
|
|
|
"invite")
|
|
|
|
EventType.STATE_ROOM_ALIASES -> listOf("aliases")
|
|
|
|
EventType.STATE_CANONICAL_ALIAS -> listOf("alias")
|
|
|
|
EventType.FEEDBACK -> listOf("type", "target_event_id")
|
|
|
|
else -> null
|
2018-11-09 08:43:12 +00:00
|
|
|
}
|
|
|
|
return Option.fromNullable(result)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|