mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 02:20:39 +00:00
Prevent last admin from leaving group
This commit is contained in:
parent
78f22c7020
commit
ea633efc9c
5 changed files with 56 additions and 8 deletions
|
@ -27,6 +27,7 @@ import org.asamk.signal.manager.groups.GroupLinkState;
|
|||
import org.asamk.signal.manager.groups.GroupNotFoundException;
|
||||
import org.asamk.signal.manager.groups.GroupPermission;
|
||||
import org.asamk.signal.manager.groups.GroupUtils;
|
||||
import org.asamk.signal.manager.groups.LastGroupAdminException;
|
||||
import org.asamk.signal.manager.groups.NotAGroupMemberException;
|
||||
import org.asamk.signal.manager.helper.GroupV2Helper;
|
||||
import org.asamk.signal.manager.helper.PinHelper;
|
||||
|
@ -763,7 +764,9 @@ public class Manager implements Closeable {
|
|||
return sendMessage(messageBuilder, g.getMembersWithout(account.getSelfRecipientId()));
|
||||
}
|
||||
|
||||
public Pair<Long, List<SendMessageResult>> sendQuitGroupMessage(GroupId groupId) throws GroupNotFoundException, IOException, NotAGroupMemberException {
|
||||
public Pair<Long, List<SendMessageResult>> sendQuitGroupMessage(
|
||||
GroupId groupId, Set<String> groupAdmins
|
||||
) throws GroupNotFoundException, IOException, NotAGroupMemberException, InvalidNumberException, LastGroupAdminException {
|
||||
SignalServiceDataMessage.Builder messageBuilder;
|
||||
|
||||
final var g = getGroupForUpdating(groupId);
|
||||
|
@ -775,7 +778,18 @@ public class Manager implements Closeable {
|
|||
account.getGroupStore().updateGroup(groupInfoV1);
|
||||
} else {
|
||||
final var groupInfoV2 = (GroupInfoV2) g;
|
||||
final var groupGroupChangePair = groupV2Helper.leaveGroup(groupInfoV2);
|
||||
final var currentAdmins = g.getAdminMembers();
|
||||
final var newAdmins = getSignalServiceAddresses(groupAdmins);
|
||||
newAdmins.removeAll(currentAdmins);
|
||||
newAdmins.retainAll(g.getMembers());
|
||||
if (currentAdmins.contains(getSelfRecipientId())
|
||||
&& currentAdmins.size() == 1
|
||||
&& g.getMembers().size() > 1
|
||||
&& newAdmins.size() == 0) {
|
||||
// Last admin can't leave the group, unless she's also the last member
|
||||
throw new LastGroupAdminException(g.getGroupId(), g.getTitle());
|
||||
}
|
||||
final var groupGroupChangePair = groupV2Helper.leaveGroup(groupInfoV2, newAdmins);
|
||||
groupInfoV2.setGroup(groupGroupChangePair.first(), this::resolveRecipient);
|
||||
messageBuilder = getGroupUpdateMessageBuilder(groupInfoV2, groupGroupChangePair.second().toByteArray());
|
||||
account.getGroupStore().updateGroup(groupInfoV2);
|
||||
|
|
|
@ -0,0 +1,8 @@
|
|||
package org.asamk.signal.manager.groups;
|
||||
|
||||
public class LastGroupAdminException extends Exception {
|
||||
|
||||
public LastGroupAdminException(GroupId groupId, String groupName) {
|
||||
super("User is last admin in group: " + groupName + " (" + groupId.toBase64() + ")");
|
||||
}
|
||||
}
|
|
@ -250,7 +250,9 @@ public class GroupV2Helper {
|
|||
return commitChange(groupInfoV2, change);
|
||||
}
|
||||
|
||||
public Pair<DecryptedGroup, GroupChange> leaveGroup(GroupInfoV2 groupInfoV2) throws IOException {
|
||||
public Pair<DecryptedGroup, GroupChange> leaveGroup(
|
||||
GroupInfoV2 groupInfoV2, Set<RecipientId> membersToMakeAdmin
|
||||
) throws IOException {
|
||||
var pendingMembersList = groupInfoV2.getGroup().getPendingMembersList();
|
||||
final var selfUuid = addressResolver.resolveSignalServiceAddress(selfRecipientIdProvider.getSelfRecipientId())
|
||||
.getUuid()
|
||||
|
@ -259,9 +261,15 @@ public class GroupV2Helper {
|
|||
|
||||
if (selfPendingMember.isPresent()) {
|
||||
return revokeInvites(groupInfoV2, Set.of(selfPendingMember.get()));
|
||||
} else {
|
||||
return ejectMembers(groupInfoV2, Set.of(selfUuid));
|
||||
}
|
||||
|
||||
final var adminUuids = membersToMakeAdmin.stream()
|
||||
.map(addressResolver::resolveSignalServiceAddress)
|
||||
.map(SignalServiceAddress::getUuid)
|
||||
.map(Optional::get)
|
||||
.collect(Collectors.toList());
|
||||
final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2);
|
||||
return commitChange(groupInfoV2, groupOperations.createLeaveAndPromoteMembersToAdmin(selfUuid, adminUuids));
|
||||
}
|
||||
|
||||
public Pair<DecryptedGroup, GroupChange> removeMembers(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue