Strongly type UUIDs as ACIs.

This commit is contained in:
Greyson Parrelli
2021-10-28 15:39:36 -04:00
parent 6c7d837964
commit 5bb48caafd
120 changed files with 1020 additions and 947 deletions

View File

@@ -23,7 +23,7 @@ public final class BucketingUtil {
* Calculate a user bucket for a given feature flag, uuid, and part per modulus.
*
* @param key Feature flag key (e.g., "research.megaphone.1")
* @param uuid Current user's UUID (see {@link Recipient#getUuid()})
* @param uuid Current user's UUID (see {@link Recipient#getAci()})
* @param modulus Drives the bucketing parts per N (e.g., passing 1,000,000 indicates bucketing into parts per million)
*/
public static long bucket(@NonNull String key, @NonNull UUID uuid, long modulus) {

View File

@@ -242,7 +242,7 @@ public class CommunicationActions {
SimpleTask.run(() -> {
Recipient recipient = Recipient.external(activity, e164);
if (!recipient.isRegistered() || !recipient.hasUuid()) {
if (!recipient.isRegistered() || !recipient.hasAci()) {
try {
DirectoryHelper.refreshDirectoryFor(activity, recipient, false);
recipient = Recipient.resolved(recipient.getId());

View File

@@ -72,12 +72,12 @@ public final class LocaleFeatureFlags {
Map<String, Integer> countryCodeValues = parseCountryValues(serialized, 0);
Recipient self = Recipient.self();
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getUuid().isPresent()) {
if (countryCodeValues.isEmpty() || !self.getE164().isPresent() || !self.getAci().isPresent()) {
return false;
}
long countEnabled = getCountryValue(countryCodeValues, self.getE164().or(""), 0);
long currentUserBucket = BucketingUtil.bucket(flag, self.requireUuid(), 1_000_000);
long currentUserBucket = BucketingUtil.bucket(flag, self.requireAci().uuid(), 1_000_000);
return countEnabled > currentUserBucket;
}

View File

@@ -284,7 +284,7 @@ public final class ProfileUtil {
ProfileKey profileKey = ProfileKeyUtil.getSelfProfileKey();
SignalServiceAccountManager accountManager = ApplicationDependencies.getSignalServiceAccountManager();
String avatarPath = accountManager.setVersionedProfile(Recipient.self().getUuid().get(),
String avatarPath = accountManager.setVersionedProfile(Recipient.self().requireAci(),
profileKey,
profileName.serialize(),
about,
@@ -321,8 +321,8 @@ public final class ProfileUtil {
private static @NonNull SignalServiceAddress toSignalServiceAddress(@NonNull Context context, @NonNull Recipient recipient) throws IOException {
if (recipient.getRegistered() == RecipientDatabase.RegisteredState.NOT_REGISTERED) {
if (recipient.hasUuid()) {
return new SignalServiceAddress(recipient.requireUuid(), recipient.getE164().orNull());
if (recipient.hasAci()) {
return new SignalServiceAddress(recipient.requireAci(), recipient.getE164().orNull());
} else {
throw new IOException(recipient.getId() + " not registered!");
}

View File

@@ -2,9 +2,9 @@ package org.thoughtcrime.securesms.util
import org.thoughtcrime.securesms.recipients.Recipient
import org.thoughtcrime.securesms.recipients.RecipientId
import org.whispersystems.signalservice.api.push.ACI
import org.whispersystems.signalservice.api.push.SignalServiceAddress
import java.lang.IllegalArgumentException
import java.util.UUID
/**
* A list of Recipients, but with some helpful methods for retrieving them by various properties. Uses lazy properties to ensure that it will be as performant
@@ -12,10 +12,10 @@ import java.util.UUID
*/
class RecipientAccessList(private val recipients: List<Recipient>) : List<Recipient> by recipients {
private val byUuid: Map<UUID, Recipient> by lazy {
private val byAci: Map<ACI, Recipient> by lazy {
recipients
.filter { it.hasUuid() }
.associateBy { it.requireUuid() }
.filter { it.hasAci() }
.associateBy { it.requireAci() }
}
private val byE164: Map<String, Recipient> by lazy {
@@ -25,10 +25,10 @@ class RecipientAccessList(private val recipients: List<Recipient>) : List<Recipi
}
fun requireByAddress(address: SignalServiceAddress): Recipient {
if (byUuid.containsKey(address.uuid)) {
return byUuid.get(address.uuid)!!
if (byAci.containsKey(address.aci)) {
return byAci[address.aci]!!
} else if (address.number.isPresent && byE164.containsKey(address.number.get())) {
return byE164.get(address.number.get())!!
return byE164[address.number.get()]!!
} else {
throw IllegalArgumentException("Could not find a matching recipient!")
}

View File

@@ -29,7 +29,7 @@ import org.thoughtcrime.securesms.notifications.NotificationChannels;
import org.thoughtcrime.securesms.preferences.widgets.NotificationPrivacyPreference;
import org.thoughtcrime.securesms.recipients.Recipient;
import org.whispersystems.libsignal.util.Medium;
import org.whispersystems.signalservice.api.util.UuidUtil;
import org.whispersystems.signalservice.api.push.ACI;
import java.io.IOException;
import java.security.SecureRandom;
@@ -82,7 +82,7 @@ public class TextSecurePreferences {
public static final String MMS_USER_AGENT = "pref_mms_user_agent";
private static final String MMS_CUSTOM_USER_AGENT = "pref_custom_mms_user_agent";
private static final String LOCAL_NUMBER_PREF = "pref_local_number";
private static final String LOCAL_UUID_PREF = "pref_local_uuid";
private static final String LOCAL_ACI_PREF = "pref_local_uuid";
private static final String LOCAL_USERNAME_PREF = "pref_local_username";
public static final String REGISTERED_GCM_PREF = "pref_gcm_registered";
private static final String GCM_PASSWORD_PREF = "pref_gcm_password";
@@ -742,12 +742,12 @@ public class TextSecurePreferences {
setStringPreference(context, LOCAL_NUMBER_PREF, localNumber);
}
public static UUID getLocalUuid(Context context) {
return UuidUtil.parseOrNull(getStringPreference(context, LOCAL_UUID_PREF, null));
public static ACI getLocalAci(Context context) {
return ACI.parseOrNull(getStringPreference(context, LOCAL_ACI_PREF, null));
}
public static void setLocalUuid(Context context, UUID uuid) {
setStringPreference(context, LOCAL_UUID_PREF, uuid.toString());
public static void setLocalAci(Context context, ACI aci) {
setStringPreference(context, LOCAL_ACI_PREF, aci.toString());
}
public static String getPushServerPassword(Context context) {

View File

@@ -14,10 +14,10 @@ import org.thoughtcrime.securesms.recipients.Recipient;
import org.thoughtcrime.securesms.recipients.RecipientId;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.profiles.SignalServiceProfile;
import org.whispersystems.signalservice.api.push.ACI;
import java.io.IOException;
import java.util.Locale;
import java.util.UUID;
import java.util.regex.Pattern;
public class UsernameUtil {
@@ -51,15 +51,15 @@ public class UsernameUtil {
}
@WorkerThread
public static @NonNull Optional<UUID> fetchUuidForUsername(@NonNull Context context, @NonNull String username) {
public static @NonNull Optional<ACI> fetchAciForUsername(@NonNull Context context, @NonNull String username) {
Optional<RecipientId> localId = DatabaseFactory.getRecipientDatabase(context).getByUsername(username);
if (localId.isPresent()) {
Recipient recipient = Recipient.resolved(localId.get());
if (recipient.getUuid().isPresent()) {
if (recipient.getAci().isPresent()) {
Log.i(TAG, "Found username locally -- using associated UUID.");
return recipient.getUuid();
return recipient.getAci();
} else {
Log.w(TAG, "Found username locally, but it had no associated UUID! Clearing it.");
DatabaseFactory.getRecipientDatabase(context).clearUsernameIfExists(username);
@@ -69,7 +69,7 @@ public class UsernameUtil {
try {
Log.d(TAG, "No local user with this username. Searching remotely.");
SignalServiceProfile profile = ApplicationDependencies.getSignalServiceMessageReceiver().retrieveProfileByUsername(username, Optional.absent(), Locale.getDefault());
return Optional.fromNullable(profile.getUuid());
return Optional.fromNullable(profile.getAci());
} catch (IOException e) {
return Optional.absent();
}