]> nmode's Git Repositories - signal-cli/blob - src/main/java/org/asamk/signal/dbus/DbusSignalImpl.java
4af7156dcd024f82e93217a19ffb49a43432feae
[signal-cli] / src / main / java / org / asamk / signal / dbus / DbusSignalImpl.java
1 package org.asamk.signal.dbus;
2
3 import org.asamk.Signal;
4 import org.asamk.signal.manager.AttachmentInvalidException;
5 import org.asamk.signal.manager.Manager;
6 import org.asamk.signal.manager.groups.GroupId;
7 import org.asamk.signal.manager.groups.GroupNotFoundException;
8 import org.asamk.signal.manager.groups.NotAGroupMemberException;
9 import org.asamk.signal.manager.storage.groups.GroupInfo;
10 import org.asamk.signal.util.ErrorUtils;
11 import org.freedesktop.dbus.exceptions.DBusExecutionException;
12 import org.whispersystems.libsignal.util.Pair;
13 import org.whispersystems.libsignal.util.guava.Optional;
14 import org.whispersystems.signalservice.api.messages.SendMessageResult;
15 import org.whispersystems.signalservice.api.push.SignalServiceAddress;
16 import org.whispersystems.signalservice.api.util.InvalidNumberException;
17
18 import java.io.File;
19 import java.io.IOException;
20 import java.util.ArrayList;
21 import java.util.List;
22 import java.util.stream.Collectors;
23
24 public class DbusSignalImpl implements Signal {
25
26 private final Manager m;
27
28 public DbusSignalImpl(final Manager m) {
29 this.m = m;
30 }
31
32 @Override
33 public boolean isRemote() {
34 return false;
35 }
36
37 @Override
38 public String getObjectPath() {
39 return null;
40 }
41
42 @Override
43 public long sendMessage(final String message, final List<String> attachments, final String recipient) {
44 List<String> recipients = new ArrayList<>(1);
45 recipients.add(recipient);
46 return sendMessage(message, attachments, recipients);
47 }
48
49 private static void checkSendMessageResult(long timestamp, SendMessageResult result) throws DBusExecutionException {
50 String error = ErrorUtils.getErrorMessageFromSendMessageResult(result);
51
52 if (error == null) {
53 return;
54 }
55
56 final String message = timestamp + "\nFailed to send message:\n" + error + '\n';
57
58 if (result.getIdentityFailure() != null) {
59 throw new Error.UntrustedIdentity(message);
60 } else {
61 throw new Error.Failure(message);
62 }
63 }
64
65 private static void checkSendMessageResults(
66 long timestamp, List<SendMessageResult> results
67 ) throws DBusExecutionException {
68 if (results.size() == 1) {
69 checkSendMessageResult(timestamp, results.get(0));
70 return;
71 }
72
73 List<String> errors = ErrorUtils.getErrorMessagesFromSendMessageResults(results);
74 if (errors.size() == 0) {
75 return;
76 }
77
78 StringBuilder message = new StringBuilder();
79 message.append(timestamp).append('\n');
80 message.append("Failed to send (some) messages:\n");
81 for (String error : errors) {
82 message.append(error).append('\n');
83 }
84
85 throw new Error.Failure(message.toString());
86 }
87
88 @Override
89 public long sendMessage(final String message, final List<String> attachments, final List<String> recipients) {
90 try {
91 final Pair<Long, List<SendMessageResult>> results = m.sendMessage(message, attachments, recipients);
92 checkSendMessageResults(results.first(), results.second());
93 return results.first();
94 } catch (InvalidNumberException e) {
95 throw new Error.InvalidNumber(e.getMessage());
96 } catch (AttachmentInvalidException e) {
97 throw new Error.AttachmentInvalid(e.getMessage());
98 } catch (IOException e) {
99 throw new Error.Failure(e.getMessage());
100 }
101 }
102
103 @Override
104 public long sendNoteToSelfMessage(
105 final String message, final List<String> attachments
106 ) throws Error.AttachmentInvalid, Error.Failure, Error.UntrustedIdentity {
107 try {
108 final Pair<Long, SendMessageResult> results = m.sendSelfMessage(message, attachments);
109 checkSendMessageResult(results.first(), results.second());
110 return results.first();
111 } catch (AttachmentInvalidException e) {
112 throw new Error.AttachmentInvalid(e.getMessage());
113 } catch (IOException e) {
114 throw new Error.Failure(e.getMessage());
115 }
116 }
117
118 @Override
119 public void sendEndSessionMessage(final List<String> recipients) {
120 try {
121 final Pair<Long, List<SendMessageResult>> results = m.sendEndSessionMessage(recipients);
122 checkSendMessageResults(results.first(), results.second());
123 } catch (IOException e) {
124 throw new Error.Failure(e.getMessage());
125 } catch (InvalidNumberException e) {
126 throw new Error.InvalidNumber(e.getMessage());
127 }
128 }
129
130 @Override
131 public long sendGroupMessage(final String message, final List<String> attachments, final byte[] groupId) {
132 try {
133 Pair<Long, List<SendMessageResult>> results = m.sendGroupMessage(message,
134 attachments,
135 GroupId.unknownVersion(groupId));
136 checkSendMessageResults(results.first(), results.second());
137 return results.first();
138 } catch (IOException e) {
139 throw new Error.Failure(e.getMessage());
140 } catch (GroupNotFoundException | NotAGroupMemberException e) {
141 throw new Error.GroupNotFound(e.getMessage());
142 } catch (AttachmentInvalidException e) {
143 throw new Error.AttachmentInvalid(e.getMessage());
144 }
145 }
146
147 @Override
148 public String getContactName(final String number) {
149 try {
150 return m.getContactName(number);
151 } catch (InvalidNumberException e) {
152 throw new Error.InvalidNumber(e.getMessage());
153 }
154 }
155
156 @Override
157 public void setContactName(final String number, final String name) {
158 try {
159 m.setContactName(number, name);
160 } catch (InvalidNumberException e) {
161 throw new Error.InvalidNumber(e.getMessage());
162 }
163 }
164
165 @Override
166 public void setContactBlocked(final String number, final boolean blocked) {
167 try {
168 m.setContactBlocked(number, blocked);
169 } catch (InvalidNumberException e) {
170 throw new Error.InvalidNumber(e.getMessage());
171 }
172 }
173
174 @Override
175 public void setGroupBlocked(final byte[] groupId, final boolean blocked) {
176 try {
177 m.setGroupBlocked(GroupId.unknownVersion(groupId), blocked);
178 } catch (GroupNotFoundException e) {
179 throw new Error.GroupNotFound(e.getMessage());
180 }
181 }
182
183 @Override
184 public List<byte[]> getGroupIds() {
185 List<GroupInfo> groups = m.getGroups();
186 List<byte[]> ids = new ArrayList<>(groups.size());
187 for (GroupInfo group : groups) {
188 ids.add(group.getGroupId().serialize());
189 }
190 return ids;
191 }
192
193 @Override
194 public String getGroupName(final byte[] groupId) {
195 GroupInfo group = m.getGroup(GroupId.unknownVersion(groupId));
196 if (group == null) {
197 return "";
198 } else {
199 return group.getTitle();
200 }
201 }
202
203 @Override
204 public List<String> getGroupMembers(final byte[] groupId) {
205 GroupInfo group = m.getGroup(GroupId.unknownVersion(groupId));
206 if (group == null) {
207 return List.of();
208 } else {
209 return group.getMembers()
210 .stream()
211 .map(m::resolveSignalServiceAddress)
212 .map(SignalServiceAddress::getLegacyIdentifier)
213 .collect(Collectors.toList());
214 }
215 }
216
217 @Override
218 public byte[] updateGroup(byte[] groupId, String name, List<String> members, String avatar) {
219 try {
220 if (groupId.length == 0) {
221 groupId = null;
222 }
223 if (name.isEmpty()) {
224 name = null;
225 }
226 if (members.isEmpty()) {
227 members = null;
228 }
229 if (avatar.isEmpty()) {
230 avatar = null;
231 }
232 final Pair<GroupId, List<SendMessageResult>> results = m.updateGroup(groupId == null
233 ? null
234 : GroupId.unknownVersion(groupId), name, members, avatar == null ? null : new File(avatar));
235 checkSendMessageResults(0, results.second());
236 return results.first().serialize();
237 } catch (IOException e) {
238 throw new Error.Failure(e.getMessage());
239 } catch (GroupNotFoundException | NotAGroupMemberException e) {
240 throw new Error.GroupNotFound(e.getMessage());
241 } catch (InvalidNumberException e) {
242 throw new Error.InvalidNumber(e.getMessage());
243 } catch (AttachmentInvalidException e) {
244 throw new Error.AttachmentInvalid(e.getMessage());
245 }
246 }
247
248 @Override
249 public boolean isRegistered() {
250 return true;
251 }
252
253 @Override
254 public void updateProfile(
255 final String name,
256 final String about,
257 final String aboutEmoji,
258 String avatarPath,
259 final boolean removeAvatar
260 ) {
261 try {
262 if (avatarPath.isEmpty()) {
263 avatarPath = null;
264 }
265 Optional<File> avatarFile = removeAvatar
266 ? Optional.absent()
267 : avatarPath == null ? null : Optional.of(new File(avatarPath));
268 m.setProfile(name, about, aboutEmoji, avatarFile);
269 } catch (IOException e) {
270 throw new Error.Failure(e.getMessage());
271 }
272 }
273
274 }