Add json output listIdentities command

This commit is contained in:
AsamK 2021-08-21 18:37:51 +02:00
parent 70fc2381d3
commit 11c90fa032
5 changed files with 94 additions and 25 deletions

View 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);
return fingerprint == null ? null : fingerprint.getScannableFingerprint().getSerialized();
}
@Deprecated

View file

@ -1,6 +1,7 @@
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;
@ -36,7 +37,7 @@ public class Utils {
return new StreamDetails(stream, mime, size);
}
public static String computeSafetyNumber(
public static Fingerprint computeSafetyNumber(
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()) {
return "INVALID ID";
return null;
}
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);
return fingerprint.getDisplayableFingerprint().getDisplayText();
}
public static SignalServiceAddress getSignalServiceAddressFromIdentifier(final String identifier) {

View file

@ -3,6 +3,7 @@ package org.asamk.signal.commands;
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;
@ -16,9 +17,12 @@ import org.slf4j.LoggerFactory;
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.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);
@ -48,26 +52,71 @@ public class ListIdentitiesCommand implements LocalCommand {
public void handleCommand(
final Namespace ns, final Manager m, final OutputWriter outputWriter
) throws CommandException {
final var writer = (PlainTextWriter) outputWriter;
var number = ns.getString("number");
if (number == null) {
for (var identity : m.getIdentities()) {
printIdentityFingerprint(writer, m, identity);
}
return;
}
List<IdentityInfo> identities;
if (number == null) {
identities = m.getIdentities();
} else {
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;
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;
}
}
}

View file

@ -8,11 +8,16 @@ public class Hex {
}
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(" ");
}
buf.deleteCharAt(buf.length() - 1);
return buf.toString();
}

View file

@ -45,11 +45,18 @@ public class Util {
}
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++) {
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();
}