Improve GV2 Invitation revoke experience.

This commit is contained in:
Alan Evans
2020-08-06 15:06:15 -03:00
committed by Greyson Parrelli
parent c8ed0b19f0
commit 810ccf8e94
9 changed files with 241 additions and 25 deletions

View File

@@ -10,7 +10,6 @@ import org.signal.storageservice.protos.groups.local.DecryptedMember;
import org.signal.storageservice.protos.groups.local.DecryptedModifyMemberRole;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.zkgroup.util.UUIDUtil;
import org.whispersystems.libsignal.logging.Log;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.util.UuidUtil;
@@ -43,7 +42,11 @@ public final class DecryptedGroupUtil {
ArrayList<UUID> uuidList = new ArrayList<>(membersList.size());
for (DecryptedMember member : membersList) {
uuidList.add(toUuid(member));
UUID uuid = toUuid(member);
if (!UuidUtil.UNKNOWN_UUID.equals(uuid)) {
uuidList.add(uuid);
}
}
return uuidList;
@@ -59,6 +62,9 @@ public final class DecryptedGroupUtil {
return uuidList;
}
/**
* Can return non-decryptable member UUIDs as {@link UuidUtil#UNKNOWN_UUID}.
*/
public static ArrayList<UUID> pendingToUuidList(Collection<DecryptedPendingMember> membersList) {
ArrayList<UUID> uuidList = new ArrayList<>(membersList.size());
@@ -69,11 +75,37 @@ public final class DecryptedGroupUtil {
return uuidList;
}
/**
* Will not return any non-decryptable member UUIDs.
*/
public static ArrayList<UUID> removedMembersUuidList(DecryptedGroupChange groupChange) {
ArrayList<UUID> uuidList = new ArrayList<>(groupChange.getDeleteMembersCount());
List<ByteString> deletedMembers = groupChange.getDeleteMembersList();
ArrayList<UUID> uuidList = new ArrayList<>(deletedMembers.size());
for (ByteString member : groupChange.getDeleteMembersList()) {
uuidList.add(toUuid(member));
for (ByteString member : deletedMembers) {
UUID uuid = toUuid(member);
if (!UuidUtil.UNKNOWN_UUID.equals(uuid)) {
uuidList.add(uuid);
}
}
return uuidList;
}
/**
* Will not return any non-decryptable member UUIDs.
*/
public static ArrayList<UUID> removedPendingMembersUuidList(DecryptedGroupChange groupChange) {
List<DecryptedPendingMemberRemoval> deletedPendingMembers = groupChange.getDeletePendingMembersList();
ArrayList<UUID> uuidList = new ArrayList<>(deletedPendingMembers.size());
for (DecryptedPendingMemberRemoval member : deletedPendingMembers) {
UUID uuid = toUuid(member.getUuid());
if(!UuidUtil.UNKNOWN_UUID.equals(uuid)) {
uuidList.add(uuid);
}
}
return uuidList;
@@ -87,8 +119,8 @@ public final class DecryptedGroupUtil {
return toUuid(member.getUuid());
}
private static UUID toUuid(ByteString member) {
return UUIDUtil.deserialize(member.toByteArray());
private static UUID toUuid(ByteString memberUuid) {
return UuidUtil.fromByteStringOrUnknown(memberUuid);
}
/**

View File

@@ -5,12 +5,25 @@ import com.google.protobuf.ByteString;
import org.junit.Test;
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
import org.signal.storageservice.protos.groups.local.DecryptedMember;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
import org.signal.storageservice.protos.groups.local.DecryptedPendingMemberRemoval;
import org.signal.zkgroup.util.UUIDUtil;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.internal.util.Util;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.UUID;
import static java.util.Arrays.asList;
import static java.util.Collections.emptyList;
import static java.util.Collections.singleton;
import static java.util.Collections.singletonList;
import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertThat;
public final class DecryptedGroupUtilTest {
@@ -26,6 +39,17 @@ public final class DecryptedGroupUtilTest {
assertEquals(uuid, parsed);
}
@Test
public void can_extract_uuid_from_bad_decrypted_member() {
DecryptedMember decryptedMember = DecryptedMember.newBuilder()
.setUuid(ByteString.copyFrom(new byte[0]))
.build();
UUID parsed = DecryptedGroupUtil.toUuid(decryptedMember);
assertEquals(UuidUtil.UNKNOWN_UUID, parsed);
}
@Test
public void can_extract_editor_uuid_from_decrypted_group_change() {
UUID uuid = UUID.randomUUID();
@@ -39,4 +63,91 @@ public final class DecryptedGroupUtilTest {
assertEquals(uuid, parsed);
}
@Test
public void can_extract_uuid_from_decrypted_pending_member() {
UUID uuid = UUID.randomUUID();
DecryptedPendingMember decryptedMember = DecryptedPendingMember.newBuilder()
.setUuid(UuidUtil.toByteString(uuid))
.build();
UUID parsed = DecryptedGroupUtil.toUuid(decryptedMember);
assertEquals(uuid, parsed);
}
@Test
public void can_extract_uuid_from_bad_decrypted_pending_member() {
DecryptedPendingMember decryptedMember = DecryptedPendingMember.newBuilder()
.setUuid(ByteString.copyFrom(Util.getSecretBytes(17)))
.build();
UUID parsed = DecryptedGroupUtil.toUuid(decryptedMember);
assertEquals(UuidUtil.UNKNOWN_UUID, parsed);
}
@Test
public void can_extract_uuids_for_all_pending_including_bad_entries() {
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.randomUUID();
DecryptedPendingMember decryptedMember1 = DecryptedPendingMember.newBuilder()
.setUuid(UuidUtil.toByteString(uuid1))
.build();
DecryptedPendingMember decryptedMember2 = DecryptedPendingMember.newBuilder()
.setUuid(UuidUtil.toByteString(uuid2))
.build();
DecryptedPendingMember decryptedMember3 = DecryptedPendingMember.newBuilder()
.setUuid(ByteString.copyFrom(Util.getSecretBytes(17)))
.build();
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder()
.addNewPendingMembers(decryptedMember1)
.addNewPendingMembers(decryptedMember2)
.addNewPendingMembers(decryptedMember3)
.build();
List<UUID> pendingUuids = DecryptedGroupUtil.pendingToUuidList(groupChange.getNewPendingMembersList());
assertThat(pendingUuids, is(asList(uuid1, uuid2, UuidUtil.UNKNOWN_UUID)));
}
@Test
public void can_extract_uuids_for_all_deleted_pending_excluding_bad_entries() {
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.randomUUID();
DecryptedPendingMemberRemoval decryptedMember1 = DecryptedPendingMemberRemoval.newBuilder()
.setUuid(UuidUtil.toByteString(uuid1))
.build();
DecryptedPendingMemberRemoval decryptedMember2 = DecryptedPendingMemberRemoval.newBuilder()
.setUuid(UuidUtil.toByteString(uuid2))
.build();
DecryptedPendingMemberRemoval decryptedMember3 = DecryptedPendingMemberRemoval.newBuilder()
.setUuid(ByteString.copyFrom(Util.getSecretBytes(17)))
.build();
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder()
.addDeletePendingMembers(decryptedMember1)
.addDeletePendingMembers(decryptedMember2)
.addDeletePendingMembers(decryptedMember3)
.build();
List<UUID> removedUuids = DecryptedGroupUtil.removedPendingMembersUuidList(groupChange);
assertThat(removedUuids, is(asList(uuid1, uuid2)));
}
@Test
public void can_extract_uuids_for_all_deleted_members_excluding_bad_entries() {
UUID uuid1 = UUID.randomUUID();
UUID uuid2 = UUID.randomUUID();
DecryptedGroupChange groupChange = DecryptedGroupChange.newBuilder()
.addDeleteMembers(UuidUtil.toByteString(uuid1))
.addDeleteMembers(UuidUtil.toByteString(uuid2))
.addDeleteMembers(ByteString.copyFrom(Util.getSecretBytes(17)))
.build();
List<UUID> removedUuids = DecryptedGroupUtil.removedMembersUuidList(groupChange);
assertThat(removedUuids, is(asList(uuid1, uuid2)));
}
}