]> nmode's Git Repositories - signal-cli/commitdiff
Merge branch master into dbus_updateConfiguration
authorJohn Freed <okgithub@johnfreed.com>
Sat, 9 Oct 2021 12:08:08 +0000 (14:08 +0200)
committerJohn Freed <okgithub@johnfreed.com>
Sat, 9 Oct 2021 12:08:08 +0000 (14:08 +0200)
man/signal-cli-dbus.5.adoc
src/main/java/org/asamk/Signal.java
src/main/java/org/asamk/signal/dbus/DbusManagerImpl.java
src/main/java/org/asamk/signal/dbus/DbusProperties.java
src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java

index 56b28ddf1f75181affa5b1701028201bd580c82d..508a788113201f0cd196a6ae808191108579094f 100755 (executable)
@@ -29,15 +29,18 @@ method(arg1<type>, arg2<type>, ...) -> return<type>
 
 Where <type> is according to DBus specification:
 
-* <s>   : String
-* <ay>  : Byte Array
-* <aay> : Array of Byte Arrays
-* <as>  : String Array
-* <ax>  : Array of signed 64 bit integer
-* <b>   : Boolean (0|1)
-* <x>   : Signed 64 bit integer
+* <a>   : Array of ... (comma-separated list, array:)
+* (...) : Struct (cannot be sent via `dbus-send`)
+* <b>   : Boolean (false|true) (boolean:)
+* <i>   : Signed 32-bit (int) integer (int32:)
+* <o>   : DBusPath object (objpath:)
+* <s>   : String (string:)
+* <x>   : Signed 64-bit (long) integer (int64:)
+* <y>   : Unsigned 8-bit (byte) integer (byte:)
 * <>    : no return value
 
+The final parenthetical value (such as "boolean:") is the type indicator used by `dbus-send`.
+
 Exceptions are the names of the Java Exceptions returned in the body field. They typically contain an additional message with details. All Exceptions begin with "org.asamk.Signal.Error." which is omitted here for better readability.
 
 Phone numbers always have the format +<countrycode><regional number>
@@ -340,8 +343,11 @@ addDevice(deviceUri<s>) -> <>::
 
 Exception: InvalidUri
 
-listDevices() -> devices<as>::
-* devices  : String array of linked devices
+listDevices() -> devices<a(oxs)>::
+* devices      : Array of structs (objectPath, id, name)
+** objectPath   : DBusPath representing the device's object path
+** id           : Long representing the deviceId
+** name         : String representing the device's name
 
 Exception: Failure
 
@@ -383,8 +389,14 @@ Update Signal configurations and sync them to linked devices. Only works from pr
 
 Exceptions: IOError, UserError
 
-== Signals
+submitRateLimitChallenge(challenge<s>, captcha<s>) -> <>::
+* challenge : The challenge token taken from the proof required error.
+* captcha   : The captcha token from the solved captcha on the Signal website..
+Can be used to lift some rate-limits by solving a captcha.
 
+Exception: IOErrorException
+
+== Signals
 SyncMessageReceived (timestamp<x>, sender<s>, destination<s>, groupId<ay>,message<s>, attachments<as>)::
 The sync message is received when the user sends a message from a linked device.
 
index cf909fa0dce48fedf4d7a4db3b765a53aea3a6c7..865db815c14a26745c4a2ff237028b4184c11eeb 100644 (file)
@@ -1,7 +1,11 @@
 package org.asamk;
 
+import org.asamk.signal.commands.exceptions.IOErrorException;
+
 import org.freedesktop.dbus.DBusPath;
+import org.freedesktop.dbus.Struct;
 import org.freedesktop.dbus.annotations.DBusProperty;
+import org.freedesktop.dbus.annotations.Position;
 import org.freedesktop.dbus.exceptions.DBusException;
 import org.freedesktop.dbus.exceptions.DBusExecutionException;
 import org.freedesktop.dbus.interfaces.DBusInterface;
@@ -102,7 +106,7 @@ public interface Signal extends DBusInterface {
 
     DBusPath getDevice(long deviceId);
 
-    List<DBusPath> listDevices() throws Error.Failure;
+    List<StructDevice> listDevices() throws Error.Failure;
 
     DBusPath getThisDevice();
 
@@ -145,6 +149,8 @@ public interface Signal extends DBusInterface {
 
     List<Boolean> getConfiguration();
 
+    void submitRateLimitChallenge(String challenge, String captchaString) throws IOErrorException;
+
     class MessageReceived extends DBusSignal {
 
         private final long timestamp;
@@ -262,7 +268,37 @@ public interface Signal extends DBusInterface {
         }
     }
 
-    @DBusProperty(name = "Id", type = Integer.class, access = DBusProperty.Access.READ)
+    class StructDevice extends Struct {
+
+        @Position(0)
+        DBusPath objectPath;
+
+        @Position(1)
+        Long id;
+
+        @Position(2)
+        String name;
+
+        public StructDevice(final DBusPath objectPath, final Long id, final String name) {
+            this.objectPath = objectPath;
+            this.id = id;
+            this.name = name;
+        }
+
+        public DBusPath getObjectPath() {
+            return objectPath;
+        }
+
+        public Long getId() {
+            return id;
+        }
+
+        public String getName() {
+            return name;
+        }
+    }
+
+    @DBusProperty(name = "Id", type = Long.class, access = DBusProperty.Access.READ)
     @DBusProperty(name = "Name", type = String.class)
     @DBusProperty(name = "Created", type = String.class, access = DBusProperty.Access.READ)
     @DBusProperty(name = "LastSeen", type = String.class, access = DBusProperty.Access.READ)
index bfd7fde9764ed552aeca4f84590d2193c3806c29..226402ddaa277fe8eebda1c7af6a4d1fbd00b7c5 100644 (file)
@@ -155,13 +155,14 @@ public class DbusManagerImpl implements Manager {
     @Override
     public List<Device> getLinkedDevices() throws IOException {
         final var thisDevice = signal.getThisDevice();
-        return signal.listDevices().stream().map(devicePath -> {
-            final var device = getRemoteObject(devicePath, Signal.Device.class).GetAll("org.asamk.Signal.Device");
+        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(devicePath));
+                    thisDevice.equals(d.getObjectPath()));
         }).collect(Collectors.toList());
     }
 
index 37cc35e340099cf2174bba29648d191e3b6ce2b3..bbe01d6b581dc9e85025c2b222b64d51f7aa666a 100644 (file)
@@ -51,6 +51,7 @@ public abstract class DbusProperties implements Properties {
     }
 
     @Override
+    @SuppressWarnings("unchecked")
     public Map<String, Variant<?>> GetAll(final String interface_name) {
         final var handler = getHandlerOptional(interface_name);
         if (handler.isEmpty()) {
@@ -61,6 +62,9 @@ public abstract class DbusProperties implements Properties {
                 .getProperties()
                 .stream()
                 .filter(p -> p.getGetter() != null)
-                .collect(Collectors.toMap(DbusProperty::getName, p -> new Variant<>(p.getGetter().get())));
+                .collect(Collectors.toMap(DbusProperty::getName, p -> {
+                    final Object o = p.getGetter().get();
+                    return o instanceof Variant ? (Variant<Object>) o : new Variant<>(o);
+                }));
     }
 }
index 55f994753d642561e54d3e6095ade4469f9ce6d8..41eca5da388306c979e8011dd8876fb0a9c0f38b 100644 (file)
@@ -3,6 +3,7 @@ package org.asamk.signal.dbus;
 import org.asamk.Signal;
 import org.asamk.Signal.Error;
 import org.asamk.signal.BaseConfig;
+import org.asamk.signal.commands.exceptions.IOErrorException;
 import org.asamk.signal.manager.AttachmentInvalidException;
 import org.asamk.signal.manager.Manager;
 import org.asamk.signal.manager.NotMasterDeviceException;
@@ -56,7 +57,7 @@ public class DbusSignalImpl implements Signal {
     private final String objectPath;
 
     private DBusPath thisDevice;
-    private final List<DBusPath> devices = new ArrayList<>();
+    private final List<StructDevice> devices = new ArrayList<>();
 
     public DbusSignalImpl(final Manager m, DBusConnection connection, final String objectPath) {
         this.m = m;
@@ -82,6 +83,18 @@ public class DbusSignalImpl implements Signal {
         return m.getSelfNumber();
     }
 
+    @Override
+    public void submitRateLimitChallenge(String challenge, String captchaString) throws IOErrorException {
+        final var captcha = captchaString == null ? null : captchaString.replace("signalcaptcha://", "");
+
+        try {
+            m.submitRateLimitRecaptchaChallenge(challenge, captcha);
+        } catch (IOException e) {
+            throw new IOErrorException("Submit challenge error: " + e.getMessage(), e);
+        }
+
+    }
+
     @Override
     public void addDevice(String uri) {
         try {
@@ -102,41 +115,11 @@ public class DbusSignalImpl implements Signal {
     }
 
     @Override
-    public List<DBusPath> listDevices() {
+    public List<StructDevice> listDevices() {
         updateDevices();
         return this.devices;
     }
 
-    private void updateDevices() {
-        List<org.asamk.signal.manager.api.Device> linkedDevices;
-        try {
-            linkedDevices = m.getLinkedDevices();
-        } catch (IOException | Error.Failure e) {
-            throw new Error.Failure("Failed to get linked devices: " + e.getMessage());
-        }
-
-        unExportDevices();
-
-        linkedDevices.forEach(d -> {
-            final var object = new DbusSignalDeviceImpl(d);
-            final var deviceObjectPath = object.getObjectPath();
-            try {
-                connection.exportObject(object);
-            } catch (DBusException e) {
-                e.printStackTrace();
-            }
-            if (d.isThisDevice()) {
-                thisDevice = new DBusPath(deviceObjectPath);
-            }
-            this.devices.add(new DBusPath(deviceObjectPath));
-        });
-    }
-
-    private void unExportDevices() {
-        this.devices.stream().map(DBusPath::getPath).forEach(connection::unExportObject);
-        this.devices.clear();
-    }
-
     @Override
     public DBusPath getThisDevice() {
         updateDevices();
@@ -813,21 +796,55 @@ public class DbusSignalImpl implements Signal {
         return name.isEmpty() ? null : name;
     }
 
+    private String emptyIfNull(final String string) {
+        return string == null ? "" : string;
+    }
+
     private static String getDeviceObjectPath(String basePath, long deviceId) {
         return basePath + "/Devices/" + deviceId;
     }
 
+    private void updateDevices() {
+        List<org.asamk.signal.manager.api.Device> linkedDevices;
+        try {
+            linkedDevices = m.getLinkedDevices();
+        } catch (IOException e) {
+            throw new Error.Failure("Failed to get linked devices: " + e.getMessage());
+        }
+
+        unExportDevices();
+
+        linkedDevices.forEach(d -> {
+            final var object = new DbusSignalDeviceImpl(d);
+            final var deviceObjectPath = object.getObjectPath();
+            try {
+                connection.exportObject(object);
+            } catch (DBusException e) {
+                e.printStackTrace();
+            }
+            if (d.isThisDevice()) {
+                thisDevice = new DBusPath(deviceObjectPath);
+            }
+            this.devices.add(new StructDevice(new DBusPath(deviceObjectPath), d.getId(), emptyIfNull(d.getName())));
+        });
+    }
+
+    private void unExportDevices() {
+        this.devices.stream()
+                .map(StructDevice::getObjectPath)
+                .map(DBusPath::getPath)
+                .forEach(connection::unExportObject);
+        this.devices.clear();
+    }
+
     public class DbusSignalDeviceImpl extends DbusProperties implements Signal.Device {
 
         private final org.asamk.signal.manager.api.Device device;
 
         public DbusSignalDeviceImpl(final org.asamk.signal.manager.api.Device device) {
-            super();
             super.addPropertiesHandler(new DbusInterfacePropertiesHandler("org.asamk.Signal.Device",
                     List.of(new DbusProperty<>("Id", device::getId),
-                            new DbusProperty<>("Name",
-                                    () -> device.getName() == null ? "" : device.getName(),
-                                    this::setDeviceName),
+                            new DbusProperty<>("Name", () -> emptyIfNull(device.getName()), this::setDeviceName),
                             new DbusProperty<>("Created", device::getCreated),
                             new DbusProperty<>("LastSeen", device::getLastSeen))));
             this.device = device;