Split unregistered contacts when in PNP mode.

This commit is contained in:
Greyson Parrelli 2023-02-07 14:49:44 -05:00
parent 9e056e5dd0
commit fdcf0a76e8
2 changed files with 71 additions and 8 deletions

View file

@ -11,6 +11,11 @@ import org.signal.core.util.CursorUtil
import org.thoughtcrime.securesms.profiles.ProfileName
import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.testing.SignalActivityRule
import org.thoughtcrime.securesms.util.FeatureFlags
import org.thoughtcrime.securesms.util.FeatureFlagsAccessor
import org.whispersystems.signalservice.api.push.ACI
import org.whispersystems.signalservice.api.push.PNI
import java.util.UUID
@RunWith(AndroidJUnit4::class)
class RecipientTableTest {
@ -159,4 +164,28 @@ class RecipientTableTest {
assertNotEquals(0, results.size)
assertFalse(blockedRecipient in results)
}
@Test
fun givenARecipientWithPniAndAci_whenIMarkItUnregistered_thenIExpectItToBeSplit() {
FeatureFlagsAccessor.forceValue(FeatureFlags.PHONE_NUMBER_PRIVACY, true)
val mainId = SignalDatabase.recipients.getAndPossiblyMerge(ACI_A, PNI_A, E164_A)
SignalDatabase.recipients.markUnregistered(mainId)
val byAci: RecipientId = SignalDatabase.recipients.getByServiceId(ACI_A).get()
val byE164: RecipientId = SignalDatabase.recipients.getByE164(E164_A).get()
val byPni: RecipientId = SignalDatabase.recipients.getByServiceId(PNI_A).get()
assertEquals(mainId, byAci)
assertEquals(byE164, byPni)
assertNotEquals(byAci, byE164)
}
companion object {
val ACI_A = ACI.from(UUID.fromString("aaaa0000-5a76-47fa-a98a-7e72c948a82e"))
val PNI_A = PNI.from(UUID.fromString("aaaa1111-c960-4f6c-8385-671ad2ffb999"))
const val E164_A = "+12222222222"
}
}

View file

@ -2207,13 +2207,53 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
fun markUnregistered(id: RecipientId) {
if (FeatureFlags.phoneNumberPrivacy()) {
val record = getRecord(id)
if (record.pni != null && record.serviceId != record.pni) {
markUnregisteredAndSplit(id, record)
} else {
markUnregisteredWithoutSplit(id)
}
} else {
markUnregisteredWithoutSplit(id)
}
}
/**
* Marks the user unregistered and also splits it into an ACI-only and PNI-only contact.
* This is to allow a new user to register the number with a new ACI.
*/
private fun markUnregisteredAndSplit(id: RecipientId, record: RecipientRecord) {
check(record.pni != null && record.pni != record.serviceId)
val contentValues = contentValuesOf(
REGISTERED to RegisteredState.NOT_REGISTERED.id,
UNREGISTERED_TIMESTAMP to System.currentTimeMillis(),
PHONE to null,
PNI_COLUMN to null
)
if (update(id, contentValues)) {
Log.i(TAG, "[WithSplit] Newly marked $id as unregistered.")
ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id)
}
val splitId = getAndPossiblyMerge(record.pni, record.pni, record.e164)
Log.i(TAG, "Split off new recipient as $splitId (ACI-only recipient is $id)")
}
/**
* Marks the user unregistered without splitting the contact into an ACI-only and PNI-only contact.
*/
private fun markUnregisteredWithoutSplit(id: RecipientId) {
val contentValues = contentValuesOf(
REGISTERED to RegisteredState.NOT_REGISTERED.id,
UNREGISTERED_TIMESTAMP to System.currentTimeMillis()
)
if (update(id, contentValues)) {
Log.i(TAG, "Newly marked $id as unregistered.")
Log.i(TAG, "[WithoutSplit] Newly marked $id as unregistered.")
ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id)
}
}
@ -2246,13 +2286,7 @@ open class RecipientTable(context: Context, databaseHelper: SignalDatabase) : Da
}
for (id in unregistered) {
val values = contentValuesOf(
REGISTERED to RegisteredState.NOT_REGISTERED.id,
UNREGISTERED_TIMESTAMP to System.currentTimeMillis()
)
if (update(id, values)) {
ApplicationDependencies.getDatabaseObserver().notifyRecipientChanged(id)
}
markUnregistered(id)
}
}
}