diff --git a/src/org/thialfihar/android/apg/provider/DataProvider.java b/src/org/thialfihar/android/apg/provider/DataProvider.java index 0667d82dd..0a4bfbad4 100644 --- a/src/org/thialfihar/android/apg/provider/DataProvider.java +++ b/src/org/thialfihar/android/apg/provider/DataProvider.java @@ -24,6 +24,7 @@ import android.content.ContentProvider; import android.content.ContentValues; import android.content.UriMatcher; import android.database.Cursor; +import android.database.DatabaseUtils; import android.database.sqlite.SQLiteQueryBuilder; import android.net.Uri; import android.text.TextUtils; @@ -31,20 +32,22 @@ import android.text.TextUtils; public class DataProvider extends ContentProvider { public static final String AUTHORITY = "org.thialfihar.android.apg.provider"; - private static final int PUBLIC_KEY_RINGS = 101; + private static final int PUBLIC_KEY_RING = 101; private static final int PUBLIC_KEY_RING_ID = 102; private static final int PUBLIC_KEY_RING_BY_KEY_ID = 103; - private static final int PUBLIC_KEY_RING_KEYS = 111; + private static final int PUBLIC_KEY_RING_BY_EMAILS = 104; + private static final int PUBLIC_KEY_RING_KEY = 111; private static final int PUBLIC_KEY_RING_KEY_RANK = 112; - private static final int PUBLIC_KEY_RING_USER_IDS = 121; + private static final int PUBLIC_KEY_RING_USER_ID = 121; private static final int PUBLIC_KEY_RING_USER_ID_RANK = 122; - private static final int SECRET_KEY_RINGS = 201; + private static final int SECRET_KEY_RING = 201; private static final int SECRET_KEY_RING_ID = 202; private static final int SECRET_KEY_RING_BY_KEY_ID = 203; - private static final int SECRET_KEY_RING_KEYS = 211; + private static final int SECRET_KEY_RING_BY_EMAILS = 204; + private static final int SECRET_KEY_RING_KEY = 211; private static final int SECRET_KEY_RING_KEY_RANK = 212; - private static final int SECRET_KEY_RING_USER_IDS = 221; + private static final int SECRET_KEY_RING_USER_ID = 221; private static final int SECRET_KEY_RING_USER_ID_RANK = 222; private static final String PUBLIC_KEY_RING_CONTENT_DIR_TYPE = @@ -84,25 +87,27 @@ public class DataProvider extends ContentProvider { static { mUriMatcher = new UriMatcher(UriMatcher.NO_MATCH); mUriMatcher.addURI(AUTHORITY, "key_rings/public/key_id/*", PUBLIC_KEY_RING_BY_KEY_ID); + mUriMatcher.addURI(AUTHORITY, "key_rings/public/emails/*", PUBLIC_KEY_RING_BY_EMAILS); - mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys", PUBLIC_KEY_RING_KEYS); + mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys", PUBLIC_KEY_RING_KEY); mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/keys/#", PUBLIC_KEY_RING_KEY_RANK); - mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids", PUBLIC_KEY_RING_USER_IDS); + mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids", PUBLIC_KEY_RING_USER_ID); mUriMatcher.addURI(AUTHORITY, "key_rings/public/*/user_ids/#", PUBLIC_KEY_RING_USER_ID_RANK); - mUriMatcher.addURI(AUTHORITY, "key_rings/public", PUBLIC_KEY_RINGS); + mUriMatcher.addURI(AUTHORITY, "key_rings/public", PUBLIC_KEY_RING); mUriMatcher.addURI(AUTHORITY, "key_rings/public/*", PUBLIC_KEY_RING_ID); mUriMatcher.addURI(AUTHORITY, "key_rings/secret/key_id/*", SECRET_KEY_RING_BY_KEY_ID); + mUriMatcher.addURI(AUTHORITY, "key_rings/secret/emails/*", SECRET_KEY_RING_BY_EMAILS); - mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys", SECRET_KEY_RING_KEYS); + mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys", SECRET_KEY_RING_KEY); mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/keys/#", SECRET_KEY_RING_KEY_RANK); - mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids", SECRET_KEY_RING_USER_IDS); + mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids", SECRET_KEY_RING_USER_ID); mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*/user_ids/#", SECRET_KEY_RING_USER_ID_RANK); - mUriMatcher.addURI(AUTHORITY, "key_rings/secret", SECRET_KEY_RINGS); + mUriMatcher.addURI(AUTHORITY, "key_rings/secret", SECRET_KEY_RING); mUriMatcher.addURI(AUTHORITY, "key_rings/secret/*", SECRET_KEY_RING_ID); } @@ -122,22 +127,24 @@ public class DataProvider extends ContentProvider { int match = mUriMatcher.match(uri); int type; switch (match) { - case PUBLIC_KEY_RINGS: + case PUBLIC_KEY_RING: case PUBLIC_KEY_RING_ID: case PUBLIC_KEY_RING_BY_KEY_ID: - case PUBLIC_KEY_RING_KEYS: + case PUBLIC_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_KEY: case PUBLIC_KEY_RING_KEY_RANK: - case PUBLIC_KEY_RING_USER_IDS: + case PUBLIC_KEY_RING_USER_ID: case PUBLIC_KEY_RING_USER_ID_RANK: type = Id.database.type_public; break; - case SECRET_KEY_RINGS: + case SECRET_KEY_RING: case SECRET_KEY_RING_ID: case SECRET_KEY_RING_BY_KEY_ID: - case SECRET_KEY_RING_KEYS: + case SECRET_KEY_RING_BY_EMAILS: + case SECRET_KEY_RING_KEY: case SECRET_KEY_RING_KEY_RANK: - case SECRET_KEY_RING_USER_IDS: + case SECRET_KEY_RING_USER_ID: case SECRET_KEY_RING_USER_ID_RANK: type = Id.database.type_secret; break; @@ -159,8 +166,8 @@ public class DataProvider extends ContentProvider { // break omitted intentionally } - case PUBLIC_KEY_RINGS: - case SECRET_KEY_RINGS: { + case PUBLIC_KEY_RING: + case SECRET_KEY_RING: { qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + @@ -214,6 +221,53 @@ public class DataProvider extends ContentProvider { break; } + case SECRET_KEY_RING_BY_EMAILS: + case PUBLIC_KEY_RING_BY_EMAILS: { + qb.setTables(KeyRings.TABLE_NAME + " INNER JOIN " + Keys.TABLE_NAME + " ON " + + "(" + KeyRings.TABLE_NAME + "." + KeyRings._ID + " = " + + Keys.TABLE_NAME + "." + Keys.KEY_RING_ID + " AND " + + Keys.TABLE_NAME + "." + Keys.IS_MASTER_KEY + " = '1'" + + ") " + + " INNER JOIN " + UserIds.TABLE_NAME + " ON " + + "(" + Keys.TABLE_NAME + "." + Keys._ID + " = " + + UserIds.TABLE_NAME + "." + UserIds.KEY_ID + " AND " + + UserIds.TABLE_NAME + "." + UserIds.RANK + " = '0') "); + + projectionMap.put(_ID, + KeyRings.TABLE_NAME + "." + KeyRings._ID); + projectionMap.put(MASTER_KEY_ID, + KeyRings.TABLE_NAME + "." + KeyRings.MASTER_KEY_ID); + projectionMap.put(USER_ID, + UserIds.TABLE_NAME + "." + UserIds.USER_ID); + + String emails = uri.getPathSegments().get(3); + String chunks[] = emails.split(" *, *"); + boolean gotCondition = false; + String emailWhere = ""; + for (int i = 0; i < chunks.length; ++i) { + if (chunks[i].length() == 0) { + continue; + } + if (i != 0) { + emailWhere += " OR "; + } + emailWhere += "tmp." + UserIds.USER_ID + " LIKE "; + // match '*', so it has to be at the *end* of the user id + emailWhere += DatabaseUtils.sqlEscapeString("%<" + chunks[i] + ">"); + gotCondition = true; + } + + if (gotCondition) { + qb.appendWhere(" AND EXISTS (SELECT tmp." + UserIds._ID + + " FROM " + UserIds.TABLE_NAME + + " AS tmp WHERE tmp." + UserIds.KEY_ID + " = " + + Keys.TABLE_NAME + "." + Keys._ID + + " AND (" + emailWhere + "))"); + } + + break; + } + default: { throw new IllegalArgumentException("Unknown URI " + uri); } @@ -240,7 +294,8 @@ public class DataProvider extends ContentProvider { @Override public String getType(Uri uri) { switch (mUriMatcher.match(uri)) { - case PUBLIC_KEY_RINGS: + case PUBLIC_KEY_RING: + case PUBLIC_KEY_RING_BY_EMAILS: return PUBLIC_KEY_RING_CONTENT_DIR_TYPE; case PUBLIC_KEY_RING_ID: @@ -249,19 +304,20 @@ public class DataProvider extends ContentProvider { case PUBLIC_KEY_RING_BY_KEY_ID: return PUBLIC_KEY_RING_CONTENT_ITEM_TYPE; - case PUBLIC_KEY_RING_KEYS: + case PUBLIC_KEY_RING_KEY: return PUBLIC_KEY_CONTENT_DIR_TYPE; case PUBLIC_KEY_RING_KEY_RANK: return PUBLIC_KEY_CONTENT_ITEM_TYPE; - case PUBLIC_KEY_RING_USER_IDS: + case PUBLIC_KEY_RING_USER_ID: return USER_ID_CONTENT_DIR_TYPE; case PUBLIC_KEY_RING_USER_ID_RANK: return USER_ID_CONTENT_ITEM_TYPE; - case SECRET_KEY_RINGS: + case SECRET_KEY_RING: + case SECRET_KEY_RING_BY_EMAILS: return SECRET_KEY_RING_CONTENT_DIR_TYPE; case SECRET_KEY_RING_ID: @@ -270,13 +326,13 @@ public class DataProvider extends ContentProvider { case SECRET_KEY_RING_BY_KEY_ID: return SECRET_KEY_RING_CONTENT_ITEM_TYPE; - case SECRET_KEY_RING_KEYS: + case SECRET_KEY_RING_KEY: return SECRET_KEY_CONTENT_DIR_TYPE; case SECRET_KEY_RING_KEY_RANK: return SECRET_KEY_CONTENT_ITEM_TYPE; - case SECRET_KEY_RING_USER_IDS: + case SECRET_KEY_RING_USER_ID: return USER_ID_CONTENT_DIR_TYPE; case SECRET_KEY_RING_USER_ID_RANK: