Handle dublicate or missing pub keys corresponding to user ids, handle navigating back from service activity properly

This commit is contained in:
Dominik Schürmann 2013-09-09 19:38:13 +02:00
parent 0a52e1ecc9
commit 8a8d7c7738
4 changed files with 115 additions and 33 deletions

View File

@ -5,14 +5,14 @@
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:orientation="vertical" > android:orientation="vertical" >
<TextView <org.sufficientlysecure.htmltextview.HtmlTextView
android:id="@+id/api_select_pub_keys_text" android:id="@+id/api_select_pub_keys_text"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:padding="8dp" android:padding="8dp"
android:paddingBottom="3dip" android:paddingBottom="0dip"
android:text="@string/api_select_pub_keys_text" android:text="Set in-code!"
android:textAppearance="?android:attr/textAppearanceLarge" /> android:textAppearance="?android:attr/textAppearanceSmall" />
<FrameLayout <FrameLayout
android:id="@+id/api_select_pub_keys_fragment_container" android:id="@+id/api_select_pub_keys_fragment_container"

View File

@ -370,6 +370,8 @@
<string name="api_register_allow">Allow access</string> <string name="api_register_allow">Allow access</string>
<string name="api_register_disallow">Disallow access</string> <string name="api_register_disallow">Disallow access</string>
<string name="api_register_error_select_key">Please select a key!</string> <string name="api_register_error_select_key">Please select a key!</string>
<string name="api_select_pub_keys_text">You have selected recipients (e.g. by selecting email addresses), which public keys could not be found. Please verify your selection!</string> <string name="api_select_pub_keys_missing_text">No public keys were found for these user ids:</string>
<string name="api_select_pub_keys_dublicates_text">More than one public key exist for these user ids:</string>
<string name="api_select_pub_keys_text">Please review the list of recipients!</string>
</resources> </resources>

View File

@ -66,6 +66,17 @@ public class CryptoService extends Service {
final Object userInputLock = new Object(); final Object userInputLock = new Object();
private class MyBaseCallback implements Handler.Callback {
public static final int OKAY = 1;
public static final int CANCEL = 0;
@Override
public boolean handleMessage(Message msg) {
return false;
}
}
@Override @Override
public void onCreate() { public void onCreate() {
super.onCreate(); super.onCreate();
@ -116,9 +127,7 @@ public class CryptoService extends Service {
return passphrase; return passphrase;
} }
public class PassphraseActivityCallback implements Handler.Callback { public class PassphraseActivityCallback extends MyBaseCallback {
public static final int SUCCESS = 1;
public static final int NO_SUCCESS = 0;
private boolean success = false; private boolean success = false;
@ -128,7 +137,7 @@ public class CryptoService extends Service {
@Override @Override
public boolean handleMessage(Message msg) { public boolean handleMessage(Message msg) {
if (msg.arg1 == SUCCESS) { if (msg.arg1 == OKAY) {
success = true; success = true;
} else { } else {
success = false; success = false;
@ -151,9 +160,13 @@ public class CryptoService extends Service {
*/ */
private long[] getKeyIdsFromEmails(String[] encryptionUserIds, long ownKeyId) { private long[] getKeyIdsFromEmails(String[] encryptionUserIds, long ownKeyId) {
// find key ids to given emails in database // find key ids to given emails in database
boolean manySameUserIds = false;
boolean missingUserIds = false;
ArrayList<Long> keyIds = new ArrayList<Long>(); ArrayList<Long> keyIds = new ArrayList<Long>();
boolean missingUserIdsCheck = false;
boolean dublicateUserIdsCheck = false;
ArrayList<String> missingUserIds = new ArrayList<String>();
ArrayList<String> dublicateUserIds = new ArrayList<String>();
for (String email : encryptionUserIds) { for (String email : encryptionUserIds) {
Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email); Uri uri = KeychainContract.KeyRings.buildPublicKeyRingsByEmailsUri(email);
Cursor cur = getContentResolver().query(uri, null, null, null, null); Cursor cur = getContentResolver().query(uri, null, null, null, null);
@ -161,11 +174,13 @@ public class CryptoService extends Service {
long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID)); long id = cur.getLong(cur.getColumnIndex(KeychainContract.KeyRings.MASTER_KEY_ID));
keyIds.add(id); keyIds.add(id);
} else { } else {
missingUserIds = true; missingUserIdsCheck = true;
missingUserIds.add(email);
Log.d(Constants.TAG, "user id missing"); Log.d(Constants.TAG, "user id missing");
} }
if (cur.moveToNext()) { if (cur.moveToNext()) {
manySameUserIds = true; dublicateUserIdsCheck = true;
dublicateUserIds.add(email);
Log.d(Constants.TAG, "more than one user id with the same email"); Log.d(Constants.TAG, "more than one user id with the same email");
} }
} }
@ -179,12 +194,16 @@ public class CryptoService extends Service {
keyIdsArray[i] = keyIds.get(i); keyIdsArray[i] = keyIds.get(i);
} }
if (missingUserIds || manySameUserIds) { if (missingUserIdsCheck || dublicateUserIdsCheck) {
SelectPubKeysActivityCallback callback = new SelectPubKeysActivityCallback(); SelectPubKeysActivityCallback callback = new SelectPubKeysActivityCallback();
Messenger messenger = new Messenger(new Handler(getMainLooper(), callback)); Messenger messenger = new Messenger(new Handler(getMainLooper(), callback));
Bundle extras = new Bundle(); Bundle extras = new Bundle();
extras.putLongArray(CryptoServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray); extras.putLongArray(CryptoServiceActivity.EXTRA_SELECTED_MASTER_KEY_IDS, keyIdsArray);
extras.putStringArrayList(CryptoServiceActivity.EXTRA_MISSING_USER_IDS, missingUserIds);
extras.putStringArrayList(CryptoServiceActivity.EXTRA_DUBLICATE_USER_IDS,
dublicateUserIds);
pauseQueueAndStartServiceActivity(CryptoServiceActivity.ACTION_SELECT_PUB_KEYS, pauseQueueAndStartServiceActivity(CryptoServiceActivity.ACTION_SELECT_PUB_KEYS,
messenger, extras); messenger, extras);
@ -199,9 +218,7 @@ public class CryptoService extends Service {
return keyIdsArray; return keyIdsArray;
} }
public class SelectPubKeysActivityCallback implements Handler.Callback { public class SelectPubKeysActivityCallback extends MyBaseCallback {
public static final int OKAY = 1;
public static final int CANCEL = 0;
public static final String PUB_KEY_IDS = "pub_key_ids"; public static final String PUB_KEY_IDS = "pub_key_ids";
private boolean newSelection = false; private boolean newSelection = false;
@ -540,17 +557,14 @@ public class CryptoService extends Service {
if (callback.isAllowed()) { if (callback.isAllowed()) {
mThreadPool.execute(r); mThreadPool.execute(r);
Log.d(Constants.TAG, "Enqueued runnable…");
} else { } else {
Log.d(Constants.TAG, "User disallowed app!"); Log.d(Constants.TAG, "User disallowed app!");
} }
Log.d(Constants.TAG, "Enqueued runnable…");
} }
} }
public class RegisterActivityCallback implements Handler.Callback { public class RegisterActivityCallback extends MyBaseCallback {
public static final int ALLOW = 1;
public static final int DISALLOW = 0;
public static final String PACKAGE_NAME = "package_name"; public static final String PACKAGE_NAME = "package_name";
private boolean allowed = false; private boolean allowed = false;
@ -566,9 +580,7 @@ public class CryptoService extends Service {
@Override @Override
public boolean handleMessage(Message msg) { public boolean handleMessage(Message msg) {
Log.d(Constants.TAG, "msg what: " + msg.what); if (msg.arg1 == OKAY) {
if (msg.arg1 == ALLOW) {
allowed = true; allowed = true;
packageName = msg.getData().getString(PACKAGE_NAME); packageName = msg.getData().getString(PACKAGE_NAME);
@ -591,7 +603,7 @@ public class CryptoService extends Service {
} }
mThreadPool.resume(); mThreadPool.resume();
} }
return false; return true;
} }
} }

View File

@ -17,6 +17,9 @@
package org.sufficientlysecure.keychain.remote_api; package org.sufficientlysecure.keychain.remote_api;
import java.util.ArrayList;
import org.sufficientlysecure.htmltextview.HtmlTextView;
import org.sufficientlysecure.keychain.Constants; import org.sufficientlysecure.keychain.Constants;
import org.sufficientlysecure.keychain.Id; import org.sufficientlysecure.keychain.Id;
import org.sufficientlysecure.keychain.R; import org.sufficientlysecure.keychain.R;
@ -48,9 +51,13 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
public static final String EXTRA_MESSENGER = "messenger"; public static final String EXTRA_MESSENGER = "messenger";
public static final String EXTRA_SECRET_KEY_ID = "secretKeyId"; public static final String EXTRA_SECRET_KEY_ID = "secret_key_id";
public static final String EXTRA_PACKAGE_NAME = "packageName"; public static final String EXTRA_PACKAGE_NAME = "package_name";
public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "masterKeyIds";
// select activity
public static final String EXTRA_SELECTED_MASTER_KEY_IDS = "master_key_ids";
public static final String EXTRA_MISSING_USER_IDS = "missing_user_ids";
public static final String EXTRA_DUBLICATE_USER_IDS = "dublicate_user_ids";
private Messenger mMessenger; private Messenger mMessenger;
@ -59,6 +66,9 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
// select pub key view // select pub key view
private SelectPublicKeyFragment mSelectFragment; private SelectPublicKeyFragment mSelectFragment;
// has the user clicked one of the buttons?
private boolean finishHandled;
@Override @Override
protected void onCreate(Bundle savedInstanceState) { protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
@ -66,7 +76,24 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
handleActions(getIntent(), savedInstanceState); handleActions(getIntent(), savedInstanceState);
} }
@Override
protected void onStop() {
super.onStop();
if (!finishHandled) {
Message msg = Message.obtain();
msg.arg1 = CryptoService.RegisterActivityCallback.CANCEL;
try {
mMessenger.send(msg);
} catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoServiceActivity", e);
}
}
}
protected void handleActions(Intent intent, Bundle savedInstanceState) { protected void handleActions(Intent intent, Bundle savedInstanceState) {
finishHandled = false;
String action = intent.getAction(); String action = intent.getAction();
Bundle extras = intent.getExtras(); Bundle extras = intent.getExtras();
@ -99,7 +126,7 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
mSettingsFragment.getAppSettings()); mSettingsFragment.getAppSettings());
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.arg1 = CryptoService.RegisterActivityCallback.ALLOW; msg.arg1 = CryptoService.RegisterActivityCallback.OKAY;
Bundle data = new Bundle(); Bundle data = new Bundle();
data.putString(CryptoService.RegisterActivityCallback.PACKAGE_NAME, data.putString(CryptoService.RegisterActivityCallback.PACKAGE_NAME,
packageName); packageName);
@ -109,6 +136,8 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoServiceActivity", e); Log.e(Constants.TAG, "CryptoServiceActivity", e);
} }
finishHandled = true;
finish(); finish();
} }
} }
@ -118,12 +147,14 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
// Disallow // Disallow
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.arg1 = CryptoService.RegisterActivityCallback.DISALLOW; msg.arg1 = CryptoService.RegisterActivityCallback.CANCEL;
try { try {
mMessenger.send(msg); mMessenger.send(msg);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoServiceActivity", e); Log.e(Constants.TAG, "CryptoServiceActivity", e);
} }
finishHandled = true;
finish(); finish();
} }
}); });
@ -141,6 +172,33 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
showPassphraseDialog(secretKeyId); showPassphraseDialog(secretKeyId);
} else if (ACTION_SELECT_PUB_KEYS.equals(action)) { } else if (ACTION_SELECT_PUB_KEYS.equals(action)) {
long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS); long[] selectedMasterKeyIds = intent.getLongArrayExtra(EXTRA_SELECTED_MASTER_KEY_IDS);
ArrayList<String> missingUserIds = intent
.getStringArrayListExtra(EXTRA_MISSING_USER_IDS);
ArrayList<String> dublicateUserIds = intent
.getStringArrayListExtra(EXTRA_DUBLICATE_USER_IDS);
String text = new String();
text += "<b>" + getString(R.string.api_select_pub_keys_text) + "</b>";
text += "<br/><br/>";
if (missingUserIds != null && missingUserIds.size() > 0) {
text += getString(R.string.api_select_pub_keys_missing_text);
text += "<br/>";
text += "<ul>";
for (String userId : missingUserIds) {
text += "<li>" + userId + "</li>";
}
text += "</ul>";
text += "<br/>";
}
if (dublicateUserIds != null && dublicateUserIds.size() > 0) {
text += getString(R.string.api_select_pub_keys_dublicates_text);
text += "<br/>";
text += "<ul>";
for (String userId : dublicateUserIds) {
text += "<li>" + userId + "</li>";
}
text += "</ul>";
}
// Inflate a "Done"/"Cancel" custom action bar view // Inflate a "Done"/"Cancel" custom action bar view
ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay, ActionBarHelper.setDoneCancelView(getSupportActionBar(), R.string.btn_okay,
@ -161,6 +219,8 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoServiceActivity", e); Log.e(Constants.TAG, "CryptoServiceActivity", e);
} }
finishHandled = true;
finish(); finish();
} }
}, R.string.btn_doNotSave, new View.OnClickListener() { }, R.string.btn_doNotSave, new View.OnClickListener() {
@ -176,12 +236,18 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoServiceActivity", e); Log.e(Constants.TAG, "CryptoServiceActivity", e);
} }
finishHandled = true;
finish(); finish();
} }
}); });
setContentView(R.layout.api_app_select_pub_keys_activity); setContentView(R.layout.api_app_select_pub_keys_activity);
// set text on view
HtmlTextView textView = (HtmlTextView) findViewById(R.id.api_select_pub_keys_text);
textView.setHtmlFromString(text);
/* Load select pub keys fragment */ /* Load select pub keys fragment */
// Check that the activity is using the layout version with // Check that the activity is using the layout version with
// the fragment_container FrameLayout // the fragment_container FrameLayout
@ -220,7 +286,7 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
public void handleMessage(Message message) { public void handleMessage(Message message) {
if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) { if (message.what == PassphraseDialogFragment.MESSAGE_OKAY) {
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.arg1 = CryptoService.PassphraseActivityCallback.SUCCESS; msg.arg1 = CryptoService.PassphraseActivityCallback.OKAY;
try { try {
mMessenger.send(msg); mMessenger.send(msg);
} catch (RemoteException e) { } catch (RemoteException e) {
@ -228,13 +294,15 @@ public class CryptoServiceActivity extends SherlockFragmentActivity {
} }
} else { } else {
Message msg = Message.obtain(); Message msg = Message.obtain();
msg.arg1 = CryptoService.PassphraseActivityCallback.NO_SUCCESS; msg.arg1 = CryptoService.PassphraseActivityCallback.CANCEL;
try { try {
mMessenger.send(msg); mMessenger.send(msg);
} catch (RemoteException e) { } catch (RemoteException e) {
Log.e(Constants.TAG, "CryptoServiceActivity", e); Log.e(Constants.TAG, "CryptoServiceActivity", e);
} }
} }
finishHandled = true;
finish(); finish();
} }
}; };