Store your own PNI.

fork-5.53.8
Greyson Parrelli 2021-12-06 12:18:42 -05:00 zatwierdzone przez GitHub
rodzic 0a84f7f505
commit c93457402c
Nie znaleziono w bazie danych klucza dla tego podpisu
ID klucza GPG: 4AEE18F83AFDEB23
17 zmienionych plików z 208 dodań i 79 usunięć

Wyświetl plik

@ -27,6 +27,7 @@ import org.thoughtcrime.securesms.util.SpanUtil
import org.thoughtcrime.securesms.util.Util
import org.thoughtcrime.securesms.util.livedata.Store
import org.whispersystems.signalservice.api.push.ACI
import org.whispersystems.signalservice.api.push.PNI
import java.util.Objects
/**
@ -60,11 +61,18 @@ class InternalConversationSettingsFragment : DSLSettingsFragment(
)
if (!recipient.isGroup) {
val uuid = recipient.aci.transform(ACI::toString).or("null")
val aci = recipient.aci.transform(ACI::toString).or("null")
longClickPref(
title = DSLSettingsText.from("UUID"),
summary = DSLSettingsText.from(uuid),
onLongClick = { copyToClipboard(uuid) }
title = DSLSettingsText.from("ACI"),
summary = DSLSettingsText.from(aci),
onLongClick = { copyToClipboard(aci) }
)
val pni = recipient.pni.transform(PNI::toString).or("null")
longClickPref(
title = DSLSettingsText.from("PNI"),
summary = DSLSettingsText.from(pni),
onLongClick = { copyToClipboard(pni) }
)
}

Wyświetl plik

@ -77,6 +77,7 @@ import org.whispersystems.libsignal.util.Pair
import org.whispersystems.libsignal.util.guava.Optional
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile
import org.whispersystems.signalservice.api.push.ACI
import org.whispersystems.signalservice.api.push.PNI
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import org.whispersystems.signalservice.api.storage.SignalAccountRecord
import org.whispersystems.signalservice.api.storage.SignalContactRecord
@ -108,6 +109,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
const val ID = "_id"
private const val ACI_COLUMN = "uuid"
private const val PNI_COLUMN = "pni"
private const val USERNAME = "username"
const val PHONE = "phone"
const val EMAIL = "email"
@ -216,17 +218,20 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
$GROUPS_IN_COMMON INTEGER DEFAULT 0,
$CHAT_COLORS BLOB DEFAULT NULL,
$CUSTOM_CHAT_COLORS_ID INTEGER DEFAULT 0,
$BADGES BLOB DEFAULT NULL
$BADGES BLOB DEFAULT NULL,
$PNI_COLUMN TEXT DEFAULT NULL
)
""".trimIndent()
val CREATE_INDEXS = arrayOf(
"CREATE INDEX IF NOT EXISTS recipient_group_type_index ON $TABLE_NAME ($GROUP_TYPE);"
"CREATE INDEX IF NOT EXISTS recipient_group_type_index ON $TABLE_NAME ($GROUP_TYPE);",
"CREATE UNIQUE INDEX IF NOT EXISTS recipient_pni_index ON $TABLE_NAME ($PNI_COLUMN)"
)
private val RECIPIENT_PROJECTION: Array<String> = arrayOf(
ID,
ACI_COLUMN,
PNI_COLUMN,
USERNAME,
PHONE,
EMAIL,
@ -1807,6 +1812,13 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
return results
}
fun setPni(id: RecipientId, pni: PNI) {
val values = ContentValues().apply {
put(PNI_COLUMN, pni.toString())
}
writableDatabase.update(TABLE_NAME, values, ID_WHERE, SqlUtil.buildArgs(id))
}
/**
* @return True if setting the UUID resulted in changed recipientId, otherwise false.
*/
@ -2777,6 +2789,7 @@ open class RecipientDatabase(context: Context, databaseHelper: SignalDatabase) :
return RecipientRecord(
id = recipientId,
aci = ACI.parseOrNull(cursor.requireString(ACI_COLUMN)),
pni = PNI.parseOrNull(cursor.requireString(PNI_COLUMN)),
username = cursor.requireString(USERNAME),
e164 = cursor.requireString(PHONE),
email = cursor.requireString(EMAIL),

Wyświetl plik

@ -178,8 +178,9 @@ object SignalDatabaseMigrations {
private const val SENDER_KEY_UUID = 119
private const val SENDER_KEY_SHARED_TIMESTAMP = 120
private const val REACTION_REFACTOR = 121
private const val PNI = 122
const val DATABASE_VERSION = 121
const val DATABASE_VERSION = 122
@JvmStatic
fun migrate(context: Context, db: SQLiteDatabase, oldVersion: Int, newVersion: Int) {
@ -2170,6 +2171,11 @@ object SignalDatabaseMigrations {
db.execSQL("UPDATE sms SET reactions = NULL WHERE reactions NOT NULL")
db.execSQL("UPDATE mms SET reactions = NULL WHERE reactions NOT NULL")
}
if (oldVersion < PNI) {
db.execSQL("ALTER TABLE recipient ADD COLUMN pni TEXT DEFAULT NULL")
db.execSQL("CREATE UNIQUE INDEX IF NOT EXISTS recipient_pni_index ON recipient (pni)")
}
}
@JvmStatic

Wyświetl plik

@ -21,6 +21,7 @@ import org.thoughtcrime.securesms.recipients.RecipientId
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper
import org.whispersystems.libsignal.util.guava.Optional
import org.whispersystems.signalservice.api.push.ACI
import org.whispersystems.signalservice.api.push.PNI
/**
* Database model for [RecipientDatabase].
@ -28,6 +29,7 @@ import org.whispersystems.signalservice.api.push.ACI
data class RecipientRecord(
val id: RecipientId,
val aci: ACI?,
val pni: PNI?,
val username: String?,
val e164: String?,
val email: String?,

Wyświetl plik

@ -47,6 +47,7 @@ import org.thoughtcrime.securesms.migrations.MigrationCompleteJob;
import org.thoughtcrime.securesms.migrations.PassingMigrationJob;
import org.thoughtcrime.securesms.migrations.PinOptOutMigration;
import org.thoughtcrime.securesms.migrations.PinReminderMigrationJob;
import org.thoughtcrime.securesms.migrations.PniMigrationJob;
import org.thoughtcrime.securesms.migrations.ProfileMigrationJob;
import org.thoughtcrime.securesms.migrations.ProfileSharingUpdateMigrationJob;
import org.thoughtcrime.securesms.migrations.RecipientSearchMigrationJob;
@ -191,6 +192,7 @@ public final class JobManagerFactories {
put(MigrationCompleteJob.KEY, new MigrationCompleteJob.Factory());
put(PinOptOutMigration.KEY, new PinOptOutMigration.Factory());
put(PinReminderMigrationJob.KEY, new PinReminderMigrationJob.Factory());
put(PniMigrationJob.KEY, new PniMigrationJob.Factory());
put(ProfileMigrationJob.KEY, new ProfileMigrationJob.Factory());
put(ProfileSharingUpdateMigrationJob.KEY, new ProfileSharingUpdateMigrationJob.Factory());
put(RecipientSearchMigrationJob.KEY, new RecipientSearchMigrationJob.Factory());

Wyświetl plik

@ -91,9 +91,10 @@ public class ApplicationMigrations {
static final int DEFAULT_REACTIONS_SYNC = 47;
static final int DB_REACTIONS_MIGRATION = 48;
//static final int CHANGE_NUMBER_CAPABILITY_3 = 49;
static final int PNI = 50;
}
public static final int CURRENT_VERSION = 49;
public static final int CURRENT_VERSION = 50;
/**
* This *must* be called after the {@link JobManager} has been instantiated, but *before* the call
@ -395,6 +396,10 @@ public class ApplicationMigrations {
jobs.put(Version.DB_REACTIONS_MIGRATION, new DatabaseMigrationJob());
}
if (lastSeenVersion < Version.PNI) {
jobs.put(Version.PNI, new PniMigrationJob());
}
return jobs;
}

Wyświetl plik

@ -0,0 +1,74 @@
package org.thoughtcrime.securesms.migrations;
import androidx.annotation.NonNull;
import org.signal.core.util.logging.Log;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.dependencies.ApplicationDependencies;
import org.thoughtcrime.securesms.jobmanager.Data;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
import org.thoughtcrime.securesms.keyvalue.SignalStore;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.signalservice.api.push.PNI;
import java.io.IOException;
/**
* Migration to fetch our own PNI from the service.
*/
public class PniMigrationJob extends MigrationJob {
public static final String KEY = "PniMigrationJob";
private static final String TAG = Log.tag(PniMigrationJob.class);
PniMigrationJob() {
this(new Parameters.Builder().addConstraint(NetworkConstraint.KEY).build());
}
private PniMigrationJob(@NonNull Parameters parameters) {
super(parameters);
}
@Override
public @NonNull String getFactoryKey() {
return KEY;
}
@Override
boolean isUiBlocking() {
return false;
}
@Override
void performMigration() throws Exception {
if (!SignalStore.account().isRegistered() || SignalStore.account().getAci() == null) {
Log.w(TAG, "Not registered! Skipping migration, as it wouldn't do anything.");
return;
}
RecipientId self = Recipient.self().getId();
PNI pni = PNI.parseOrNull(ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI().getPni());
if (pni == null) {
throw new IOException("Invalid PNI!");
}
SignalDatabase.recipients().setPni(self, pni);
SignalStore.account().setPni(pni);
}
@Override
boolean shouldRetry(@NonNull Exception e) {
return e instanceof IOException;
}
public static class Factory implements Job.Factory<PniMigrationJob> {
@Override
public @NonNull PniMigrationJob create(@NonNull Parameters parameters, @NonNull Data data) {
return new PniMigrationJob(parameters);
}
}
}

Wyświetl plik

@ -71,7 +71,11 @@ public class UuidMigrationJob extends MigrationJob {
private static void fetchOwnUuid(@NonNull Context context) throws IOException {
RecipientId self = Recipient.self().getId();
ACI localUuid = ApplicationDependencies.getSignalServiceAccountManager().getOwnAci();
ACI localUuid = ACI.parseOrNull(ApplicationDependencies.getSignalServiceAccountManager().getWhoAmI().getAci());
if (localUuid == null) {
throw new IOException("Invalid UUID!");
}
SignalDatabase.recipients().markRegisteredOrThrow(self, localUuid);
SignalStore.account().setAci(localUuid);

Wyświetl plik

@ -49,6 +49,7 @@ import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.libsignal.util.guava.Preconditions;
import org.whispersystems.signalservice.api.push.ACI;
import org.whispersystems.signalservice.api.push.PNI;
import org.whispersystems.signalservice.api.push.SignalServiceAddress;
import org.whispersystems.signalservice.api.util.UuidUtil;
@ -78,6 +79,7 @@ public class Recipient {
private final RecipientId id;
private final boolean resolving;
private final ACI aci;
private final PNI pni;
private final String username;
private final String e164;
private final String email;
@ -329,9 +331,10 @@ public class Recipient {
Recipient(@NonNull RecipientId id) {
this.id = id;
this.resolving = true;
this.aci = null;
this.username = null;
this.resolving = true;
this.aci = null;
this.pni = null;
this.username = null;
this.e164 = null;
this.email = null;
this.groupId = null;
@ -385,6 +388,7 @@ public class Recipient {
this.id = id;
this.resolving = !resolved;
this.aci = details.aci;
this.pni = details.pni;
this.username = details.username;
this.e164 = details.e164;
this.email = details.email;
@ -607,6 +611,10 @@ public class Recipient {
return Optional.fromNullable(aci);
}
public @NonNull Optional<PNI> getPni() {
return Optional.fromNullable(pni);
}
public @NonNull Optional<String> getUsername() {
if (FeatureFlags.usernames()) {
return Optional.fromNullable(username);

Wyświetl plik

@ -24,6 +24,7 @@ import org.thoughtcrime.securesms.util.Util;
import org.thoughtcrime.securesms.wallpaper.ChatWallpaper;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.push.ACI;
import org.whispersystems.signalservice.api.push.PNI;
import java.util.Collections;
import java.util.LinkedList;
@ -32,6 +33,7 @@ import java.util.List;
public class RecipientDetails {
final ACI aci;
final PNI pni;
final String username;
final String e164;
final String email;
@ -88,59 +90,60 @@ public class RecipientDetails {
boolean systemContact,
boolean isSelf,
@NonNull RegisteredState registeredState,
@NonNull RecipientRecord settings,
@NonNull RecipientRecord record,
@Nullable List<Recipient> participants)
{
this.groupAvatarId = groupAvatarId;
this.systemContactPhoto = Util.uri(settings.getSystemContactPhotoUri());
this.customLabel = settings.getSystemPhoneLabel();
this.contactUri = Util.uri(settings.getSystemContactUri());
this.aci = settings.getAci();
this.username = settings.getUsername();
this.e164 = settings.getE164();
this.email = settings.getEmail();
this.groupId = settings.getGroupId();
this.messageRingtone = settings.getMessageRingtone();
this.callRingtone = settings.getCallRingtone();
this.mutedUntil = settings.getMuteUntil();
this.messageVibrateState = settings.getMessageVibrateState();
this.callVibrateState = settings.getCallVibrateState();
this.blocked = settings.isBlocked();
this.expireMessages = settings.getExpireMessages();
this.systemContactPhoto = Util.uri(record.getSystemContactPhotoUri());
this.customLabel = record.getSystemPhoneLabel();
this.contactUri = Util.uri(record.getSystemContactUri());
this.aci = record.getAci();
this.pni = record.getPni();
this.username = record.getUsername();
this.e164 = record.getE164();
this.email = record.getEmail();
this.groupId = record.getGroupId();
this.messageRingtone = record.getMessageRingtone();
this.callRingtone = record.getCallRingtone();
this.mutedUntil = record.getMuteUntil();
this.messageVibrateState = record.getMessageVibrateState();
this.callVibrateState = record.getCallVibrateState();
this.blocked = record.isBlocked();
this.expireMessages = record.getExpireMessages();
this.participants = participants == null ? new LinkedList<>() : participants;
this.profileName = settings.getProfileName();
this.defaultSubscriptionId = settings.getDefaultSubscriptionId();
this.profileName = record.getProfileName();
this.defaultSubscriptionId = record.getDefaultSubscriptionId();
this.registered = registeredState;
this.profileKey = settings.getProfileKey();
this.profileKeyCredential = settings.getProfileKeyCredential();
this.profileAvatar = settings.getProfileAvatar();
this.hasProfileImage = settings.hasProfileImage();
this.profileSharing = settings.isProfileSharing();
this.lastProfileFetch = settings.getLastProfileFetch();
this.profileKey = record.getProfileKey();
this.profileKeyCredential = record.getProfileKeyCredential();
this.profileAvatar = record.getProfileAvatar();
this.hasProfileImage = record.hasProfileImage();
this.profileSharing = record.isProfileSharing();
this.lastProfileFetch = record.getLastProfileFetch();
this.systemContact = systemContact;
this.isSelf = isSelf;
this.notificationChannel = settings.getNotificationChannel();
this.unidentifiedAccessMode = settings.getUnidentifiedAccessMode();
this.forceSmsSelection = settings.isForceSmsSelection();
this.groupsV2Capability = settings.getGroupsV2Capability();
this.groupsV1MigrationCapability = settings.getGroupsV1MigrationCapability();
this.senderKeyCapability = settings.getSenderKeyCapability();
this.announcementGroupCapability = settings.getAnnouncementGroupCapability();
this.changeNumberCapability = settings.getChangeNumberCapability();
this.insightsBannerTier = settings.getInsightsBannerTier();
this.storageId = settings.getStorageId();
this.mentionSetting = settings.getMentionSetting();
this.wallpaper = settings.getWallpaper();
this.chatColors = settings.getChatColors();
this.avatarColor = settings.getAvatarColor();
this.about = settings.getAbout();
this.aboutEmoji = settings.getAboutEmoji();
this.systemProfileName = settings.getSystemProfileName();
this.notificationChannel = record.getNotificationChannel();
this.unidentifiedAccessMode = record.getUnidentifiedAccessMode();
this.forceSmsSelection = record.isForceSmsSelection();
this.groupsV2Capability = record.getGroupsV2Capability();
this.groupsV1MigrationCapability = record.getGroupsV1MigrationCapability();
this.senderKeyCapability = record.getSenderKeyCapability();
this.announcementGroupCapability = record.getAnnouncementGroupCapability();
this.changeNumberCapability = record.getChangeNumberCapability();
this.insightsBannerTier = record.getInsightsBannerTier();
this.storageId = record.getStorageId();
this.mentionSetting = record.getMentionSetting();
this.wallpaper = record.getWallpaper();
this.chatColors = record.getChatColors();
this.avatarColor = record.getAvatarColor();
this.about = record.getAbout();
this.aboutEmoji = record.getAboutEmoji();
this.systemProfileName = record.getSystemProfileName();
this.groupName = groupName;
this.systemContactName = systemContactName;
this.extras = Optional.fromNullable(settings.getExtras());
this.hasGroupsInCommon = settings.hasGroupsInCommon();
this.badges = settings.getBadges();
this.extras = Optional.fromNullable(record.getExtras());
this.hasGroupsInCommon = record.hasGroupsInCommon();
this.badges = record.getBadges();
}
/**
@ -150,9 +153,10 @@ public class RecipientDetails {
this.groupAvatarId = null;
this.systemContactPhoto = null;
this.customLabel = null;
this.contactUri = null;
this.aci = null;
this.username = null;
this.contactUri = null;
this.aci = null;
this.pni = null;
this.username = null;
this.e164 = null;
this.email = null;
this.groupId = null;

Wyświetl plik

@ -38,6 +38,7 @@ import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.KbsPinData;
import org.whispersystems.signalservice.api.SignalServiceAccountManager;
import org.whispersystems.signalservice.api.push.ACI;
import org.whispersystems.signalservice.api.push.PNI;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.internal.ServiceResponse;
import org.whispersystems.signalservice.internal.push.VerifyAccountResponse;
@ -130,6 +131,7 @@ public final class RegistrationRepository {
SenderKeyUtil.clearAllState(context);
ACI aci = ACI.parseOrThrow(response.getUuid());
PNI pni = PNI.parseOrThrow(response.getPni());
boolean hasPin = response.isStorageCapable();
IdentityKeyPair identityKey = IdentityKeyUtil.getIdentityKeyPair(context);
@ -148,9 +150,11 @@ public final class RegistrationRepository {
recipientDatabase.setProfileSharing(selfId, true);
recipientDatabase.markRegisteredOrThrow(selfId, aci);
recipientDatabase.setPni(selfId, pni);
SignalStore.account().setE164(registrationData.getE164());
SignalStore.account().setAci(aci);
SignalStore.account().setPni(pni);
recipientDatabase.setProfileKey(selfId, registrationData.getProfileKey());
ApplicationDependencies.getRecipientCache().clearSelf();

Wyświetl plik

@ -93,6 +93,7 @@ object RecipientDatabaseTestUtils {
RecipientRecord(
recipientId,
aci,
null,
username,
e164,
email,

Wyświetl plik

@ -176,10 +176,6 @@ public class SignalServiceAccountManager {
this.pushServiceSocket.removeRegistrationLockV1();
}
public ACI getOwnAci() throws IOException {
return this.pushServiceSocket.getOwnAci();
}
public WhoAmIResponse getWhoAmI() throws IOException {
return this.pushServiceSocket.getWhoAmI();
}

Wyświetl plik

@ -10,8 +10,6 @@ import java.util.List;
import java.util.UUID;
import java.util.stream.Collectors;
import io.reactivex.rxjava3.annotations.NonNull;
/**
* An ACI is an "Account Identity". They're just UUIDs, but given multiple different things could be UUIDs, this wrapper exists to give us type safety around
* this *specific type* of UUID.
@ -65,7 +63,7 @@ public final class ACI extends AccountIdentifier {
return uuid != null ? uuid : UNKNOWN;
}
public static List<ACI> filterKnown(@NonNull Collection<ACI> acis) {
public static List<ACI> filterKnown(Collection<ACI> acis) {
return acis.stream().filter(aci -> !aci.equals(UNKNOWN)).collect(Collectors.toList());
}

Wyświetl plik

@ -19,6 +19,10 @@ public final class PNI extends AccountIdentifier {
return uuid != null ? from(uuid) : null;
}
public static PNI parseOrThrow(String raw) {
return from(UUID.fromString(raw));
}
private PNI(UUID uuid) {
super(uuid);
}
@ -36,4 +40,9 @@ public final class PNI extends AccountIdentifier {
return false;
}
}
@Override
public String toString() {
return uuid.toString();
}
}

Wyświetl plik

@ -327,18 +327,6 @@ public class PushServiceSocket {
makeServiceRequest(path, "GET", null, headers, new VerificationCodeResponseHandler());
}
public ACI getOwnAci() throws IOException {
String body = makeServiceRequest(WHO_AM_I, "GET", null);
WhoAmIResponse response = JsonUtil.fromJson(body, WhoAmIResponse.class);
Optional<ACI> aci = ACI.parse(response.getAci());
if (aci.isPresent()) {
return aci.get();
} else {
throw new IOException("Invalid UUID!");
}
}
public WhoAmIResponse getWhoAmI() throws IOException {
return JsonUtil.fromJson(makeServiceRequest(WHO_AM_I, "GET", null), WhoAmIResponse.class);
}
@ -580,7 +568,7 @@ public class PushServiceSocket {
signedPreKey.getKeyPair().getPublicKey(),
signedPreKey.getSignature());
makeServiceRequest(String.format(PREKEY_PATH, ""), "PUT",
String response = makeServiceRequest(String.format(PREKEY_PATH, ""), "PUT",
JsonUtil.toJson(new PreKeyState(entities, signedPreKeyEntity, identityKey)));
}

Wyświetl plik

@ -6,6 +6,9 @@ public class VerifyAccountResponse {
@JsonProperty
private String uuid;
@JsonProperty
private String pni;
@JsonProperty
private boolean storageCapable;
@ -16,4 +19,8 @@ public class VerifyAccountResponse {
public boolean isStorageCapable() {
return storageCapable;
}
public String getPni() {
return pni;
}
}