Remove UUIDs from GV1 membership lists.
parent
1ab61beeb9
commit
5c110ca359
|
@ -36,6 +36,7 @@ import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupC
|
|||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.security.SecureRandom;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
@ -122,12 +123,15 @@ final class GroupManagerV1 {
|
|||
RecipientId groupRecipientId = DatabaseFactory.getRecipientDatabase(context).getOrInsertFromGroupId(groupId);
|
||||
Recipient groupRecipient = Recipient.resolved(groupRecipientId);
|
||||
|
||||
List<GroupContext.Member> uuidMembers = new LinkedList<>();
|
||||
List<String> e164Members = new LinkedList<>();
|
||||
List<GroupContext.Member> uuidMembers = new ArrayList<>(members.size());
|
||||
List<String> e164Members = new ArrayList<>(members.size());
|
||||
|
||||
for (RecipientId member : members) {
|
||||
Recipient recipient = Recipient.resolved(member);
|
||||
uuidMembers.add(GroupV1MessageProcessor.createMember(RecipientUtil.toSignalServiceAddress(context, recipient)));
|
||||
if (recipient.hasE164()) {
|
||||
e164Members.add(recipient.requireE164());
|
||||
uuidMembers.add(GroupV1MessageProcessor.createMember(recipient.requireE164()));
|
||||
}
|
||||
}
|
||||
|
||||
GroupContext.Builder groupContextBuilder = GroupContext.newBuilder()
|
||||
|
@ -135,7 +139,9 @@ final class GroupManagerV1 {
|
|||
.setType(GroupContext.Type.UPDATE)
|
||||
.addAllMembersE164(e164Members)
|
||||
.addAllMembers(uuidMembers);
|
||||
|
||||
if (groupName != null) groupContextBuilder.setName(groupName);
|
||||
|
||||
GroupContext groupContext = groupContextBuilder.build();
|
||||
|
||||
if (avatar != null) {
|
||||
|
|
|
@ -101,7 +101,7 @@ public final class GroupV1MessageProcessor {
|
|||
|
||||
if (group.getMembers().isPresent()) {
|
||||
for (SignalServiceAddress member : group.getMembers().get()) {
|
||||
members.add(Recipient.externalPush(context, member).getId());
|
||||
members.add(Recipient.externalGV1Member(context, member).getId());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -131,8 +131,10 @@ public final class GroupV1MessageProcessor {
|
|||
Set<RecipientId> recordMembers = new HashSet<>(groupRecord.getMembers());
|
||||
Set<RecipientId> messageMembers = new HashSet<>();
|
||||
|
||||
for (SignalServiceAddress messageMember : group.getMembers().get()) {
|
||||
messageMembers.add(Recipient.externalPush(context, messageMember).getId());
|
||||
if (group.getMembers().isPresent()) {
|
||||
for (SignalServiceAddress messageMember : group.getMembers().get()) {
|
||||
messageMembers.add(Recipient.externalGV1Member(context, messageMember).getId());
|
||||
}
|
||||
}
|
||||
|
||||
Set<RecipientId> addedMembers = new HashSet<>(messageMembers);
|
||||
|
@ -150,18 +152,19 @@ public final class GroupV1MessageProcessor {
|
|||
database.updateMembers(id, new LinkedList<>(unionMembers));
|
||||
|
||||
builder.clearMembers();
|
||||
builder.clearMembersE164();
|
||||
|
||||
for (RecipientId addedMember : addedMembers) {
|
||||
Recipient recipient = Recipient.resolved(addedMember);
|
||||
|
||||
if (recipient.getE164().isPresent()) {
|
||||
builder.addMembersE164(recipient.getE164().get());
|
||||
builder.addMembersE164(recipient.requireE164());
|
||||
builder.addMembers(createMember(recipient.requireE164()));
|
||||
}
|
||||
|
||||
builder.addMembers(createMember(RecipientUtil.toSignalServiceAddress(context, recipient)));
|
||||
}
|
||||
} else {
|
||||
builder.clearMembers();
|
||||
builder.clearMembersE164();
|
||||
}
|
||||
|
||||
if (missingMembers.size() > 0) {
|
||||
|
@ -287,6 +290,8 @@ public final class GroupV1MessageProcessor {
|
|||
.map(a -> a.getNumber().get())
|
||||
.toList());
|
||||
builder.addAllMembers(Stream.of(group.getMembers().get())
|
||||
.filter(address -> address.getNumber().isPresent())
|
||||
.map(address -> address.getNumber().get())
|
||||
.map(GroupV1MessageProcessor::createMember)
|
||||
.toList());
|
||||
}
|
||||
|
@ -294,17 +299,9 @@ public final class GroupV1MessageProcessor {
|
|||
return builder;
|
||||
}
|
||||
|
||||
public static GroupContext.Member createMember(SignalServiceAddress address) {
|
||||
public static GroupContext.Member createMember(@NonNull String e164) {
|
||||
GroupContext.Member.Builder member = GroupContext.Member.newBuilder();
|
||||
|
||||
if (address.getUuid().isPresent()) {
|
||||
member.setUuid(address.getUuid().get().toString());
|
||||
}
|
||||
|
||||
if (address.getNumber().isPresent()) {
|
||||
member.setE164(address.getNumber().get());
|
||||
}
|
||||
|
||||
member.setE164(e164);
|
||||
return member.build();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -323,8 +323,8 @@ public final class PushGroupSendJob extends PushSendJob {
|
|||
GroupContext groupContext = properties.getGroupContext();
|
||||
SignalServiceAttachment avatar = attachmentPointers.isEmpty() ? null : attachmentPointers.get(0);
|
||||
SignalServiceGroup.Type type = properties.isQuit() ? SignalServiceGroup.Type.QUIT : SignalServiceGroup.Type.UPDATE;
|
||||
List<SignalServiceAddress> members = Stream.of(groupContext.getMembersList())
|
||||
.map(m -> new SignalServiceAddress(UuidUtil.parseOrNull(m.getUuid()), m.getE164()))
|
||||
List<SignalServiceAddress> members = Stream.of(groupContext.getMembersE164List())
|
||||
.map(e164 -> new SignalServiceAddress(null, e164))
|
||||
.toList();
|
||||
SignalServiceGroup group = new SignalServiceGroup(type, groupId.getDecodedId(), groupContext.getName(), members, avatar);
|
||||
SignalServiceDataMessage groupDataMessage = SignalServiceDataMessage.newBuilder()
|
||||
|
|
|
@ -3,6 +3,8 @@ package org.thoughtcrime.securesms.mms;
|
|||
import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import com.annimon.stream.Stream;
|
||||
|
||||
import org.signal.storageservice.protos.groups.local.DecryptedMember;
|
||||
import org.signal.zkgroup.InvalidInputException;
|
||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||
|
@ -11,6 +13,7 @@ import org.thoughtcrime.securesms.recipients.Recipient;
|
|||
import org.thoughtcrime.securesms.recipients.RecipientId;
|
||||
import org.thoughtcrime.securesms.util.Base64;
|
||||
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
|
||||
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
|
||||
import org.whispersystems.signalservice.api.util.UuidUtil;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContext;
|
||||
import org.whispersystems.signalservice.internal.push.SignalServiceProtos.GroupContextV2;
|
||||
|
@ -123,20 +126,13 @@ public final class MessageGroupContext {
|
|||
|
||||
@Override
|
||||
public @NonNull List<RecipientId> getMembersListExcludingSelf() {
|
||||
List<GroupContext.Member> membersList = groupContext.getMembersList();
|
||||
if (membersList.isEmpty()) {
|
||||
return Collections.emptyList();
|
||||
} else {
|
||||
LinkedList<RecipientId> members = new LinkedList<>();
|
||||
RecipientId selfId = Recipient.self().getId();
|
||||
|
||||
for (GroupContext.Member member : membersList) {
|
||||
RecipientId recipient = RecipientId.from(UuidUtil.parseOrNull(member.getUuid()), member.getE164());
|
||||
if (!Recipient.self().getId().equals(recipient)) {
|
||||
members.add(recipient);
|
||||
}
|
||||
}
|
||||
return members;
|
||||
}
|
||||
return Stream.of(groupContext.getMembersE164List())
|
||||
.map(e164 -> new SignalServiceAddress(null, e164))
|
||||
.map(RecipientId::from)
|
||||
.filterNot(selfId::equals)
|
||||
.toList();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -157,6 +157,20 @@ public class Recipient {
|
|||
return externalPush(context, signalServiceAddress.getUuid().orNull(), signalServiceAddress.getNumber().orNull(), false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fully-populated {@link Recipient} based off of a {@link SignalServiceAddress},
|
||||
* creating one in the database if necessary. We special-case GV1 members because we want to
|
||||
* prioritize E164 addresses and not use the UUIDs if possible.
|
||||
*/
|
||||
@WorkerThread
|
||||
public static @NonNull Recipient externalGV1Member(@NonNull Context context, @NonNull SignalServiceAddress address) {
|
||||
if (address.getNumber().isPresent()) {
|
||||
return externalPush(context, null, address.getNumber().get(), false);
|
||||
} else {
|
||||
return externalPush(context, address.getUuid().orNull(), null, false);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a fully-populated {@link Recipient} based off of a {@link SignalServiceAddress},
|
||||
* creating one in the database if necessary. This should only used for high-trust sources,
|
||||
|
|
|
@ -1060,19 +1060,12 @@ public class SignalServiceMessageSender {
|
|||
for (SignalServiceAddress address : group.getMembers().get()) {
|
||||
if (address.getNumber().isPresent()) {
|
||||
builder.addMembersE164(address.getNumber().get());
|
||||
}
|
||||
|
||||
GroupContext.Member.Builder memberBuilder = GroupContext.Member.newBuilder();
|
||||
|
||||
if (address.getUuid().isPresent()) {
|
||||
memberBuilder.setUuid(address.getUuid().get().toString());
|
||||
}
|
||||
|
||||
if (address.getNumber().isPresent()) {
|
||||
GroupContext.Member.Builder memberBuilder = GroupContext.Member.newBuilder();
|
||||
memberBuilder.setE164(address.getNumber().get());
|
||||
}
|
||||
|
||||
builder.addMembers(memberBuilder.build());
|
||||
builder.addMembers(memberBuilder.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -873,8 +873,8 @@ public final class SignalServiceContent {
|
|||
members = new ArrayList<>(content.getGroup().getMembersCount());
|
||||
|
||||
for (SignalServiceProtos.GroupContext.Member member : content.getGroup().getMembersList()) {
|
||||
if (SignalServiceAddress.isValidAddress(member.getUuid(), member.getE164())) {
|
||||
members.add(new SignalServiceAddress(UuidUtil.parseOrNull(member.getUuid()), member.getE164()));
|
||||
if (SignalServiceAddress.isValidAddress(null, member.getE164())) {
|
||||
members.add(new SignalServiceAddress(null, member.getE164()));
|
||||
} else {
|
||||
throw new ProtocolInvalidMessageException(new InvalidMessageException("GroupContext.Member had no address!"), null, 0);
|
||||
}
|
||||
|
|
|
@ -61,8 +61,8 @@ public class DeviceGroupsInputStream extends ChunkedInputStream{
|
|||
|
||||
List<SignalServiceAddress> addressMembers = new ArrayList<>(members.size());
|
||||
for (GroupDetails.Member member : members) {
|
||||
if (SignalServiceAddress.isValidAddress(member.getUuid(), member.getE164())) {
|
||||
addressMembers.add(new SignalServiceAddress(UuidUtil.parseOrNull(member.getUuid()), member.getE164()));
|
||||
if (SignalServiceAddress.isValidAddress(null, member.getE164())) {
|
||||
addressMembers.add(new SignalServiceAddress(null, member.getE164()));
|
||||
} else {
|
||||
throw new IOException("Missing group member address!");
|
||||
}
|
||||
|
|
|
@ -65,18 +65,13 @@ public class DeviceGroupsOutputStream extends ChunkedOutputStream {
|
|||
List<String> membersE164 = new ArrayList<>(group.getMembers().size());
|
||||
|
||||
for (SignalServiceAddress address : group.getMembers()) {
|
||||
GroupDetails.Member.Builder builder = GroupDetails.Member.newBuilder();
|
||||
|
||||
if (address.getUuid().isPresent()) {
|
||||
builder.setUuid(address.getUuid().get().toString());
|
||||
}
|
||||
|
||||
if (address.getNumber().isPresent()) {
|
||||
builder.setE164(address.getNumber().get());
|
||||
membersE164.add(address.getNumber().get());
|
||||
}
|
||||
|
||||
members.add(builder.build());
|
||||
GroupDetails.Member.Builder builder = GroupDetails.Member.newBuilder();
|
||||
builder.setE164(address.getNumber().get());
|
||||
members.add(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
groupDetails.addAllMembers(members);
|
||||
|
|
|
@ -435,7 +435,7 @@ message GroupContext {
|
|||
}
|
||||
|
||||
message Member {
|
||||
optional string uuid = 1;
|
||||
// 1 is reserved
|
||||
optional string e164 = 2;
|
||||
}
|
||||
|
||||
|
@ -479,7 +479,7 @@ message GroupDetails {
|
|||
}
|
||||
|
||||
message Member {
|
||||
optional string uuid = 1;
|
||||
// 1 is reserved
|
||||
optional string e164 = 2;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue