Update request and response properties for batch identity checks.

This commit is contained in:
Cody Henthorne
2023-07-31 13:32:35 -04:00
committed by Greyson Parrelli
parent a2c3b5d64e
commit e7972d4903
5 changed files with 43 additions and 43 deletions

View File

@@ -50,12 +50,12 @@ class SafetyNumberRepository(
if (recipients.isNotEmpty()) { if (recipients.isNotEmpty()) {
Log.i(TAG, "Checking on ${recipients.size} identities...") Log.i(TAG, "Checking on ${recipients.size} identities...")
val requests: List<Single<List<IdentityCheckResponse.AciIdentityPair>>> = recipients.chunked(batchSize) { it.createBatchRequestSingle() } val requests: List<Single<List<IdentityCheckResponse.ServiceIdentityPair>>> = recipients.chunked(batchSize) { it.createBatchRequestSingle() }
stopwatch.split("requests") stopwatch.split("requests")
val aciKeyPairs: List<IdentityCheckResponse.AciIdentityPair> = Single.zip(requests) { responses -> val aciKeyPairs: List<IdentityCheckResponse.ServiceIdentityPair> = Single.zip(requests) { responses ->
responses responses
.map { it as List<IdentityCheckResponse.AciIdentityPair> } .map { it as List<IdentityCheckResponse.ServiceIdentityPair> }
.flatten() .flatten()
}.safeBlockingGet() }.safeBlockingGet()
@@ -65,8 +65,8 @@ class SafetyNumberRepository(
Log.d(TAG, "No identity key mismatches") Log.d(TAG, "No identity key mismatches")
} else { } else {
aciKeyPairs aciKeyPairs
.filter { it.aci != null && it.identityKey != null } .filter { it.serviceId != null && it.identityKey != null }
.forEach { IdentityUtil.saveIdentity(it.aci.toString(), it.identityKey) } .forEach { IdentityUtil.saveIdentity(it.serviceId.toString(), it.identityKey) }
} }
recentlyFetched += recipients.associate { it.id to now } recentlyFetched += recipients.associate { it.id to now }
stopwatch.split("saving-identities") stopwatch.split("saving-identities")
@@ -95,7 +95,7 @@ class SafetyNumberRepository(
.apply { remove(Recipient.self().id) } .apply { remove(Recipient.self().id) }
} }
private fun List<Recipient>.createBatchRequestSingle(): Single<List<IdentityCheckResponse.AciIdentityPair>> { private fun List<Recipient>.createBatchRequestSingle(): Single<List<IdentityCheckResponse.ServiceIdentityPair>> {
return profileService return profileService
.performIdentityCheck( .performIdentityCheck(
mapNotNull { r -> mapNotNull { r ->
@@ -107,7 +107,7 @@ class SafetyNumberRepository(
} }
}.associate { it } }.associate { it }
) )
.map { ServiceResponseProcessor.DefaultProcessor(it).resultOrThrow.aciKeyPairs ?: emptyList() } .map { ServiceResponseProcessor.DefaultProcessor(it).resultOrThrow.serviceIdKeyPairs ?: emptyList() }
.onErrorReturn { t -> .onErrorReturn { t ->
Log.w(TAG, "Unable to fetch identities", t) Log.w(TAG, "Unable to fetch identities", t)
emptyList() emptyList()

View File

@@ -130,7 +130,7 @@ class SafetyNumberRepositoryTest {
staticRecipient.`when`<List<Recipient>> { Recipient.resolvedList(argThat { containsAll(keys.map { it.recipientId }) }) }.thenReturn(listOf(other)) staticRecipient.`when`<List<Recipient>> { Recipient.resolvedList(argThat { containsAll(keys.map { it.recipientId }) }) }.thenReturn(listOf(other))
whenever(profileService.performIdentityCheck(mapOf(other.requireServiceId() to identityPool[other]!!.identityKey))) whenever(profileService.performIdentityCheck(mapOf(other.requireServiceId() to identityPool[other]!!.identityKey)))
.thenReturn(Single.just(ServiceResponse.forResult(IdentityCheckResponse(listOf(IdentityCheckResponse.AciIdentityPair(otherAci, otherNewIdentityKey))), 200, ""))) .thenReturn(Single.just(ServiceResponse.forResult(IdentityCheckResponse(listOf(IdentityCheckResponse.ServiceIdentityPair(otherAci, otherNewIdentityKey))), 200, "")))
repository.batchSafetyNumberCheckSync(keys, now) repository.batchSafetyNumberCheckSync(keys, now)
@@ -151,7 +151,7 @@ class SafetyNumberRepositoryTest {
staticRecipient.`when`<List<Recipient>> { Recipient.resolvedList(argThat { containsAll(keys.map { it.recipientId }) }) }.thenReturn(listOf(other, secondOther)) staticRecipient.`when`<List<Recipient>> { Recipient.resolvedList(argThat { containsAll(keys.map { it.recipientId }) }) }.thenReturn(listOf(other, secondOther))
whenever(profileService.performIdentityCheck(mapOf(other.requireServiceId() to identityPool[other]!!.identityKey, secondOther.requireServiceId() to identityPool[secondOther]!!.identityKey))) whenever(profileService.performIdentityCheck(mapOf(other.requireServiceId() to identityPool[other]!!.identityKey, secondOther.requireServiceId() to identityPool[secondOther]!!.identityKey)))
.thenReturn(Single.just(ServiceResponse.forResult(IdentityCheckResponse(listOf(IdentityCheckResponse.AciIdentityPair(otherAci, otherNewIdentityKey))), 200, ""))) .thenReturn(Single.just(ServiceResponse.forResult(IdentityCheckResponse(listOf(IdentityCheckResponse.ServiceIdentityPair(otherAci, otherNewIdentityKey))), 200, "")))
repository.batchSafetyNumberCheckSync(keys, now) repository.batchSafetyNumberCheckSync(keys, now)

View File

@@ -22,7 +22,7 @@ import org.whispersystems.signalservice.api.push.exceptions.MalformedResponseExc
import org.whispersystems.signalservice.internal.ServiceResponse; import org.whispersystems.signalservice.internal.ServiceResponse;
import org.whispersystems.signalservice.internal.ServiceResponseProcessor; import org.whispersystems.signalservice.internal.ServiceResponseProcessor;
import org.whispersystems.signalservice.internal.push.IdentityCheckRequest; import org.whispersystems.signalservice.internal.push.IdentityCheckRequest;
import org.whispersystems.signalservice.internal.push.IdentityCheckRequest.AciFingerprintPair; import org.whispersystems.signalservice.internal.push.IdentityCheckRequest.ServiceIdFingerprintPair;
import org.whispersystems.signalservice.internal.push.IdentityCheckResponse; import org.whispersystems.signalservice.internal.push.IdentityCheckResponse;
import org.whispersystems.signalservice.internal.push.http.AcceptLanguagesUtil; import org.whispersystems.signalservice.internal.push.http.AcceptLanguagesUtil;
import org.whispersystems.signalservice.internal.util.Hex; import org.whispersystems.signalservice.internal.util.Hex;
@@ -120,13 +120,13 @@ public final class ProfileService {
.onErrorReturn(ServiceResponse::forUnknownError); .onErrorReturn(ServiceResponse::forUnknownError);
} }
public @NonNull Single<ServiceResponse<IdentityCheckResponse>> performIdentityCheck(@Nonnull Map<ServiceId, IdentityKey> aciIdentityKeyMap) { public @NonNull Single<ServiceResponse<IdentityCheckResponse>> performIdentityCheck(@Nonnull Map<ServiceId, IdentityKey> serviceIdIdentityKeyMap) {
List<AciFingerprintPair> aciKeyPairs = aciIdentityKeyMap.entrySet() List<ServiceIdFingerprintPair> serviceIdKeyPairs = serviceIdIdentityKeyMap.entrySet()
.stream() .stream()
.map(e -> new AciFingerprintPair(e.getKey(), e.getValue())) .map(e -> new ServiceIdFingerprintPair(e.getKey(), e.getValue()))
.collect(Collectors.toList()); .collect(Collectors.toList());
IdentityCheckRequest request = new IdentityCheckRequest(aciKeyPairs); IdentityCheckRequest request = new IdentityCheckRequest(serviceIdKeyPairs);
WebSocketRequestMessage.Builder builder = WebSocketRequestMessage.newBuilder() WebSocketRequestMessage.Builder builder = WebSocketRequestMessage.newBuilder()
.setId(new SecureRandom().nextLong()) .setId(new SecureRandom().nextLong())

View File

@@ -16,27 +16,27 @@ import javax.annotation.Nonnull;
public class IdentityCheckRequest { public class IdentityCheckRequest {
@JsonProperty("elements") @JsonProperty("elements")
private final List<AciFingerprintPair> aciFingerprintPairs; private final List<ServiceIdFingerprintPair> serviceIdFingerprintPairs;
public IdentityCheckRequest(@Nonnull List<AciFingerprintPair> aciKeyPairs) { public IdentityCheckRequest(@Nonnull List<ServiceIdFingerprintPair> serviceIdKeyPairs) {
this.aciFingerprintPairs = aciKeyPairs; this.serviceIdFingerprintPairs = serviceIdKeyPairs;
} }
public List<AciFingerprintPair> getAciFingerprintPairs() { public List<ServiceIdFingerprintPair> getServiceIdFingerprintPairs() {
return aciFingerprintPairs; return serviceIdFingerprintPairs;
} }
public static final class AciFingerprintPair { public static final class ServiceIdFingerprintPair {
@JsonProperty @JsonProperty("uuid")
@JsonSerialize(using = JsonUtil.ServiceIdSerializer.class) @JsonSerialize(using = JsonUtil.ServiceIdSerializer.class)
private final ServiceId aci; private final ServiceId serviceId;
@JsonProperty @JsonProperty
private final String fingerprint; private final String fingerprint;
public AciFingerprintPair(@Nonnull ServiceId aci, @Nonnull IdentityKey identityKey) { public ServiceIdFingerprintPair(@Nonnull ServiceId serviceId, @Nonnull IdentityKey identityKey) {
this.aci = aci; this.serviceId = serviceId;
try { try {
MessageDigest messageDigest = MessageDigest.getInstance("SHA-256"); MessageDigest messageDigest = MessageDigest.getInstance("SHA-256");
@@ -46,8 +46,8 @@ public class IdentityCheckRequest {
} }
} }
public ServiceId getAci() { public ServiceId getServiceId() {
return aci; return serviceId;
} }
public String getFingerprint() { public String getFingerprint() {

View File

@@ -4,7 +4,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
import org.signal.libsignal.protocol.IdentityKey; import org.signal.libsignal.protocol.IdentityKey;
import org.whispersystems.signalservice.api.push.ServiceId.ACI; import org.whispersystems.signalservice.api.push.ServiceId;
import org.whispersystems.signalservice.internal.util.JsonUtil; import org.whispersystems.signalservice.internal.util.JsonUtil;
import java.util.List; import java.util.List;
@@ -14,39 +14,39 @@ import javax.annotation.Nullable;
public class IdentityCheckResponse { public class IdentityCheckResponse {
@JsonProperty("elements") @JsonProperty("elements")
private List<AciIdentityPair> aciKeyPairs; private List<ServiceIdentityPair> serviceIdKeyPairs;
public IdentityCheckResponse() {} public IdentityCheckResponse() {}
// Visible for testing // Visible for testing
public IdentityCheckResponse(List<AciIdentityPair> aciKeyPairs) { public IdentityCheckResponse(List<ServiceIdentityPair> serviceIdKeyPairs) {
this.aciKeyPairs = aciKeyPairs; this.serviceIdKeyPairs = serviceIdKeyPairs;
} }
public @Nullable List<AciIdentityPair> getAciKeyPairs() { public @Nullable List<ServiceIdentityPair> getServiceIdKeyPairs() {
return aciKeyPairs; return serviceIdKeyPairs;
} }
public static final class AciIdentityPair { public static final class ServiceIdentityPair {
@JsonProperty @JsonProperty("uuid")
@JsonDeserialize(using = JsonUtil.AciDeserializer.class) @JsonDeserialize(using = JsonUtil.ServiceIdDeserializer.class)
private ACI aci; private ServiceId serviceId;
@JsonProperty @JsonProperty
@JsonDeserialize(using = JsonUtil.IdentityKeyDeserializer.class) @JsonDeserialize(using = JsonUtil.IdentityKeyDeserializer.class)
private IdentityKey identityKey; private IdentityKey identityKey;
public AciIdentityPair() {} public ServiceIdentityPair() {}
// Visible for testing // Visible for testing
public AciIdentityPair(ACI aci, IdentityKey identityKey) { public ServiceIdentityPair(ServiceId serviceId, IdentityKey identityKey) {
this.aci = aci; this.serviceId = serviceId;
this.identityKey = identityKey; this.identityKey = identityKey;
} }
public @Nullable ACI getAci() { public @Nullable ServiceId getServiceId() {
return aci; return serviceId;
} }
public @Nullable IdentityKey getIdentityKey() { public @Nullable IdentityKey getIdentityKey() {