move UidStatus querying logic into UserIdDao
This commit is contained in:
@@ -8,6 +8,7 @@ import android.arch.persistence.db.SupportSQLiteDatabase;
|
||||
import android.arch.persistence.db.SupportSQLiteQuery;
|
||||
import android.database.Cursor;
|
||||
|
||||
import com.squareup.sqldelight.RowMapper;
|
||||
import org.sufficientlysecure.keychain.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.daos.KeyRepository.NotFoundException;
|
||||
|
||||
@@ -33,7 +34,7 @@ class AbstractDao {
|
||||
return databaseNotifyManager;
|
||||
}
|
||||
|
||||
<T> List<T> mapAllRows(SupportSQLiteQuery query, Mapper<T> mapper) {
|
||||
<T> List<T> mapAllRows(SupportSQLiteQuery query, RowMapper<T> mapper) {
|
||||
ArrayList<T> result = new ArrayList<>();
|
||||
try (Cursor cursor = getReadableDb().query(query)) {
|
||||
while (cursor.moveToNext()) {
|
||||
@@ -44,7 +45,7 @@ class AbstractDao {
|
||||
return result;
|
||||
}
|
||||
|
||||
<T> T mapSingleRowOrThrow(SupportSQLiteQuery query, Mapper<T> mapper) throws NotFoundException {
|
||||
<T> T mapSingleRowOrThrow(SupportSQLiteQuery query, RowMapper<T> mapper) throws NotFoundException {
|
||||
T result = mapSingleRow(query, mapper);
|
||||
if (result == null) {
|
||||
throw new NotFoundException();
|
||||
@@ -52,7 +53,7 @@ class AbstractDao {
|
||||
return result;
|
||||
}
|
||||
|
||||
<T> T mapSingleRow(SupportSQLiteQuery query, Mapper<T> mapper) {
|
||||
<T> T mapSingleRow(SupportSQLiteQuery query, RowMapper<T> mapper) {
|
||||
try (Cursor cursor = getReadableDb().query(query)) {
|
||||
if (cursor.moveToNext()) {
|
||||
return mapper.map(cursor);
|
||||
@@ -60,8 +61,4 @@ class AbstractDao {
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
interface Mapper<T> {
|
||||
T map(Cursor cursor);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -129,48 +129,48 @@ public class KeyRepository extends AbstractDao {
|
||||
|
||||
public List<Long> getAllMasterKeyIds() {
|
||||
SqlDelightQuery query = KeyRingPublic.FACTORY.selectAllMasterKeyIds();
|
||||
return mapAllRows(query, KeyRingPublic.FACTORY.selectAllMasterKeyIdsMapper()::map);
|
||||
return mapAllRows(query, KeyRingPublic.FACTORY.selectAllMasterKeyIdsMapper());
|
||||
}
|
||||
|
||||
public List<Long> getMasterKeyIdsBySigner(List<Long> signerMasterKeyIds) {
|
||||
long[] signerKeyIds = getLongListAsArray(signerMasterKeyIds);
|
||||
SqlDelightQuery query = KeySignature.FACTORY.selectMasterKeyIdsBySigner(signerKeyIds);
|
||||
return mapAllRows(query, KeySignature.FACTORY.selectMasterKeyIdsBySignerMapper()::map);
|
||||
return mapAllRows(query, KeySignature.FACTORY.selectMasterKeyIdsBySignerMapper());
|
||||
}
|
||||
|
||||
public Long getMasterKeyIdBySubkeyId(long subKeyId) {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectMasterKeyIdBySubkey(subKeyId);
|
||||
return mapSingleRow(query, SubKey.FACTORY.selectMasterKeyIdBySubkeyMapper()::map);
|
||||
return mapSingleRow(query, SubKey.FACTORY.selectMasterKeyIdBySubkeyMapper());
|
||||
}
|
||||
|
||||
public UnifiedKeyInfo getUnifiedKeyInfo(long masterKeyId) {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectUnifiedKeyInfoByMasterKeyId(masterKeyId);
|
||||
return mapSingleRow(query, SubKey.UNIFIED_KEY_INFO_MAPPER::map);
|
||||
return mapSingleRow(query, SubKey.UNIFIED_KEY_INFO_MAPPER);
|
||||
}
|
||||
|
||||
public List<UnifiedKeyInfo> getUnifiedKeyInfo(long... masterKeyIds) {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectUnifiedKeyInfoByMasterKeyIds(masterKeyIds);
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER::map);
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER);
|
||||
}
|
||||
|
||||
public List<UnifiedKeyInfo> getUnifiedKeyInfosByMailAddress(String mailAddress) {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectUnifiedKeyInfoSearchMailAddress('%' + mailAddress + '%');
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER::map);
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER);
|
||||
}
|
||||
|
||||
public List<UnifiedKeyInfo> getAllUnifiedKeyInfo() {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectAllUnifiedKeyInfo();
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER::map);
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER);
|
||||
}
|
||||
|
||||
public List<UnifiedKeyInfo> getAllUnifiedKeyInfoWithSecret() {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectAllUnifiedKeyInfoWithSecret();
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER::map);
|
||||
return mapAllRows(query, SubKey.UNIFIED_KEY_INFO_MAPPER);
|
||||
}
|
||||
|
||||
public List<UserId> getUserIds(long... masterKeyIds) {
|
||||
SqlDelightQuery query = UserPacket.FACTORY.selectUserIdsByMasterKeyId(masterKeyIds);
|
||||
return mapAllRows(query, UserPacket.USER_ID_MAPPER::map);
|
||||
return mapAllRows(query, UserPacket.USER_ID_MAPPER);
|
||||
}
|
||||
|
||||
public List<String> getConfirmedUserIds(long masterKeyId) {
|
||||
@@ -181,17 +181,17 @@ public class KeyRepository extends AbstractDao {
|
||||
|
||||
public List<SubKey> getSubKeysByMasterKeyId(long masterKeyId) {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectSubkeysByMasterKeyId(masterKeyId);
|
||||
return mapAllRows(query, SubKey.SUBKEY_MAPPER::map);
|
||||
return mapAllRows(query, SubKey.SUBKEY_MAPPER);
|
||||
}
|
||||
|
||||
public SecretKeyType getSecretKeyType(long keyId) throws NotFoundException {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectSecretKeyType(keyId);
|
||||
return mapSingleRowOrThrow(query, SubKey.SKT_MAPPER::map);
|
||||
return mapSingleRowOrThrow(query, SubKey.SKT_MAPPER);
|
||||
}
|
||||
|
||||
public byte[] getFingerprintByKeyId(long keyId) throws NotFoundException {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectFingerprintByKeyId(keyId);
|
||||
return mapSingleRowOrThrow(query, SubKey.FACTORY.selectFingerprintByKeyIdMapper()::map);
|
||||
return mapSingleRowOrThrow(query, SubKey.FACTORY.selectFingerprintByKeyIdMapper());
|
||||
}
|
||||
|
||||
private byte[] getKeyRingAsArmoredData(byte[] data) throws IOException {
|
||||
@@ -247,12 +247,12 @@ public class KeyRepository extends AbstractDao {
|
||||
|
||||
public long getSecretSignId(long masterKeyId) throws NotFoundException {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectEffectiveSignKeyIdByMasterKeyId(masterKeyId);
|
||||
return mapSingleRowOrThrow(query, SubKey.FACTORY.selectEffectiveSignKeyIdByMasterKeyIdMapper()::map);
|
||||
return mapSingleRowOrThrow(query, SubKey.FACTORY.selectEffectiveSignKeyIdByMasterKeyIdMapper());
|
||||
}
|
||||
|
||||
public long getSecretAuthenticationId(long masterKeyId) throws NotFoundException {
|
||||
SqlDelightQuery query = SubKey.FACTORY.selectEffectiveAuthKeyIdByMasterKeyId(masterKeyId);
|
||||
return mapSingleRowOrThrow(query, SubKey.FACTORY.selectEffectiveAuthKeyIdByMasterKeyIdMapper()::map);
|
||||
return mapSingleRowOrThrow(query, SubKey.FACTORY.selectEffectiveAuthKeyIdByMasterKeyIdMapper());
|
||||
}
|
||||
|
||||
public static class NotFoundException extends Exception {
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package org.sufficientlysecure.keychain.daos;
|
||||
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.squareup.sqldelight.SqlDelightQuery;
|
||||
import org.sufficientlysecure.keychain.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket.UidStatus;
|
||||
|
||||
|
||||
public class UserIdDao extends AbstractDao {
|
||||
public UserIdDao(KeychainDatabase db, DatabaseNotifyManager databaseNotifyManager) {
|
||||
super(db, databaseNotifyManager);
|
||||
}
|
||||
|
||||
public List<UidStatus> getUidStatusByEmailLike(String emailLike) {
|
||||
SqlDelightQuery query = UserPacket.FACTORY.selectUserIdStatusByEmailLike(emailLike);
|
||||
return mapAllRows(query, UserPacket.UID_STATUS_MAPPER);
|
||||
}
|
||||
|
||||
public List<UidStatus> getUidStatusByEmail(String... emails) {
|
||||
SqlDelightQuery query = UserPacket.FACTORY.selectUserIdStatusByEmail(emails);
|
||||
return mapAllRows(query, UserPacket.UID_STATUS_MAPPER);
|
||||
}
|
||||
}
|
||||
@@ -36,18 +36,16 @@ import android.net.Uri;
|
||||
import android.support.annotation.NonNull;
|
||||
import android.text.TextUtils;
|
||||
|
||||
import com.squareup.sqldelight.SqlDelightQuery;
|
||||
import org.sufficientlysecure.keychain.BuildConfig;
|
||||
import org.sufficientlysecure.keychain.Constants;
|
||||
import org.sufficientlysecure.keychain.KeychainDatabase;
|
||||
import org.sufficientlysecure.keychain.KeychainDatabase.Tables;
|
||||
import org.sufficientlysecure.keychain.daos.ApiAppDao;
|
||||
import org.sufficientlysecure.keychain.daos.DatabaseNotifyManager;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket;
|
||||
import org.sufficientlysecure.keychain.daos.UserIdDao;
|
||||
import org.sufficientlysecure.keychain.model.UserPacket.UidStatus;
|
||||
import org.sufficientlysecure.keychain.pgp.CanonicalizedKeyRing.VerificationStatus;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Certs;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.Keys;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainContract.UserPackets;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainExternalContract;
|
||||
import org.sufficientlysecure.keychain.provider.KeychainExternalContract.AutocryptStatus;
|
||||
@@ -71,24 +69,12 @@ public class KeychainExternalProvider extends ContentProvider {
|
||||
private ApiPermissionHelper apiPermissionHelper;
|
||||
|
||||
|
||||
/**
|
||||
* Build and return a {@link UriMatcher} that catches all {@link Uri} variations supported by
|
||||
* this {@link ContentProvider}.
|
||||
*/
|
||||
protected UriMatcher buildUriMatcher() {
|
||||
final UriMatcher matcher = new UriMatcher(UriMatcher.NO_MATCH);
|
||||
|
||||
String authority = KeychainExternalContract.CONTENT_AUTHORITY_EXTERNAL;
|
||||
|
||||
/*
|
||||
* list email_status
|
||||
*
|
||||
* <pre>
|
||||
* email_status/
|
||||
* </pre>
|
||||
*/
|
||||
matcher.addURI(authority, KeychainExternalContract.BASE_EMAIL_STATUS, EMAIL_STATUS);
|
||||
|
||||
matcher.addURI(authority, KeychainExternalContract.BASE_AUTOCRYPT_STATUS, AUTOCRYPT_STATUS);
|
||||
matcher.addURI(authority, KeychainExternalContract.BASE_AUTOCRYPT_STATUS + "/*", AUTOCRYPT_STATUS_INTERNAL);
|
||||
|
||||
@@ -138,7 +124,8 @@ public class KeychainExternalProvider extends ContentProvider {
|
||||
|
||||
String groupBy = null;
|
||||
|
||||
SupportSQLiteDatabase db = KeychainDatabase.getTemporaryInstance(getContext()).getReadableDatabase();
|
||||
KeychainDatabase temporaryDb = KeychainDatabase.getTemporaryInstance(getContext());
|
||||
SupportSQLiteDatabase db = temporaryDb.getReadableDatabase();
|
||||
|
||||
String callingPackageName = apiPermissionHelper.getCurrentCallingPackage();
|
||||
|
||||
@@ -243,28 +230,38 @@ public class KeychainExternalProvider extends ContentProvider {
|
||||
db.insert(TEMP_TABLE_QUERIED_ADDRESSES, SQLiteDatabase.CONFLICT_FAIL, cv);
|
||||
}
|
||||
|
||||
boolean isWildcardSelector = selectionArgs.length == 1 && selectionArgs[0].contains("%");
|
||||
|
||||
List<String> plist = Arrays.asList(projection);
|
||||
|
||||
boolean isWildcardSelector = selectionArgs.length == 1 && selectionArgs[0].contains("%");
|
||||
boolean queriesUidResult = plist.contains(AutocryptStatus.UID_KEY_STATUS) ||
|
||||
plist.contains(AutocryptStatus.UID_ADDRESS) ||
|
||||
plist.contains(AutocryptStatus.UID_MASTER_KEY_ID) ||
|
||||
plist.contains(AutocryptStatus.UID_CANDIDATES);
|
||||
if (queriesUidResult) {
|
||||
fillTempTableWithUidResult(db, isWildcardSelector, selectionArgs);
|
||||
}
|
||||
|
||||
boolean queriesAutocryptResult = plist.contains(AutocryptStatus.AUTOCRYPT_PEER_STATE) ||
|
||||
plist.contains(AutocryptStatus.AUTOCRYPT_MASTER_KEY_ID) ||
|
||||
plist.contains(AutocryptStatus.AUTOCRYPT_KEY_STATUS);
|
||||
if (isWildcardSelector && queriesAutocryptResult) {
|
||||
throw new UnsupportedOperationException("Cannot wildcard-query autocrypt results!");
|
||||
}
|
||||
if (!isWildcardSelector && queriesAutocryptResult) {
|
||||
|
||||
UserIdDao userIdDao = new UserIdDao(temporaryDb, DatabaseNotifyManager.create(getContext()));
|
||||
|
||||
if (queriesUidResult) {
|
||||
List<UidStatus> uidStatuses;
|
||||
if (isWildcardSelector) {
|
||||
uidStatuses = userIdDao.getUidStatusByEmailLike(selectionArgs[0]);
|
||||
} else {
|
||||
uidStatuses = userIdDao.getUidStatusByEmail(selectionArgs);
|
||||
}
|
||||
fillTempTableWithUidResult(db, uidStatuses, isWildcardSelector ? selectionArgs[0] : null);
|
||||
}
|
||||
|
||||
if (queriesAutocryptResult) {
|
||||
AutocryptInteractor autocryptInteractor =
|
||||
AutocryptInteractor.getInstance(getContext(), callingPackageName);
|
||||
fillTempTableWithAutocryptRecommendations(db, autocryptInteractor, selectionArgs);
|
||||
List<AutocryptRecommendationResult> autocryptStates =
|
||||
autocryptInteractor.determineAutocryptRecommendations(selectionArgs);
|
||||
|
||||
fillTempTableWithAutocryptRecommendations(db, autocryptStates);
|
||||
}
|
||||
|
||||
HashMap<String, String> projectionMap = new HashMap<>();
|
||||
@@ -320,14 +317,6 @@ public class KeychainExternalProvider extends ContentProvider {
|
||||
return cursor;
|
||||
}
|
||||
|
||||
private void fillTempTableWithAutocryptRecommendations(SupportSQLiteDatabase db,
|
||||
AutocryptInteractor autocryptInteractor, String[] peerIds) {
|
||||
List<AutocryptRecommendationResult> autocryptStates =
|
||||
autocryptInteractor.determineAutocryptRecommendations(peerIds);
|
||||
|
||||
fillTempTableWithAutocryptRecommendations(db, autocryptStates);
|
||||
}
|
||||
|
||||
private void fillTempTableWithAutocryptRecommendations(SupportSQLiteDatabase db,
|
||||
List<AutocryptRecommendationResult> autocryptRecommendations) {
|
||||
ContentValues cv = new ContentValues();
|
||||
@@ -347,19 +336,9 @@ public class KeychainExternalProvider extends ContentProvider {
|
||||
}
|
||||
}
|
||||
|
||||
private void fillTempTableWithUidResult(SupportSQLiteDatabase db,
|
||||
boolean isWildcardSelector, String[] selectionArgs) {
|
||||
SqlDelightQuery query;
|
||||
if (isWildcardSelector) {
|
||||
query = UserPacket.FACTORY.selectUserIdStatusByEmailLike(selectionArgs[0]);
|
||||
} else {
|
||||
query = UserPacket.FACTORY.selectUserIdStatusByEmail(selectionArgs);
|
||||
}
|
||||
|
||||
try (Cursor cursor = db.query(query)) {
|
||||
private void fillTempTableWithUidResult(SupportSQLiteDatabase db, List<UidStatus> uidStatuses, String key) {
|
||||
ContentValues cv = new ContentValues();
|
||||
while (cursor.moveToNext()) {
|
||||
UidStatus uidStatus = UserPacket.UID_STATUS_MAPPER.map(cursor);
|
||||
for (UidStatus uidStatus : uidStatuses) {
|
||||
int keyStatus = uidStatus.keyStatus() == VerificationStatus.VERIFIED_SECRET ?
|
||||
KeychainExternalContract.KEY_STATUS_VERIFIED : KeychainExternalContract.KEY_STATUS_UNVERIFIED;
|
||||
|
||||
@@ -370,8 +349,7 @@ public class KeychainExternalProvider extends ContentProvider {
|
||||
|
||||
db.update(TEMP_TABLE_QUERIED_ADDRESSES, SQLiteDatabase.CONFLICT_IGNORE, cv,
|
||||
TEMP_TABLE_COLUMN_ADDRES + "= ?",
|
||||
new String[] { isWildcardSelector ? selectionArgs[0] : uidStatus.email() });
|
||||
}
|
||||
new String[] { key != null ? key : uidStatus.email() });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user