From 2a20e70aabaad0106774157a78eba60428604ac1 Mon Sep 17 00:00:00 2001 From: AsamK Date: Sat, 9 Apr 2022 19:01:37 +0200 Subject: [PATCH] Add support for banning/unbanning group members --- client/src/cli.rs | 6 + client/src/jsonrpc.rs | 2 + client/src/main.rs | 4 + graalvm-config-dir/reflect-config.json | 6 + .../org/asamk/signal/manager/ManagerImpl.java | 6 + .../org/asamk/signal/manager/api/Group.java | 5 + .../asamk/signal/manager/api/UpdateGroup.java | 121 ++++++++++++++++-- .../signal/manager/helper/GroupHelper.java | 32 +++++ .../signal/manager/helper/GroupV2Helper.java | 40 +++++- .../manager/storage/groups/GroupInfo.java | 4 + .../manager/storage/groups/GroupInfoV2.java | 12 ++ man/signal-cli.1.adoc | 7 + src/main/java/org/asamk/Signal.java | 1 + .../signal/commands/ListGroupsCommand.java | 5 +- .../signal/commands/UpdateGroupCommand.java | 6 + .../asamk/signal/dbus/DbusManagerImpl.java | 3 + .../org/asamk/signal/dbus/DbusSignalImpl.java | 2 + 17 files changed, 246 insertions(+), 16 deletions(-) diff --git a/client/src/cli.rs b/client/src/cli.rs index bc6a3079..a8cee165 100644 --- a/client/src/cli.rs +++ b/client/src/cli.rs @@ -268,6 +268,12 @@ pub enum CliCommands { #[clap(long = "remove-admin")] remove_admin: Vec, + #[clap(long)] + ban: Vec, + + #[clap(long)] + unban: Vec, + #[clap(long = "reset-link")] reset_link: bool, diff --git a/client/src/jsonrpc.rs b/client/src/jsonrpc.rs index c0feddd0..d4ed4084 100644 --- a/client/src/jsonrpc.rs +++ b/client/src/jsonrpc.rs @@ -227,6 +227,8 @@ pub trait Rpc { #[allow(non_snake_case)] removeMember: Vec, admin: Vec, #[allow(non_snake_case)] removeAdmin: Vec, + ban: Vec, + unban: Vec, #[allow(non_snake_case)] resetLink: bool, #[allow(non_snake_case)] link: Option, #[allow(non_snake_case)] setPermissionAddMember: Option, diff --git a/client/src/main.rs b/client/src/main.rs index 1ad8dbcf..6266d224 100644 --- a/client/src/main.rs +++ b/client/src/main.rs @@ -243,6 +243,8 @@ async fn main() -> Result<(), anyhow::Error> { remove_member, admin, remove_admin, + ban, + unban, reset_link, link, set_permission_add_member, @@ -261,6 +263,8 @@ async fn main() -> Result<(), anyhow::Error> { remove_member, admin, remove_admin, + ban, + unban, reset_link, link.map(|link| match link { LinkState::Enabled => "enabled".to_owned(), diff --git a/graalvm-config-dir/reflect-config.json b/graalvm-config-dir/reflect-config.json index 98492ef8..53f611b0 100644 --- a/graalvm-config-dir/reflect-config.json +++ b/graalvm-config-dir/reflect-config.json @@ -2057,6 +2057,12 @@ "queryAllDeclaredMethods":true, "queryAllDeclaredConstructors":true }, +{ + "name":"org.whispersystems.signalservice.api.push.ServiceId", + "allDeclaredFields":true, + "queryAllDeclaredMethods":true, + "queryAllDeclaredConstructors":true +}, { "name":"org.whispersystems.signalservice.api.push.SignedPreKeyEntity", "allDeclaredFields":true, diff --git a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java index 45ec09f9..addc3bb7 100644 --- a/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java +++ b/lib/src/main/java/org/asamk/signal/manager/ManagerImpl.java @@ -386,6 +386,12 @@ class ManagerImpl implements Manager { updateGroup.getRemoveAdmins() == null ? null : context.getRecipientHelper().resolveRecipients(updateGroup.getRemoveAdmins()), + updateGroup.getBanMembers() == null + ? null + : context.getRecipientHelper().resolveRecipients(updateGroup.getBanMembers()), + updateGroup.getUnbanMembers() == null + ? null + : context.getRecipientHelper().resolveRecipients(updateGroup.getUnbanMembers()), updateGroup.isResetGroupLink(), updateGroup.getGroupLinkState(), updateGroup.getAddMemberPermission(), diff --git a/lib/src/main/java/org/asamk/signal/manager/api/Group.java b/lib/src/main/java/org/asamk/signal/manager/api/Group.java index a8dfdff1..9b2d988a 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/Group.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/Group.java @@ -20,6 +20,7 @@ public record Group( Set pendingMembers, Set requestingMembers, Set adminMembers, + Set bannedMembers, boolean isBlocked, int messageExpirationTimer, GroupPermission permissionAddMember, @@ -52,6 +53,10 @@ public record Group( .stream() .map(recipientStore::resolveRecipientAddress) .collect(Collectors.toSet()), + groupInfo.getBannedMembers() + .stream() + .map(recipientStore::resolveRecipientAddress) + .collect(Collectors.toSet()), groupInfo.isBlocked(), groupInfo.getMessageExpirationTimer(), groupInfo.getPermissionAddMember(), diff --git a/lib/src/main/java/org/asamk/signal/manager/api/UpdateGroup.java b/lib/src/main/java/org/asamk/signal/manager/api/UpdateGroup.java index b5877ae5..077542e1 100644 --- a/lib/src/main/java/org/asamk/signal/manager/api/UpdateGroup.java +++ b/lib/src/main/java/org/asamk/signal/manager/api/UpdateGroup.java @@ -14,6 +14,8 @@ public class UpdateGroup { private final Set removeMembers; private final Set admins; private final Set removeAdmins; + private final Set banMembers; + private final Set unbanMembers; private final boolean resetGroupLink; private final GroupLinkState groupLinkState; private final GroupPermission addMemberPermission; @@ -29,6 +31,8 @@ public class UpdateGroup { removeMembers = builder.removeMembers; admins = builder.admins; removeAdmins = builder.removeAdmins; + banMembers = builder.banMembers; + unbanMembers = builder.unbanMembers; resetGroupLink = builder.resetGroupLink; groupLinkState = builder.groupLinkState; addMemberPermission = builder.addMemberPermission; @@ -43,23 +47,58 @@ public class UpdateGroup { } public static Builder newBuilder(final UpdateGroup copy) { - Builder builder = new Builder(); - builder.name = copy.getName(); - builder.description = copy.getDescription(); - builder.members = copy.getMembers(); - builder.removeMembers = copy.getRemoveMembers(); - builder.admins = copy.getAdmins(); - builder.removeAdmins = copy.getRemoveAdmins(); - builder.resetGroupLink = copy.isResetGroupLink(); - builder.groupLinkState = copy.getGroupLinkState(); - builder.addMemberPermission = copy.getAddMemberPermission(); - builder.editDetailsPermission = copy.getEditDetailsPermission(); - builder.avatarFile = copy.getAvatarFile(); - builder.expirationTimer = copy.getExpirationTimer(); - builder.isAnnouncementGroup = copy.getIsAnnouncementGroup(); + Builder builder = new Builder(copy.name, + copy.description, + copy.members, + copy.removeMembers, + copy.admins, + copy.removeAdmins, + copy.banMembers, + copy.unbanMembers, + copy.resetGroupLink, + copy.groupLinkState, + copy.addMemberPermission, + copy.editDetailsPermission, + copy.avatarFile, + copy.expirationTimer, + copy.isAnnouncementGroup); return builder; } + public static Builder newBuilder( + final String name, + final String description, + final Set members, + final Set removeMembers, + final Set admins, + final Set removeAdmins, + final Set banMembers, + final Set unbanMembers, + final boolean resetGroupLink, + final GroupLinkState groupLinkState, + final GroupPermission addMemberPermission, + final GroupPermission editDetailsPermission, + final File avatarFile, + final Integer expirationTimer, + final Boolean isAnnouncementGroup + ) { + return new Builder(name, + description, + members, + removeMembers, + admins, + removeAdmins, + banMembers, + unbanMembers, + resetGroupLink, + groupLinkState, + addMemberPermission, + editDetailsPermission, + avatarFile, + expirationTimer, + isAnnouncementGroup); + } + public String getName() { return name; } @@ -84,6 +123,14 @@ public class UpdateGroup { return removeAdmins; } + public Set getBanMembers() { + return banMembers; + } + + public Set getUnbanMembers() { + return unbanMembers; + } + public boolean isResetGroupLink() { return resetGroupLink; } @@ -120,6 +167,8 @@ public class UpdateGroup { private Set removeMembers; private Set admins; private Set removeAdmins; + private Set banMembers; + private Set unbanMembers; private boolean resetGroupLink; private GroupLinkState groupLinkState; private GroupPermission addMemberPermission; @@ -131,6 +180,40 @@ public class UpdateGroup { private Builder() { } + private Builder( + final String name, + final String description, + final Set members, + final Set removeMembers, + final Set admins, + final Set removeAdmins, + final Set banMembers, + final Set unbanMembers, + final boolean resetGroupLink, + final GroupLinkState groupLinkState, + final GroupPermission addMemberPermission, + final GroupPermission editDetailsPermission, + final File avatarFile, + final Integer expirationTimer, + final Boolean isAnnouncementGroup + ) { + this.name = name; + this.description = description; + this.members = members; + this.removeMembers = removeMembers; + this.admins = admins; + this.removeAdmins = removeAdmins; + this.banMembers = banMembers; + this.unbanMembers = unbanMembers; + this.resetGroupLink = resetGroupLink; + this.groupLinkState = groupLinkState; + this.addMemberPermission = addMemberPermission; + this.editDetailsPermission = editDetailsPermission; + this.avatarFile = avatarFile; + this.expirationTimer = expirationTimer; + this.isAnnouncementGroup = isAnnouncementGroup; + } + public Builder withName(final String val) { name = val; return this; @@ -161,6 +244,16 @@ public class UpdateGroup { return this; } + public Builder withBanMembers(final Set val) { + banMembers = val; + return this; + } + + public Builder withUnbanMembers(final Set val) { + unbanMembers = val; + return this; + } + public Builder withResetGroupLink(final boolean val) { resetGroupLink = val; return this; diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java index b730fe2d..57f9c924 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupHelper.java @@ -194,6 +194,8 @@ public class GroupHelper { final Set removeMembers, final Set admins, final Set removeAdmins, + final Set banMembers, + final Set unbanMembers, final boolean resetGroupLink, final GroupLinkState groupLinkState, final GroupPermission addMemberPermission, @@ -213,6 +215,8 @@ public class GroupHelper { removeMembers, admins, removeAdmins, + banMembers, + unbanMembers, resetGroupLink, groupLinkState, addMemberPermission, @@ -230,6 +234,8 @@ public class GroupHelper { removeMembers, admins, removeAdmins, + banMembers, + unbanMembers, resetGroupLink, groupLinkState, addMemberPermission, @@ -467,6 +473,8 @@ public class GroupHelper { final Set removeMembers, final Set admins, final Set removeAdmins, + final Set banMembers, + final Set unbanMembers, final boolean resetGroupLink, final GroupLinkState groupLinkState, final GroupPermission addMemberPermission, @@ -493,7 +501,13 @@ public class GroupHelper { if (removeMembers != null) { var existingRemoveMembers = new HashSet<>(removeMembers); + if (banMembers != null) { + existingRemoveMembers.addAll(banMembers); + } existingRemoveMembers.retainAll(group.getMembers()); + if (members != null) { + existingRemoveMembers.removeAll(members); + } existingRemoveMembers.remove(account.getSelfRecipientId());// self can be removed with sendQuitGroupMessage if (existingRemoveMembers.size() > 0) { var groupGroupChangePair = groupV2Helper.removeMembers(group, existingRemoveMembers); @@ -535,6 +549,24 @@ public class GroupHelper { } } + if (banMembers != null) { + final var newlyBannedMembers = new HashSet<>(banMembers); + newlyBannedMembers.removeAll(group.getBannedMembers()); + if (newlyBannedMembers.size() > 0) { + var groupGroupChangePair = groupV2Helper.banMembers(group, newlyBannedMembers); + result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second()); + } + } + + if (unbanMembers != null) { + var existingUnbanMembers = new HashSet<>(unbanMembers); + existingUnbanMembers.retainAll(group.getBannedMembers()); + if (existingUnbanMembers.size() > 0) { + var groupGroupChangePair = groupV2Helper.unbanMembers(group, existingUnbanMembers); + result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second()); + } + } + if (resetGroupLink) { var groupGroupChangePair = groupV2Helper.resetGroupLinkPassword(group); result = sendUpdateGroupV2Message(group, groupGroupChangePair.first(), groupGroupChangePair.second()); diff --git a/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java b/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java index 49582ac9..d56ce98f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java +++ b/lib/src/main/java/org/asamk/signal/manager/helper/GroupV2Helper.java @@ -203,9 +203,13 @@ class GroupV2Helper { credentials, (uuid, credential) -> new GroupCandidate(uuid, Optional.ofNullable(credential))) .collect(Collectors.toSet()); + final var bannedUuids = groupInfoV2.getBannedMembers() + .stream() + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) + .collect(Collectors.toSet()); final var aci = getSelfAci(); - final var change = groupOperations.createModifyGroupMembershipChange(candidates, Set.of(), aci.uuid()); + final var change = groupOperations.createModifyGroupMembershipChange(candidates, bannedUuids, aci.uuid()); change.setSourceUuid(getSelfAci().toByteString()); @@ -259,6 +263,40 @@ class GroupV2Helper { return revokeInvites(groupInfoV2, memberUuids); } + Pair banMembers( + GroupInfoV2 groupInfoV2, Set block + ) throws IOException { + GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); + + final var uuids = block.stream() + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) + .collect(Collectors.toSet()); + + final var change = groupOperations.createBanUuidsChange(uuids, + false, + groupInfoV2.getGroup().getBannedMembersList()); + + change.setSourceUuid(getSelfAci().toByteString()); + + return commitChange(groupInfoV2, change); + } + + Pair unbanMembers( + GroupInfoV2 groupInfoV2, Set block + ) throws IOException { + GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); + + final var uuids = block.stream() + .map(member -> context.getRecipientHelper().resolveSignalServiceAddress(member).getServiceId().uuid()) + .collect(Collectors.toSet()); + + final var change = groupOperations.createUnbanUuidsChange(uuids); + + change.setSourceUuid(getSelfAci().toByteString()); + + return commitChange(groupInfoV2, change); + } + Pair resetGroupLinkPassword(GroupInfoV2 groupInfoV2) throws IOException { final GroupsV2Operations.GroupOperations groupOperations = getGroupOperations(groupInfoV2); final var newGroupLinkPassword = GroupLinkPassword.createNew().serialize(); diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java index 4d94eb01..3816dcc6 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfo.java @@ -26,6 +26,10 @@ public sealed abstract class GroupInfo permits GroupInfoV1, GroupInfoV2 { public abstract Set getMembers(); + public Set getBannedMembers() { + return Set.of(); + } + public Set getPendingMembers() { return Set.of(); } diff --git a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java index 23c80ba9..dc803f0f 100644 --- a/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java +++ b/lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV2.java @@ -117,6 +117,18 @@ public final class GroupInfoV2 extends GroupInfo { .collect(Collectors.toSet()); } + @Override + public Set getBannedMembers() { + if (this.group == null) { + return Set.of(); + } + return group.getBannedMembersList() + .stream() + .map(m -> ServiceId.fromByteString(m.getUuid())) + .map(recipientResolver::resolveRecipient) + .collect(Collectors.toSet()); + } + @Override public Set getPendingMembers() { if (this.group == null) { diff --git a/man/signal-cli.1.adoc b/man/signal-cli.1.adoc index 1a30b2e0..0562fcca 100644 --- a/man/signal-cli.1.adoc +++ b/man/signal-cli.1.adoc @@ -357,6 +357,13 @@ Specify one or more members to make a group admin *--remove-admin* [MEMBER [MEMBER ...]]:: Specify one or more members to remove group admin privileges +*--ban* [MEMBER [MEMBER ...]]:: +Specify one or more members to ban from joining the group. +Banned members cannot join or request to join via a group link. + +*--unban* [MEMBER [MEMBER ...]]:: +Specify one or more members to remove from the ban list + *--reset-link*:: Reset group link and create new link password diff --git a/src/main/java/org/asamk/Signal.java b/src/main/java/org/asamk/Signal.java index fd91d8af..caf55555 100644 --- a/src/main/java/org/asamk/Signal.java +++ b/src/main/java/org/asamk/Signal.java @@ -523,6 +523,7 @@ public interface Signal extends DBusInterface { @DBusProperty(name = "PendingMembers", type = String[].class, access = DBusProperty.Access.READ) @DBusProperty(name = "RequestingMembers", type = String[].class, access = DBusProperty.Access.READ) @DBusProperty(name = "Admins", type = String[].class, access = DBusProperty.Access.READ) + @DBusProperty(name = "Banned", type = String[].class, access = DBusProperty.Access.READ) @DBusProperty(name = "PermissionAddMember", type = String.class) @DBusProperty(name = "PermissionEditDetails", type = String.class) @DBusProperty(name = "PermissionSendMessage", type = String.class) diff --git a/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java b/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java index 84e458b3..80e583af 100644 --- a/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java +++ b/src/main/java/org/asamk/signal/commands/ListGroupsCommand.java @@ -53,7 +53,7 @@ public class ListGroupsCommand implements JsonRpcLocalCommand { final var groupInviteLink = group.groupInviteLinkUrl(); writer.println( - "Id: {} Name: {} Description: {} Active: {} Blocked: {} Members: {} Pending members: {} Requesting members: {} Admins: {} Message expiration: {} Link: {}", + "Id: {} Name: {} Description: {} Active: {} Blocked: {} Members: {} Pending members: {} Requesting members: {} Admins: {} Banned: {} Message expiration: {} Link: {}", group.groupId().toBase64(), group.title(), group.description(), @@ -63,6 +63,7 @@ public class ListGroupsCommand implements JsonRpcLocalCommand { resolveMembers(group.pendingMembers()), resolveMembers(group.requestingMembers()), resolveMembers(group.adminMembers()), + resolveMembers(group.bannedMembers()), group.messageExpirationTimer() == 0 ? "disabled" : group.messageExpirationTimer() + "s", groupInviteLink == null ? '-' : groupInviteLink.getUrl()); } else { @@ -95,6 +96,7 @@ public class ListGroupsCommand implements JsonRpcLocalCommand { resolveJsonMembers(group.pendingMembers()), resolveJsonMembers(group.requestingMembers()), resolveJsonMembers(group.adminMembers()), + resolveJsonMembers(group.bannedMembers()), group.permissionAddMember().name(), group.permissionEditDetails().name(), group.permissionSendMessage().name(), @@ -122,6 +124,7 @@ public class ListGroupsCommand implements JsonRpcLocalCommand { Set pendingMembers, Set requestingMembers, Set admins, + Set banned, String permissionAddMember, String permissionEditDetails, String permissionSendMessage, diff --git a/src/main/java/org/asamk/signal/commands/UpdateGroupCommand.java b/src/main/java/org/asamk/signal/commands/UpdateGroupCommand.java index 2a6d7d15..411ae747 100644 --- a/src/main/java/org/asamk/signal/commands/UpdateGroupCommand.java +++ b/src/main/java/org/asamk/signal/commands/UpdateGroupCommand.java @@ -55,6 +55,8 @@ public class UpdateGroupCommand implements JsonRpcLocalCommand { subparser.addArgument("--remove-admin") .nargs("*") .help("Specify one or more members to remove group admin privileges"); + subparser.addArgument("--ban").nargs("*").help("Specify one or more members to ban from joining the group"); + subparser.addArgument("--unban").nargs("*").help("Specify one or more members to remove from the ban list"); subparser.addArgument("--reset-link") .action(Arguments.storeTrue()) @@ -114,6 +116,8 @@ public class UpdateGroupCommand implements JsonRpcLocalCommand { var groupRemoveMembers = CommandUtil.getSingleRecipientIdentifiers(ns.getList("remove-member"), localNumber); var groupAdmins = CommandUtil.getSingleRecipientIdentifiers(ns.getList("admin"), localNumber); var groupRemoveAdmins = CommandUtil.getSingleRecipientIdentifiers(ns.getList("remove-admin"), localNumber); + var groupBan = CommandUtil.getSingleRecipientIdentifiers(ns.getList("ban"), localNumber); + var groupUnban = CommandUtil.getSingleRecipientIdentifiers(ns.getList("unban"), localNumber); var groupAvatar = ns.getString("avatar"); var groupResetLink = Boolean.TRUE.equals(ns.getBoolean("reset-link")); var groupLinkState = getGroupLinkState(ns.getString("link")); @@ -145,6 +149,8 @@ public class UpdateGroupCommand implements JsonRpcLocalCommand { .withRemoveMembers(groupRemoveMembers) .withAdmins(groupAdmins) .withRemoveAdmins(groupRemoveAdmins) + .withBanMembers(groupBan) + .withUnbanMembers(groupUnban) .withResetGroupLink(groupResetLink) .withGroupLinkState(groupLinkState) .withAddMemberPermission(groupAddMemberPermission) diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index 8d8d333f..ed27ad6d 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -583,6 +583,9 @@ public class DbusManagerImpl implements Manager { ((List) group.get("Admins").getValue()).stream() .map(m -> new RecipientAddress(null, m)) .collect(Collectors.toSet()), + ((List) group.get("Banned").getValue()).stream() + .map(m -> new RecipientAddress(null, m)) + .collect(Collectors.toSet()), (boolean) group.get("IsBlocked").getValue(), (int) group.get("MessageExpirationTimer").getValue(), GroupPermission.valueOf((String) group.get("PermissionAddMember").getValue()), diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index ad6f4546..850bcf1d 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -1162,6 +1162,8 @@ public class DbusSignalImpl implements Signal { () -> new Variant<>(getRecipientStrings(getGroup().requestingMembers()), "as")), new DbusProperty<>("Admins", () -> new Variant<>(getRecipientStrings(getGroup().adminMembers()), "as")), + new DbusProperty<>("Banned", + () -> new Variant<>(getRecipientStrings(getGroup().bannedMembers()), "as")), new DbusProperty<>("PermissionAddMember", () -> getGroup().permissionAddMember().name(), this::setGroupPermissionAddMember), -- 2.50.1