]> nmode's Git Repositories - signal-cli/blobdiff - src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java
Improve handling of CDSI resource exhaustion
[signal-cli] / src / main / java / org / asamk / signal / dbus / DbusSignalImpl.java
index 6a44ff979c533732b2c4ca0e675e1ab20cbda92a..2223c96a6d31d2af3d6bf672523a3d09185c563c 100644 (file)
@@ -11,6 +11,7 @@ import org.asamk.signal.manager.api.GroupLinkState;
 import org.asamk.signal.manager.api.GroupNotFoundException;
 import org.asamk.signal.manager.api.GroupPermission;
 import org.asamk.signal.manager.api.GroupSendingNotAllowedException;
+import org.asamk.signal.manager.api.IdentityVerificationCode;
 import org.asamk.signal.manager.api.InactiveGroupLinkException;
 import org.asamk.signal.manager.api.InvalidDeviceLinkException;
 import org.asamk.signal.manager.api.InvalidNumberException;
@@ -20,6 +21,7 @@ import org.asamk.signal.manager.api.Message;
 import org.asamk.signal.manager.api.NotAGroupMemberException;
 import org.asamk.signal.manager.api.NotPrimaryDeviceException;
 import org.asamk.signal.manager.api.PendingAdminApprovalException;
+import org.asamk.signal.manager.api.RateLimitException;
 import org.asamk.signal.manager.api.RecipientAddress;
 import org.asamk.signal.manager.api.RecipientIdentifier;
 import org.asamk.signal.manager.api.SendMessageResult;
@@ -30,7 +32,7 @@ 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.IdentityVerificationCode;
+import org.asamk.signal.util.DateUtils;
 import org.asamk.signal.util.SendMessageResultUtils;
 import org.freedesktop.dbus.DBusPath;
 import org.freedesktop.dbus.connections.impl.DBusConnection;
@@ -55,8 +57,8 @@ import java.util.Map;
 import java.util.Objects;
 import java.util.Optional;
 import java.util.Set;
-import java.util.stream.Collectors;
 import java.util.UUID;
+import java.util.stream.Collectors;
 
 import static org.asamk.signal.dbus.DbusUtils.makeValidObjectPathElement;
 
@@ -185,6 +187,8 @@ public class DbusSignalImpl implements Signal {
             m.addDeviceLink(deviceLinkUrl);
         } catch (IOException | InvalidDeviceLinkException e) {
             throw new Error.Failure(e.getClass().getSimpleName() + " Add device link failed. " + e.getMessage());
+        } catch (NotPrimaryDeviceException e) {
+            throw new Error.Failure("This command doesn't work on linked devices.");
         } catch (URISyntaxException e) {
             throw new Error.InvalidUri(e.getClass().getSimpleName()
                     + " Device link uri has invalid format: "
@@ -679,6 +683,10 @@ public class DbusSignalImpl implements Signal {
             registered = m.getUserStatus(new HashSet<>(numbers));
         } catch (IOException e) {
             throw new Error.Failure(e.getMessage());
+        } catch (RateLimitException e) {
+            throw new Error.Failure(e.getMessage()
+                    + ", retry at "
+                    + DateUtils.formatTimestamp(e.getNextAttemptTimestamp()));
         }
 
         return numbers.stream().map(number -> registered.get(number).uuid() != null).toList();
@@ -891,7 +899,7 @@ public class DbusSignalImpl implements Signal {
         }
 
         var errors = SendMessageResultUtils.getErrorMessagesFromSendMessageResults(results);
-        if (errors.size() == 0 || errors.size() < results.size()) {
+        if (errors.isEmpty() || errors.size() < results.size()) {
             return;
         }
 
@@ -1030,7 +1038,7 @@ public class DbusSignalImpl implements Signal {
             connection.exportObject(object);
             logger.debug("Exported dbus object: " + object.getObjectPath());
         } catch (DBusException e) {
-            e.printStackTrace();
+            logger.warn("Failed to export dbus object (" + object.getObjectPath() + "): " + e.getMessage());
         }
     }
 
@@ -1044,8 +1052,8 @@ public class DbusSignalImpl implements Signal {
             final var object = new DbusSignalIdentityImpl(i);
             exportObject(object);
             this.identities.add(new StructIdentity(new DBusPath(object.getObjectPath()),
-                emptyIfNull(i.recipient().getIdentifier()),
-                i.recipient().getLegacyIdentifier()));
+                    i.recipient().uuid().map(UUID::toString).orElse(""),
+                    i.recipient().number().orElse("")));
         });
     }
 
@@ -1054,19 +1062,21 @@ public class DbusSignalImpl implements Signal {
     }
 
     private void unExportIdentities() {
-        this.identities.stream().map(StructIdentity::getObjectPath).map(DBusPath::getPath).forEach(connection::unExportObject);
+        this.identities.stream()
+                .map(StructIdentity::getObjectPath)
+                .map(DBusPath::getPath)
+                .forEach(connection::unExportObject);
         this.identities.clear();
     }
 
     @Override
     public DBusPath getIdentity(String number) throws Error.Failure {
-
         final var found = identities.stream()
-                            .filter(identity -> identity.getName().equals(number))
-                            .findFirst();
-        
+                .filter(identity -> identity.getNumber().equals(number) || identity.getUuid().equals(number))
+                .findFirst();
+
         if (found.isEmpty()) {
-            throw new Error.Failure("Identity for " + number + " unkown");
+            throw new Error.Failure("Identity for " + number + " unknown");
         }
         return found.get().getObjectPath();
     }
@@ -1082,40 +1092,41 @@ public class DbusSignalImpl implements Signal {
         private final org.asamk.signal.manager.api.Identity identity;
 
         public DbusSignalIdentityImpl(final org.asamk.signal.manager.api.Identity identity) {
-            this.identity=identity;
+            this.identity = identity;
             super.addPropertiesHandler(new DbusInterfacePropertiesHandler("org.asamk.Signal.Identity",
                     List.of(new DbusProperty<>("Number", () -> identity.recipient().number().orElse("")),
-                            new DbusProperty<>("Uuid", () -> identity.recipient().uuid().map(UUID::toString).orElse("")),
-                            new DbusProperty<>("Fingerprint", () -> identity.getFingerprint()),
+                            new DbusProperty<>("Uuid",
+                                    () -> identity.recipient().uuid().map(UUID::toString).orElse("")),
+                            new DbusProperty<>("Fingerprint", identity::getFingerprint),
                             new DbusProperty<>("SafetyNumber", identity::safetyNumber),
                             new DbusProperty<>("ScannableSafetyNumber", identity::scannableSafetyNumber),
                             new DbusProperty<>("TrustLevel", identity::trustLevel),
-                            new DbusProperty<>("AddedDate", identity::dateAddedTimestamp)
-                            )));
+                            new DbusProperty<>("AddedDate", identity::dateAddedTimestamp))));
         }
 
         @Override
         public String getObjectPath() {
-            return getIdentityObjectPath(objectPath, identity.recipient().getLegacyIdentifier());
+            return getIdentityObjectPath(objectPath,
+                    identity.recipient().getLegacyIdentifier() + "_" + identity.recipient().getIdentifier());
         }
 
         @Override
-        public void trust() throws Error.Failure  {
-            var recipient=RecipientIdentifier.Single.fromAddress(identity.recipient());
+        public void trust() throws Error.Failure {
+            var recipient = RecipientIdentifier.Single.fromAddress(identity.recipient());
             try {
                 m.trustIdentityAllKeys(recipient);
             } catch (UnregisteredRecipientException e) {
                 throw new Error.Failure("The user " + e.getSender().getIdentifier() + " is not registered.");
             }
-        };
+            updateIdentities();
+        }
 
         @Override
         public void trustVerified(String safetyNumber) throws Error.Failure {
-             var recipient = RecipientIdentifier.Single.fromAddress(identity.recipient());
+            var recipient = RecipientIdentifier.Single.fromAddress(identity.recipient());
+
             if (safetyNumber == null) {
-                throw new Error.Failure(
-                    "You need to specify a fingerprint/safety number");
+                throw new Error.Failure("You need to specify a fingerprint/safety number");
             }
             final IdentityVerificationCode verificationCode;
             try {
@@ -1134,6 +1145,7 @@ public class DbusSignalImpl implements Signal {
             } catch (UnregisteredRecipientException e) {
                 throw new Error.Failure("The user " + e.getSender().getIdentifier() + " is not registered.");
             }
+            updateIdentities();
         }
     }
 
@@ -1181,8 +1193,7 @@ public class DbusSignalImpl implements Signal {
 
     public class DbusSignalConfigurationImpl extends DbusProperties implements Signal.Configuration {
 
-        public DbusSignalConfigurationImpl(
-        ) {
+        public DbusSignalConfigurationImpl() {
             super.addPropertiesHandler(new DbusInterfacePropertiesHandler("org.asamk.Signal.Configuration",
                     List.of(new DbusProperty<>("ReadReceipts", this::getReadReceipts, this::setReadReceipts),
                             new DbusProperty<>("UnidentifiedDeliveryIndicators",