Fix bugs around PNI only contacts and storage service.

This commit is contained in:
Cody Henthorne
2023-09-29 20:15:34 -04:00
committed by GitHub
parent 7fbdcb8a88
commit c90ad7c1e2
6 changed files with 39 additions and 19 deletions

View File

@@ -803,10 +803,11 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
recipientId = RecipientId.from(id)
}
if (insert.identityKey.isPresent && insert.aci.isPresent) {
if (insert.identityKey.isPresent && (insert.aci.isPresent || insert.pni.isPresent)) {
try {
val serviceId: ServiceId = insert.aci.orNull() ?: insert.pni.get()
val identityKey = IdentityKey(insert.identityKey.get(), 0)
identities.updateIdentityAfterSync(insert.aci.get().toString(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(insert.identityState))
identities.updateIdentityAfterSync(serviceId.toString(), recipientId, identityKey, StorageSyncModels.remoteToLocalIdentityStatus(insert.identityState))
} catch (e: InvalidKeyException) {
Log.w(TAG, "Failed to process identity key during insert! Skipping.", e)
}
@@ -1071,7 +1072,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
private fun getRecordForSync(query: String?, args: Array<String>?): List<RecipientRecord> {
val table =
"""
$TABLE_NAME LEFT OUTER JOIN ${IdentityTable.TABLE_NAME} ON $TABLE_NAME.$ACI_COLUMN = ${IdentityTable.TABLE_NAME}.${IdentityTable.ADDRESS}
$TABLE_NAME LEFT OUTER JOIN ${IdentityTable.TABLE_NAME} ON ($TABLE_NAME.$ACI_COLUMN = ${IdentityTable.TABLE_NAME}.${IdentityTable.ADDRESS} OR ($TABLE_NAME.$ACI_COLUMN IS NULL AND $TABLE_NAME.$PNI_COLUMN = ${IdentityTable.TABLE_NAME}.${IdentityTable.ADDRESS}))
LEFT OUTER JOIN ${GroupTable.TABLE_NAME} ON $TABLE_NAME.$GROUP_ID = ${GroupTable.TABLE_NAME}.${GroupTable.GROUP_ID}
LEFT OUTER JOIN ${ThreadTable.TABLE_NAME} ON $TABLE_NAME.$ID = ${ThreadTable.TABLE_NAME}.${ThreadTable.RECIPIENT_ID}
"""
@@ -1115,7 +1116,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
.where(
"""
$STORAGE_SERVICE_ID NOT NULL AND (
($TYPE = ? AND $ACI_COLUMN NOT NULL AND $ID != ?)
($TYPE = ? AND ($ACI_COLUMN NOT NULL OR $PNI_COLUMN NOT NULL) AND $ID != ?)
OR
$TYPE = ?
OR
@@ -2382,12 +2383,6 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
is PnpOperation.SetPni -> {
writableDatabase
.update(TABLE_NAME)
.values(ACI_COLUMN to operation.pni.toString())
.where("$ID = ? AND ($ACI_COLUMN IS NULL OR $ACI_COLUMN = $PNI_COLUMN)", operation.recipientId)
.run()
writableDatabase
.update(TABLE_NAME)
.values(

View File

@@ -63,6 +63,7 @@ import org.thoughtcrime.securesms.database.helpers.migration.V204_GroupForeignKe
import org.thoughtcrime.securesms.database.helpers.migration.V205_DropPushTable
import org.thoughtcrime.securesms.database.helpers.migration.V206_AddConversationCountIndex
import org.thoughtcrime.securesms.database.helpers.migration.V207_AddChunkSizeColumn
import org.thoughtcrime.securesms.database.helpers.migration.V208_ClearRecipientPniFromAciColumn
/**
* Contains all of the database migrations for [SignalDatabase]. Broken into a separate file for cleanliness.
@@ -71,7 +72,7 @@ object SignalDatabaseMigrations {
val TAG: String = Log.tag(SignalDatabaseMigrations.javaClass)
const val DATABASE_VERSION = 207
const val DATABASE_VERSION = 208
@JvmStatic
fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@@ -310,6 +311,10 @@ object SignalDatabaseMigrations {
if (oldVersion < 207) {
V207_AddChunkSizeColumn.migrate(context, db, oldVersion, newVersion)
}
if (oldVersion < 208) {
V208_ClearRecipientPniFromAciColumn.migrate(context, db, oldVersion, newVersion)
}
}
@JvmStatic

View File

@@ -0,0 +1,19 @@
/*
* Copyright 2023 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.thoughtcrime.securesms.database.helpers.migration
import android.app.Application
import net.zetetic.database.sqlcipher.SQLiteDatabase
/**
* PNIs were incorrectly being set to ACI column, remove them if present.
*/
@Suppress("ClassName")
object V208_ClearRecipientPniFromAciColumn : SignalDatabaseMigration {
override fun migrate(context: Application, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
db.execSQL("DELETE FROM recipient WHERE aci LIKE 'PNI:%'")
}
}

View File

@@ -305,7 +305,7 @@ public class ContactRecordProcessor extends DefaultStorageRecordProcessor<Signal
private static boolean doParamsMatch(@NonNull SignalContactRecord contact,
@Nullable byte[] unknownFields,
@NonNull ACI aci,
@Nullable ACI aci,
@Nullable PNI pni,
@Nullable String e164,
@NonNull String profileGivenName,

View File

@@ -57,9 +57,9 @@ public final class StorageSyncModels {
public static @NonNull SignalStorageRecord localToRemoteRecord(@NonNull RecipientRecord settings, @NonNull byte[] rawStorageId) {
switch (settings.getRecipientType()) {
case INDIVIDUAL: return SignalStorageRecord.forContact(localToRemoteContact(settings, rawStorageId));
case GV1: return SignalStorageRecord.forGroupV1(localToRemoteGroupV1(settings, rawStorageId));
case GV2: return SignalStorageRecord.forGroupV2(localToRemoteGroupV2(settings, rawStorageId, settings.getSyncExtras().getGroupMasterKey()));
case INDIVIDUAL: return SignalStorageRecord.forContact(localToRemoteContact(settings, rawStorageId));
case GV1: return SignalStorageRecord.forGroupV1(localToRemoteGroupV1(settings, rawStorageId));
case GV2: return SignalStorageRecord.forGroupV2(localToRemoteGroupV2(settings, rawStorageId, settings.getSyncExtras().getGroupMasterKey()));
case DISTRIBUTION_LIST: return SignalStorageRecord.forStoryDistributionList(localToRemoteStoryDistributionList(settings, rawStorageId));
default: throw new AssertionError("Unsupported type!");
}
@@ -134,10 +134,9 @@ public final class StorageSyncModels {
throw new AssertionError("Must have either a UUID or a phone number!");
}
ACI aci = recipient.getAci() != null ? recipient.getAci() : ACI.UNKNOWN;
boolean hideStory = recipient.getExtras() != null && recipient.getExtras().hideStory();
return new SignalContactRecord.Builder(rawStorageId, aci, recipient.getSyncExtras().getStorageProto())
return new SignalContactRecord.Builder(rawStorageId, recipient.getAci(), recipient.getSyncExtras().getStorageProto())
.setE164(recipient.getE164())
.setPni(recipient.getPni())
.setProfileKey(recipient.getProfileKey())

View File

@@ -16,6 +16,8 @@ import java.util.List;
import java.util.Objects;
import java.util.Optional;
import javax.annotation.Nullable;
import okio.ByteString;
public final class SignalContactRecord implements SignalRecord {
@@ -292,7 +294,7 @@ public final class SignalContactRecord implements SignalRecord {
private final StorageId id;
private final ContactRecord.Builder builder;
public Builder(byte[] rawId, ACI aci, byte[] serializedUnknowns) {
public Builder(byte[] rawId, @Nullable ACI aci, byte[] serializedUnknowns) {
this.id = StorageId.forContact(rawId);
if (serializedUnknowns != null) {
@@ -301,7 +303,7 @@ public final class SignalContactRecord implements SignalRecord {
this.builder = new ContactRecord.Builder();
}
builder.aci(aci.toString());
builder.aci(aci == null ? "" : aci.toString());
}
public Builder setE164(String e164) {