Merge branch 'linked-identities' (and fix OperationHelper ids)
Merge Linked Identities. Also includes an important fix for OperationHelper ids, which had an error in the bit mask logic. Conflicts: Graphics/update-drawables.sh OpenKeychain/build.gradle OpenKeychain/src/main/java/org/sufficientlysecure/keychain/operations/results/OperationResult.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/KeychainProvider.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/provider/ProviderHelper.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/CertifyActionsParcel.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/service/KeychainIntentService.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/CreateYubiKeyImportFragment.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/KeyListFragment.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/ViewKeyActivity.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/adapter/KeyAdapter.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/CertifyKeySpinner.java OpenKeychain/src/main/java/org/sufficientlysecure/keychain/ui/widget/KeySpinner.java OpenKeychain/src/main/res/anim/fade_in.xml OpenKeychain/src/main/res/anim/fade_out.xml OpenKeychain/src/main/res/layout/decrypt_text_fragment.xml OpenKeychain/src/main/res/layout/encrypt_decrypt_overview_fragment.xml OpenKeychain/src/main/res/layout/view_key_fragment.xml OpenKeychain/src/main/res/menu/key_view.xml OpenKeychain/src/main/res/values/strings.xml OpenKeychain/src/test/java/org/sufficientlysecure/keychain/operations/CertifyOperationTest.java README.md
This commit is contained in:
@@ -113,6 +113,7 @@ public class KeychainContract {
|
||||
public static final String PATH_PUBLIC = "public";
|
||||
public static final String PATH_SECRET = "secret";
|
||||
public static final String PATH_USER_IDS = "user_ids";
|
||||
public static final String PATH_LINKED_IDS = "linked_ids";
|
||||
public static final String PATH_KEYS = "keys";
|
||||
public static final String PATH_CERTS = "certs";
|
||||
|
||||
@@ -279,6 +280,11 @@ public class KeychainContract {
|
||||
public static Uri buildUserIdsUri(Uri uri) {
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_USER_IDS).build();
|
||||
}
|
||||
|
||||
public static Uri buildLinkedIdsUri(Uri uri) {
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_LINKED_IDS).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public static class ApiApps implements ApiAppsColumns, BaseColumns {
|
||||
@@ -367,7 +373,14 @@ public class KeychainContract {
|
||||
}
|
||||
|
||||
public static Uri buildCertsUri(Uri uri) {
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1)).appendPath(PATH_CERTS).build();
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1))
|
||||
.appendPath(PATH_CERTS).build();
|
||||
}
|
||||
|
||||
public static Uri buildLinkedIdCertsUri(Uri uri, int rank) {
|
||||
return CONTENT_URI.buildUpon().appendPath(uri.getPathSegments().get(1))
|
||||
.appendPath(PATH_LINKED_IDS).appendPath(Integer.toString(rank))
|
||||
.appendPath(PATH_CERTS).build();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ import android.net.Uri;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAccounts;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
|
||||
@@ -63,6 +64,8 @@ public class KeychainProvider extends ContentProvider {
|
||||
private static final int KEY_RING_SECRET = 204;
|
||||
private static final int KEY_RING_CERTS = 205;
|
||||
private static final int KEY_RING_CERTS_SPECIFIC = 206;
|
||||
private static final int KEY_RING_LINKED_IDS = 207;
|
||||
private static final int KEY_RING_LINKED_ID_CERTS = 208;
|
||||
|
||||
private static final int API_APPS = 301;
|
||||
private static final int API_APPS_BY_PACKAGE_NAME = 302;
|
||||
@@ -131,6 +134,9 @@ public class KeychainProvider extends ContentProvider {
|
||||
* key_rings/_/unified
|
||||
* key_rings/_/keys
|
||||
* key_rings/_/user_ids
|
||||
* key_rings/_/linked_ids
|
||||
* key_rings/_/linked_ids/_
|
||||
* key_rings/_/linked_ids/_/certs
|
||||
* key_rings/_/public
|
||||
* key_rings/_/secret
|
||||
* key_rings/_/certs
|
||||
@@ -146,6 +152,13 @@ public class KeychainProvider extends ContentProvider {
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_USER_IDS,
|
||||
KEY_RING_USER_IDS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_LINKED_IDS,
|
||||
KEY_RING_LINKED_IDS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_LINKED_IDS + "/*/"
|
||||
+ KeychainContract.PATH_CERTS,
|
||||
KEY_RING_LINKED_ID_CERTS);
|
||||
matcher.addURI(authority, KeychainContract.BASE_KEY_RINGS + "/*/"
|
||||
+ KeychainContract.PATH_PUBLIC,
|
||||
KEY_RING_PUBLIC);
|
||||
@@ -492,7 +505,8 @@ public class KeychainProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
case KEY_RINGS_USER_IDS:
|
||||
case KEY_RING_USER_IDS: {
|
||||
case KEY_RING_USER_IDS:
|
||||
case KEY_RING_LINKED_IDS: {
|
||||
HashMap<String, String> projectionMap = new HashMap<>();
|
||||
projectionMap.put(UserPackets._ID, Tables.USER_PACKETS + ".oid AS _id");
|
||||
projectionMap.put(UserPackets.MASTER_KEY_ID, Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID);
|
||||
@@ -517,13 +531,15 @@ public class KeychainProvider extends ContentProvider {
|
||||
groupBy = Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID
|
||||
+ ", " + Tables.USER_PACKETS + "." + UserPackets.RANK;
|
||||
|
||||
// for now, we only respect user ids here, so TYPE must be NULL
|
||||
// TODO expand with KEY_RING_USER_PACKETS query type which lifts this restriction
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL");
|
||||
if (match == KEY_RING_LINKED_IDS) {
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " = "
|
||||
+ WrappedUserAttribute.UAT_URI_ATTRIBUTE);
|
||||
} else {
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL");
|
||||
}
|
||||
|
||||
// If we are searching for a particular keyring's ids, add where
|
||||
if (match == KEY_RING_USER_IDS) {
|
||||
// TODO remove with the thing above
|
||||
if (match == KEY_RING_USER_IDS || match == KEY_RING_LINKED_IDS) {
|
||||
qb.appendWhere(" AND ");
|
||||
qb.appendWhere(Tables.USER_PACKETS + "." + UserPackets.MASTER_KEY_ID + " = ");
|
||||
qb.appendWhereEscapeString(uri.getPathSegments().get(1));
|
||||
@@ -574,7 +590,8 @@ public class KeychainProvider extends ContentProvider {
|
||||
}
|
||||
|
||||
case KEY_RING_CERTS:
|
||||
case KEY_RING_CERTS_SPECIFIC: {
|
||||
case KEY_RING_CERTS_SPECIFIC:
|
||||
case KEY_RING_LINKED_ID_CERTS: {
|
||||
HashMap<String, String> projectionMap = new HashMap<>();
|
||||
projectionMap.put(Certs._ID, Tables.CERTS + ".oid AS " + Certs._ID);
|
||||
projectionMap.put(Certs.MASTER_KEY_ID, Tables.CERTS + "." + Certs.MASTER_KEY_ID);
|
||||
@@ -595,10 +612,6 @@ public class KeychainProvider extends ContentProvider {
|
||||
+ " AND "
|
||||
+ Tables.CERTS + "." + Certs.RANK + " = "
|
||||
+ Tables.USER_PACKETS + "." + UserPackets.RANK
|
||||
// for now, we only return user ids here, so TYPE must be NULL
|
||||
// TODO at some point, we should lift this restriction
|
||||
+ " AND "
|
||||
+ Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL"
|
||||
+ ") LEFT JOIN " + Tables.USER_PACKETS + " AS signer ON ("
|
||||
+ Tables.CERTS + "." + Certs.KEY_ID_CERTIFIER + " = "
|
||||
+ "signer." + UserPackets.MASTER_KEY_ID
|
||||
@@ -618,6 +631,17 @@ public class KeychainProvider extends ContentProvider {
|
||||
qb.appendWhereEscapeString(uri.getPathSegments().get(4));
|
||||
}
|
||||
|
||||
if (match == KEY_RING_LINKED_ID_CERTS) {
|
||||
qb.appendWhere(" AND " + Tables.USER_PACKETS + "."
|
||||
+ UserPackets.TYPE + " IS NOT NULL");
|
||||
|
||||
qb.appendWhere(" AND " + Tables.USER_PACKETS + "."
|
||||
+ UserPackets.RANK + " = ");
|
||||
qb.appendWhereEscapeString(uri.getPathSegments().get(3));
|
||||
} else {
|
||||
qb.appendWhere(" AND " + Tables.USER_PACKETS + "." + UserPackets.TYPE + " IS NULL");
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -32,10 +32,15 @@ import android.support.v4.util.LongSparseArray;
|
||||
import org.spongycastle.bcpg.CompressionAlgorithmTags;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.R;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.keyimport.ParcelableKeyRing;
|
||||
import org.sufficientlysecure.keychain.operations.ImportOperation;
|
||||
import org.sufficientlysecure.keychain.operations.results.ConsolidateResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.ImportKeyResult;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.LogType;
|
||||
import org.sufficientlysecure.keychain.operations.results.OperationResult.OperationLog;
|
||||
import org.sufficientlysecure.keychain.operations.results.SaveKeyringResult;
|
||||
@@ -50,7 +55,6 @@ import org.sufficientlysecure.keychain.pgp.Progressable;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedKeyRing;
|
||||
import org.sufficientlysecure.keychain.pgp.UncachedPublicKey;
|
||||
import org.sufficientlysecure.keychain.pgp.WrappedSignature;
|
||||
import org.sufficientlysecure.keychain.pgp.WrappedUserAttribute;
|
||||
import org.sufficientlysecure.keychain.pgp.exception.PgpGeneralException;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiAllowedKeys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.ApiApps;
|
||||
@@ -62,12 +66,9 @@ import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UpdatedKeys;
|
||||
import org.sufficientlysecure.keychain.remote.AccountSettings;
|
||||
import org.sufficientlysecure.keychain.remote.AppSettings;
|
||||
import org.sufficientlysecure.keychain.ui.util.KeyFormattingUtils;
|
||||
import org.sufficientlysecure.keychain.util.IterableIterator;
|
||||
import org.sufficientlysecure.keychain.util.Log;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache;
|
||||
import org.sufficientlysecure.keychain.util.ParcelableFileCache.IteratorWithSize;
|
||||
import org.sufficientlysecure.keychain.util.Preferences;
|
||||
import org.sufficientlysecure.keychain.util.ProgressFixedScaler;
|
||||
import org.sufficientlysecure.keychain.util.ProgressScaler;
|
||||
import org.sufficientlysecure.keychain.util.Utf8Util;
|
||||
|
||||
Reference in New Issue
Block a user