Remove the Canonical Address Database

This was a holdover from Signal's origins as a pure SMS app.
It causes problems, depends on undefined device specific behavior,
and should no longer be necessary now that we have all the
information we need to E164 all numbers.

// FREEBIE
This commit is contained in:
Moxie Marlinspike
2017-07-26 09:59:15 -07:00
parent e452862813
commit 737810475e
113 changed files with 2029 additions and 2130 deletions

View File

@@ -38,7 +38,7 @@ public class IdentityDatabase extends Database {
private static final String TABLE_NAME = "identities";
private static final String ID = "_id";
private static final String RECIPIENT = "recipient";
private static final String ADDRESS = "address";
private static final String IDENTITY_KEY = "key";
private static final String TIMESTAMP = "timestamp";
private static final String FIRST_USE = "first_use";
@@ -47,7 +47,7 @@ public class IdentityDatabase extends Database {
public static final String CREATE_TABLE = "CREATE TABLE " + TABLE_NAME +
" (" + ID + " INTEGER PRIMARY KEY, " +
RECIPIENT + " INTEGER UNIQUE, " +
ADDRESS + " TEXT UNIQUE, " +
IDENTITY_KEY + " TEXT, " +
FIRST_USE + " INTEGER DEFAULT 0, " +
TIMESTAMP + " INTEGER DEFAULT 0, " +
@@ -65,8 +65,8 @@ public class IdentityDatabase extends Database {
}
public static VerifiedStatus forState(int state) {
if (state == 0) return DEFAULT;
else if (state == 1) return VERIFIED;
if (state == 0) return DEFAULT;
else if (state == 1) return VERIFIED;
else if (state == 2) return UNVERIFIED;
else throw new AssertionError("No such state: " + state);
}
@@ -86,13 +86,13 @@ public class IdentityDatabase extends Database {
return new IdentityReader(cursor);
}
public Optional<IdentityRecord> getIdentity(long recipientId) {
public Optional<IdentityRecord> getIdentity(Address address) {
SQLiteDatabase database = databaseHelper.getReadableDatabase();
Cursor cursor = null;
try {
cursor = database.query(TABLE_NAME, null, RECIPIENT + " = ?",
new String[] {recipientId + ""}, null, null, null);
cursor = database.query(TABLE_NAME, null, ADDRESS + " = ?",
new String[] {address.serialize()}, null, null, null);
if (cursor != null && cursor.moveToFirst()) {
return Optional.of(getIdentityRecord(cursor));
@@ -106,14 +106,14 @@ public class IdentityDatabase extends Database {
return Optional.absent();
}
public void saveIdentity(long recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus,
public void saveIdentity(Address address, IdentityKey identityKey, VerifiedStatus verifiedStatus,
boolean firstUse, long timestamp, boolean nonBlockingApproval)
{
SQLiteDatabase database = databaseHelper.getWritableDatabase();
String identityKeyString = Base64.encodeBytes(identityKey.serialize());
ContentValues contentValues = new ContentValues();
contentValues.put(RECIPIENT, recipientId);
contentValues.put(ADDRESS, address.serialize());
contentValues.put(IDENTITY_KEY, identityKeyString);
contentValues.put(TIMESTAMP, timestamp);
contentValues.put(VERIFIED, verifiedStatus.toInt());
@@ -122,38 +122,36 @@ public class IdentityDatabase extends Database {
database.replace(TABLE_NAME, null, contentValues);
EventBus.getDefault().post(new IdentityRecord(recipientId, identityKey, verifiedStatus,
EventBus.getDefault().post(new IdentityRecord(address, identityKey, verifiedStatus,
firstUse, timestamp, nonBlockingApproval));
}
public void setApproval(long recipientId, boolean nonBlockingApproval) {
public void setApproval(Address address, boolean nonBlockingApproval) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues(2);
contentValues.put(NONBLOCKING_APPROVAL, nonBlockingApproval);
database.update(TABLE_NAME, contentValues, RECIPIENT + " = ?",
new String[] {String.valueOf(recipientId)});
database.update(TABLE_NAME, contentValues, ADDRESS + " = ?", new String[] {address.serialize()});
}
public void setVerified(long recipientId, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
public void setVerified(Address address, IdentityKey identityKey, VerifiedStatus verifiedStatus) {
SQLiteDatabase database = databaseHelper.getWritableDatabase();
ContentValues contentValues = new ContentValues(1);
contentValues.put(VERIFIED, verifiedStatus.toInt());
int updated = database.update(TABLE_NAME, contentValues, RECIPIENT + " = ? AND " + IDENTITY_KEY + " = ?",
new String[] {String.valueOf(recipientId),
Base64.encodeBytes(identityKey.serialize())});
int updated = database.update(TABLE_NAME, contentValues, ADDRESS + " = ? AND " + IDENTITY_KEY + " = ?",
new String[] {address.serialize(), Base64.encodeBytes(identityKey.serialize())});
if (updated > 0) {
Optional<IdentityRecord> record = getIdentity(recipientId);
Optional<IdentityRecord> record = getIdentity(address);
if (record.isPresent()) EventBus.getDefault().post(record.get());
}
}
private IdentityRecord getIdentityRecord(@NonNull Cursor cursor) throws IOException, InvalidKeyException {
long recipientId = cursor.getLong(cursor.getColumnIndexOrThrow(RECIPIENT));
String address = cursor.getString(cursor.getColumnIndexOrThrow(ADDRESS));
String serializedIdentity = cursor.getString(cursor.getColumnIndexOrThrow(IDENTITY_KEY));
long timestamp = cursor.getLong(cursor.getColumnIndexOrThrow(TIMESTAMP));
int verifiedStatus = cursor.getInt(cursor.getColumnIndexOrThrow(VERIFIED));
@@ -161,23 +159,23 @@ public class IdentityDatabase extends Database {
boolean firstUse = cursor.getInt(cursor.getColumnIndexOrThrow(FIRST_USE)) == 1;
IdentityKey identity = new IdentityKey(Base64.decode(serializedIdentity), 0);
return new IdentityRecord(recipientId, identity, VerifiedStatus.forState(verifiedStatus), firstUse, timestamp, nonblockingApproval);
return new IdentityRecord(Address.fromSerialized(address), identity, VerifiedStatus.forState(verifiedStatus), firstUse, timestamp, nonblockingApproval);
}
public static class IdentityRecord {
private final long recipientId;
private final Address address;
private final IdentityKey identitykey;
private final VerifiedStatus verifiedStatus;
private final boolean firstUse;
private final long timestamp;
private final boolean nonblockingApproval;
private IdentityRecord(long recipientId,
private IdentityRecord(Address address,
IdentityKey identitykey, VerifiedStatus verifiedStatus,
boolean firstUse, long timestamp, boolean nonblockingApproval)
{
this.recipientId = recipientId;
this.address = address;
this.identitykey = identitykey;
this.verifiedStatus = verifiedStatus;
this.firstUse = firstUse;
@@ -185,8 +183,8 @@ public class IdentityDatabase extends Database {
this.nonblockingApproval = nonblockingApproval;
}
public long getRecipientId() {
return recipientId;
public Address getAddress() {
return address;
}
public IdentityKey getIdentityKey() {
@@ -211,7 +209,7 @@ public class IdentityDatabase extends Database {
@Override
public String toString() {
return "{recipientId: " + recipientId + ", identityKey: " + identitykey + ", verifiedStatus: " + verifiedStatus + ", firstUse: " + firstUse + "}";
return "{address: " + address + ", identityKey: " + identitykey + ", verifiedStatus: " + verifiedStatus + ", firstUse: " + firstUse + "}";
}
}