diff --git a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java index eafbd9a9b9..9ac584a53a 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java +++ b/app/src/main/java/org/thoughtcrime/securesms/groups/v2/processing/GroupsV2StateProcessor.java @@ -9,9 +9,11 @@ import androidx.annotation.WorkerThread; import org.signal.storageservice.protos.groups.local.DecryptedGroup; import org.signal.storageservice.protos.groups.local.DecryptedGroupChange; +import org.signal.storageservice.protos.groups.local.DecryptedPendingMember; import org.signal.zkgroup.VerificationFailedException; import org.signal.zkgroup.groups.GroupMasterKey; import org.signal.zkgroup.groups.GroupSecretParams; +import org.signal.zkgroup.util.UUIDUtil; import org.thoughtcrime.securesms.database.DatabaseFactory; import org.thoughtcrime.securesms.database.GroupDatabase; import org.thoughtcrime.securesms.database.MmsDatabase; @@ -279,7 +281,10 @@ public final class GroupsV2StateProcessor { final ProfileKeySet profileKeys = new ProfileKeySet(); for (GroupLogEntry entry : globalGroupState.getHistory()) { - profileKeys.addKeysFromGroupState(entry.getGroup(), DecryptedGroupUtil.editorUuid(entry.getChange())); + Optional editor = DecryptedGroupUtil.editorUuid(entry.getChange()); + if (editor.isPresent()) { + profileKeys.addKeysFromGroupState(entry.getGroup(), editor.get()); + } } Collection updated = recipientDatabase.persistProfileKeySet(profileKeys); @@ -335,8 +340,14 @@ public final class GroupsV2StateProcessor { } private void storeMessage(@NonNull DecryptedGroupV2Context decryptedGroupV2Context, long timestamp) { - UUID editor = DecryptedGroupUtil.editorUuid(decryptedGroupV2Context.getChange()); - boolean outgoing = Recipient.self().getUuid().get().equals(editor); + Optional editor = getEditor(decryptedGroupV2Context); + + if (!editor.isPresent() || UuidUtil.UNKNOWN_UUID.equals(editor.get())) { + Log.w(TAG, "Cannot determine editor of change, can't insert message"); + return; + } + + boolean outgoing = Recipient.self().requireUuid().equals(editor.get()); if (outgoing) { try { @@ -353,12 +364,26 @@ public final class GroupsV2StateProcessor { } } else { SmsDatabase smsDatabase = DatabaseFactory.getSmsDatabase(context); - RecipientId sender = Recipient.externalPush(context, editor, null).getId(); + RecipientId sender = RecipientId.from(editor.get(), null); IncomingTextMessage incoming = new IncomingTextMessage(sender, -1, timestamp, timestamp, "", Optional.of(groupId), 0, false); IncomingGroupUpdateMessage groupMessage = new IncomingGroupUpdateMessage(incoming, decryptedGroupV2Context); smsDatabase.insertMessageInbox(groupMessage); } } + + private Optional getEditor(@NonNull DecryptedGroupV2Context decryptedGroupV2Context) { + DecryptedGroupChange change = decryptedGroupV2Context.getChange(); + Optional changeEditor = DecryptedGroupUtil.editorUuid(change); + if (changeEditor.isPresent()) { + return changeEditor; + } else { + Optional pendingByUuid = DecryptedGroupUtil.findPendingByUuid(decryptedGroupV2Context.getGroupState().getPendingMembersList(), Recipient.self().requireUuid()); + if (pendingByUuid.isPresent()) { + return Optional.fromNullable(UuidUtil.fromByteStringOrNull(pendingByUuid.get().getAddedByUuid())); + } + } + return Optional.absent(); + } } } diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil.java index bead7b2d65..7971e8cd77 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil.java @@ -88,8 +88,8 @@ public final class DecryptedGroupUtil { /** * The UUID of the member that made the change. */ - public static UUID editorUuid(DecryptedGroupChange change) { - return change != null ? UuidUtil.fromByteStringOrUnknown(change.getEditor()) : UuidUtil.UNKNOWN_UUID; + public static Optional editorUuid(DecryptedGroupChange change) { + return Optional.fromNullable(change != null ? UuidUtil.fromByteStringOrNull(change.getEditor()) : null); } public static Optional findMemberByUuid(Collection members, UUID uuid) { diff --git a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java index 1467e35c69..89d634fb95 100644 --- a/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java +++ b/libsignal/service/src/main/java/org/whispersystems/signalservice/api/util/UuidUtil.java @@ -63,11 +63,6 @@ public final class UuidUtil { return parseOrNull(bytes.toByteArray()); } - public static UUID fromByteStringOrUnknown(ByteString bytes) { - UUID uuid = parseOrNull(bytes.toByteArray()); - return uuid != null ? uuid : UNKNOWN_UUID; - } - private static UUID parseOrNull(byte[] byteArray) { return byteArray != null && byteArray.length == 16 ? parseOrThrow(byteArray) : null; } diff --git a/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtilTest.java b/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtilTest.java index 6eacc3750a..672ec4498c 100644 --- a/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtilTest.java +++ b/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtilTest.java @@ -34,7 +34,7 @@ public final class DecryptedGroupUtilTest { .setEditor(editor) .build(); - UUID parsed = DecryptedGroupUtil.editorUuid(groupChange); + UUID parsed = DecryptedGroupUtil.editorUuid(groupChange).get(); assertEquals(uuid, parsed); }