X-Git-Url: https://git.nmode.ca/signal-cli/blobdiff_plain/593cd7d8ca6e8e0ab654accfd7e3c9d2ee01b001..3c40b11:/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java diff --git a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java index 1a4fdc10..41eca5da 100644 --- a/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java +++ b/src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java @@ -1,13 +1,14 @@ 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; import org.asamk.signal.manager.StickerPackInvalidException; import org.asamk.signal.manager.UntrustedIdentityException; -import org.asamk.signal.manager.api.Device; import org.asamk.signal.manager.api.Identity; import org.asamk.signal.manager.api.Message; import org.asamk.signal.manager.api.RecipientIdentifier; @@ -21,6 +22,9 @@ import org.asamk.signal.manager.groups.NotAGroupMemberException; import org.asamk.signal.manager.storage.recipients.Profile; import org.asamk.signal.manager.storage.recipients.RecipientAddress; import org.asamk.signal.util.ErrorUtils; +import org.freedesktop.dbus.DBusPath; +import org.freedesktop.dbus.connections.impl.DBusConnection; +import org.freedesktop.dbus.exceptions.DBusException; import org.freedesktop.dbus.exceptions.DBusExecutionException; import org.whispersystems.libsignal.InvalidKeyException; import org.whispersystems.libsignal.util.Pair; @@ -49,16 +53,24 @@ import java.util.stream.Stream; public class DbusSignalImpl implements Signal { private final Manager m; + private final DBusConnection connection; private final String objectPath; - public DbusSignalImpl(final Manager m, final String objectPath) { + private DBusPath thisDevice; + private final List devices = new ArrayList<>(); + + public DbusSignalImpl(final Manager m, DBusConnection connection, final String objectPath) { this.m = m; + this.connection = connection; this.objectPath = objectPath; } - @Override - public boolean isRemote() { - return false; + public void initObjects() { + updateDevices(); + } + + public void close() { + unExportDevices(); } @Override @@ -71,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 { @@ -85,33 +109,21 @@ public class DbusSignalImpl implements Signal { } @Override - public void removeDevice(int deviceId) { - try { - m.removeLinkedDevices(deviceId); - } catch (IOException e) { - throw new Error.Failure(e.getClass().getSimpleName() + ": Error while removing device: " + e.getMessage()); - } + public DBusPath getDevice(long deviceId) { + updateDevices(); + return new DBusPath(getDeviceObjectPath(objectPath, deviceId)); } @Override - public List listDevices() { - List devices; - try { - devices = m.getLinkedDevices(); - } catch (IOException | Error.Failure e) { - throw new Error.Failure("Failed to get linked devices: " + e.getMessage()); - } - - return devices.stream().map(d -> d.getName() == null ? "" : d.getName()).collect(Collectors.toList()); + public List listDevices() { + updateDevices(); + return this.devices; } @Override - public void updateDeviceName(String deviceName) { - try { - m.updateAccountAttributes(deviceName); - } catch (IOException | Signal.Error.Failure e) { - throw new Error.Failure("UpdateAccount error: " + e.getMessage()); - } + public DBusPath getThisDevice() { + updateDevices(); + return thisDevice; } @Override @@ -655,12 +667,36 @@ public class DbusSignalImpl implements Signal { try { return m.uploadStickerPack(path).toString(); } catch (IOException e) { - throw new Error.Failure("Upload error (maybe image size is too large):" + e.getMessage()); + throw new Error.IOError("Upload error (maybe image size is too large):" + e.getMessage()); } catch (StickerPackInvalidException e) { throw new Error.Failure("Invalid sticker pack: " + e.getMessage()); } } + @Override + public void setConfiguration(boolean readReceipts, boolean unidentifiedDeliveryIndicators, boolean typingIndicators, boolean linkPreviews) { + try { + m.updateConfiguration(readReceipts, unidentifiedDeliveryIndicators, typingIndicators, linkPreviews); + } catch (IOException e) { + throw new Error.IOError("UpdateAccount error: " + e.getMessage()); + } catch (NotMasterDeviceException e) { + throw new Error.UserError("This command doesn't work on linked devices."); + } + } + + @Override + public List getConfiguration() { + List config = new ArrayList<>(4); + try { + config = m.getConfiguration(); + } catch (IOException e) { + throw new Error.IOError("Configuration storage error: " + e.getMessage()); + } catch (NotMasterDeviceException e) { + throw new Error.UserError("This command doesn't work on linked devices."); + } + return config; + } + private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException { var error = ErrorUtils.getErrorMessageFromSendMessageResult(result); @@ -759,4 +795,87 @@ public class DbusSignalImpl implements Signal { private String nullIfEmpty(final String name) { 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 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.addPropertiesHandler(new DbusInterfacePropertiesHandler("org.asamk.Signal.Device", + List.of(new DbusProperty<>("Id", device::getId), + new DbusProperty<>("Name", () -> emptyIfNull(device.getName()), this::setDeviceName), + new DbusProperty<>("Created", device::getCreated), + new DbusProperty<>("LastSeen", device::getLastSeen)))); + this.device = device; + } + + @Override + public String getObjectPath() { + return getDeviceObjectPath(objectPath, device.getId()); + } + + @Override + public void removeDevice() throws Error.Failure { + try { + m.removeLinkedDevices(device.getId()); + updateDevices(); + } catch (IOException e) { + throw new Error.Failure(e.getMessage()); + } + } + + private void setDeviceName(String name) { + if (!device.isThisDevice()) { + throw new Error.Failure("Only the name of this device can be changed"); + } + try { + m.updateAccountAttributes(name); + // update device list + updateDevices(); + } catch (IOException e) { + throw new Error.Failure(e.getMessage()); + } + } + } }