From 3b09f2d0f6e2e8afb5158a718264c38f5014ba50 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Dominik=20Sch=C3=BCrmann?= Date: Sun, 16 Dec 2012 18:53:23 +0100 Subject: [PATCH] Fix for email query, add new email query with like --- .../android/apg/demo/AidlDemoActivity.java | 4 +- .../android/apg/demo/AidlDemoActivity2.java | 3 +- .../apg/demo/ContentProviderDemoActivity.java | 4 +- .../integration/ApgContentProviderHelper.java | 99 ++++++++++++++++--- .../apg/integration/ApgIntentHelper.java | 2 +- APG/AndroidManifest.xml | 13 +++ APG/project.properties | 2 +- .../android/apg/provider/ApgContract.java | 11 +++ .../android/apg/provider/ApgProvider.java | 49 ++++++--- 9 files changed, 151 insertions(+), 36 deletions(-) diff --git a/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity.java b/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity.java index 65bd3caf5..2174b6e09 100644 --- a/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity.java +++ b/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity.java @@ -19,6 +19,7 @@ package org.thialfihar.android.apg.demo; import org.thialfihar.android.apg.integration.ApgData; import org.thialfihar.android.apg.integration.ApgIntentHelper; import org.thialfihar.android.apg.service.IApgApiService; +import org.thialfihar.android.apg.service.IApgKeyService; import org.thialfihar.android.apg.service.handler.IApgDecryptHandler; import org.thialfihar.android.apg.service.handler.IApgEncryptHandler; import org.thialfihar.android.apg.service.handler.IApgGetDecryptionKeyIdHandler; @@ -70,8 +71,7 @@ public class AidlDemoActivity extends Activity { mApgIntentHelper = new ApgIntentHelper(mActivity); mApgData = new ApgData(); - bindService(new Intent("org.thialfihar.android.apg.service.IApgApiService"), svcConn, - Context.BIND_AUTO_CREATE); + bindService(new Intent(IApgApiService.class.getName()), svcConn, Context.BIND_AUTO_CREATE); } public void encryptOnClick(View view) { diff --git a/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity2.java b/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity2.java index 51054f58a..4a862e8ae 100644 --- a/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity2.java +++ b/APG-API-Demo/src/org/thialfihar/android/apg/demo/AidlDemoActivity2.java @@ -72,8 +72,7 @@ public class AidlDemoActivity2 extends Activity { mApgIntentHelper = new ApgIntentHelper(mActivity); mApgData = new ApgData(); - bindService(new Intent("org.thialfihar.android.apg.service.IApgKeyService"), svcConn, - Context.BIND_AUTO_CREATE); + bindService(new Intent(IApgKeyService.class.getName()), svcConn, Context.BIND_AUTO_CREATE); } public void getKeyringsStringsOnClick(View view) { diff --git a/APG-API-Demo/src/org/thialfihar/android/apg/demo/ContentProviderDemoActivity.java b/APG-API-Demo/src/org/thialfihar/android/apg/demo/ContentProviderDemoActivity.java index 6d7696a32..892b41429 100644 --- a/APG-API-Demo/src/org/thialfihar/android/apg/demo/ContentProviderDemoActivity.java +++ b/APG-API-Demo/src/org/thialfihar/android/apg/demo/ContentProviderDemoActivity.java @@ -52,12 +52,12 @@ public class ContentProviderDemoActivity extends Activity { } public void test1OnClick(View view) { - long[] test = mApgContentProviderHelper.getPublicKeyIdsFromEmail("user@example.com"); + long[] test = mApgContentProviderHelper.getPublicKeyringIdsByEmail("user@example.com"); mOutputTextView.setText(Arrays.toString(test)); } public void test2OnClick(View view) { - boolean test = mApgContentProviderHelper.hasPublicKeyForEmail("user@example.com"); + boolean test = mApgContentProviderHelper.hasPublicKeyringByEmail("user@example.com"); if (test) { mOutputTextView.setText("true"); } else { diff --git a/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgContentProviderHelper.java b/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgContentProviderHelper.java index 2c2531b02..39d79d494 100644 --- a/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgContentProviderHelper.java +++ b/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgContentProviderHelper.java @@ -17,7 +17,6 @@ package org.thialfihar.android.apg.integration; -import android.app.Activity; import android.content.ContentUris; import android.content.Context; import android.database.Cursor; @@ -31,16 +30,20 @@ public class ApgContentProviderHelper { + AUTHORITY + "/key_rings/public/key_id/"); public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS = Uri.parse("content://" + AUTHORITY + "/key_rings/public/emails/"); + public static final Uri CONTENT_URI_PUBLIC_KEY_RING_BY_LIKE_EMAIL = Uri.parse("content://" + + AUTHORITY + "/key_rings/public/like_email/"); public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID = Uri.parse("content://" + AUTHORITY + "/key_rings/secret/key_id/"); public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_EMAILS = Uri.parse("content://" + AUTHORITY + "/key_rings/secret/emails/"); + public static final Uri CONTENT_URI_SECRET_KEY_RING_BY_LIKE_EMAIL = Uri.parse("content://" + + AUTHORITY + "/key_rings/secret/like_email/"); - private Context activity; + private Context mContext; - public ApgContentProviderHelper(Activity activity) { - this.activity = activity; + public ApgContentProviderHelper(Context context) { + this.mContext = context; } /** @@ -51,11 +54,45 @@ public class ApgContentProviderHelper { * The email in question. * @return key ids */ - public long[] getSecretKeyIdsFromEmail(String email) { + public long[] getSecretKeyringIdsByEmail(String email) { long ids[] = null; try { Uri contentUri = Uri.withAppendedPath(CONTENT_URI_SECRET_KEY_RING_BY_EMAILS, email); - Cursor c = activity.getContentResolver().query(contentUri, + Cursor c = mContext.getContentResolver().query(contentUri, + new String[] { "master_key_id" }, null, null, null); + if (c != null && c.getCount() > 0) { + ids = new long[c.getCount()]; + while (c.moveToNext()) { + ids[c.getPosition()] = c.getLong(0); + } + } + + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissions(); + } + + return ids; + } + + /** + * Get secret key ids based on a given String that is part of the email. + * + * Example: String: example, then emails: test@example.com, example@google.com are returned + * + * @param context + * @param email + * The email in question. + * @return key ids + */ + public long[] getSecretKeyringIdsByLikeEmail(String likeEmail) { + long ids[] = null; + try { + Uri contentUri = Uri.withAppendedPath(CONTENT_URI_SECRET_KEY_RING_BY_LIKE_EMAIL, + likeEmail); + Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "master_key_id" }, null, null, null); if (c != null && c.getCount() > 0) { ids = new long[c.getCount()]; @@ -82,11 +119,45 @@ public class ApgContentProviderHelper { * The email in question. * @return key ids */ - public long[] getPublicKeyIdsFromEmail(String email) { + public long[] getPublicKeyringIdsByEmail(String email) { long ids[] = null; try { Uri contentUri = Uri.withAppendedPath(CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, email); - Cursor c = activity.getContentResolver().query(contentUri, + Cursor c = mContext.getContentResolver().query(contentUri, + new String[] { "master_key_id" }, null, null, null); + if (c != null && c.getCount() > 0) { + ids = new long[c.getCount()]; + while (c.moveToNext()) { + ids[c.getPosition()] = c.getLong(0); + } + } + + if (c != null) { + c.close(); + } + } catch (SecurityException e) { + insufficientPermissions(); + } + + return ids; + } + + /** + * Get public key ids based on a given String that is part of the email. + * + * Example: String: example, then emails: test@example.com, example@google.com are returned + * + * @param context + * @param email + * The email in question. + * @return key ids + */ + public long[] getPublicKeyringIdsByLikeEmail(String likeEmail) { + long ids[] = null; + try { + Uri contentUri = Uri.withAppendedPath(CONTENT_URI_PUBLIC_KEY_RING_BY_LIKE_EMAIL, + likeEmail); + Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "master_key_id" }, null, null, null); if (c != null && c.getCount() > 0) { ids = new long[c.getCount()]; @@ -113,10 +184,10 @@ public class ApgContentProviderHelper { * The email in question. * @return true if there is a secret key for this email. */ - public boolean hasSecretKeyForEmail(String email) { + public boolean hasSecretKeyringByEmail(String email) { try { Uri contentUri = Uri.withAppendedPath(CONTENT_URI_SECRET_KEY_RING_BY_EMAILS, email); - Cursor c = activity.getContentResolver().query(contentUri, + Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "master_key_id" }, null, null, null); if (c != null && c.getCount() > 0) { c.close(); @@ -139,10 +210,10 @@ public class ApgContentProviderHelper { * The email in question. * @return true if there is a public key for this email. */ - public boolean hasPublicKeyForEmail(String email) { + public boolean hasPublicKeyringByEmail(String email) { try { Uri contentUri = Uri.withAppendedPath(CONTENT_URI_PUBLIC_KEY_RING_BY_EMAILS, email); - Cursor c = activity.getContentResolver().query(contentUri, + Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "master_key_id" }, null, null, null); if (c != null && c.getCount() > 0) { c.close(); @@ -169,7 +240,7 @@ public class ApgContentProviderHelper { try { Uri contentUri = ContentUris.withAppendedId(CONTENT_URI_SECRET_KEY_RING_BY_KEY_ID, keyId); - Cursor c = activity.getContentResolver().query(contentUri, new String[] { "user_id" }, + Cursor c = mContext.getContentResolver().query(contentUri, new String[] { "user_id" }, null, null, null); if (c != null && c.moveToFirst()) { userId = c.getString(0); @@ -189,7 +260,7 @@ public class ApgContentProviderHelper { } private void insufficientPermissions() { - Toast.makeText(activity, "Permission to access APG Provider is missing!", Toast.LENGTH_LONG) + Toast.makeText(mContext, "Permission to access APG Provider is missing!", Toast.LENGTH_LONG) .show(); } } diff --git a/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgIntentHelper.java b/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgIntentHelper.java index c92f2ebed..1b95e8986 100644 --- a/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgIntentHelper.java +++ b/APG-API-Lib/src/org/thialfihar/android/apg/integration/ApgIntentHelper.java @@ -356,7 +356,7 @@ public class ApgIntentHelper { if (apgData == null || !apgData.hasPublicKeys()) { ApgContentProviderHelper cPHelper = new ApgContentProviderHelper(activity); - initialKeyIds = cPHelper.getPublicKeyIdsFromEmail(emails); + initialKeyIds = cPHelper.getPublicKeyringIdsByEmail(emails); } else { initialKeyIds = apgData.getPublicKeys(); } diff --git a/APG/AndroidManifest.xml b/APG/AndroidManifest.xml index f76e4f1dc..491de65a9 100644 --- a/APG/AndroidManifest.xml +++ b/APG/AndroidManifest.xml @@ -49,6 +49,19 @@ android:minSdkVersion="8" android:targetSdkVersion="14" /> + + + + + diff --git a/APG/project.properties b/APG/project.properties index 63019788e..d39cb7982 100644 --- a/APG/project.properties +++ b/APG/project.properties @@ -9,4 +9,4 @@ # Project target. target=android-15 -android.library.reference.1=android-libs/ActionBarSherlock +android.library.reference.1=../../CryptoCall-UI/CryptoCall-UI/android-libs/ActionBarSherlock diff --git a/APG/src/org/thialfihar/android/apg/provider/ApgContract.java b/APG/src/org/thialfihar/android/apg/provider/ApgContract.java index c68eec750..3f01f4093 100644 --- a/APG/src/org/thialfihar/android/apg/provider/ApgContract.java +++ b/APG/src/org/thialfihar/android/apg/provider/ApgContract.java @@ -72,6 +72,7 @@ public class ApgContract { public static final String PATH_BY_MASTER_KEY_ID = "master_key_id"; public static final String PATH_BY_KEY_ID = "key_id"; public static final String PATH_BY_EMAILS = "emails"; + public static final String PATH_BY_LIKE_EMAIL = "like_email"; public static final String PATH_USER_IDS = "user_ids"; public static final String PATH_KEYS = "keys"; @@ -109,6 +110,11 @@ public class ApgContract { .appendPath(emails).build(); } + public static Uri buildPublicKeyRingsByLikeEmailUri(String emails) { + return CONTENT_URI.buildUpon().appendPath(PATH_PUBLIC).appendPath(PATH_BY_LIKE_EMAIL) + .appendPath(emails).build(); + } + public static Uri buildSecretKeyRingsUri() { return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).build(); } @@ -131,6 +137,11 @@ public class ApgContract { return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_EMAILS) .appendPath(emails).build(); } + + public static Uri buildSecretKeyRingsByLikeEmails(String emails) { + return CONTENT_URI.buildUpon().appendPath(PATH_SECRET).appendPath(PATH_BY_LIKE_EMAIL) + .appendPath(emails).build(); + } } public static class Keys implements KeysColumns, BaseColumns { diff --git a/APG/src/org/thialfihar/android/apg/provider/ApgProvider.java b/APG/src/org/thialfihar/android/apg/provider/ApgProvider.java index f3b8e7085..a5bb26507 100644 --- a/APG/src/org/thialfihar/android/apg/provider/ApgProvider.java +++ b/APG/src/org/thialfihar/android/apg/provider/ApgProvider.java @@ -52,6 +52,7 @@ public class ApgProvider extends ContentProvider { private static final int PUBLIC_KEY_RING_BY_MASTER_KEY_ID = 103; private static final int PUBLIC_KEY_RING_BY_KEY_ID = 104; private static final int PUBLIC_KEY_RING_BY_EMAILS = 105; + private static final int PUBLIC_KEY_RING_BY_LIKE_EMAIL = 106; private static final int PUBLIC_KEY_RING_KEY = 111; private static final int PUBLIC_KEY_RING_KEY_BY_ROW_ID = 112; @@ -64,6 +65,7 @@ public class ApgProvider extends ContentProvider { private static final int SECRET_KEY_RING_BY_MASTER_KEY_ID = 203; private static final int SECRET_KEY_RING_BY_KEY_ID = 204; private static final int SECRET_KEY_RING_BY_EMAILS = 205; + private static final int SECRET_KEY_RING_BY_LIKE_EMAIL = 206; private static final int SECRET_KEY_RING_KEY = 211; private static final int SECRET_KEY_RING_KEY_BY_ROW_ID = 212; @@ -99,6 +101,7 @@ public class ApgProvider extends ContentProvider { * key_rings/public/master_key_id/_ * key_rings/public/key_id/_ * key_rings/public/emails/_ + * key_rings/public/like_email/_ * */ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC, @@ -112,6 +115,8 @@ public class ApgProvider extends ContentProvider { + ApgContract.PATH_BY_KEY_ID + "/*", PUBLIC_KEY_RING_BY_KEY_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/" + ApgContract.PATH_BY_EMAILS + "/*", PUBLIC_KEY_RING_BY_EMAILS); + matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_PUBLIC + "/" + + ApgContract.PATH_BY_LIKE_EMAIL + "/*", PUBLIC_KEY_RING_BY_LIKE_EMAIL); /** * public keys @@ -148,6 +153,7 @@ public class ApgProvider extends ContentProvider { * key_rings/secret/master_key_id/_ * key_rings/secret/key_id/_ * key_rings/secret/emails/_ + * key_rings/secret/like_email/_ * */ matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET, @@ -161,6 +167,8 @@ public class ApgProvider extends ContentProvider { + ApgContract.PATH_BY_KEY_ID + "/*", SECRET_KEY_RING_BY_KEY_ID); matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/" + ApgContract.PATH_BY_EMAILS + "/*", SECRET_KEY_RING_BY_EMAILS); + matcher.addURI(authority, ApgContract.BASE_KEY_RINGS + "/" + ApgContract.PATH_SECRET + "/" + + ApgContract.PATH_BY_LIKE_EMAIL + "/*", SECRET_KEY_RING_BY_LIKE_EMAIL); /** * secret keys @@ -217,8 +225,10 @@ public class ApgProvider extends ContentProvider { switch (match) { case PUBLIC_KEY_RING: case PUBLIC_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_BY_LIKE_EMAIL: case SECRET_KEY_RING: case SECRET_KEY_RING_BY_EMAILS: + case SECRET_KEY_RING_BY_LIKE_EMAIL: return KeyRings.CONTENT_TYPE; case PUBLIC_KEY_RING_BY_ROW_ID: @@ -264,6 +274,7 @@ public class ApgProvider extends ContentProvider { case PUBLIC_KEY_RING_BY_MASTER_KEY_ID: case PUBLIC_KEY_RING_BY_KEY_ID: case PUBLIC_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_BY_LIKE_EMAIL: case PUBLIC_KEY_RING_KEY: case PUBLIC_KEY_RING_KEY_BY_ROW_ID: case PUBLIC_KEY_RING_USER_ID: @@ -276,6 +287,7 @@ public class ApgProvider extends ContentProvider { case SECRET_KEY_RING_BY_MASTER_KEY_ID: case SECRET_KEY_RING_BY_KEY_ID: case SECRET_KEY_RING_BY_EMAILS: + case SECRET_KEY_RING_BY_LIKE_EMAIL: case SECRET_KEY_RING_KEY: case SECRET_KEY_RING_KEY_BY_ROW_ID: case SECRET_KEY_RING_USER_ID: @@ -341,7 +353,7 @@ public class ApgProvider extends ContentProvider { } /** - * Builds default query for keyRings: KeyRings table is joined with Keys and UserIds + * Builds default query for keyRings: KeyRings table is joined with UserIds * * @param qb * @param match @@ -350,9 +362,11 @@ public class ApgProvider extends ContentProvider { * @return */ private SQLiteQueryBuilder buildKeyRingQuery(SQLiteQueryBuilder qb, int match, String sortOrder) { + // public or secret keyring qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); + // join keyrings with userIds to every keyring qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.USER_IDS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " + Tables.USER_IDS + "." @@ -374,9 +388,11 @@ public class ApgProvider extends ContentProvider { */ private SQLiteQueryBuilder buildKeyRingQueryWithKeys(SQLiteQueryBuilder qb, int match, String sortOrder) { + // public or secret keyring qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); + // join keyrings with keys and userIds to every keyring qb.setTables(Tables.KEY_RINGS + " INNER JOIN " + Tables.KEYS + " ON " + "(" + Tables.KEY_RINGS + "." + BaseColumns._ID + " = " + Tables.KEYS + "." + KeysColumns.KEY_RING_ROW_ID + ") " + " INNER JOIN " + Tables.USER_IDS + " ON " @@ -453,18 +469,7 @@ public class ApgProvider extends ContentProvider { case SECRET_KEY_RING_BY_EMAILS: case PUBLIC_KEY_RING_BY_EMAILS: - qb.appendWhere(Tables.KEY_RINGS + "." + KeyRingsColumns.TYPE + " = "); - qb.appendWhereEscapeString(Integer.toString(getKeyType(match))); - - 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.IS_MASTER_KEY + " = '1'" + ") " + " INNER JOIN " - + Tables.USER_IDS + " ON " + "(" + Tables.KEYS + "." + BaseColumns._ID + " = " - + Tables.USER_IDS + "." + UserIdsColumns.KEY_RING_ROW_ID + " AND " - + Tables.USER_IDS + "." + UserIdsColumns.RANK + " = '0')"); - - qb.setProjectionMap(getProjectionMapForKeyRings()); + qb = buildKeyRingQuery(qb, match, sortOrder); String emails = uri.getLastPathSegment(); String chunks[] = emails.split(" *, *"); @@ -486,12 +491,28 @@ public class ApgProvider extends ContentProvider { if (gotCondition) { qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID - + " = " + Tables.KEYS + "." + BaseColumns._ID + " AND (" + emailWhere + + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + emailWhere + "))"); } break; + case SECRET_KEY_RING_BY_LIKE_EMAIL: + case PUBLIC_KEY_RING_BY_LIKE_EMAIL: + qb = buildKeyRingQuery(qb, match, sortOrder); + + String likeEmail = uri.getLastPathSegment(); + + String likeEmailWhere = "tmp." + UserIdsColumns.USER_ID + " LIKE " + + DatabaseUtils.sqlEscapeString("%<%" + likeEmail + "%>"); + + qb.appendWhere(" AND EXISTS (SELECT tmp." + BaseColumns._ID + " FROM " + + Tables.USER_IDS + " AS tmp WHERE tmp." + UserIdsColumns.KEY_RING_ROW_ID + + " = " + Tables.KEY_RINGS + "." + BaseColumns._ID + " AND (" + likeEmailWhere + + "))"); + + break; + case PUBLIC_KEY_RING_KEY: case SECRET_KEY_RING_KEY: qb.setTables(Tables.KEYS);