1 package org
.asamk
.signal
.storage
.protocol
;
3 import com
.fasterxml
.jackson
.core
.JsonGenerator
;
4 import com
.fasterxml
.jackson
.core
.JsonParser
;
5 import com
.fasterxml
.jackson
.databind
.*;
6 import org
.whispersystems
.libsignal
.SignalProtocolAddress
;
7 import org
.whispersystems
.libsignal
.state
.SessionRecord
;
8 import org
.whispersystems
.libsignal
.state
.SessionStore
;
9 import org
.whispersystems
.signalservice
.internal
.util
.Base64
;
11 import java
.io
.IOException
;
14 class JsonSessionStore
implements SessionStore
{
16 private final Map
<SignalProtocolAddress
, byte[]> sessions
= new HashMap
<>();
18 public JsonSessionStore() {
22 private void addSessions(Map
<SignalProtocolAddress
, byte[]> sessions
) {
23 this.sessions
.putAll(sessions
);
27 public synchronized SessionRecord
loadSession(SignalProtocolAddress remoteAddress
) {
29 if (containsSession(remoteAddress
)) {
30 return new SessionRecord(sessions
.get(remoteAddress
));
32 return new SessionRecord();
34 } catch (IOException e
) {
35 throw new AssertionError(e
);
40 public synchronized List
<Integer
> getSubDeviceSessions(String name
) {
41 List
<Integer
> deviceIds
= new LinkedList
<>();
43 for (SignalProtocolAddress key
: sessions
.keySet()) {
44 if (key
.getName().equals(name
) &&
45 key
.getDeviceId() != 1) {
46 deviceIds
.add(key
.getDeviceId());
54 public synchronized void storeSession(SignalProtocolAddress address
, SessionRecord
record) {
55 sessions
.put(address
, record.serialize());
59 public synchronized boolean containsSession(SignalProtocolAddress address
) {
60 return sessions
.containsKey(address
);
64 public synchronized void deleteSession(SignalProtocolAddress address
) {
65 sessions
.remove(address
);
69 public synchronized void deleteAllSessions(String name
) {
70 for (SignalProtocolAddress key
: new ArrayList
<>(sessions
.keySet())) {
71 if (key
.getName().equals(name
)) {
77 public static class JsonSessionStoreDeserializer
extends JsonDeserializer
<JsonSessionStore
> {
80 public JsonSessionStore
deserialize(JsonParser jsonParser
, DeserializationContext deserializationContext
) throws IOException
{
81 JsonNode node
= jsonParser
.getCodec().readTree(jsonParser
);
83 Map
<SignalProtocolAddress
, byte[]> sessionMap
= new HashMap
<>();
85 for (JsonNode session
: node
) {
86 String sessionName
= session
.get("name").asText();
88 sessionMap
.put(new SignalProtocolAddress(sessionName
, session
.get("deviceId").asInt()), Base64
.decode(session
.get("record").asText()));
89 } catch (IOException e
) {
90 System
.out
.println(String
.format("Error while decoding session for: %s", sessionName
));
95 JsonSessionStore sessionStore
= new JsonSessionStore();
96 sessionStore
.addSessions(sessionMap
);
103 public static class JsonPreKeyStoreSerializer
extends JsonSerializer
<JsonSessionStore
> {
106 public void serialize(JsonSessionStore jsonSessionStore
, JsonGenerator json
, SerializerProvider serializerProvider
) throws IOException
{
107 json
.writeStartArray();
108 for (Map
.Entry
<SignalProtocolAddress
, byte[]> preKey
: jsonSessionStore
.sessions
.entrySet()) {
109 json
.writeStartObject();
110 json
.writeStringField("name", preKey
.getKey().getName());
111 json
.writeNumberField("deviceId", preKey
.getKey().getDeviceId());
112 json
.writeStringField("record", Base64
.encodeBytes(preKey
.getValue()));
113 json
.writeEndObject();
115 json
.writeEndArray();