X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/6f5e72119e0c996f1efefecda11e33422d44a171..ce70a623c21a267679d59838d041f9bc1d486cd9:/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java diff --git a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java index ea776797..ea591224 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -1,6 +1,7 @@ package org.asamk.signal.dbus; import org.asamk.Signal; +import org.asamk.signal.DbusConfig; import org.asamk.signal.manager.AttachmentInvalidException; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.NotMasterDeviceException; @@ -14,9 +15,9 @@ import org.asamk.signal.manager.api.RecipientIdentifier; import org.asamk.signal.manager.api.SendGroupMessageResults; import org.asamk.signal.manager.api.SendMessageResults; import org.asamk.signal.manager.api.TypingAction; +import org.asamk.signal.manager.api.UpdateGroup; import org.asamk.signal.manager.groups.GroupId; import org.asamk.signal.manager.groups.GroupInviteLinkUrl; -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.GroupSendingNotAllowedException; @@ -25,7 +26,10 @@ import org.asamk.signal.manager.groups.NotAGroupMemberException; import org.asamk.signal.manager.storage.recipients.Contact; import org.asamk.signal.manager.storage.recipients.Profile; import org.asamk.signal.manager.storage.recipients.RecipientAddress; -import org.whispersystems.libsignal.IdentityKey; +import org.freedesktop.dbus.DBusPath; +import org.freedesktop.dbus.connections.impl.DBusConnection; +import org.freedesktop.dbus.exceptions.DBusException; +import org.freedesktop.dbus.interfaces.DBusInterface; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.util.Pair; import org.whispersystems.libsignal.util.guava.Optional; @@ -58,9 +62,11 @@ import java.util.stream.Collectors; public class DbusManagerImpl implements Manager { private final Signal signal; + private final DBusConnection connection; - public DbusManagerImpl(final Signal signal) { + public DbusManagerImpl(final Signal signal, DBusConnection connection) { this.signal = signal; + this.connection = connection; } @Override @@ -89,7 +95,8 @@ public class DbusManagerImpl implements Manager { @Override public void updateAccountAttributes(final String deviceName) throws IOException { if (deviceName != null) { - signal.updateDeviceName(deviceName); + final var devicePath = signal.getThisDevice(); + getRemoteObject(devicePath, Signal.Device.class).Set("org.asamk.Signal.Device", "Name", deviceName); } } @@ -136,15 +143,22 @@ public class DbusManagerImpl implements Manager { @Override public List getLinkedDevices() throws IOException { - return signal.listDevices() - .stream() - .map(name -> new Device(-1, name, 0, 0, false)) - .collect(Collectors.toList()); + final var thisDevice = signal.getThisDevice(); + return signal.listDevices().stream().map(d -> { + final var device = getRemoteObject(d.getObjectPath(), + Signal.Device.class).GetAll("org.asamk.Signal.Device"); + return new Device((long) device.get("Id").getValue(), + (String) device.get("Name").getValue(), + (long) device.get("Created").getValue(), + (long) device.get("LastSeen").getValue(), + thisDevice.equals(d.getObjectPath())); + }).collect(Collectors.toList()); } @Override - public void removeLinkedDevices(final int deviceId) throws IOException { - signal.removeDevice(deviceId); + public void removeLinkedDevices(final long deviceId) throws IOException { + final var devicePath = signal.getDevice(deviceId); + getRemoteObject(devicePath, Signal.Device.class).removeDevice(); } @Override @@ -168,8 +182,8 @@ public class DbusManagerImpl implements Manager { @Override public List getGroups() { - final var groupIds = signal.getGroupIds(); - return groupIds.stream().map(id -> getGroup(GroupId.unknownVersion(id))).collect(Collectors.toList()); + final var groups = signal.listGroups(); + return groups.stream().map(Signal.StructGroup::getObjectPath).map(this::getGroup).collect(Collectors.toList()); } @Override @@ -179,7 +193,8 @@ public class DbusManagerImpl implements Manager { if (groupAdmins.size() > 0) { throw new UnsupportedOperationException(); } - signal.quitGroup(groupId.serialize()); + final var group = getRemoteObject(signal.getGroup(groupId.serialize()), Signal.Group.class); + group.quitGroup(); return new SendGroupMessageResults(0, List.of()); } @@ -192,8 +207,7 @@ public class DbusManagerImpl implements Manager { public Pair createGroup( final String name, final Set members, final File avatarFile ) throws IOException, AttachmentInvalidException { - final var newGroupId = signal.updateGroup(new byte[0], - emptyIfNull(name), + final var newGroupId = signal.createGroup(emptyIfNull(name), members.stream().map(RecipientIdentifier.Single::getIdentifier).collect(Collectors.toList()), avatarFile == null ? "" : avatarFile.getPath()); return new Pair<>(GroupId.unknownVersion(newGroupId), new SendGroupMessageResults(0, List.of())); @@ -201,25 +215,70 @@ public class DbusManagerImpl implements Manager { @Override public SendGroupMessageResults updateGroup( - final GroupId groupId, - final String name, - final String description, - final Set members, - final Set removeMembers, - final Set admins, - final Set removeAdmins, - final boolean resetGroupLink, - final GroupLinkState groupLinkState, - final GroupPermission addMemberPermission, - final GroupPermission editDetailsPermission, - final File avatarFile, - final Integer expirationTimer, - final Boolean isAnnouncementGroup + final GroupId groupId, final UpdateGroup updateGroup ) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException { - signal.updateGroup(groupId.serialize(), - emptyIfNull(name), - members.stream().map(RecipientIdentifier.Single::getIdentifier).collect(Collectors.toList()), - avatarFile == null ? "" : avatarFile.getPath()); + final var group = getRemoteObject(signal.getGroup(groupId.serialize()), Signal.Group.class); + if (updateGroup.getName() != null) { + group.Set("org.asamk.Signal.Group", "Name", updateGroup.getName()); + } + if (updateGroup.getDescription() != null) { + group.Set("org.asamk.Signal.Group", "Description", updateGroup.getDescription()); + } + if (updateGroup.getAvatarFile() != null) { + group.Set("org.asamk.Signal.Group", + "Avatar", + updateGroup.getAvatarFile() == null ? "" : updateGroup.getAvatarFile().getPath()); + } + if (updateGroup.getExpirationTimer() != null) { + group.Set("org.asamk.Signal.Group", "MessageExpirationTimer", updateGroup.getExpirationTimer()); + } + if (updateGroup.getAddMemberPermission() != null) { + group.Set("org.asamk.Signal.Group", "PermissionAddMember", updateGroup.getAddMemberPermission().name()); + } + if (updateGroup.getEditDetailsPermission() != null) { + group.Set("org.asamk.Signal.Group", "PermissionEditDetails", updateGroup.getEditDetailsPermission().name()); + } + if (updateGroup.getIsAnnouncementGroup() != null) { + group.Set("org.asamk.Signal.Group", + "PermissionSendMessage", + updateGroup.getIsAnnouncementGroup() + ? GroupPermission.ONLY_ADMINS.name() + : GroupPermission.EVERY_MEMBER.name()); + } + if (updateGroup.getMembers() != null) { + group.addMembers(updateGroup.getMembers() + .stream() + .map(RecipientIdentifier.Single::getIdentifier) + .collect(Collectors.toList())); + } + if (updateGroup.getRemoveMembers() != null) { + group.removeMembers(updateGroup.getRemoveMembers() + .stream() + .map(RecipientIdentifier.Single::getIdentifier) + .collect(Collectors.toList())); + } + if (updateGroup.getAdmins() != null) { + group.addAdmins(updateGroup.getAdmins() + .stream() + .map(RecipientIdentifier.Single::getIdentifier) + .collect(Collectors.toList())); + } + if (updateGroup.getRemoveAdmins() != null) { + group.removeAdmins(updateGroup.getRemoveAdmins() + .stream() + .map(RecipientIdentifier.Single::getIdentifier) + .collect(Collectors.toList())); + } + if (updateGroup.isResetGroupLink()) { + group.resetLink(); + } + if (updateGroup.getGroupLinkState() != null) { + switch (updateGroup.getGroupLinkState()) { + case DISABLED -> group.disableLink(); + case ENABLED -> group.enableLink(false); + case ENABLED_WITH_APPROVAL -> group.enableLink(true); + } + } return new SendGroupMessageResults(0, List.of()); } @@ -329,7 +388,12 @@ public class DbusManagerImpl implements Manager { public void setGroupBlocked( final GroupId groupId, final boolean blocked ) throws GroupNotFoundException, IOException { - signal.setGroupBlocked(groupId.serialize(), blocked); + setGroupProperty(groupId, "IsBlocked", blocked); + } + + private void setGroupProperty(final GroupId groupId, final String propertyName, final boolean blocked) { + final var group = getRemoteObject(signal.getGroup(groupId.serialize()), Signal.Group.class); + group.Set("org.asamk.Signal.Group", propertyName, blocked); } @Override @@ -353,17 +417,38 @@ public class DbusManagerImpl implements Manager { signal.sendSyncRequest(); } + @Override + public void addReceiveHandler(final ReceiveMessageHandler handler) { + throw new UnsupportedOperationException(); + } + + @Override + public void removeReceiveHandler(final ReceiveMessageHandler handler) { + throw new UnsupportedOperationException(); + } + + @Override + public boolean isReceiving() { + throw new UnsupportedOperationException(); + } + + @Override + public void receiveMessages(final ReceiveMessageHandler handler) throws IOException { + throw new UnsupportedOperationException(); + } + @Override public void receiveMessages( - final long timeout, - final TimeUnit unit, - final boolean returnOnTimeout, - final boolean ignoreAttachments, - final ReceiveMessageHandler handler + final long timeout, final TimeUnit unit, final ReceiveMessageHandler handler ) throws IOException { throw new UnsupportedOperationException(); } + @Override + public void setIgnoreAttachments(final boolean ignoreAttachments) { + throw new UnsupportedOperationException(); + } + @Override public boolean hasCaughtUpWithOldMessages() { throw new UnsupportedOperationException(); @@ -396,19 +481,41 @@ public class DbusManagerImpl implements Manager { @Override public Group getGroup(final GroupId groupId) { - final var id = groupId.serialize(); - return new Group(groupId, - signal.getGroupName(id), - null, - null, - signal.getGroupMembers(id).stream().map(m -> new RecipientAddress(null, m)).collect(Collectors.toSet()), - Set.of(), - Set.of(), - Set.of(), - signal.isGroupBlocked(id), - 0, - false, - signal.isMember(id)); + final var groupPath = signal.getGroup(groupId.serialize()); + return getGroup(groupPath); + } + + @SuppressWarnings("unchecked") + private Group getGroup(final DBusPath groupPath) { + final var group = getRemoteObject(groupPath, Signal.Group.class).GetAll("org.asamk.Signal.Group"); + final var id = (byte[]) group.get("Id").getValue(); + try { + return new Group(GroupId.unknownVersion(id), + (String) group.get("Name").getValue(), + (String) group.get("Description").getValue(), + GroupInviteLinkUrl.fromUri((String) group.get("GroupInviteLink").getValue()), + ((List) group.get("Members").getValue()).stream() + .map(m -> new RecipientAddress(null, m)) + .collect(Collectors.toSet()), + ((List) group.get("PendingMembers").getValue()).stream() + .map(m -> new RecipientAddress(null, m)) + .collect(Collectors.toSet()), + ((List) group.get("RequestingMembers").getValue()).stream() + .map(m -> new RecipientAddress(null, m)) + .collect(Collectors.toSet()), + ((List) group.get("Admins").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()), + GroupPermission.valueOf((String) group.get("PermissionEditDetails").getValue()), + GroupPermission.valueOf((String) group.get("PermissionSendMessage").getValue()), + (boolean) group.get("IsMember").getValue(), + (boolean) group.get("IsAdmin").getValue()); + } catch (GroupInviteLinkUrl.InvalidGroupLinkException | GroupInviteLinkUrl.UnknownGroupLinkVersionException e) { + throw new AssertionError(e); + } } @Override @@ -445,13 +552,6 @@ public class DbusManagerImpl implements Manager { throw new UnsupportedOperationException(); } - @Override - public String computeSafetyNumber( - final SignalServiceAddress theirAddress, final IdentityKey theirIdentityKey - ) { - throw new UnsupportedOperationException(); - } - @Override public SignalServiceAddress resolveSignalServiceAddress(final SignalServiceAddress address) { return address; @@ -494,4 +594,12 @@ public class DbusManagerImpl implements Manager { private String emptyIfNull(final String string) { return string == null ? "" : string; } + + private T getRemoteObject(final DBusPath devicePath, final Class type) { + try { + return connection.getRemoteObject(DbusConfig.getBusname(), devicePath.getPath(), type); + } catch (DBusException e) { + throw new AssertionError(e); + } + } }