diff options
Diffstat (limited to 'OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider')
3 files changed, 108 insertions, 2 deletions
diff --git a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java index d8de30b37..706b30d05 100644 --- a/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java +++ b/OpenPGP-Keychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainContract.java @@ -78,6 +78,7 @@ public class KeychainContract { public static final String PATH_PUBLIC = "public"; public static final String PATH_SECRET = "secret"; + public static final String PATH_UNIFIED = "unified"; public static final String PATH_BY_MASTER_KEY_ID = "master_key_id"; public static final String PATH_BY_KEY_ID = "key_id"; @@ -100,6 +101,10 @@ public class KeychainContract { /** Use if a single item is returned */ public static final String CONTENT_ITEM_TYPE = "vnd.android.cursor.item/vnd.thialfihar.apg.key_ring"; + public static Uri buildUnifiedKeyRingsUri() { + return CONTENT_URI.buildUpon().appendPath(PATH_UNIFIED).build(); + } + public static Uri buildPublicKeyRingsUri() { return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).build(); } 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 3b60ffc87..8b0efdbbd 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 @@ -81,6 +81,8 @@ public class KeychainProvider extends ContentProvider { private static final int API_APPS_BY_ROW_ID = 302; private static final int API_APPS_BY_PACKAGE_NAME = 303; + private static final int UNIFIED_KEY_RING = 401; + // private static final int DATA_STREAM = 401; protected UriMatcher mUriMatcher; @@ -227,6 +229,16 @@ public class KeychainProvider extends ContentProvider { + KeychainContract.PATH_BY_PACKAGE_NAME + "/*", API_APPS_BY_PACKAGE_NAME); /** + * unified key rings + * <pre> + * + * key_rings/unified + * + */ + matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/" + + KeychainContract.PATH_UNIFIED, UNIFIED_KEY_RING); + + /** * data stream * * <pre> @@ -455,6 +467,69 @@ public class KeychainProvider extends ContentProvider { int match = mUriMatcher.match(uri); + // screw that switch + if(match == UNIFIED_KEY_RING) { + + // join keyrings with keys and userIds + // Only get user id and key with rank 0 (main user id and main key) + qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" + + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + + KeysColumns.KEY_RING_ROW_ID + " AND " + Tables.KEYS + "." + + KeysColumns.RANK + " = '0') " + " INNER JOIN " + Tables.USER_IDS + " ON " + + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." + + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." + + UserIdsColumns.RANK + " = '0')"); + + { + HashMap<String, String> projectionMap = new HashMap<String, String>(); + + projectionMap.put(KeyRingsColumns.TYPE, "MAX(" + Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + ")"); + + projectionMap.put(BaseColumns._ID, Tables.KEY_RINGS + "." + BaseColumns._ID); + projectionMap.put(KeyRingsColumns.KEY_RING_DATA, Tables.KEY_RINGS + "." + + KeyRingsColumns.KEY_RING_DATA); + projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID); + // TODO: deprecated master key id + //projectionMap.put(KeyRingsColumns.MASTER_KEY_ID, Tables.KEYS + "." + KeysColumns.KEY_ID); + + projectionMap.put(KeysColumns.FINGERPRINT, Tables.KEYS + "." + KeysColumns.FINGERPRINT); + projectionMap.put(KeysColumns.IS_REVOKED, Tables.KEYS + "." + KeysColumns.IS_REVOKED); + + projectionMap.put(UserIdsColumns.USER_ID, Tables.USER_IDS + "." + UserIdsColumns.USER_ID); + + qb.setProjectionMap(projectionMap); + } + + if (TextUtils.isEmpty(sortOrder)) { + sortOrder = Tables.USER_IDS + "." + UserIdsColumns.USER_ID + " ASC"; + } + + // If no sort order is specified use the default + String orderBy; + if (TextUtils.isEmpty(sortOrder)) { + orderBy = Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " DESC"; + } else { + orderBy = Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " DESC, " + sortOrder; + } + + Cursor c = qb.query(db, projection, selection, selectionArgs, + Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID, + null, orderBy); + + // Tell the cursor what uri to watch, so it knows when its source data changes + c.setNotificationUri(getContext().getContentResolver(), uri); + + if (Constants.DEBUG) { + Log.d(Constants.TAG, + "Query: " + + qb.buildQuery(projection, selection, selectionArgs, Tables.KEY_RINGS + "." + KeyRingsColumns.MASTER_KEY_ID, null, + orderBy, null)); + Log.d(Constants.TAG, "Cursor: " + DatabaseUtils.dumpCursorToString(c)); + } + + return c; + } + switch (match) { case PUBLIC_KEY_RING: case SECRET_KEY_RING: 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 dd538fbf4..1c05344d6 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 @@ -483,13 +483,13 @@ public class ProviderHelper { */ public static boolean getSecretMasterKeyCanSign(Context context, long keyRingRowId) { Uri queryUri = KeyRings.buildSecretKeyRingsUri(String.valueOf(keyRingRowId)); - return getMasterKeyCanSign(context, queryUri, keyRingRowId); + return getMasterKeyCanSign(context, queryUri); } /** * Private helper method to get master key private empty status of keyring by its row id */ - private static boolean getMasterKeyCanSign(Context context, Uri queryUri, long keyRingRowId) { + public static boolean getMasterKeyCanSign(Context context, Uri queryUri) { String[] projection = new String[]{ KeyRings.MASTER_KEY_ID, "(SELECT COUNT(sign_keys." + Keys._ID + ") FROM " + Tables.KEYS @@ -515,6 +515,12 @@ public class ProviderHelper { return (masterKeyId > 0); } + public static boolean hasSecretKeyByMasterKeyId(Context context, long masterKeyId) { + Uri queryUri = KeyRings.buildSecretKeyRingsByMasterKeyIdUri(Long.toString(masterKeyId)); + // see if we can get our master key id back from the uri + return getMasterKeyId(context, queryUri) == masterKeyId; + } + /** * Get master key id of keyring by its row id */ @@ -546,6 +552,26 @@ public class ProviderHelper { return masterKeyId; } + public static long getRowId(Context context, Uri queryUri) { + String[] projection = new String[]{KeyRings._ID}; + Cursor cursor = context.getContentResolver().query(queryUri, projection, null, null, null); + + long rowId = 0; + try { + if (cursor != null && cursor.moveToFirst()) { + int idCol = cursor.getColumnIndexOrThrow(KeyRings._ID); + + rowId = cursor.getLong(idCol); + } + } finally { + if (cursor != null) { + cursor.close(); + } + } + + return rowId; + } + /** * Get fingerprint of key */ |