Implement remove group members

This commit is contained in:
AsamK 2021-05-14 22:23:13 +02:00
parent 4ebacd0e1f
commit a91e3f762e
4 changed files with 77 additions and 6 deletions

View file

@ -826,22 +826,33 @@ public class Manager implements Closeable {
}
public Pair<Long, List<SendMessageResult>> updateGroup(
GroupId groupId, String name, String description, List<String> members, File avatarFile
GroupId groupId,
String name,
String description,
List<String> members,
List<String> removeMembers,
File avatarFile
) throws IOException, GroupNotFoundException, AttachmentInvalidException, InvalidNumberException, NotAGroupMemberException {
return updateGroup(groupId,
name,
description,
members == null ? null : getSignalServiceAddresses(members),
removeMembers == null ? null : getSignalServiceAddresses(removeMembers),
avatarFile);
}
private Pair<Long, List<SendMessageResult>> updateGroup(
GroupId groupId, String name, String description, Set<RecipientId> members, File avatarFile
GroupId groupId,
String name,
String description,
Set<RecipientId> members,
final Set<RecipientId> removeMembers,
File avatarFile
) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException {
var group = getGroupForUpdating(groupId);
if (group instanceof GroupInfoV2) {
return updateGroupV2((GroupInfoV2) group, name, description, members, avatarFile);
return updateGroupV2((GroupInfoV2) group, name, description, members, removeMembers, avatarFile);
}
return updateGroupV1((GroupInfoV1) group, name, members, avatarFile);
@ -901,6 +912,7 @@ public class Manager implements Closeable {
final String name,
final String description,
final Set<RecipientId> members,
final Set<RecipientId> removeMembers,
final File avatarFile
) throws IOException {
Pair<Long, List<SendMessageResult>> result = null;
@ -917,6 +929,24 @@ public class Manager implements Closeable {
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
}
}
if (removeMembers != null) {
var existingRemoveMembers = new HashSet<>(removeMembers);
existingRemoveMembers.retainAll(group.getMembers());
existingRemoveMembers.remove(getSelfRecipientId());// self can be removed with sendQuitGroupMessage
if (existingRemoveMembers.size() > 0) {
var groupGroupChangePair = groupHelper.removeMembers(group, existingRemoveMembers);
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
}
var pendingRemoveMembers = new HashSet<>(removeMembers);
pendingRemoveMembers.retainAll(group.getPendingMembers());
if (pendingRemoveMembers.size() > 0) {
var groupGroupChangePair = groupHelper.revokeInvitedMembers(group, pendingRemoveMembers);
result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second());
}
}
if (result == null || name != null || description != null || avatarFile != null) {
var groupGroupChangePair = groupHelper.updateGroupV2(group, name, description, avatarFile);
if (avatarFile != null) {
@ -954,10 +984,14 @@ public class Manager implements Closeable {
private Pair<Long, List<SendMessageResult>> sendUpdateGroupV2Message(
GroupInfoV2 group, DecryptedGroup newDecryptedGroup, GroupChange groupChange
) throws IOException {
final var selfRecipientId = account.getSelfRecipientId();
final var members = group.getMembersIncludingPendingWithout(selfRecipientId);
group.setGroup(newDecryptedGroup, this::resolveRecipient);
members.addAll(group.getMembersIncludingPendingWithout(selfRecipientId));
final var messageBuilder = getGroupUpdateMessageBuilder(group, groupChange.toByteArray());
account.getGroupStore().updateGroup(group);
return sendMessage(messageBuilder, group.getMembersIncludingPendingWithout(account.getSelfRecipientId()));
return sendMessage(messageBuilder, members);
}
private static int currentTimeDays() {

View file

@ -263,6 +263,34 @@ public class GroupHelper {
}
}
public Pair<DecryptedGroup, GroupChange> removeMembers(
GroupInfoV2 groupInfoV2, Set<RecipientId> members
) throws IOException {
final var memberUuids = members.stream()
.map(addressResolver::resolveSignalServiceAddress)
.map(SignalServiceAddress::getUuid)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());
return ejectMembers(groupInfoV2, memberUuids);
}
public Pair<DecryptedGroup, GroupChange> revokeInvitedMembers(
GroupInfoV2 groupInfoV2, Set<RecipientId> members
) throws IOException {
var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
final var memberUuids = members.stream()
.map(addressResolver::resolveSignalServiceAddress)
.map(SignalServiceAddress::getUuid)
.filter(Optional::isPresent)
.map(Optional::get)
.map(uuid -> DecryptedGroupUtil.findPendingByUuid(pendingMembersList, uuid))
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toSet());
return revokeInvites(groupInfoV2, memberUuids);
}
public GroupChange joinGroup(
GroupMasterKey groupMasterKey,
GroupLinkPassword groupLinkPassword,
@ -309,7 +337,7 @@ public class GroupHelper {
return commitChange(groupInfoV2, change);
}
public Pair<DecryptedGroup, GroupChange> revokeInvites(
private Pair<DecryptedGroup, GroupChange> revokeInvites(
GroupInfoV2 groupInfoV2, Set<DecryptedPendingMember> pendingMembers
) throws IOException {
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
@ -324,7 +352,9 @@ public class GroupHelper {
return commitChange(groupInfoV2, groupOperations.createRemoveInvitationChange(uuidCipherTexts));
}
public Pair<DecryptedGroup, GroupChange> ejectMembers(GroupInfoV2 groupInfoV2, Set<UUID> uuids) throws IOException {
private Pair<DecryptedGroup, GroupChange> ejectMembers(
GroupInfoV2 groupInfoV2, Set<UUID> uuids
) throws IOException {
final var groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
final var groupOperations = groupsV2Operations.forGroup(groupSecretParams);
return commitChange(groupInfoV2, groupOperations.createRemoveMembersChange(uuids));

View file

@ -38,6 +38,9 @@ public class UpdateGroupCommand implements DbusCommand, LocalCommand {
subparser.addArgument("-d", "--description").help("Specify the new group description.");
subparser.addArgument("-a", "--avatar").help("Specify a new group avatar image file");
subparser.addArgument("-m", "--member").nargs("*").help("Specify one or more members to add to the group");
subparser.addArgument("-r", "--remove-member")
.nargs("*")
.help("Specify one or more members to remove from the group");
}
@Override
@ -59,6 +62,8 @@ public class UpdateGroupCommand implements DbusCommand, LocalCommand {
List<String> groupMembers = ns.getList("member");
List<String> groupRemoveMembers = ns.getList("remove-member");
var groupAvatar = ns.getString("avatar");
try {
@ -74,6 +79,7 @@ public class UpdateGroupCommand implements DbusCommand, LocalCommand {
groupName,
groupDescription,
groupMembers,
groupRemoveMembers,
groupAvatar == null ? null : new File(groupAvatar));
ErrorUtils.handleTimestampAndSendMessageResults(writer, results.first(), results.second());
}

View file

@ -344,6 +344,7 @@ public class DbusSignalImpl implements Signal {
name,
null,
members,
null,
avatar == null ? null : new File(avatar));
checkSendMessageResults(results.first(), results.second());
return groupId;