mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 18:40:39 +00:00
Implement quit group
This commit is contained in:
parent
1fd62ee342
commit
1098b64711
2 changed files with 48 additions and 3 deletions
|
@ -739,17 +739,24 @@ public class Manager implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
public Pair<Long, List<SendMessageResult>> sendQuitGroupMessage(byte[] groupId) throws GroupNotFoundException, IOException, NotAGroupMemberException {
|
public Pair<Long, List<SendMessageResult>> sendQuitGroupMessage(byte[] groupId) throws GroupNotFoundException, IOException, NotAGroupMemberException {
|
||||||
SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.QUIT).withId(groupId).build();
|
|
||||||
|
|
||||||
SignalServiceDataMessage.Builder messageBuilder = SignalServiceDataMessage.newBuilder().asGroupMessage(group);
|
SignalServiceDataMessage.Builder messageBuilder;
|
||||||
|
|
||||||
final GroupInfo g = getGroupForSending(groupId);
|
final GroupInfo g = getGroupForSending(groupId);
|
||||||
if (g instanceof GroupInfoV1) {
|
if (g instanceof GroupInfoV1) {
|
||||||
GroupInfoV1 groupInfoV1 = (GroupInfoV1) g;
|
GroupInfoV1 groupInfoV1 = (GroupInfoV1) g;
|
||||||
|
SignalServiceGroup group = SignalServiceGroup.newBuilder(SignalServiceGroup.Type.QUIT)
|
||||||
|
.withId(groupId)
|
||||||
|
.build();
|
||||||
|
messageBuilder = SignalServiceDataMessage.newBuilder().asGroupMessage(group);
|
||||||
groupInfoV1.removeMember(account.getSelfAddress());
|
groupInfoV1.removeMember(account.getSelfAddress());
|
||||||
account.getGroupStore().updateGroup(groupInfoV1);
|
account.getGroupStore().updateGroup(groupInfoV1);
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("TODO Not implemented!");
|
final GroupInfoV2 groupInfoV2 = (GroupInfoV2) g;
|
||||||
|
final Pair<DecryptedGroup, GroupChange> groupGroupChangePair = groupHelper.leaveGroup(groupInfoV2);
|
||||||
|
groupInfoV2.setGroup(groupGroupChangePair.first());
|
||||||
|
messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().toByteArray());
|
||||||
|
account.getGroupStore().updateGroup(groupInfoV2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return sendMessage(messageBuilder, g.getMembersWithout(account.getSelfAddress()));
|
return sendMessage(messageBuilder, g.getMembersWithout(account.getSelfAddress()));
|
||||||
|
|
|
@ -8,9 +8,12 @@ import org.signal.storageservice.protos.groups.GroupChange;
|
||||||
import org.signal.storageservice.protos.groups.Member;
|
import org.signal.storageservice.protos.groups.Member;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
|
||||||
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
import org.signal.storageservice.protos.groups.local.DecryptedGroupChange;
|
||||||
|
import org.signal.storageservice.protos.groups.local.DecryptedPendingMember;
|
||||||
|
import org.signal.zkgroup.InvalidInputException;
|
||||||
import org.signal.zkgroup.VerificationFailedException;
|
import org.signal.zkgroup.VerificationFailedException;
|
||||||
import org.signal.zkgroup.groups.GroupMasterKey;
|
import org.signal.zkgroup.groups.GroupMasterKey;
|
||||||
import org.signal.zkgroup.groups.GroupSecretParams;
|
import org.signal.zkgroup.groups.GroupSecretParams;
|
||||||
|
import org.signal.zkgroup.groups.UuidCiphertext;
|
||||||
import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
import org.signal.zkgroup.profiles.ProfileKeyCredential;
|
||||||
import org.whispersystems.libsignal.util.Pair;
|
import org.whispersystems.libsignal.util.Pair;
|
||||||
import org.whispersystems.libsignal.util.guava.Optional;
|
import org.whispersystems.libsignal.util.guava.Optional;
|
||||||
|
@ -28,6 +31,7 @@ import java.io.FileInputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
@ -198,6 +202,40 @@ public class GroupHelper {
|
||||||
return commitChange(groupInfoV2, change);
|
return commitChange(groupInfoV2, change);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Pair<DecryptedGroup, GroupChange> leaveGroup(GroupInfoV2 groupInfoV2) throws IOException {
|
||||||
|
List<DecryptedPendingMember> pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
|
||||||
|
final UUID selfUuid = selfAddressProvider.getSelfAddress().getUuid().get();
|
||||||
|
Optional<DecryptedPendingMember> selfPendingMember = DecryptedGroupUtil.findPendingByUuid(pendingMembersList,
|
||||||
|
selfUuid);
|
||||||
|
|
||||||
|
if (selfPendingMember.isPresent()) {
|
||||||
|
return revokeInvites(groupInfoV2, Set.of(selfPendingMember.get()));
|
||||||
|
} else {
|
||||||
|
return ejectMembers(groupInfoV2, Set.of(selfUuid));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<DecryptedGroup, GroupChange> revokeInvites(
|
||||||
|
GroupInfoV2 groupInfoV2, Set<DecryptedPendingMember> pendingMembers
|
||||||
|
) throws IOException {
|
||||||
|
final GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||||
|
final GroupsV2Operations.GroupOperations groupOperations = groupsV2Operations.forGroup(groupSecretParams);
|
||||||
|
final Set<UuidCiphertext> uuidCipherTexts = pendingMembers.stream().map(member -> {
|
||||||
|
try {
|
||||||
|
return new UuidCiphertext(member.getUuidCipherText().toByteArray());
|
||||||
|
} catch (InvalidInputException e) {
|
||||||
|
throw new AssertionError(e);
|
||||||
|
}
|
||||||
|
}).collect(Collectors.toSet());
|
||||||
|
return commitChange(groupInfoV2, groupOperations.createRemoveInvitationChange(uuidCipherTexts));
|
||||||
|
}
|
||||||
|
|
||||||
|
public Pair<DecryptedGroup, GroupChange> ejectMembers(GroupInfoV2 groupInfoV2, Set<UUID> uuids) throws IOException {
|
||||||
|
final GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
|
||||||
|
final GroupsV2Operations.GroupOperations groupOperations = groupsV2Operations.forGroup(groupSecretParams);
|
||||||
|
return commitChange(groupInfoV2, groupOperations.createRemoveMembersChange(uuids));
|
||||||
|
}
|
||||||
|
|
||||||
private Pair<DecryptedGroup, GroupChange> commitChange(
|
private Pair<DecryptedGroup, GroupChange> commitChange(
|
||||||
GroupInfoV2 groupInfoV2, GroupChange.Actions.Builder change
|
GroupInfoV2 groupInfoV2, GroupChange.Actions.Builder change
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue