]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/storage/profiles/ProfileStore.java
43a39671befdf4c16c91a015f1382e8d245daada
[signal-cli] / src / main / java / org / asamk / signal / storage / profiles / ProfileStore.java
1 package org.asamk.signal.storage.profiles;
2
3 import com.fasterxml.jackson.annotation.JsonProperty;
4 import com.fasterxml.jackson.core.JsonGenerator;
5 import com.fasterxml.jackson.core.JsonParser;
6 import com.fasterxml.jackson.databind.DeserializationContext;
7 import com.fasterxml.jackson.databind.JsonDeserializer;
8 import com.fasterxml.jackson.databind.JsonNode;
9 import com.fasterxml.jackson.databind.JsonSerializer;
10 import com.fasterxml.jackson.databind.ObjectMapper;
11 import com.fasterxml.jackson.databind.SerializerProvider;
12 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
13 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
14
15 import org.signal.zkgroup.InvalidInputException;
16 import org.signal.zkgroup.profiles.ProfileKey;
17 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
18 import org.whispersystems.signalservice.api.util.UuidUtil;
19 import org.whispersystems.util.Base64;
20
21 import java.io.IOException;
22 import java.util.HashMap;
23 import java.util.Map;
24 import java.util.UUID;
25
26 public class ProfileStore {
27
28 private static final ObjectMapper jsonProcessor = new ObjectMapper();
29
30 @JsonProperty("profiles")
31 @JsonDeserialize(using = ProfileStoreDeserializer.class)
32 @JsonSerialize(using = ProfileStoreSerializer.class)
33 private final Map<SignalServiceAddress, SignalProfileEntry> profiles = new HashMap<>();
34
35 public SignalProfileEntry getProfile(SignalServiceAddress serviceAddress) {
36 return profiles.get(serviceAddress);
37 }
38
39 public void updateProfile(SignalServiceAddress serviceAddress, SignalProfileEntry profile) {
40 profiles.put(serviceAddress, profile);
41 }
42
43 public static class ProfileStoreDeserializer extends JsonDeserializer<Map<SignalServiceAddress, SignalProfileEntry>> {
44
45 @Override
46 public Map<SignalServiceAddress, SignalProfileEntry> deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException {
47 JsonNode node = jsonParser.getCodec().readTree(jsonParser);
48
49 Map<SignalServiceAddress, SignalProfileEntry> addresses = new HashMap<>();
50
51 if (node.isArray()) {
52 for (JsonNode entry : node) {
53 String name = entry.hasNonNull("name")
54 ? entry.get("name").asText()
55 : null;
56 UUID uuid = entry.hasNonNull("uuid")
57 ? UuidUtil.parseOrNull(entry.get("uuid").asText())
58 : null;
59 final SignalServiceAddress serviceAddress = new SignalServiceAddress(uuid, name);
60 ProfileKey profileKey = null;
61 try {
62 profileKey = new ProfileKey(Base64.decode(entry.get("profileKey").asText()));
63 } catch (InvalidInputException ignored) {
64 }
65 long lastUpdateTimestamp = entry.get("lastUpdateTimestamp").asLong();
66 SignalProfile profile = jsonProcessor.treeToValue(entry.get("profile"), SignalProfile.class);
67 addresses.put(serviceAddress, new SignalProfileEntry(profileKey, lastUpdateTimestamp, profile));
68 }
69 }
70
71 return addresses;
72 }
73 }
74
75 public static class ProfileStoreSerializer extends JsonSerializer<Map<SignalServiceAddress, SignalProfileEntry>> {
76
77 @Override
78 public void serialize(Map<SignalServiceAddress, SignalProfileEntry> profiles, JsonGenerator json, SerializerProvider serializerProvider) throws IOException {
79 json.writeStartArray();
80 for (Map.Entry<SignalServiceAddress, SignalProfileEntry> entry : profiles.entrySet()) {
81 final SignalServiceAddress address = entry.getKey();
82 final SignalProfileEntry profileEntry = entry.getValue();
83 json.writeStartObject();
84 if (address.getNumber().isPresent()) {
85 json.writeStringField("name", address.getNumber().get());
86 }
87 if (address.getUuid().isPresent()) {
88 json.writeStringField("uuid", address.getUuid().get().toString());
89 }
90 json.writeStringField("profileKey", Base64.encodeBytes(profileEntry.getProfileKey().serialize()));
91 json.writeNumberField("lastUpdateTimestamp", profileEntry.getLastUpdateTimestamp());
92 json.writeObjectField("profile", profileEntry.getProfile());
93 json.writeEndObject();
94 }
95 json.writeEndArray();
96 }
97 }
98 }