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