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 e2f5f9919d..370937b286 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 @@ -55,6 +55,16 @@ public final class DecryptedGroupUtil { return uuidList; } + public static Set membersToUuidByteStringSet(Collection membersList) { + Set uuidList = new HashSet<>(membersList.size()); + + for (DecryptedMember member : membersList) { + uuidList.add(member.getUuid()); + } + + return uuidList; + } + public static ArrayList pendingToUuidList(Collection membersList) { ArrayList uuidList = new ArrayList<>(membersList.size()); @@ -268,9 +278,22 @@ public final class DecryptedGroupUtil { .build()); } + removePendingMembersNowInGroup(builder); + return builder.setRevision(change.getRevision()).build(); } + static void removePendingMembersNowInGroup(DecryptedGroup.Builder builder) { + Set allMembers = membersToUuidByteStringSet(builder.getMembersList()); + + for (int i = builder.getPendingMembersCount() - 1; i >= 0; i--) { + DecryptedPendingMember pendingMember = builder.getPendingMembers(i); + if (allMembers.contains(pendingMember.getUuid())) { + builder.removePendingMembers(i); + } + } + } + private static int indexOfUuid(List memberList, ByteString uuid) { for (int i = 0; i < memberList.size(); i++) { if(uuid.equals(memberList.get(i).getUuid())) return i; diff --git a/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil_apply_Test.java b/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil_apply_Test.java index 721488d724..f0f77d670b 100644 --- a/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil_apply_Test.java +++ b/libsignal/service/src/test/java/org/whispersystems/signalservice/api/groupsv2/DecryptedGroupUtil_apply_Test.java @@ -269,6 +269,43 @@ public final class DecryptedGroupUtil_apply_Test { newGroup); } + @Test + public void skip_promote_pending_member_by_direct_add() throws DecryptedGroupUtil.NotAbleToApplyChangeException { + ProfileKey profileKey2 = randomProfileKey(); + ProfileKey profileKey3 = randomProfileKey(); + DecryptedMember member1 = member(UUID.randomUUID()); + UUID pending2Uuid = UUID.randomUUID(); + UUID pending3Uuid = UUID.randomUUID(); + UUID pending4Uuid = UUID.randomUUID(); + DecryptedPendingMember pending2 = pendingMember(pending2Uuid); + DecryptedPendingMember pending3 = pendingMember(pending3Uuid); + DecryptedPendingMember pending4 = pendingMember(pending4Uuid); + DecryptedMember member2 = member(pending2Uuid, profileKey2); + DecryptedMember member3 = member(pending3Uuid, profileKey3); + + DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder() + .setRevision(10) + .addMembers(member1) + .addPendingMembers(pending2) + .addPendingMembers(pending3) + .addPendingMembers(pending4) + .build(), + DecryptedGroupChange.newBuilder() + .setRevision(11) + .addNewMembers(member2) + .addNewMembers(member3) + .build()); + + assertEquals(DecryptedGroup.newBuilder() + .setRevision(11) + .addMembers(member1) + .addMembers(member2) + .addMembers(member3) + .addPendingMembers(pending4) + .build(), + newGroup); + } + @Test public void title() throws DecryptedGroupUtil.NotAbleToApplyChangeException { DecryptedGroup newGroup = DecryptedGroupUtil.apply(DecryptedGroup.newBuilder()