]> nmode's Git Repositories - signal-cli/commitdiff
Add json output listIdentities command
authorAsamK <asamk@gmx.de>
Sat, 21 Aug 2021 16:37:51 +0000 (18:37 +0200)
committerAsamK <asamk@gmx.de>
Sat, 21 Aug 2021 16:54:55 +0000 (18:54 +0200)
lib/src/main/java/org/asamk/signal/manager/Manager.java
lib/src/main/java/org/asamk/signal/manager/util/Utils.java
src/main/java/org/asamk/signal/commands/ListIdentitiesCommand.java
src/main/java/org/asamk/signal/util/Hex.java
src/main/java/org/asamk/signal/util/Util.java

index c4b696657d3679cbfc3d4df9a72a69fe980daddd..e2306dece3cc73ad69ab0832bc60810339f0533a 100644 (file)
@@ -2664,14 +2664,22 @@ public class Manager implements Closeable {
         }
     }
 
         }
     }
 
-    public String computeSafetyNumber(
-            SignalServiceAddress theirAddress, IdentityKey theirIdentityKey
-    ) {
-        return Utils.computeSafetyNumber(ServiceConfig.capabilities.isUuid(),
+    public String computeSafetyNumber(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
+        final var fingerprint = Utils.computeSafetyNumber(capabilities.isUuid(),
+                account.getSelfAddress(),
+                getIdentityKeyPair().getPublicKey(),
+                theirAddress,
+                theirIdentityKey);
+        return fingerprint == null ? null : fingerprint.getDisplayableFingerprint().getDisplayText();
+    }
+
+    public byte[] computeSafetyNumberForScanning(SignalServiceAddress theirAddress, IdentityKey theirIdentityKey) {
+        final var fingerprint = Utils.computeSafetyNumber(capabilities.isUuid(),
                 account.getSelfAddress(),
                 getIdentityKeyPair().getPublicKey(),
                 theirAddress,
                 theirIdentityKey);
                 account.getSelfAddress(),
                 getIdentityKeyPair().getPublicKey(),
                 theirAddress,
                 theirIdentityKey);
+        return fingerprint == null ? null : fingerprint.getScannableFingerprint().getSerialized();
     }
 
     @Deprecated
     }
 
     @Deprecated
index b0a9bbb184ba5c35a3065de47c5749b6217c7694..a2466311680f3580c70394c8ef5b6eea9032b38a 100644 (file)
@@ -1,6 +1,7 @@
 package org.asamk.signal.manager.util;
 
 import org.whispersystems.libsignal.IdentityKey;
 package org.asamk.signal.manager.util;
 
 import org.whispersystems.libsignal.IdentityKey;
+import org.whispersystems.libsignal.fingerprint.Fingerprint;
 import org.whispersystems.libsignal.fingerprint.NumericFingerprintGenerator;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.util.StreamDetails;
 import org.whispersystems.libsignal.fingerprint.NumericFingerprintGenerator;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.util.StreamDetails;
@@ -36,7 +37,7 @@ public class Utils {
         return new StreamDetails(stream, mime, size);
     }
 
         return new StreamDetails(stream, mime, size);
     }
 
-    public static String computeSafetyNumber(
+    public static Fingerprint computeSafetyNumber(
             boolean isUuidCapable,
             SignalServiceAddress ownAddress,
             IdentityKey ownIdentityKey,
             boolean isUuidCapable,
             SignalServiceAddress ownAddress,
             IdentityKey ownIdentityKey,
@@ -56,18 +57,17 @@ public class Utils {
             // Version 1: E164 user
             version = 1;
             if (!ownAddress.getNumber().isPresent() || !theirAddress.getNumber().isPresent()) {
             // Version 1: E164 user
             version = 1;
             if (!ownAddress.getNumber().isPresent() || !theirAddress.getNumber().isPresent()) {
-                return "INVALID ID";
+                return null;
             }
             ownId = ownAddress.getNumber().get().getBytes();
             theirId = theirAddress.getNumber().get().getBytes();
         }
 
             }
             ownId = ownAddress.getNumber().get().getBytes();
             theirId = theirAddress.getNumber().get().getBytes();
         }
 
-        var fingerprint = new NumericFingerprintGenerator(5200).createFor(version,
+        return new NumericFingerprintGenerator(5200).createFor(version,
                 ownId,
                 ownIdentityKey,
                 theirId,
                 theirIdentityKey);
                 ownId,
                 ownIdentityKey,
                 theirId,
                 theirIdentityKey);
-        return fingerprint.getDisplayableFingerprint().getDisplayText();
     }
 
     public static SignalServiceAddress getSignalServiceAddressFromIdentifier(final String identifier) {
     }
 
     public static SignalServiceAddress getSignalServiceAddressFromIdentifier(final String identifier) {
index f996f3b5633bd029786d39c5d59ac1ebf0ca2934..49ca2546f30a0698fdfd429d329fc25d84706b75 100644 (file)
@@ -3,6 +3,7 @@ package org.asamk.signal.commands;
 import net.sourceforge.argparse4j.inf.Namespace;
 import net.sourceforge.argparse4j.inf.Subparser;
 
 import net.sourceforge.argparse4j.inf.Namespace;
 import net.sourceforge.argparse4j.inf.Subparser;
 
+import org.asamk.signal.JsonWriter;
 import org.asamk.signal.OutputWriter;
 import org.asamk.signal.PlainTextWriter;
 import org.asamk.signal.commands.exceptions.CommandException;
 import org.asamk.signal.OutputWriter;
 import org.asamk.signal.PlainTextWriter;
 import org.asamk.signal.commands.exceptions.CommandException;
@@ -16,9 +17,12 @@ import org.slf4j.LoggerFactory;
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.util.InvalidNumberException;
 
 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
 import org.whispersystems.signalservice.api.util.InvalidNumberException;
 
+import java.util.Base64;
 import java.util.List;
 import java.util.List;
+import java.util.UUID;
+import java.util.stream.Collectors;
 
 
-public class ListIdentitiesCommand implements LocalCommand {
+public class ListIdentitiesCommand implements JsonRpcLocalCommand {
 
     private final static Logger logger = LoggerFactory.getLogger(ListIdentitiesCommand.class);
 
 
     private final static Logger logger = LoggerFactory.getLogger(ListIdentitiesCommand.class);
 
@@ -48,26 +52,71 @@ public class ListIdentitiesCommand implements LocalCommand {
     public void handleCommand(
             final Namespace ns, final Manager m, final OutputWriter outputWriter
     ) throws CommandException {
     public void handleCommand(
             final Namespace ns, final Manager m, final OutputWriter outputWriter
     ) throws CommandException {
-        final var writer = (PlainTextWriter) outputWriter;
-
         var number = ns.getString("number");
 
         var number = ns.getString("number");
 
+        List<IdentityInfo> identities;
         if (number == null) {
         if (number == null) {
-            for (var identity : m.getIdentities()) {
-                printIdentityFingerprint(writer, m, identity);
+            identities = m.getIdentities();
+        } else {
+            try {
+                identities = m.getIdentities(number);
+            } catch (InvalidNumberException e) {
+                throw new UserErrorException("Invalid number: " + e.getMessage());
             }
             }
-            return;
         }
 
         }
 
-        List<IdentityInfo> identities;
-        try {
-            identities = m.getIdentities(number);
-        } catch (InvalidNumberException e) {
-            throw new UserErrorException("Invalid number: " + e.getMessage());
+        if (outputWriter instanceof PlainTextWriter) {
+            final var writer = (PlainTextWriter) outputWriter;
+            for (var id : identities) {
+                printIdentityFingerprint(writer, m, id);
+            }
+        } else {
+            final var writer = (JsonWriter) outputWriter;
+            final var jsonIdentities = identities.stream().map(id -> {
+                final var address = m.resolveSignalServiceAddress(id.getRecipientId());
+                var safetyNumber = Util.formatSafetyNumber(m.computeSafetyNumber(address, id.getIdentityKey()));
+                var scannableSafetyNumber = m.computeSafetyNumberForScanning(address, id.getIdentityKey());
+                return new JsonIdentity(address.getNumber().orNull(),
+                        address.getUuid().transform(UUID::toString).orNull(),
+                        Hex.toString(id.getFingerprint()),
+                        safetyNumber,
+                        scannableSafetyNumber == null
+                                ? null
+                                : Base64.getEncoder().encodeToString(scannableSafetyNumber),
+                        id.getTrustLevel().name(),
+                        id.getDateAdded().getTime());
+            }).collect(Collectors.toList());
+
+            writer.write(jsonIdentities);
         }
         }
+    }
+
+    private static final class JsonIdentity {
+
+        public final String number;
+        public final String uuid;
+        public final String fingerprint;
+        public final String safetyNumber;
+        public final String scannableSafetyNumber;
+        public final String trustLevel;
+        public final long addedTimestamp;
 
 
-        for (var id : identities) {
-            printIdentityFingerprint(writer, m, id);
+        private JsonIdentity(
+                final String number,
+                final String uuid,
+                final String fingerprint,
+                final String safetyNumber,
+                final String scannableSafetyNumber,
+                final String trustLevel,
+                final long addedTimestamp
+        ) {
+            this.number = number;
+            this.uuid = uuid;
+            this.fingerprint = fingerprint;
+            this.safetyNumber = safetyNumber;
+            this.scannableSafetyNumber = scannableSafetyNumber;
+            this.trustLevel = trustLevel;
+            this.addedTimestamp = addedTimestamp;
         }
     }
 }
         }
     }
 }
index f5f7a6adeaaf0b23741457112f25f3ff4dae5868..596f23a96a64c658de0490432bd5fc7a107df2cd 100644 (file)
@@ -8,11 +8,16 @@ public class Hex {
     }
 
     public static String toString(byte[] bytes) {
     }
 
     public static String toString(byte[] bytes) {
+        if (bytes.length == 0) {
+            return "";
+        }
+
         var buf = new StringBuffer();
         for (final var aByte : bytes) {
             appendHexChar(buf, aByte);
             buf.append(" ");
         }
         var buf = new StringBuffer();
         for (final var aByte : bytes) {
             appendHexChar(buf, aByte);
             buf.append(" ");
         }
+        buf.deleteCharAt(buf.length() - 1);
         return buf.toString();
     }
 
         return buf.toString();
     }
 
index 31c6b68e987316ed9bdac52db7655abd01eb1bee..0afe09105457b7dcafe01bb99340546c6b506aa1 100644 (file)
@@ -45,11 +45,18 @@ public class Util {
     }
 
     public static String formatSafetyNumber(String digits) {
     }
 
     public static String formatSafetyNumber(String digits) {
+        if (digits == null) {
+            return null;
+        }
+
         final var partCount = 12;
         var partSize = digits.length() / partCount;
         var f = new StringBuilder(digits.length() + partCount);
         for (var i = 0; i < partCount; i++) {
         final var partCount = 12;
         var partSize = digits.length() / partCount;
         var f = new StringBuilder(digits.length() + partCount);
         for (var i = 0; i < partCount; i++) {
-            f.append(digits, i * partSize, (i * partSize) + partSize).append(" ");
+            f.append(digits, i * partSize, (i * partSize) + partSize);
+            if (i != partCount - 1) {
+                f.append(" ");
+            }
         }
         return f.toString();
     }
         }
         return f.toString();
     }