Clean ClosedGroupsProtocol ahead of SSK changes

This commit is contained in:
nielsandriesse 2020-08-07 09:15:36 +10:00
parent 9c3814df9c
commit c2d1953116
6 changed files with 32 additions and 44 deletions

View File

@ -1166,7 +1166,7 @@ public class ConversationActivity extends PassphraseRequiredActionBarActivity
builder.setMessage(getString(R.string.ConversationActivity_are_you_sure_you_want_to_leave_this_group));
builder.setPositiveButton(R.string.yes, (dialog, which) -> {
Recipient groupRecipient = getRecipient();
if (ClosedGroupsProtocol.leaveGroup(this, groupRecipient)) {
if (ClosedGroupsProtocol.leaveLegacyGroup(this, groupRecipient)) {
initializeEnabledCheck();
} else {
Toast.makeText(this, R.string.ConversationActivity_error_leaving_group, Toast.LENGTH_LONG).show();

View File

@ -97,11 +97,6 @@ public class GroupMessageProcessor {
}
}
// Loki - Ignore message if needed
if (ClosedGroupsProtocol.shouldIgnoreGroupCreatedMessage(context, group)) {
return null;
}
// Loki - Parse admins
if (group.getAdmins().isPresent()) {
for (String admin : group.getAdmins().get()) {

View File

@ -1454,7 +1454,7 @@ public class PushDecryptJob extends BaseJob implements InjectableType {
boolean isGroupActive = groupId.isPresent() && groupDatabase.isActive(groupId.get());
boolean isLeaveMessage = message.getGroupInfo().isPresent() && message.getGroupInfo().get().getType() == SignalServiceGroup.Type.QUIT;
boolean shouldIgnoreContentMessage = ClosedGroupsProtocol.shouldIgnoreContentMessage(context, conversation, groupId.orNull(), content);
boolean shouldIgnoreContentMessage = ClosedGroupsProtocol.shouldIgnoreContentMessage(context, conversation.getAddress(), groupId.orNull(), content.getSender());
return (isContentMessage && !isGroupActive) || (sender.isBlocked() && !isLeaveMessage) || (isContentMessage && shouldIgnoreContentMessage);
} else {
return sender.isBlocked();

View File

@ -154,7 +154,7 @@ public class PushGroupSendJob extends PushSendJob implements InjectableType {
if (filterAddress != null) targets = Collections.singletonList(Address.fromSerialized(filterAddress));
else if (!existingNetworkFailures.isEmpty()) targets = Stream.of(existingNetworkFailures).map(NetworkFailure::getAddress).toList();
else targets = ClosedGroupsProtocol.getDestinations(message.getRecipient().getAddress().toGroupString(), context).get();
else targets = ClosedGroupsProtocol.getMessageDestinations(context, message.getRecipient().getAddress().toGroupString());
List<SendMessageResult> results = deliver(message, targets);
List<NetworkFailure> networkFailures = Stream.of(results).filter(SendMessageResult::isNetworkFailure).map(result -> new NetworkFailure(Address.fromSerialized(result.getAddress().getNumber()))).toList();

View File

@ -31,7 +31,6 @@ import org.thoughtcrime.securesms.database.DatabaseFactory
import org.thoughtcrime.securesms.database.ThreadDatabase
import org.thoughtcrime.securesms.database.model.ThreadRecord
import org.thoughtcrime.securesms.jobs.MultiDeviceBlockedUpdateJob
import org.thoughtcrime.securesms.loki.database.LokiAPIDatabase
import org.thoughtcrime.securesms.loki.dialogs.ConversationOptionsBottomSheet
import org.thoughtcrime.securesms.loki.dialogs.MultiDeviceRemovalBottomSheet
import org.thoughtcrime.securesms.loki.protocol.ClosedGroupsProtocol
@ -333,7 +332,7 @@ class HomeActivity : PassphraseRequiredActionBarActivity, ConversationClickListe
val isClosedGroup = recipient.address.isClosedGroup
// Send a leave group message if this is an active closed group
if (isClosedGroup && DatabaseFactory.getGroupDatabase(this).isActive(recipient.address.toGroupString())) {
if (!ClosedGroupsProtocol.leaveGroup(this, recipient)) {
if (!ClosedGroupsProtocol.leaveLegacyGroup(this, recipient)) {
Toast.makeText(this, R.string.activity_home_leaving_group_failed_message, Toast.LENGTH_LONG).show()
return@setPositiveButton
}

View File

@ -1,6 +1,7 @@
package org.thoughtcrime.securesms.loki.protocol
import android.content.Context
import android.util.Log
import nl.komponents.kovenant.Promise
import nl.komponents.kovenant.functional.map
import org.thoughtcrime.securesms.ApplicationContext
@ -24,39 +25,27 @@ import java.util.*
object ClosedGroupsProtocol {
/**
* Blocks the calling thread.
*/
@JvmStatic
fun shouldIgnoreContentMessage(context: Context, conversation: Recipient, groupID: String?, content: SignalServiceContent): Boolean {
if (!conversation.address.isClosedGroup || groupID == null) { return false }
// A closed group's members should never include slave devices
val senderPublicKey = content.sender
fun shouldIgnoreContentMessage(context: Context, address: Address, groupID: String?, senderPublicKey: String): Boolean {
if (!address.isClosedGroup || groupID == null) { return false }
/*
FileServerAPI.shared.getDeviceLinks(senderPublicKey).timeout(6000).get()
val senderMasterPublicKey = MultiDeviceProtocol.shared.getMasterDevice(senderPublicKey)
val publicKeyToCheckFor = senderMasterPublicKey ?: senderPublicKey
*/
val members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupID, true)
return !members.contains(recipient(context, publicKeyToCheckFor))
return !members.contains(recipient(context, senderPublicKey))
}
@JvmStatic
fun shouldIgnoreGroupCreatedMessage(context: Context, group: SignalServiceGroup): Boolean {
val members = group.members
val masterPublicKeyOrNull = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
val masterPublicKey = masterPublicKeyOrNull ?: TextSecurePreferences.getLocalNumber(context)
return !members.isPresent || !members.get().contains(masterPublicKey)
}
@JvmStatic
fun getDestinations(groupID: String, context: Context): Promise<List<Address>, Exception> {
if (GroupUtil.isRSSFeed(groupID)) { return Promise.of(listOf()) }
fun getMessageDestinations(context: Context, groupID: String): List<Address> {
if (GroupUtil.isRSSFeed(groupID)) { return listOf() }
if (GroupUtil.isOpenGroup(groupID)) {
val result = mutableListOf<Address>()
result.add(Address.fromSerialized(groupID))
return Promise.of(result)
return listOf( Address.fromSerialized(groupID) )
} else {
// A closed group's members should never include slave devices
val members = DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupID, false)
// TODO: Shared sender keys
return DatabaseFactory.getGroupDatabase(context).getGroupMembers(groupID, false).map { it.address }
/*
return FileServerAPI.shared.getDeviceLinks(members.map { it.address.serialize() }.toSet()).map {
val result = members.flatMap { member ->
MultiDeviceProtocol.shared.getAllLinkedDevices(member.address.serialize()).map { Address.fromSerialized(it) }
@ -71,29 +60,33 @@ object ClosedGroupsProtocol {
}
result.toList()
}
*/
}
}
@JvmStatic
fun leaveGroup(context: Context, recipient: Recipient): Boolean {
fun leaveLegacyGroup(context: Context, recipient: Recipient): Boolean {
if (!recipient.address.isClosedGroup) { return true }
val threadID = DatabaseFactory.getThreadDatabase(context).getThreadIdFor(recipient)
val message = GroupUtil.createGroupLeaveMessage(context, recipient)
if (threadID < 0 || !message.isPresent) { return false }
MessageSender.send(context, message.get(), threadID, false, null)
// Remove the master device from the group (a closed group's members should never include slave devices)
val message = GroupUtil.createGroupLeaveMessage(context, recipient).orNull()
if (threadID < 0 || message == null) { return false }
MessageSender.send(context, message, threadID, false, null)
/*
val masterPublicKey = TextSecurePreferences.getMasterHexEncodedPublicKey(context)
val publicKeyToRemove = masterPublicKey ?: TextSecurePreferences.getLocalNumber(context)
*/
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
val groupDatabase = DatabaseFactory.getGroupDatabase(context)
val groupID = recipient.address.toGroupString()
groupDatabase.setActive(groupID, false)
groupDatabase.remove(groupID, Address.fromSerialized(publicKeyToRemove))
groupDatabase.remove(groupID, Address.fromSerialized(userPublicKey))
return true
}
@JvmStatic
fun establishSessionsWithMembersIfNeeded(context: Context, members: List<String>) {
// A closed group's members should never include slave devices
@Suppress("NAME_SHADOWING") val members = members.toMutableSet()
/*
val allDevices = members.flatMap { member ->
MultiDeviceProtocol.shared.getAllLinkedDevices(member)
}.toMutableSet()
@ -101,12 +94,13 @@ object ClosedGroupsProtocol {
if (userMasterPublicKey != null && allDevices.contains(userMasterPublicKey)) {
allDevices.remove(userMasterPublicKey)
}
*/
val userPublicKey = TextSecurePreferences.getLocalNumber(context)
if (userPublicKey != null && allDevices.contains(userPublicKey)) {
allDevices.remove(userPublicKey)
if (userPublicKey != null && members.contains(userPublicKey)) {
members.remove(userPublicKey)
}
for (device in allDevices) {
ApplicationContext.getInstance(context).sendSessionRequestIfNeeded(device)
for (member in members) {
ApplicationContext.getInstance(context).sendSessionRequestIfNeeded(member)
}
}
}