X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/37c65ca6b4d86c918740de323be797bd8246ffc9..5e16123632d839bc0fa0648d8fabbec48c03a7f9:/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 985e2674..5658d0d3 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java @@ -1,7 +1,6 @@ package org.asamk.signal.dbus; import org.asamk.Signal; -import org.asamk.signal.DbusConfig; import org.asamk.signal.manager.Manager; import org.asamk.signal.manager.api.AlreadyReceivingException; import org.asamk.signal.manager.api.AttachmentInvalidException; @@ -39,15 +38,17 @@ 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.StickerPack; +import org.asamk.signal.manager.api.StickerPackId; import org.asamk.signal.manager.api.StickerPackInvalidException; import org.asamk.signal.manager.api.StickerPackUrl; +import org.asamk.signal.manager.api.TrustLevel; import org.asamk.signal.manager.api.TypingAction; import org.asamk.signal.manager.api.UnregisteredRecipientException; import org.asamk.signal.manager.api.UpdateGroup; import org.asamk.signal.manager.api.UpdateProfile; import org.asamk.signal.manager.api.UserStatus; import org.asamk.signal.manager.api.UsernameLinkUrl; -import org.freedesktop.dbus.DBusMap; +import org.asamk.signal.manager.api.UsernameStatus; import org.freedesktop.dbus.DBusPath; import org.freedesktop.dbus.connections.impl.DBusConnection; import org.freedesktop.dbus.exceptions.DBusException; @@ -90,14 +91,16 @@ public class DbusManagerImpl implements Manager { private final Set weakHandlers = new HashSet<>(); private final Set messageHandlers = new HashSet<>(); private final List closedListeners = new ArrayList<>(); + private final String busname; private DBusSigHandler dbusMsgHandler; private DBusSigHandler dbusEditMsgHandler; private DBusSigHandler dbusRcptHandler; private DBusSigHandler dbusSyncHandler; - public DbusManagerImpl(final Signal signal, DBusConnection connection) { + public DbusManagerImpl(final Signal signal, DBusConnection connection, final String busname) { this.signal = signal; this.connection = connection; + this.busname = busname; } @Override @@ -121,10 +124,22 @@ public class DbusManagerImpl implements Manager { } @Override - public void updateAccountAttributes(final String deviceName) throws IOException { + public Map getUsernameStatus(final Set usernames) { + throw new UnsupportedOperationException(); + } + + @Override + public void updateAccountAttributes( + final String deviceName, + final Boolean unrestrictedUnidentifiedSender, + final Boolean discoverableByNumber, + final Boolean numberSharing + ) throws IOException { if (deviceName != null) { final var devicePath = signal.getThisDevice(); getRemoteObject(devicePath, Signal.Device.class).Set("org.asamk.Signal.Device", "Name", deviceName); + } else { + throw new UnsupportedOperationException(); } } @@ -186,14 +201,18 @@ public class DbusManagerImpl implements Manager { @Override public void startChangeNumber( - final String newNumber, final boolean voiceVerification, final String captcha + final String newNumber, + final boolean voiceVerification, + final String captcha ) throws RateLimitException, IOException, CaptchaRequiredException, NonNormalizedPhoneNumberException { throw new UnsupportedOperationException(); } @Override public void finishChangeNumber( - final String newNumber, final String verificationCode, final String pin + final String newNumber, + final String verificationCode, + final String pin ) throws IncorrectPinException, PinLockedException, IOException { throw new UnsupportedOperationException(); } @@ -255,7 +274,8 @@ public class DbusManagerImpl implements Manager { @Override public SendGroupMessageResults quitGroup( - final GroupId groupId, final Set groupAdmins + final GroupId groupId, + final Set groupAdmins ) throws GroupNotFoundException, IOException, NotAGroupMemberException, LastGroupAdminException { if (!groupAdmins.isEmpty()) { throw new UnsupportedOperationException(); @@ -281,7 +301,9 @@ public class DbusManagerImpl implements Manager { @Override public Pair createGroup( - final String name, final Set members, final String avatarFile + final String name, + final Set members, + final String avatarFile ) throws IOException, AttachmentInvalidException { final var newGroupId = signal.createGroup(emptyIfNull(name), members.stream().map(RecipientIdentifier.Single::getIdentifier).toList(), @@ -291,7 +313,8 @@ public class DbusManagerImpl implements Manager { @Override public SendGroupMessageResults updateGroup( - final GroupId groupId, final UpdateGroup updateGroup + final GroupId groupId, + final UpdateGroup updateGroup ) throws IOException, GroupNotFoundException, AttachmentInvalidException, NotAGroupMemberException, GroupSendingNotAllowedException { final var group = getRemoteObject(signal.getGroup(groupId.serialize()), Signal.Group.class); if (updateGroup.getName() != null) { @@ -365,7 +388,8 @@ public class DbusManagerImpl implements Manager { @Override public SendMessageResults sendTypingMessage( - final TypingAction action, final Set recipients + final TypingAction action, + final Set recipients ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { return handleMessage(recipients, numbers -> { numbers.forEach(n -> signal.sendTyping(n, action == TypingAction.STOP)); @@ -380,24 +404,22 @@ public class DbusManagerImpl implements Manager { } @Override - public SendMessageResults sendReadReceipt( - final RecipientIdentifier.Single sender, final List messageIds - ) { + public SendMessageResults sendReadReceipt(final RecipientIdentifier.Single sender, final List messageIds) { signal.sendReadReceipt(sender.getIdentifier(), messageIds); return new SendMessageResults(0, Map.of()); } @Override - public SendMessageResults sendViewedReceipt( - final RecipientIdentifier.Single sender, final List messageIds - ) { + public SendMessageResults sendViewedReceipt(final RecipientIdentifier.Single sender, final List messageIds) { signal.sendViewedReceipt(sender.getIdentifier(), messageIds); return new SendMessageResults(0, Map.of()); } @Override public SendMessageResults sendMessage( - final Message message, final Set recipients + final Message message, + final Set recipients, + final boolean notifySelf ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { return handleMessage(recipients, numbers -> signal.sendMessage(message.messageText(), message.attachments(), numbers), @@ -407,14 +429,17 @@ public class DbusManagerImpl implements Manager { @Override public SendMessageResults sendEditMessage( - final Message message, final Set recipients, final long editTargetTimestamp + final Message message, + final Set recipients, + final long editTargetTimestamp ) throws IOException, AttachmentInvalidException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException, UnregisteredRecipientException, InvalidStickerException { throw new UnsupportedOperationException(); } @Override public SendMessageResults sendRemoteDeleteMessage( - final long targetSentTimestamp, final Set recipients + final long targetSentTimestamp, + final Set recipients ) throws IOException, NotAGroupMemberException, GroupNotFoundException, GroupSendingNotAllowedException { return handleMessage(recipients, numbers -> signal.sendRemoteDeleteMessage(targetSentTimestamp, numbers), @@ -451,7 +476,9 @@ public class DbusManagerImpl implements Manager { @Override public SendMessageResults sendPaymentNotificationMessage( - final byte[] receipt, final String note, final RecipientIdentifier.Single recipient + final byte[] receipt, + final String note, + final RecipientIdentifier.Single recipient ) throws IOException { final var timestamp = signal.sendPaymentNotification(receipt, note, recipient.getIdentifier()); return new SendMessageResults(timestamp, Map.of()); @@ -463,6 +490,14 @@ public class DbusManagerImpl implements Manager { return new SendMessageResults(0, Map.of()); } + @Override + public SendMessageResults sendMessageRequestResponse( + final MessageEnvelope.Sync.MessageRequestResponse.Type type, + final Set recipientIdentifiers + ) { + throw new UnsupportedOperationException(); + } + public void hideRecipient(final RecipientIdentifier.Single recipient) { throw new UnsupportedOperationException(); } @@ -479,14 +514,20 @@ public class DbusManagerImpl implements Manager { @Override public void setContactName( - final RecipientIdentifier.Single recipient, final String givenName, final String familyName + final RecipientIdentifier.Single recipient, + final String givenName, + final String familyName, + final String nickGivenName, + final String nickFamilyName, + final String note ) throws NotPrimaryDeviceException { signal.setContactName(recipient.getIdentifier(), givenName); } @Override public void setContactsBlocked( - final Collection recipients, final boolean blocked + final Collection recipients, + final boolean blocked ) throws NotPrimaryDeviceException, IOException { for (final var recipient : recipients) { signal.setContactBlocked(recipient.getIdentifier(), blocked); @@ -495,7 +536,8 @@ public class DbusManagerImpl implements Manager { @Override public void setGroupsBlocked( - final Collection groupIds, final boolean blocked + final Collection groupIds, + final boolean blocked ) throws GroupNotFoundException, IOException { for (final var groupId : groupIds) { setGroupProperty(groupId, "IsBlocked", blocked); @@ -509,7 +551,8 @@ public class DbusManagerImpl implements Manager { @Override public void setExpirationTimer( - final RecipientIdentifier.Single recipient, final int messageExpirationTimer + final RecipientIdentifier.Single recipient, + final int messageExpirationTimer ) throws IOException { signal.setExpirationTimer(recipient.getIdentifier(), messageExpirationTimer); } @@ -574,7 +617,9 @@ public class DbusManagerImpl implements Manager { @Override public void receiveMessages( - Optional timeout, Optional maxMessages, ReceiveMessageHandler handler + Optional timeout, + Optional maxMessages, + ReceiveMessageHandler handler ) throws IOException, AlreadyReceivingException { if (receiveThread != null) { throw new AlreadyReceivingException("Already receiving message."); @@ -667,8 +712,23 @@ public class DbusManagerImpl implements Manager { return null; } return Recipient.newBuilder() - .withAddress(new RecipientAddress(null, n)) - .withContact(new Contact(contactName, null, null, 0, contactBlocked, false, false, false)) + .withAddress(new RecipientAddress(n)) + .withContact(new Contact(contactName, + null, + null, + null, + null, + null, + null, + 0, + 1, + 0, + false, + contactBlocked, + false, + false, + false, + null)) .build(); }).filter(Objects::nonNull).toList(); } @@ -694,19 +754,19 @@ public class DbusManagerImpl implements Manager { (String) group.get("Description").getValue(), GroupInviteLinkUrl.fromUri((String) group.get("GroupInviteLink").getValue()), ((List) group.get("Members").getValue()).stream() - .map(m -> new RecipientAddress(null, m)) + .map(m -> new RecipientAddress(m)) .collect(Collectors.toSet()), ((List) group.get("PendingMembers").getValue()).stream() - .map(m -> new RecipientAddress(null, m)) + .map(m -> new RecipientAddress(m)) .collect(Collectors.toSet()), ((List) group.get("RequestingMembers").getValue()).stream() - .map(m -> new RecipientAddress(null, m)) + .map(m -> new RecipientAddress(m)) .collect(Collectors.toSet()), ((List) group.get("Admins").getValue()).stream() - .map(m -> new RecipientAddress(null, m)) + .map(m -> new RecipientAddress(m)) .collect(Collectors.toSet()), ((List) group.get("Banned").getValue()).stream() - .map(m -> new RecipientAddress(null, m)) + .map(m -> new RecipientAddress(m)) .collect(Collectors.toSet()), (boolean) group.get("IsBlocked").getValue(), (int) group.get("MessageExpirationTimer").getValue(), @@ -722,17 +782,32 @@ public class DbusManagerImpl implements Manager { @Override public List getIdentities() { - throw new UnsupportedOperationException(); + final var identities = signal.listIdentities(); + return identities.stream().map(Signal.StructIdentity::getObjectPath).map(this::getIdentity).toList(); } @Override public List getIdentities(final RecipientIdentifier.Single recipient) { - throw new UnsupportedOperationException(); + final var path = signal.getIdentity(recipient.getIdentifier()); + return List.of(getIdentity(path)); + } + + private Identity getIdentity(final DBusPath identityPath) { + final var group = getRemoteObject(identityPath, Signal.Identity.class).GetAll("org.asamk.Signal.Identity"); + final var aci = (String) group.get("Uuid").getValue(); + final var number = (String) group.get("Number").getValue(); + return new Identity(new RecipientAddress(aci, null, number, null), + (byte[]) group.get("Fingerprint").getValue(), + (String) group.get("SafetyNumber").getValue(), + (byte[]) group.get("ScannableSafetyNumber").getValue(), + TrustLevel.valueOf((String) group.get("TrustLevel").getValue()), + (Long) group.get("AddedDate").getValue()); } @Override public boolean trustIdentityVerified( - final RecipientIdentifier.Single recipient, final IdentityVerificationCode verificationCode + final RecipientIdentifier.Single recipient, + final IdentityVerificationCode verificationCode ) { throw new UnsupportedOperationException(); } @@ -807,7 +882,7 @@ public class DbusManagerImpl implements Manager { private T getRemoteObject(final DBusPath path, final Class type) { try { - return connection.getRemoteObject(DbusConfig.getBusname(), path.getPath(), type); + return connection.getRemoteObject(busname, path.getPath(), type); } catch (DBusException e) { throw new AssertionError(e); } @@ -817,8 +892,7 @@ public class DbusManagerImpl implements Manager { try { this.dbusMsgHandler = messageReceived -> { final var extras = messageReceived.getExtras(); - final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null, - messageReceived.getSender())), + final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(messageReceived.getSender())), 0, messageReceived.getTimestamp(), 0, @@ -847,7 +921,7 @@ public class DbusManagerImpl implements Manager { Optional.empty(), Optional.empty(), List.of(), - List.of(), + getMentions(extras), List.of(), List.of())), Optional.empty(), @@ -859,8 +933,7 @@ public class DbusManagerImpl implements Manager { connection.addSigHandler(Signal.MessageReceivedV2.class, signal, this.dbusMsgHandler); this.dbusEditMsgHandler = messageReceived -> { final var extras = messageReceived.getExtras(); - final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null, - messageReceived.getSender())), + final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(messageReceived.getSender())), 0, messageReceived.getTimestamp(), 0, @@ -891,7 +964,7 @@ public class DbusManagerImpl implements Manager { Optional.empty(), Optional.empty(), List.of(), - List.of(), + getMentions(extras), List.of(), List.of()))), Optional.empty(), @@ -908,8 +981,7 @@ public class DbusManagerImpl implements Manager { case "delivery" -> MessageEnvelope.Receipt.Type.DELIVERY; default -> MessageEnvelope.Receipt.Type.UNKNOWN; }; - final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null, - receiptReceived.getSender())), + final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(receiptReceived.getSender())), 0, receiptReceived.getTimestamp(), 0, @@ -930,8 +1002,7 @@ public class DbusManagerImpl implements Manager { this.dbusSyncHandler = syncReceived -> { final var extras = syncReceived.getExtras(); - final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(null, - syncReceived.getSource())), + final var envelope = new MessageEnvelope(Optional.of(new RecipientAddress(syncReceived.getSource())), 0, syncReceived.getTimestamp(), 0, @@ -945,7 +1016,7 @@ public class DbusManagerImpl implements Manager { syncReceived.getTimestamp(), syncReceived.getDestination().isEmpty() ? Optional.empty() - : Optional.of(new RecipientAddress(null, syncReceived.getDestination())), + : Optional.of(new RecipientAddress(syncReceived.getDestination())), Set.of(), Optional.of(new MessageEnvelope.Data(syncReceived.getTimestamp(), syncReceived.getGroupId().length > 0 @@ -968,7 +1039,7 @@ public class DbusManagerImpl implements Manager { Optional.empty(), Optional.empty(), List.of(), - List.of(), + getMentions(extras), List.of(), List.of())), Optional.empty(), @@ -1015,7 +1086,7 @@ public class DbusManagerImpl implements Manager { return List.of(); } - final List>> attachments = getValue(extras, "attachments"); + final List>> attachments = getValue(extras, "attachments"); return attachments.stream().map(a -> { final String file = a.containsKey("file") ? getValue(a, "file") : null; return new MessageEnvelope.Data.Attachment(a.containsKey("remoteId") @@ -1037,15 +1108,46 @@ public class DbusManagerImpl implements Manager { }).toList(); } + private List getMentions(final Map> extras) { + if (!extras.containsKey("mentions")) { + return List.of(); + } + + final List>> mentions = getValue(extras, "mentions"); + return mentions.stream() + .map(a -> new MessageEnvelope.Data.Mention(new RecipientAddress(this.getValue(a, "recipient")), + getValue(a, "start"), + getValue(a, "length"))) + .toList(); + } + @Override public InputStream retrieveAttachment(final String id) throws IOException { throw new UnsupportedOperationException(); } + @Override + public InputStream retrieveContactAvatar(final RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException { + throw new UnsupportedOperationException(); + } + + @Override + public InputStream retrieveProfileAvatar(final RecipientIdentifier.Single recipient) throws IOException, UnregisteredRecipientException { + throw new UnsupportedOperationException(); + } + + @Override + public InputStream retrieveGroupAvatar(final GroupId groupId) throws IOException { + throw new UnsupportedOperationException(); + } + + @Override + public InputStream retrieveSticker(final StickerPackId stickerPackId, final int stickerId) throws IOException { + throw new UnsupportedOperationException(); + } + @SuppressWarnings("unchecked") - private T getValue( - final Map> stringVariantMap, final String field - ) { + private T getValue(final Map> stringVariantMap, final String field) { return (T) stringVariantMap.get(field).getValue(); } }