]> nmode's Git Repositories - signal-cli/blob - lib/src/main/java/org/asamk/signal/manager/storage/groups/GroupInfoV1.java
d1230b278257e0e14d86cd07e48d925de6ffddea
[signal-cli] / lib / src / main / java / org / asamk / signal / manager / storage / groups / GroupInfoV1.java
1 package org.asamk.signal.manager.storage.groups;
2
3 import com.fasterxml.jackson.annotation.JsonIgnore;
4 import com.fasterxml.jackson.annotation.JsonProperty;
5 import com.fasterxml.jackson.core.JsonGenerator;
6 import com.fasterxml.jackson.core.JsonParser;
7 import com.fasterxml.jackson.databind.DeserializationContext;
8 import com.fasterxml.jackson.databind.JsonDeserializer;
9 import com.fasterxml.jackson.databind.JsonNode;
10 import com.fasterxml.jackson.databind.JsonSerializer;
11 import com.fasterxml.jackson.databind.ObjectMapper;
12 import com.fasterxml.jackson.databind.SerializerProvider;
13 import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
14 import com.fasterxml.jackson.databind.annotation.JsonSerialize;
15
16 import org.asamk.signal.manager.groups.GroupId;
17 import org.asamk.signal.manager.groups.GroupIdV1;
18 import org.asamk.signal.manager.groups.GroupIdV2;
19 import org.asamk.signal.manager.groups.GroupInviteLinkUrl;
20 import org.asamk.signal.manager.groups.GroupUtils;
21 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
22
23 import java.io.IOException;
24 import java.util.Collection;
25 import java.util.HashSet;
26 import java.util.Set;
27 import java.util.UUID;
28
29 public class GroupInfoV1 extends GroupInfo {
30
31 private static final ObjectMapper jsonProcessor = new ObjectMapper();
32
33 private final GroupIdV1 groupId;
34
35 private GroupIdV2 expectedV2Id;
36
37 @JsonProperty
38 public String name;
39
40 @JsonProperty
41 @JsonDeserialize(using = MembersDeserializer.class)
42 @JsonSerialize(using = MembersSerializer.class)
43 public Set<SignalServiceAddress> members = new HashSet<>();
44 @JsonProperty
45 public String color;
46 @JsonProperty(defaultValue = "0")
47 public int messageExpirationTime;
48 @JsonProperty(defaultValue = "false")
49 public boolean blocked;
50 @JsonProperty
51 public Integer inboxPosition;
52 @JsonProperty(defaultValue = "false")
53 public boolean archived;
54
55 public GroupInfoV1(GroupIdV1 groupId) {
56 this.groupId = groupId;
57 }
58
59 public GroupInfoV1(
60 @JsonProperty("groupId") byte[] groupId,
61 @JsonProperty("expectedV2Id") byte[] expectedV2Id,
62 @JsonProperty("name") String name,
63 @JsonProperty("members") Collection<SignalServiceAddress> members,
64 @JsonProperty("avatarId") long _ignored_avatarId,
65 @JsonProperty("color") String color,
66 @JsonProperty("blocked") boolean blocked,
67 @JsonProperty("inboxPosition") Integer inboxPosition,
68 @JsonProperty("archived") boolean archived,
69 @JsonProperty("messageExpirationTime") int messageExpirationTime,
70 @JsonProperty("active") boolean _ignored_active
71 ) {
72 this.groupId = GroupId.v1(groupId);
73 this.expectedV2Id = GroupId.v2(expectedV2Id);
74 this.name = name;
75 this.members.addAll(members);
76 this.color = color;
77 this.blocked = blocked;
78 this.inboxPosition = inboxPosition;
79 this.archived = archived;
80 this.messageExpirationTime = messageExpirationTime;
81 }
82
83 @Override
84 @JsonIgnore
85 public GroupIdV1 getGroupId() {
86 return groupId;
87 }
88
89 @JsonProperty("groupId")
90 private byte[] getGroupIdJackson() {
91 return groupId.serialize();
92 }
93
94 @JsonIgnore
95 public GroupIdV2 getExpectedV2Id() {
96 if (expectedV2Id == null) {
97 expectedV2Id = GroupUtils.getGroupIdV2(groupId);
98 }
99 return expectedV2Id;
100 }
101
102 @JsonProperty("expectedV2Id")
103 private byte[] getExpectedV2IdJackson() {
104 return getExpectedV2Id().serialize();
105 }
106
107 @Override
108 public String getTitle() {
109 return name;
110 }
111
112 @Override
113 public GroupInviteLinkUrl getGroupInviteLink() {
114 return null;
115 }
116
117 @JsonIgnore
118 public Set<SignalServiceAddress> getMembers() {
119 return members;
120 }
121
122 @Override
123 public boolean isBlocked() {
124 return blocked;
125 }
126
127 @Override
128 public void setBlocked(final boolean blocked) {
129 this.blocked = blocked;
130 }
131
132 @Override
133 public int getMessageExpirationTime() {
134 return messageExpirationTime;
135 }
136
137 public void addMembers(Collection<SignalServiceAddress> addresses) {
138 for (SignalServiceAddress address : addresses) {
139 if (this.members.contains(address)) {
140 continue;
141 }
142 removeMember(address);
143 this.members.add(address);
144 }
145 }
146
147 public void removeMember(SignalServiceAddress address) {
148 this.members.removeIf(member -> member.matches(address));
149 }
150
151 private static final class JsonSignalServiceAddress {
152
153 @JsonProperty
154 private UUID uuid;
155
156 @JsonProperty
157 private String number;
158
159 JsonSignalServiceAddress(@JsonProperty("uuid") final UUID uuid, @JsonProperty("number") final String number) {
160 this.uuid = uuid;
161 this.number = number;
162 }
163
164 JsonSignalServiceAddress(SignalServiceAddress address) {
165 this.uuid = address.getUuid().orNull();
166 this.number = address.getNumber().orNull();
167 }
168
169 SignalServiceAddress toSignalServiceAddress() {
170 return new SignalServiceAddress(uuid, number);
171 }
172 }
173
174 private static class MembersSerializer extends JsonSerializer<Set<SignalServiceAddress>> {
175
176 @Override
177 public void serialize(
178 final Set<SignalServiceAddress> value, final JsonGenerator jgen, final SerializerProvider provider
179 ) throws IOException {
180 jgen.writeStartArray(value.size());
181 for (SignalServiceAddress address : value) {
182 if (address.getUuid().isPresent()) {
183 jgen.writeObject(new JsonSignalServiceAddress(address));
184 } else {
185 jgen.writeString(address.getNumber().get());
186 }
187 }
188 jgen.writeEndArray();
189 }
190 }
191
192 private static class MembersDeserializer extends JsonDeserializer<Set<SignalServiceAddress>> {
193
194 @Override
195 public Set<SignalServiceAddress> deserialize(
196 JsonParser jsonParser, DeserializationContext deserializationContext
197 ) throws IOException {
198 Set<SignalServiceAddress> addresses = new HashSet<>();
199 JsonNode node = jsonParser.getCodec().readTree(jsonParser);
200 for (JsonNode n : node) {
201 if (n.isTextual()) {
202 addresses.add(new SignalServiceAddress(null, n.textValue()));
203 } else {
204 JsonSignalServiceAddress address = jsonProcessor.treeToValue(n, JsonSignalServiceAddress.class);
205 addresses.add(address.toSignalServiceAddress());
206 }
207 }
208
209 return addresses;
210 }
211 }
212 }