From ba67f108d44f5e71a12264ca3996ec33023c52bd Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Mon, 21 Sep 2015 13:31:57 -0700 Subject: [PATCH] Support unregistration from RedPhone // FREEBIE --- src/org/thoughtcrime/redphone/RedPhone.java | 31 ++++++++++--------- .../signaling/RedPhoneAccountManager.java | 23 +++++++++++++- .../redphone/signaling/RedPhoneGcmId.java | 17 ++++++++++ .../AdvancedPreferenceFragment.java | 12 +++++-- 4 files changed, 66 insertions(+), 17 deletions(-) create mode 100644 src/org/thoughtcrime/redphone/signaling/RedPhoneGcmId.java diff --git a/src/org/thoughtcrime/redphone/RedPhone.java b/src/org/thoughtcrime/redphone/RedPhone.java index da475dfc2f..79d1f9891e 100644 --- a/src/org/thoughtcrime/redphone/RedPhone.java +++ b/src/org/thoughtcrime/redphone/RedPhone.java @@ -38,6 +38,8 @@ import android.view.KeyEvent; import android.view.Window; import android.view.WindowManager; +import com.afollestad.materialdialogs.AlertDialogWrapper; + import org.thoughtcrime.redphone.crypto.zrtp.SASInfo; import org.thoughtcrime.redphone.ui.CallControls; import org.thoughtcrime.redphone.ui.CallScreen; @@ -289,22 +291,23 @@ public class RedPhone extends Activity { private void handleNoSuchUser(final Recipient recipient) { if (isFinishing()) return; // XXX Stuart added this check above, not sure why, so I'm repeating in ignorance. - moxie - AlertDialog.Builder dialog = new AlertDialog.Builder(this); + AlertDialogWrapper.Builder dialog = new AlertDialogWrapper.Builder(this); dialog.setTitle("Number not registered!"); - dialog.setIcon(android.R.drawable.ic_dialog_info); - dialog.setMessage("The number you dialed is not registered"); + dialog.setIconAttribute(R.attr.dialog_alert_icon); + dialog.setMessage("The number you dialed does not support secure voice!"); dialog.setCancelable(true); -// dialog.setPositiveButton(R.string.RedPhone_yes_exclamation, new OnClickListener() { -// public void onClick(DialogInterface dialog, int arg) { -// RedPhone.this.sendInstallLink(user); -// RedPhone.this.handleTerminate(LOCAL_TERMINATE); -// } -// }); -// dialog.setNegativeButton(R.string.RedPhone_no_thanks_exclamation, new OnClickListener() { -// public void onClick(DialogInterface dialog, int arg) { -// RedPhone.this.handleTerminate(LOCAL_TERMINATE); -// } -// }); + dialog.setPositiveButton("Got it", new OnClickListener() { + @Override + public void onClick(DialogInterface dialog, int which) { + RedPhone.this.handleTerminate(LOCAL_TERMINATE); + } + }); + dialog.setOnCancelListener(new DialogInterface.OnCancelListener() { + @Override + public void onCancel(DialogInterface dialog) { + RedPhone.this.handleTerminate(LOCAL_TERMINATE); + } + }); dialog.show(); } diff --git a/src/org/thoughtcrime/redphone/signaling/RedPhoneAccountManager.java b/src/org/thoughtcrime/redphone/signaling/RedPhoneAccountManager.java index fa275ec8cf..d10215bcba 100644 --- a/src/org/thoughtcrime/redphone/signaling/RedPhoneAccountManager.java +++ b/src/org/thoughtcrime/redphone/signaling/RedPhoneAccountManager.java @@ -1,5 +1,6 @@ package org.thoughtcrime.redphone.signaling; +import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; import com.squareup.okhttp.MediaType; import com.squareup.okhttp.OkHttpClient; @@ -8,6 +9,7 @@ import com.squareup.okhttp.RequestBody; import com.squareup.okhttp.Response; import org.thoughtcrime.securesms.util.Base64; +import org.whispersystems.libaxolotl.util.guava.Optional; import org.whispersystems.textsecure.api.push.TrustStore; import java.io.IOException; @@ -44,6 +46,25 @@ public class RedPhoneAccountManager { } } + public void setGcmId(Optional gcmId) throws IOException { + Request.Builder builder = new Request.Builder(); + builder.url(baseUrl + "/api/v1/accounts/gcm/"); + builder.header("Authorization", "Basic " + Base64.encodeBytes((login + ":" + password).getBytes())); + + if (gcmId.isPresent()) { + String body = new ObjectMapper().writeValueAsString(new RedPhoneGcmId(gcmId.get())); + builder.put(RequestBody.create(MediaType.parse("application/json; charset=utf-8"), body)); + } else { + builder.delete(); + } + + Response response = client.newCall(builder.build()).execute(); + + if (!response.isSuccessful()) { + throw new IOException("Failed to perform GCM operation: " + response.code()); + } + } + public void createAccount(String verificationToken, RedPhoneAccountAttributes attributes) throws IOException { String body = new ObjectMapper().writeValueAsString(attributes); @@ -56,7 +77,7 @@ public class RedPhoneAccountManager { Response response = client.newCall(request).execute(); if (!response.isSuccessful()) { - throw new IOException("Failed to create account"); + throw new IOException("Failed to create account: " + response.code()); } } diff --git a/src/org/thoughtcrime/redphone/signaling/RedPhoneGcmId.java b/src/org/thoughtcrime/redphone/signaling/RedPhoneGcmId.java new file mode 100644 index 0000000000..234adee67e --- /dev/null +++ b/src/org/thoughtcrime/redphone/signaling/RedPhoneGcmId.java @@ -0,0 +1,17 @@ +package org.thoughtcrime.redphone.signaling; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class RedPhoneGcmId { + + @JsonProperty + private String gcmRegistrationId; + + public RedPhoneGcmId() {} + + public RedPhoneGcmId(String gcmRegistrationId) { + this.gcmRegistrationId = gcmRegistrationId; + } + + +} diff --git a/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java b/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java index 684df211c7..18a4ccfde4 100644 --- a/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java +++ b/src/org/thoughtcrime/securesms/preferences/AdvancedPreferenceFragment.java @@ -19,7 +19,10 @@ import android.widget.Toast; import com.afollestad.materialdialogs.AlertDialogWrapper; import com.google.android.gms.gcm.GoogleCloudMessaging; +import org.thoughtcrime.redphone.signaling.RedPhoneAccountManager; +import org.thoughtcrime.redphone.signaling.RedPhoneTrustStore; import org.thoughtcrime.securesms.ApplicationPreferencesActivity; +import org.thoughtcrime.securesms.BuildConfig; import org.thoughtcrime.securesms.LogSubmitActivity; import org.thoughtcrime.securesms.R; import org.thoughtcrime.securesms.RegistrationActivity; @@ -174,10 +177,15 @@ public class AdvancedPreferenceFragment extends PreferenceFragment { @Override protected Integer doInBackground(Void... params) { try { - Context context = getActivity(); - TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context); + Context context = getActivity(); + TextSecureAccountManager accountManager = TextSecureCommunicationFactory.createManager(context); + RedPhoneAccountManager redPhoneAccountManager = new RedPhoneAccountManager(BuildConfig.REDPHONE_MASTER_URL, + new RedPhoneTrustStore(context), + TextSecurePreferences.getLocalNumber(context), + TextSecurePreferences.getPushServerPassword(context)); accountManager.setGcmId(Optional.absent()); + redPhoneAccountManager.setGcmId(Optional.absent()); GoogleCloudMessaging.getInstance(context).unregister(); return SUCCESS;