From e8ad4317a49cc86ddd5e147fe18f82beb02f9717 Mon Sep 17 00:00:00 2001 From: Vincent Breitmoser Date: Mon, 17 Mar 2014 14:10:40 +0100 Subject: [PATCH] certs: more filters, better initial uid selection, code cosmetics - add three types of filters for certificate list (ui looks like crap there, need to work on that) - select uncertified uids by default in CertifyKeyActivity - move some code around in KeychainProvider, 's slightly less hacky now --- .../keychain/provider/KeychainProvider.java | 49 ++++++++++++------- .../keychain/provider/ProviderHelper.java | 2 +- .../keychain/ui/ViewKeyCertsFragment.java | 48 ++++++++++++------ .../ui/adapter/ViewKeyUserIdsAdapter.java | 9 ++-- .../res/layout/view_key_certs_fragment.xml | 31 ++++++------ .../src/main/res/values/strings.xml | 3 ++ 6 files changed, 87 insertions(+), 55 deletions(-) diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java index 7ee30a304..f34423a71 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java @@ -82,6 +82,7 @@ public class KeychainProvider extends ContentProvider { private static final int CERTS_BY_KEY_ROW_ID = 404; private static final int CERTS_BY_KEY_ROW_ID_ALL = 405; private static final int CERTS_BY_CERTIFIER_ID = 406; + private static final int CERTS_BY_KEY_ROW_ID_HAS_SECRET = 407; // private static final int DATA_STREAM = 401; @@ -256,6 +257,8 @@ public class KeychainProvider extends ContentProvider { + KeychainContract.PATH_BY_KEY_ROW_ID + "/#", CERTS_BY_KEY_ROW_ID); matcher.addURI(authority, KeychainContract.BASE_CERTS + "/" + KeychainContract.PATH_BY_KEY_ROW_ID + "/#/all", CERTS_BY_KEY_ROW_ID_ALL); + matcher.addURI(authority, KeychainContract.BASE_CERTS + "/" + + KeychainContract.PATH_BY_KEY_ROW_ID + "/#/has_secret", CERTS_BY_KEY_ROW_ID_HAS_SECRET); matcher.addURI(authority, KeychainContract.BASE_CERTS + "/" + KeychainContract.PATH_BY_KEY_ID + "/#", CERTS_BY_KEY_ID); matcher.addURI(authority, KeychainContract.BASE_CERTS + "/" @@ -456,6 +459,23 @@ public class KeychainProvider extends ContentProvider { return projectionMap; } + private HashMap getProjectionMapForCerts() { + + HashMap pmap = new HashMap(); + pmap.put(Certs._ID, Tables.CERTS + "." + Certs._ID); + pmap.put(Certs.KEY_ID, Tables.CERTS + "." + Certs.KEY_ID); + pmap.put(Certs.RANK, Tables.CERTS + "." + Certs.RANK); + pmap.put(Certs.CREATION, Tables.CERTS + "." + Certs.CREATION); + pmap.put(Certs.KEY_ID_CERTIFIER, Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER); + pmap.put(Certs.KEY_DATA, Tables.CERTS + "." + Certs.KEY_DATA); + pmap.put(Certs.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); + // verified key data + pmap.put(UserIds.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID); + // verifying key data + pmap.put("signer_uid", "signer." + UserIds.USER_ID + " AS signer_uid"); + + return pmap; + } /** * Builds default query for keyRings: KeyRings table is joined with UserIds and Keys @@ -521,7 +541,6 @@ public class KeychainProvider extends ContentProvider { // all query() parameters, for good measure String groupBy = null, having = null; - boolean all = false; switch (match) { case UNIFIED_KEY_RING: @@ -709,7 +728,7 @@ public class KeychainProvider extends ContentProvider { case CERTS_BY_ROW_ID: case CERTS_BY_KEY_ROW_ID_ALL: - all = true; + case CERTS_BY_KEY_ROW_ID_HAS_SECRET: case CERTS_BY_KEY_ROW_ID: qb.setTables(Tables.CERTS + " JOIN " + Tables.USER_IDS + " ON (" @@ -719,10 +738,13 @@ public class KeychainProvider extends ContentProvider { + Tables.CERTS + "." + Certs.RANK + " = " + Tables.USER_IDS + "." + UserIds.RANK // noooooooot sure about this~ database design - + ")" + (all ? " LEFT" : "") + + ")" + (match == CERTS_BY_KEY_ROW_ID_ALL ? " LEFT" : "") + " JOIN " + Tables.KEYS + " ON (" + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER + " = " + Tables.KEYS + "." + Keys.KEY_ID + + (match == CERTS_BY_KEY_ROW_ID_HAS_SECRET ? + " AND " + Tables.KEYS + "." + Keys.TYPE + " = " + KeyTypes.SECRET : "" + ) + ") LEFT JOIN " + Tables.USER_IDS + " AS signer ON (" + Tables.KEYS + "." + Keys.KEY_RING_ROW_ID + " = " + "signer." + UserIds.KEY_RING_ROW_ID @@ -730,23 +752,11 @@ public class KeychainProvider extends ContentProvider { + "signer." + Keys.RANK + " = 0" + ")"); + qb.setProjectionMap(getProjectionMapForCerts()); + groupBy = Tables.CERTS + "." + Certs.RANK + ", " + Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER; - HashMap pmap2 = new HashMap(); - pmap2.put(Certs._ID, Tables.CERTS + "." + Certs._ID); - pmap2.put(Certs.KEY_ID, Tables.CERTS + "." + Certs.KEY_ID); - pmap2.put(Certs.RANK, Tables.CERTS + "." + Certs.RANK); - pmap2.put(Certs.CREATION, Tables.CERTS + "." + Certs.CREATION); - pmap2.put(Certs.KEY_ID_CERTIFIER, Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER); - pmap2.put(Certs.KEY_DATA, Tables.CERTS + "." + Certs.KEY_DATA); - pmap2.put(Certs.VERIFIED, Tables.CERTS + "." + Certs.VERIFIED); - // verified key data - pmap2.put(UserIds.USER_ID, Tables.USER_IDS + "." + UserIds.USER_ID); - // verifying key data - pmap2.put("signer_uid", "signer." + UserIds.USER_ID + " AS signer_uid"); - qb.setProjectionMap(pmap2); - if(match == CERTS_BY_ROW_ID) { qb.appendWhere(Tables.CERTS + "." + Certs._ID + " = "); qb.appendWhereEscapeString(uri.getPathSegments().get(1)); @@ -867,10 +877,11 @@ public class KeychainProvider extends ContentProvider { rowUri = ApiApps.buildIdUri(Long.toString(rowId)); break; - case CERTS_BY_ROW_ID: + case CERTS_BY_KEY_ROW_ID: rowId = db.insertOrThrow(Tables.CERTS, null, values); // kinda useless.. should this be buildCertsByKeyRowIdUri? - rowUri = Certs.buildCertsUri(Long.toString(rowId)); + // rowUri = Certs.buildCertsUri(Long.toString(rowId)); + rowUri = uri; break; default: diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java index 3d81743f1..1d249c67e 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java @@ -374,7 +374,7 @@ public class ProviderHelper { values.put(Certs.VERIFIED, verified); values.put(Certs.KEY_DATA, cert.getEncoded()); - Uri uri = Certs.buildCertsUri(Long.toString(keyRingRowId)); + Uri uri = Certs.buildCertsByKeyRowIdUri(Long.toString(keyRingRowId)); return ContentProviderOperation.newInsert(uri).withValues(values).build(); } diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java index e4c96b34b..c65e9e691 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyCertsFragment.java @@ -31,8 +31,8 @@ import android.view.LayoutInflater; import android.view.View; import android.view.ViewGroup; import android.widget.AdapterView; -import android.widget.CheckBox; -import android.widget.CompoundButton; +import android.widget.ArrayAdapter; +import android.widget.Spinner; import android.widget.TextView; import org.sufficientlysecure.keychain.Constants; @@ -42,8 +42,6 @@ import org.sufficientlysecure.keychain.provider.KeychainContract; import org.sufficientlysecure.keychain.provider.KeychainDatabase; import org.sufficientlysecure.keychain.util.Log; -import com.beardedhen.androidbootstrap.BootstrapButton; - import se.emilsjolander.stickylistheaders.ApiLevelTooLowException; import se.emilsjolander.stickylistheaders.StickyListHeadersAdapter; import se.emilsjolander.stickylistheaders.StickyListHeadersListView; @@ -64,14 +62,14 @@ public class ViewKeyCertsFragment extends Fragment // sort by our user id, static final String SORT_ORDER = - KeychainDatabase.Tables.USER_IDS + "." + KeychainContract.UserIds.USER_ID + " ASC, " + KeychainDatabase.Tables.USER_IDS + "." + KeychainContract.UserIds.RANK + " ASC, " + KeychainDatabase.Tables.CERTS + "." + KeychainContract.Certs.VERIFIED + " DESC, " + "signer_uid ASC"; public static final String ARG_KEYRING_ROW_ID = "row_id"; private StickyListHeadersListView mStickyList; - private CheckBox mShowUnknown; + private Spinner mSpinner; private CertListAdapter mAdapter; private boolean mUnknownShown = false; @@ -85,11 +83,18 @@ public class ViewKeyCertsFragment extends Fragment return view; } - private void toggleShowUnknown(boolean shown) { - if(shown) - mDataUri = mBaseUri.buildUpon().appendPath("all").build(); - else - mDataUri = mBaseUri; + private void changeShowState(int type) { + switch(type) { + case 0: + mDataUri = mBaseUri.buildUpon().appendPath("has_secret").build(); + break; + case 1: + mDataUri = mBaseUri; + break; + case 2: + mDataUri = mBaseUri.buildUpon().appendPath("all").build(); + break; + } getLoaderManager().restartLoader(0, null, this); } @@ -97,11 +102,24 @@ public class ViewKeyCertsFragment extends Fragment public void onActivityCreated(Bundle savedInstanceState) { super.onActivityCreated(savedInstanceState); - mShowUnknown = (CheckBox) getActivity().findViewById(R.id.showUnknown); - mShowUnknown.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { + mSpinner = (Spinner) getActivity().findViewById(R.id.spinner); + ArrayAdapter adapter = new ArrayAdapter(getActivity(), + android.R.layout.simple_spinner_item, new String[] { + getResources().getString(R.string.certs_list_known_secret), + getResources().getString(R.string.certs_list_known), + getResources().getString(R.string.certs_list_all) + } ); + adapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item); + mSpinner.setAdapter(adapter); + mSpinner.setSelection(1); + mSpinner.setOnItemSelectedListener(new AdapterView.OnItemSelectedListener() { @Override - public void onCheckedChanged(CompoundButton compoundButton, boolean b) { - toggleShowUnknown(b); + public void onItemSelected(AdapterView adapterView, View view, int i, long l) { + changeShowState(i); + } + + @Override + public void onNothingSelected(AdapterView adapterView) { } }); diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java index 4ae6131c9..2778ed08c 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/ViewKeyUserIdsAdapter.java @@ -63,8 +63,11 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { int count = newCursor.getCount(); mCheckStates.ensureCapacity(count); // initialize to true (use case knowledge: we usually want to sign all uids) - for(int i = 0; i < count; i++) - mCheckStates.add(true); + for(int i = 0; i < count; i++) { + newCursor.moveToPosition(i); + int verified = newCursor.getInt(mVerifiedId); + mCheckStates.add(verified == 0); + } } } @@ -116,7 +119,7 @@ public class ViewKeyUserIdsAdapter extends CursorAdapter { final CheckBox vCheckBox = (CheckBox) view.findViewById(R.id.checkBox); final int position = cursor.getPosition(); - vCheckBox.setClickable(false); + vCheckBox.setOnCheckedChangeListener(null); vCheckBox.setChecked(mCheckStates.get(position)); vCheckBox.setOnCheckedChangeListener(new CompoundButton.OnCheckedChangeListener() { @Override diff --git a/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml index 60f071bd4..b2bfe1700 100644 --- a/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml +++ b/OpenPGP-Keychain/src/main/res/layout/view_key_certs_fragment.xml @@ -9,29 +9,26 @@ android:layout_height="wrap_content" android:orientation="vertical"> + + - - + android:paddingLeft="16dp" + android:layout_alignParentStart="false" + android:layout_alignParentEnd="false" + android:layout_below="@+id/spinner" /> No certificates for this key User IDs to sign Reapplying certificates + Show by known secret keys + Show by known public keys + Show all certificates