move UidStatus querying logic into UserIdDao

This commit is contained in:
Vincent Breitmoser
2018-07-09 14:29:53 +02:00
parent 58e0da0d8c
commit 3150d2d3f9
4 changed files with 78 additions and 77 deletions

View File

@@ -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);
}
}

View File

@@ -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 {

View File

@@ -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);
}
}

View File

@@ -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() });
}
}