]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/commands/ListIdentitiesCommand.java
Add json output listIdentities command
[signal-cli] / src / main / java / org / asamk / signal / commands / ListIdentitiesCommand.java
1 package org.asamk.signal.commands;
2
3 import net.sourceforge.argparse4j.inf.Namespace;
4 import net.sourceforge.argparse4j.inf.Subparser;
5
6 import org.asamk.signal.JsonWriter;
7 import org.asamk.signal.OutputWriter;
8 import org.asamk.signal.PlainTextWriter;
9 import org.asamk.signal.commands.exceptions.CommandException;
10 import org.asamk.signal.commands.exceptions.UserErrorException;
11 import org.asamk.signal.manager.Manager;
12 import org.asamk.signal.manager.storage.identities.IdentityInfo;
13 import org.asamk.signal.util.Hex;
14 import org.asamk.signal.util.Util;
15 import org.slf4j.Logger;
16 import org.slf4j.LoggerFactory;
17 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
18 import org.whispersystems.signalservice.api.util.InvalidNumberException;
19
20 import java.util.Base64;
21 import java.util.List;
22 import java.util.UUID;
23 import java.util.stream.Collectors;
24
25 public class ListIdentitiesCommand implements JsonRpcLocalCommand {
26
27 private final static Logger logger = LoggerFactory.getLogger(ListIdentitiesCommand.class);
28
29 @Override
30 public String getName() {
31 return "listIdentities";
32 }
33
34 private static void printIdentityFingerprint(PlainTextWriter writer, Manager m, IdentityInfo theirId) {
35 final SignalServiceAddress address = m.resolveSignalServiceAddress(theirId.getRecipientId());
36 var digits = Util.formatSafetyNumber(m.computeSafetyNumber(address, theirId.getIdentityKey()));
37 writer.println("{}: {} Added: {} Fingerprint: {} Safety Number: {}",
38 address.getNumber().orNull(),
39 theirId.getTrustLevel(),
40 theirId.getDateAdded(),
41 Hex.toString(theirId.getFingerprint()),
42 digits);
43 }
44
45 @Override
46 public void attachToSubparser(final Subparser subparser) {
47 subparser.help("List all known identity keys and their trust status, fingerprint and safety number.");
48 subparser.addArgument("-n", "--number").help("Only show identity keys for the given phone number.");
49 }
50
51 @Override
52 public void handleCommand(
53 final Namespace ns, final Manager m, final OutputWriter outputWriter
54 ) throws CommandException {
55 var number = ns.getString("number");
56
57 List<IdentityInfo> identities;
58 if (number == null) {
59 identities = m.getIdentities();
60 } else {
61 try {
62 identities = m.getIdentities(number);
63 } catch (InvalidNumberException e) {
64 throw new UserErrorException("Invalid number: " + e.getMessage());
65 }
66 }
67
68 if (outputWriter instanceof PlainTextWriter) {
69 final var writer = (PlainTextWriter) outputWriter;
70 for (var id : identities) {
71 printIdentityFingerprint(writer, m, id);
72 }
73 } else {
74 final var writer = (JsonWriter) outputWriter;
75 final var jsonIdentities = identities.stream().map(id -> {
76 final var address = m.resolveSignalServiceAddress(id.getRecipientId());
77 var safetyNumber = Util.formatSafetyNumber(m.computeSafetyNumber(address, id.getIdentityKey()));
78 var scannableSafetyNumber = m.computeSafetyNumberForScanning(address, id.getIdentityKey());
79 return new JsonIdentity(address.getNumber().orNull(),
80 address.getUuid().transform(UUID::toString).orNull(),
81 Hex.toString(id.getFingerprint()),
82 safetyNumber,
83 scannableSafetyNumber == null
84 ? null
85 : Base64.getEncoder().encodeToString(scannableSafetyNumber),
86 id.getTrustLevel().name(),
87 id.getDateAdded().getTime());
88 }).collect(Collectors.toList());
89
90 writer.write(jsonIdentities);
91 }
92 }
93
94 private static final class JsonIdentity {
95
96 public final String number;
97 public final String uuid;
98 public final String fingerprint;
99 public final String safetyNumber;
100 public final String scannableSafetyNumber;
101 public final String trustLevel;
102 public final long addedTimestamp;
103
104 private JsonIdentity(
105 final String number,
106 final String uuid,
107 final String fingerprint,
108 final String safetyNumber,
109 final String scannableSafetyNumber,
110 final String trustLevel,
111 final long addedTimestamp
112 ) {
113 this.number = number;
114 this.uuid = uuid;
115 this.fingerprint = fingerprint;
116 this.safetyNumber = safetyNumber;
117 this.scannableSafetyNumber = scannableSafetyNumber;
118 this.trustLevel = trustLevel;
119 this.addedTimestamp = addedTimestamp;
120 }
121 }
122 }