From 71664926e9f861435681a0a2b0e28ea5eeeeaf1e Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Sat, 7 Dec 2013 16:04:34 -0800 Subject: [PATCH] Better handling for unregistered users on outgoing message. --- .../textsecure/push/PushServiceSocket.java | 6 ++++-- .../push/UnregisteredUserException.java | 19 +++++++++++++++++ .../securesms/transport/PushTransport.java | 21 +++++++++++++++++++ 3 files changed, 44 insertions(+), 2 deletions(-) create mode 100644 library/src/org/whispersystems/textsecure/push/UnregisteredUserException.java diff --git a/library/src/org/whispersystems/textsecure/push/PushServiceSocket.java b/library/src/org/whispersystems/textsecure/push/PushServiceSocket.java index 4cd6018e96..e2961917d8 100644 --- a/library/src/org/whispersystems/textsecure/push/PushServiceSocket.java +++ b/library/src/org/whispersystems/textsecure/push/PushServiceSocket.java @@ -116,12 +116,14 @@ public class PushServiceSocket { sendMessage(new OutgoingPushMessageList(messages)); } - private void sendMessage(OutgoingPushMessageList messages) throws IOException { + private void sendMessage(OutgoingPushMessageList messages) + throws IOException + { String responseText = makeRequest(MESSAGE_PATH, "POST", new Gson().toJson(messages)); PushMessageResponse response = new Gson().fromJson(responseText, PushMessageResponse.class); if (response.getFailure().size() != 0) - throw new IOException("Got send failure: " + response.getFailure().get(0)); + throw new UnregisteredUserException(response.getFailure()); } public void registerPreKeys(IdentityKey identityKey, diff --git a/library/src/org/whispersystems/textsecure/push/UnregisteredUserException.java b/library/src/org/whispersystems/textsecure/push/UnregisteredUserException.java new file mode 100644 index 0000000000..3ad0327251 --- /dev/null +++ b/library/src/org/whispersystems/textsecure/push/UnregisteredUserException.java @@ -0,0 +1,19 @@ +package org.whispersystems.textsecure.push; + +import java.io.IOException; +import java.util.List; + +public class UnregisteredUserException extends IOException { + + private final List addresses; + + public UnregisteredUserException(List addresses) { + super(); + this.addresses = addresses; + } + + public List getAddresses() { + return addresses; + } + +} diff --git a/src/org/thoughtcrime/securesms/transport/PushTransport.java b/src/org/thoughtcrime/securesms/transport/PushTransport.java index 4d7ae61a49..1bf26195cc 100644 --- a/src/org/thoughtcrime/securesms/transport/PushTransport.java +++ b/src/org/thoughtcrime/securesms/transport/PushTransport.java @@ -46,6 +46,7 @@ import org.whispersystems.textsecure.push.PushDestination; import org.whispersystems.textsecure.push.PushMessageProtos.PushMessageContent; import org.whispersystems.textsecure.push.PushServiceSocket; import org.whispersystems.textsecure.push.RateLimitException; +import org.whispersystems.textsecure.push.UnregisteredUserException; import org.whispersystems.textsecure.storage.SessionRecordV2; import org.whispersystems.textsecure.util.InvalidNumberException; @@ -83,6 +84,10 @@ public class PushTransport extends BaseTransport { socket.sendMessage(destination, pushBody); context.sendBroadcast(constructSentIntent(context, message.getId(), message.getType(), true)); + } catch (UnregisteredUserException e) { + Log.w("PushTransport", e); + destroySessions(e.getAddresses()); + throw new IOException("Not push registered after all."); } catch (RateLimitException e) { Log.w("PushTransport", e); throw new IOException("Rate limit exceeded."); @@ -128,6 +133,10 @@ public class PushTransport extends BaseTransport { socket.sendMessage(destinations, pushBodies); + } catch (UnregisteredUserException e) { + Log.w("PushTransport", e); + destroySessions(e.getAddresses()); + throw new IOException("No push registered after all."); } catch (RateLimitException e) { Log.w("PushTransport", e); throw new IOException("Rate limit exceeded."); @@ -188,4 +197,16 @@ public class PushTransport extends BaseTransport { throw new AssertionError("Unknown ciphertext type: " + message.getType()); } } + + private void destroySessions(List unregisteredUsers) { + for (String unregisteredUser : unregisteredUsers) { + Log.w("PushTransport", "Destroying session for: " + unregisteredUser); + try { + Recipients recipients = RecipientFactory.getRecipientsFromString(context, unregisteredUser, false); + SessionRecordV2.delete(context, recipients.getPrimaryRecipient()); + } catch (RecipientFormattingException e) { + Log.w("PushTransport", e); + } + } + } }