SES-1156 - Ban and delete functionality fix (#1428)

* WIP

* Investigation in progress

* End of day push

* WIP

* Fixes #1416

* Cleanup

* Added code to remove zombie messages caught in limbo during a ban & delete - still chock full o' debug while finding root cause

* Root cause debug WIP

* Push prior to cleanup

* Cleaned up for PR

* fix: mms delete, remove unnecessary values from sms

* Addressed PR feedback

* fix: fix unit tests

* Added '.run' folder with test setup

* Update README.md

Test commit for CI

* Re-added accidentally removed closing brace

---------

Co-authored-by: alansley <aclansley@gmail.com>
Co-authored-by: Al Lansley <alansley@users.noreply.github.com>
Co-authored-by: 0x330a <92654767+0x330a@users.noreply.github.com>
This commit is contained in:
AL-Session
2024-04-03 09:30:15 +11:00
committed by GitHub
parent 9ad5bd2374
commit a8a257a1a6
44 changed files with 350 additions and 142 deletions

View File

@@ -77,7 +77,7 @@ class Contact(val sessionID: String) {
companion object {
fun contextForRecipient(recipient: Recipient): ContactContext {
return if (recipient.isOpenGroupRecipient) ContactContext.OPEN_GROUP else ContactContext.REGULAR
return if (recipient.isCommunityRecipient) ContactContext.OPEN_GROUP else ContactContext.REGULAR
}
}
}

View File

@@ -22,7 +22,7 @@ class OpenGroupDeleteJob(private val messageServerIds: LongArray, private val th
override suspend fun execute(dispatcherName: String) {
val dataProvider = MessagingModuleConfiguration.shared.messageDataProvider
val numberToDelete = messageServerIds.size
Log.d(TAG, "Deleting $numberToDelete messages")
Log.d(TAG, "About to attempt to delete $numberToDelete messages")
// FIXME: This entire process should probably run in a transaction (with the attachment deletion happening only if it succeeded)
try {
@@ -42,6 +42,7 @@ class OpenGroupDeleteJob(private val messageServerIds: LongArray, private val th
delegate?.handleJobSucceeded(this, dispatcherName)
}
catch (e: Exception) {
Log.w(TAG, "OpenGroupDeleteJob failed: $e")
delegate?.handleJobFailed(this, dispatcherName, e)
}
}

View File

@@ -43,14 +43,14 @@ sealed class Destination {
val groupPublicKey = GroupUtil.doubleDecodeGroupID(groupID).toHexString()
ClosedGroup(groupPublicKey)
}
address.isOpenGroup -> {
address.isCommunity -> {
val storage = MessagingModuleConfiguration.shared.storage
val threadID = storage.getThreadId(address)!!
storage.getOpenGroup(threadID)?.let {
OpenGroup(roomToken = it.room, server = it.server, fileIds = fileIds)
} ?: throw Exception("Missing open group for thread with ID: $threadID.")
}
address.isOpenGroupInbox -> {
address.isCommunityInbox -> {
val groupInboxId = GroupUtil.getDecodedGroupID(address.serialize()).split("!")
OpenGroupInbox(
groupInboxId.dropLast(2).joinToString("!"),

View File

@@ -602,8 +602,7 @@ object OpenGroupApi {
// region Message Deletion
@JvmStatic
fun deleteMessage(serverID: Long, room: String, server: String): Promise<Unit, Exception> {
val request =
Request(verb = DELETE, room = room, server = server, endpoint = Endpoint.RoomMessageIndividual(room, serverID))
val request = Request(verb = DELETE, room = room, server = server, endpoint = Endpoint.RoomMessageIndividual(room, serverID))
return send(request).map {
Log.d("Loki", "Message deletion successful.")
}
@@ -659,7 +658,9 @@ object OpenGroupApi {
}
fun banAndDeleteAll(publicKey: String, room: String, server: String): Promise<Unit, Exception> {
val requests = mutableListOf<BatchRequestInfo<*>>(
// Ban request
BatchRequestInfo(
request = BatchRequest(
method = POST,
@@ -669,6 +670,7 @@ object OpenGroupApi {
endpoint = Endpoint.UserBan(publicKey),
responseType = object: TypeReference<Any>(){}
),
// Delete request
BatchRequestInfo(
request = BatchRequest(DELETE, "/room/$room/all/$publicKey"),
endpoint = Endpoint.RoomDeleteMessages(room, publicKey),

View File

@@ -22,17 +22,17 @@ class Address private constructor(address: String) : Parcelable, Comparable<Addr
get() = GroupUtil.isEncodedGroup(address)
val isClosedGroup: Boolean
get() = GroupUtil.isClosedGroup(address)
val isOpenGroup: Boolean
get() = GroupUtil.isOpenGroup(address)
val isOpenGroupInbox: Boolean
get() = GroupUtil.isOpenGroupInbox(address)
val isOpenGroupOutbox: Boolean
val isCommunity: Boolean
get() = GroupUtil.isCommunity(address)
val isCommunityInbox: Boolean
get() = GroupUtil.isCommunityInbox(address)
val isCommunityOutbox: Boolean
get() = address.startsWith(IdPrefix.BLINDED.value) || address.startsWith(IdPrefix.BLINDEDV2.value)
val isContact: Boolean
get() = !(isGroup || isOpenGroupInbox)
get() = !(isGroup || isCommunityInbox)
fun contactIdentifier(): String {
if (!isContact && !isOpenGroup) {
if (!isContact && !isCommunity) {
if (isGroup) throw AssertionError("Not e164, is group")
throw AssertionError("Not e164, unknown")
}

View File

@@ -22,7 +22,7 @@ class GroupRecord(
}
val isOpenGroup: Boolean
get() = Address.fromSerialized(encodedId).isOpenGroup
get() = Address.fromSerialized(encodedId).isCommunity
val isClosedGroup: Boolean
get() = Address.fromSerialized(encodedId).isClosedGroup

View File

@@ -8,12 +8,12 @@ import java.io.IOException
object GroupUtil {
const val CLOSED_GROUP_PREFIX = "__textsecure_group__!"
const val OPEN_GROUP_PREFIX = "__loki_public_chat_group__!"
const val OPEN_GROUP_INBOX_PREFIX = "__open_group_inbox__!"
const val COMMUNITY_PREFIX = "__loki_public_chat_group__!"
const val COMMUNITY_INBOX_PREFIX = "__open_group_inbox__!"
@JvmStatic
fun getEncodedOpenGroupID(groupID: ByteArray): String {
return OPEN_GROUP_PREFIX + Hex.toStringCondensed(groupID)
return COMMUNITY_PREFIX + Hex.toStringCondensed(groupID)
}
@JvmStatic
@@ -25,7 +25,7 @@ object GroupUtil {
@JvmStatic
fun getEncodedOpenGroupInboxID(groupInboxID: ByteArray): Address {
return Address.fromSerialized(OPEN_GROUP_INBOX_PREFIX + Hex.toStringCondensed(groupInboxID))
return Address.fromSerialized(COMMUNITY_INBOX_PREFIX + Hex.toStringCondensed(groupInboxID))
}
@JvmStatic
@@ -69,17 +69,17 @@ object GroupUtil {
}
fun isEncodedGroup(groupId: String): Boolean {
return groupId.startsWith(CLOSED_GROUP_PREFIX) || groupId.startsWith(OPEN_GROUP_PREFIX)
return groupId.startsWith(CLOSED_GROUP_PREFIX) || groupId.startsWith(COMMUNITY_PREFIX)
}
@JvmStatic
fun isOpenGroup(groupId: String): Boolean {
return groupId.startsWith(OPEN_GROUP_PREFIX)
fun isCommunity(groupId: String): Boolean {
return groupId.startsWith(COMMUNITY_PREFIX)
}
@JvmStatic
fun isOpenGroupInbox(groupId: String): Boolean {
return groupId.startsWith(OPEN_GROUP_INBOX_PREFIX)
fun isCommunityInbox(groupId: String): Boolean {
return groupId.startsWith(COMMUNITY_INBOX_PREFIX)
}
@JvmStatic

View File

@@ -459,16 +459,16 @@ public class Recipient implements RecipientModifiedListener {
}
public boolean is1on1() { return address.isContact() && !isLocalNumber; }
public boolean isOpenGroupRecipient() {
return address.isOpenGroup();
public boolean isCommunityRecipient() {
return address.isCommunity();
}
public boolean isOpenGroupOutboxRecipient() {
return address.isOpenGroupOutbox();
return address.isCommunityOutbox();
}
public boolean isOpenGroupInboxRecipient() {
return address.isOpenGroupInbox();
return address.isCommunityInbox();
}
public boolean isClosedGroupRecipient() {