republish pgp signature when changing status

Daniel Gultsch created

Change summary

src/main/java/eu/siacs/conversations/crypto/PgpEngine.java               |  5 
src/main/java/eu/siacs/conversations/entities/Account.java               |  4 
src/main/java/eu/siacs/conversations/services/XmppConnectionService.java | 10 
src/main/java/eu/siacs/conversations/ui/ConversationActivity.java        |  6 
src/main/java/eu/siacs/conversations/ui/ConversationFragment.java        |  2 
src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java       |  6 
src/main/java/eu/siacs/conversations/ui/SetPresenceActivity.java         | 45 
src/main/java/eu/siacs/conversations/ui/SettingsActivity.java            |  3 
src/main/java/eu/siacs/conversations/ui/XmppActivity.java                | 39 
src/main/res/values/strings.xml                                          |  2 
10 files changed, 97 insertions(+), 25 deletions(-)

Detailed changes

src/main/java/eu/siacs/conversations/crypto/PgpEngine.java 🔗

@@ -2,6 +2,7 @@ package eu.siacs.conversations.crypto;
 
 import android.app.PendingIntent;
 import android.content.Intent;
+import android.util.Log;
 
 import org.openintents.openpgp.OpenPgpSignatureResult;
 import org.openintents.openpgp.util.OpenPgpApi;
@@ -16,6 +17,7 @@ import java.io.InputStream;
 import java.io.OutputStream;
 import java.net.URL;
 
+import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
 import eu.siacs.conversations.entities.Account;
 import eu.siacs.conversations.entities.Contact;
@@ -299,7 +301,7 @@ public class PgpEngine {
 
 	public void generateSignature(final Account account, String status,
 			final UiCallback<Account> callback) {
-		if (account.getPgpId() == -1) {
+		if (account.getPgpId() == 0) {
 			return;
 		}
 		Intent params = new Intent();
@@ -308,6 +310,7 @@ public class PgpEngine {
 		params.putExtra(OpenPgpApi.EXTRA_SIGN_KEY_ID, account.getPgpId());
 		InputStream is = new ByteArrayInputStream(status.getBytes());
 		final OutputStream os = new ByteArrayOutputStream();
+		Log.d(Config.LOGTAG,account.getJid().toBareJid()+": signing status message \""+status+"\"");
 		api.executeApiAsync(params, is, os, new IOpenPgpCallback() {
 
 			@Override

src/main/java/eu/siacs/conversations/services/XmppConnectionService.java 🔗

@@ -3258,18 +3258,18 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 		return pending;
 	}
 
-	public void changeStatus(Account account, Presence.Status status, String statusMessage) {
+	public void changeStatus(Account account, Presence.Status status, String statusMessage, boolean send) {
 		if (!statusMessage.isEmpty()) {
 			databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
 		}
-		changeStatusReal(account, status, statusMessage);
+		changeStatusReal(account, status, statusMessage, send);
 	}
 
-	private void changeStatusReal(Account account, Presence.Status status, String statusMessage) {
+	private void changeStatusReal(Account account, Presence.Status status, String statusMessage, boolean send) {
 		account.setPresenceStatus(status);
 		account.setPresenceStatusMessage(statusMessage);
 		databaseBackend.updateAccount(account);
-		if (!account.isOptionSet(Account.OPTION_DISABLED)) {
+		if (!account.isOptionSet(Account.OPTION_DISABLED) && send) {
 			sendPresence(account);
 		}
 	}
@@ -3279,7 +3279,7 @@ public class XmppConnectionService extends Service implements OnPhoneContactsLoa
 			databaseBackend.insertPresenceTemplate(new PresenceTemplate(status, statusMessage));
 		}
 		for(Account account : getAccounts()) {
-			changeStatusReal(account, status, statusMessage);
+			changeStatusReal(account, status, statusMessage, true);
 		}
 	}
 

src/main/java/eu/siacs/conversations/ui/ConversationActivity.java 🔗

@@ -825,7 +825,7 @@ public class ConversationActivity extends XmppActivity
 									conversation.setNextEncryption(Message.ENCRYPTION_PGP);
 									item.setChecked(true);
 								} else {
-									announcePgp(conversation.getAccount(), conversation);
+									announcePgp(conversation.getAccount(), conversation, onOpenPGPKeyPublished);
 								}
 							} else {
 								showInstallPgpDialog();
@@ -1284,7 +1284,7 @@ public class ConversationActivity extends XmppActivity
 						// associate selected PGP keyId with the account
 						mSelectedConversation.getAccount().setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
 						// we need to announce the key as described in XEP-027
-						announcePgp(mSelectedConversation.getAccount(), null);
+						announcePgp(mSelectedConversation.getAccount(), null, onOpenPGPKeyPublished);
 					} else {
 						choosePgpSignId(mSelectedConversation.getAccount());
 					}
@@ -1294,7 +1294,7 @@ public class ConversationActivity extends XmppActivity
 				}
 			} else if (requestCode == REQUEST_ANNOUNCE_PGP) {
 				if (xmppConnectionServiceBound) {
-					announcePgp(mSelectedConversation.getAccount(), mSelectedConversation);
+					announcePgp(mSelectedConversation.getAccount(), mSelectedConversation, onOpenPGPKeyPublished);
 					this.mPostponedActivityResult = null;
 				} else {
 					this.mPostponedActivityResult = new Pair<>(requestCode, data);

src/main/java/eu/siacs/conversations/ui/ConversationFragment.java 🔗

@@ -1188,7 +1188,7 @@ public class ConversationFragment extends Fragment implements EditMessage.Keyboa
 			return;
 		}
 		if (conversation.getAccount().getPgpSignature() == null) {
-			activity.announcePgp(conversation.getAccount(), conversation);
+			activity.announcePgp(conversation.getAccount(), conversation, activity.onOpenPGPKeyPublished);
 			return;
 		}
 		if (conversation.getMode() == Conversation.MODE_SINGLE) {

src/main/java/eu/siacs/conversations/ui/ManageAccountActivity.java 🔗

@@ -328,7 +328,7 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
 
 	private void publishOpenPGPPublicKey(Account account) {
 		if (ManageAccountActivity.this.hasPgp()) {
-			choosePgpSignId(selectedAccount);
+			announcePgp(selectedAccount, null, onOpenPGPKeyPublished);
 		} else {
 			this.showInstallPgpDialog();
 		}
@@ -360,12 +360,12 @@ public class ManageAccountActivity extends XmppActivity implements OnAccountUpda
 				if (requestCode == REQUEST_CHOOSE_PGP_ID) {
 					if (data.getExtras().containsKey(OpenPgpApi.EXTRA_SIGN_KEY_ID)) {
 						selectedAccount.setPgpSignId(data.getExtras().getLong(OpenPgpApi.EXTRA_SIGN_KEY_ID));
-						announcePgp(selectedAccount, null);
+						announcePgp(selectedAccount, null, onOpenPGPKeyPublished);
 					} else {
 						choosePgpSignId(selectedAccount);
 					}
 				} else if (requestCode == REQUEST_ANNOUNCE_PGP) {
-					announcePgp(selectedAccount, null);
+					announcePgp(selectedAccount, null, onOpenPGPKeyPublished);
 				}
 				this.mPostponedActivityResult = null;
 			} else {

src/main/java/eu/siacs/conversations/ui/SetPresenceActivity.java 🔗

@@ -1,7 +1,9 @@
 package eu.siacs.conversations.ui;
 
+import android.content.Intent;
 import android.os.Bundle;
 import android.os.Handler;
+import android.util.Pair;
 import android.view.LayoutInflater;
 import android.view.Menu;
 import android.view.MenuItem;
@@ -18,6 +20,8 @@ import android.widget.TextView;
 
 import android.util.Log;
 
+import org.openintents.openpgp.util.OpenPgpApi;
+
 import java.util.List;
 import java.util.concurrent.RunnableFuture;
 import java.util.concurrent.atomic.AtomicBoolean;
@@ -42,6 +46,14 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
 	protected Spinner mShowSpinner;
 	protected CheckBox mAllAccounts;
 	protected LinearLayout mTemplatesView;
+	private Pair<Integer, Intent> mPostponedActivityResult;
+
+	private Runnable onPresenceChanged = new Runnable() {
+		@Override
+		public void run() {
+			finish();
+		}
+	};
 
 	protected void onCreate(final Bundle savedInstanceState) {
 		super.onCreate(savedInstanceState);
@@ -83,16 +95,37 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
 		}
 	}
 
+	@Override
+	protected void onActivityResult(int requestCode, int resultCode, Intent data) {
+		super.onActivityResult(requestCode, resultCode, data);
+		if (resultCode == RESULT_OK) {
+			if (xmppConnectionServiceBound && mAccount != null) {
+				if (requestCode == REQUEST_ANNOUNCE_PGP) {
+					announcePgp(mAccount, null, onPresenceChanged);
+				}
+				this.mPostponedActivityResult = null;
+			} else {
+				this.mPostponedActivityResult = new Pair<>(requestCode, data);
+			}
+		}
+	}
+
 	private void executeChangePresence() {
 		Presence.Status status = getStatusFromSpinner();
 		boolean allAccounts = mAllAccounts.isChecked();
 		String statusMessage = mStatusMessage.getText().toString().trim();
-		if (allAccounts) {
+		if (allAccounts && noAccountUsesPgp()) {
 			xmppConnectionService.changeStatus(status, statusMessage);
+			finish();
 		} else if (mAccount != null) {
-			xmppConnectionService.changeStatus(mAccount, status, statusMessage);
+			if (mAccount.getPgpId() == 0) {
+				xmppConnectionService.changeStatus(mAccount, status, statusMessage, true);
+				finish();
+			} else {
+				xmppConnectionService.changeStatus(mAccount, status, statusMessage, false);
+				announcePgp(mAccount, null, onPresenceChanged);
+			}
 		}
-		finish();
 	}
 
 	private Presence.Status getStatusFromSpinner() {
@@ -145,6 +178,12 @@ public class SetPresenceActivity extends XmppActivity implements View.OnClickLis
 				mStatusMessage.append(message);
 			}
 			mTemplates = xmppConnectionService.databaseBackend.getPresenceTemplates();
+			if (this.mPostponedActivityResult != null) {
+				this.onActivityResult(mPostponedActivityResult.first, RESULT_OK, mPostponedActivityResult.second);
+			}
+			boolean e = noAccountUsesPgp();
+			mAllAccounts.setEnabled(e);
+			mAllAccounts.setTextColor(e ? getPrimaryTextColor() : getSecondaryTextColor());
 		}
 		redrawTemplates();
 	}

src/main/java/eu/siacs/conversations/ui/SettingsActivity.java 🔗

@@ -187,6 +187,9 @@ public class SettingsActivity extends XmppActivity implements
 						|| name.equals("manually_change_presence")) {
 					xmppConnectionService.toggleScreenEventReceiver();
 				}
+				if (name.equals("manually_change_presence") && !noAccountUsesPgp()) {
+					Toast.makeText(this, R.string.republish_pgp_keys, Toast.LENGTH_LONG).show();
+				}
 				xmppConnectionService.refreshAllPresences();
 			}
 		} else if (name.equals("dont_trust_system_cas")) {

src/main/java/eu/siacs/conversations/ui/XmppActivity.java 🔗

@@ -68,6 +68,7 @@ import java.util.ArrayList;
 import java.util.Hashtable;
 import java.util.List;
 import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.RunnableFuture;
 
 import eu.siacs.conversations.Config;
 import eu.siacs.conversations.R;
@@ -118,6 +119,13 @@ public abstract class XmppActivity extends Activity {
 	protected int mTheme;
 	protected boolean mUsingEnterKey = false;
 
+	protected Runnable onOpenPGPKeyPublished = new Runnable() {
+		@Override
+		public void run() {
+			Toast.makeText(XmppActivity.this,R.string.openpgp_has_been_published, Toast.LENGTH_SHORT).show();
+		}
+	};
+
 	private long mLastUiRefresh = 0;
 	private Handler mRefreshUiHandler = new Handler();
 	private Runnable mRefreshUiRunnable = new Runnable() {
@@ -489,18 +497,23 @@ public abstract class XmppActivity extends Activity {
 		startActivityForResult(intent, REQUEST_INVITE_TO_CONVERSATION);
 	}
 
-	protected void announcePgp(Account account, final Conversation conversation) {
-		if (account.getPgpId() == -1) {
+	protected void announcePgp(Account account, final Conversation conversation, final Runnable onSuccess) {
+		if (account.getPgpId() == 0) {
 			choosePgpSignId(account);
 		} else {
-			xmppConnectionService.getPgpEngine().generateSignature(account, "", new UiCallback<Account>() {
+			String status = null;
+			if (manuallyChangePresence()) {
+				status = account.getPresenceStatusMessage();
+			}
+			if (status == null) {
+				status = "";
+			}
+			xmppConnectionService.getPgpEngine().generateSignature(account, status, new UiCallback<Account>() {
 
 				@Override
-				public void userInputRequried(PendingIntent pi,
-											  Account account) {
+				public void userInputRequried(PendingIntent pi, Account account) {
 					try {
-						startIntentSenderForResult(pi.getIntentSender(),
-								REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
+						startIntentSenderForResult(pi.getIntentSender(), REQUEST_ANNOUNCE_PGP, null, 0, 0, 0);
 					} catch (final SendIntentException ignored) {
 					}
 				}
@@ -513,6 +526,9 @@ public abstract class XmppActivity extends Activity {
 						conversation.setNextEncryption(Message.ENCRYPTION_PGP);
 						xmppConnectionService.databaseBackend.updateConversation(conversation);
 					}
+					if (onSuccess != null) {
+						runOnUiThread(onSuccess);
+					}
 				}
 
 				@Override
@@ -523,6 +539,15 @@ public abstract class XmppActivity extends Activity {
 		}
 	}
 
+	protected  boolean noAccountUsesPgp() {
+		for(Account account : xmppConnectionService.getAccounts()) {
+			if (account.getPgpId() != 0) {
+				return false;
+			}
+		}
+		return true;
+	}
+
 	@SuppressWarnings("deprecation")
 	@TargetApi(Build.VERSION_CODES.JELLY_BEAN)
 	protected void setListItemBackgroundOnView(View view) {

src/main/res/values/strings.xml 🔗

@@ -167,6 +167,8 @@
 	<string name="mgmt_account_disable">Temporarily disable</string>
 	<string name="mgmt_account_publish_avatar">Publish avatar</string>
 	<string name="mgmt_account_publish_pgp">Publish OpenPGP public key</string>
+	<string name="openpgp_has_been_published">OpenPGP public key has been published.</string>
+	<string name="republish_pgp_keys">Remember to republish your OpenPGP public keys!</string>
 	<string name="mgmt_account_enable">Enable account</string>
 	<string name="mgmt_account_are_you_sure">Are you sure?</string>
 	<string name="mgmt_account_delete_confirm_text">If you delete your account your entire conversation history will be lost</string>