Update batch check entities from two optional fields to a single field
This commit is contained in:
parent
320c5eac53
commit
8b65c11e1e
|
@ -394,8 +394,15 @@ public class ProfileController {
|
|||
maybeAccount = accountsManager.getByAccountIdentifier(element.aci());
|
||||
usePhoneNumberIdentity = false;
|
||||
} else {
|
||||
maybeAccount = accountsManager.getByPhoneNumberIdentifier(element.pni());
|
||||
usePhoneNumberIdentity = true;
|
||||
final Optional<Account> maybeAciAccount = accountsManager.getByAccountIdentifier(element.uuid());
|
||||
|
||||
if (maybeAciAccount.isEmpty()) {
|
||||
maybeAccount = accountsManager.getByPhoneNumberIdentifier(element.uuid());
|
||||
usePhoneNumberIdentity = true;
|
||||
} else {
|
||||
maybeAccount = maybeAciAccount;
|
||||
usePhoneNumberIdentity = false;
|
||||
}
|
||||
}
|
||||
|
||||
maybeAccount.ifPresent(account -> {
|
||||
|
@ -414,7 +421,7 @@ public class ProfileController {
|
|||
byte[] fingerprint = Util.truncate(digest, 4);
|
||||
|
||||
if (!Arrays.equals(fingerprint, element.fingerprint())) {
|
||||
responseElements.add(new BatchIdentityCheckResponse.Element(element.aci(), element.pni(), identityKeyBytes));
|
||||
responseElements.add(new BatchIdentityCheckResponse.Element(element.aci(), element.uuid(), identityKeyBytes));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
|
@ -16,22 +16,21 @@ import org.whispersystems.textsecuregcm.util.ExactlySize;
|
|||
public record BatchIdentityCheckRequest(@Valid @NotNull @Size(max = 1000) List<Element> elements) {
|
||||
|
||||
/**
|
||||
* Exactly one of {@code aci} and {@code pni} must be non-null
|
||||
*
|
||||
* @param aci account id
|
||||
* @param pni phone number id
|
||||
* @param uuid account id or phone number id
|
||||
* @param fingerprint most significant 4 bytes of SHA-256 of the 33-byte identity key field (32-byte curve25519 public
|
||||
* key prefixed with 0x05)
|
||||
*/
|
||||
public record Element(@Nullable UUID aci, @Nullable UUID pni, @NotNull @ExactlySize(4) byte[] fingerprint) {
|
||||
public record Element(@Deprecated @Nullable UUID aci,
|
||||
@Nullable UUID uuid,
|
||||
@NotNull @ExactlySize(4) byte[] fingerprint) {
|
||||
|
||||
public Element {
|
||||
if (aci == null && pni == null) {
|
||||
throw new IllegalArgumentException("aci and pni cannot both be null");
|
||||
if (aci == null && uuid == null) {
|
||||
throw new IllegalArgumentException("aci and uuid cannot both be null");
|
||||
}
|
||||
|
||||
if (aci != null && pni != null) {
|
||||
throw new IllegalArgumentException("aci and pni cannot both be non-null");
|
||||
if (aci != null && uuid != null) {
|
||||
throw new IllegalArgumentException("aci and uuid cannot both be non-null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package org.whispersystems.textsecuregcm.entities;
|
||||
|
||||
import com.fasterxml.jackson.annotation.JsonInclude;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import javax.annotation.Nullable;
|
||||
|
@ -14,18 +15,17 @@ import org.whispersystems.textsecuregcm.util.ExactlySize;
|
|||
|
||||
public record BatchIdentityCheckResponse(@Valid List<Element> elements) {
|
||||
|
||||
/**
|
||||
* Exactly one of {@code aci} and {@code pni} must be non-null
|
||||
*/
|
||||
public record Element(@Nullable UUID aci, @Nullable UUID pni, @NotNull @ExactlySize(33) byte[] identityKey) {
|
||||
public record Element(@Deprecated @JsonInclude(JsonInclude.Include.NON_EMPTY) @Nullable UUID aci,
|
||||
@JsonInclude(JsonInclude.Include.NON_EMPTY) @Nullable UUID uuid,
|
||||
@NotNull @ExactlySize(33) byte[] identityKey) {
|
||||
|
||||
public Element {
|
||||
if (aci == null && pni == null) {
|
||||
throw new IllegalArgumentException("aci and pni cannot both be null");
|
||||
if (aci == null && uuid == null) {
|
||||
throw new IllegalArgumentException("aci and uuid cannot both be null");
|
||||
}
|
||||
|
||||
if (aci != null && pni != null) {
|
||||
throw new IllegalArgumentException("aci and pni cannot both be non-null");
|
||||
if (aci != null && uuid != null) {
|
||||
throw new IllegalArgumentException("aci and uuid cannot both be non-null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1237,6 +1237,8 @@ class ProfileControllerTest {
|
|||
convertStringToFingerprint(ACCOUNT_IDENTITY_KEY)),
|
||||
new BatchIdentityCheckRequest.Element(null, AuthHelper.VALID_PNI_TWO,
|
||||
convertStringToFingerprint(ACCOUNT_TWO_PHONE_NUMBER_IDENTITY_KEY)),
|
||||
new BatchIdentityCheckRequest.Element(null, AuthHelper.VALID_UUID_TWO,
|
||||
convertStringToFingerprint(ACCOUNT_TWO_IDENTITY_KEY)),
|
||||
new BatchIdentityCheckRequest.Element(AuthHelper.INVALID_UUID, null,
|
||||
convertStringToFingerprint(ACCOUNT_TWO_PHONE_NUMBER_IDENTITY_KEY))
|
||||
))))) {
|
||||
|
@ -1250,8 +1252,10 @@ class ProfileControllerTest {
|
|||
Condition<BatchIdentityCheckResponse.Element> isAnExpectedUuid = new Condition<>(element -> {
|
||||
if (AuthHelper.VALID_UUID.equals(element.aci())) {
|
||||
return Arrays.equals(Base64.getDecoder().decode(ACCOUNT_IDENTITY_KEY), element.identityKey());
|
||||
} else if (AuthHelper.VALID_PNI_TWO.equals(element.pni())) {
|
||||
} else if (AuthHelper.VALID_PNI_TWO.equals(element.uuid())) {
|
||||
return Arrays.equals(Base64.getDecoder().decode(ACCOUNT_TWO_PHONE_NUMBER_IDENTITY_KEY), element.identityKey());
|
||||
} else if (AuthHelper.VALID_UUID_TWO.equals(element.uuid())) {
|
||||
return Arrays.equals(Base64.getDecoder().decode(ACCOUNT_TWO_IDENTITY_KEY), element.identityKey());
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
|
@ -1262,15 +1266,18 @@ class ProfileControllerTest {
|
|||
new BatchIdentityCheckRequest.Element(AuthHelper.VALID_UUID, null, convertStringToFingerprint("else1234")),
|
||||
new BatchIdentityCheckRequest.Element(null, AuthHelper.VALID_PNI_TWO,
|
||||
convertStringToFingerprint("another1")),
|
||||
new BatchIdentityCheckRequest.Element(null, AuthHelper.VALID_UUID_TWO,
|
||||
convertStringToFingerprint("another2")),
|
||||
new BatchIdentityCheckRequest.Element(AuthHelper.INVALID_UUID, null, convertStringToFingerprint("456"))
|
||||
))))) {
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
BatchIdentityCheckResponse identityCheckResponse = response.readEntity(BatchIdentityCheckResponse.class);
|
||||
assertThat(identityCheckResponse).isNotNull();
|
||||
assertThat(identityCheckResponse.elements()).isNotNull().hasSize(2);
|
||||
assertThat(identityCheckResponse.elements()).isNotNull().hasSize(3);
|
||||
assertThat(identityCheckResponse.elements()).element(0).isNotNull().is(isAnExpectedUuid);
|
||||
assertThat(identityCheckResponse.elements()).element(1).isNotNull().is(isAnExpectedUuid);
|
||||
assertThat(identityCheckResponse.elements()).element(2).isNotNull().is(isAnExpectedUuid);
|
||||
}
|
||||
|
||||
List<BatchIdentityCheckRequest.Element> largeElementList = new ArrayList<>(List.of(
|
||||
|
@ -1294,12 +1301,12 @@ class ProfileControllerTest {
|
|||
}
|
||||
|
||||
@Test
|
||||
void testBatchIdentityCheckDeserialization() {
|
||||
void testBatchIdentityCheckDeserialization() throws Exception {
|
||||
|
||||
Condition<BatchIdentityCheckResponse.Element> isAnExpectedUuid = new Condition<>(element -> {
|
||||
if (AuthHelper.VALID_UUID.equals(element.aci())) {
|
||||
return Arrays.equals(Base64.getDecoder().decode(ACCOUNT_IDENTITY_KEY), element.identityKey());
|
||||
} else if (AuthHelper.VALID_PNI_TWO.equals(element.pni())) {
|
||||
} else if (AuthHelper.VALID_PNI_TWO.equals(element.uuid())) {
|
||||
return Arrays.equals(Base64.getDecoder().decode(ACCOUNT_TWO_PHONE_NUMBER_IDENTITY_KEY), element.identityKey());
|
||||
} else {
|
||||
return false;
|
||||
|
@ -1311,7 +1318,7 @@ class ProfileControllerTest {
|
|||
{
|
||||
"elements": [
|
||||
{ "aci": "%s", "fingerprint": "%s" },
|
||||
{ "pni": "%s", "fingerprint": "%s" },
|
||||
{ "uuid": "%s", "fingerprint": "%s" },
|
||||
{ "aci": "%s", "fingerprint": "%s" }
|
||||
]
|
||||
}
|
||||
|
@ -1322,7 +1329,13 @@ class ProfileControllerTest {
|
|||
.post(Entity.entity(json, "application/json"))) {
|
||||
assertThat(response).isNotNull();
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
BatchIdentityCheckResponse identityCheckResponse = response.readEntity(BatchIdentityCheckResponse.class);
|
||||
String responseJson = response.readEntity(String.class);
|
||||
|
||||
// `null` properties should be omitted from the response
|
||||
assertThat(responseJson).doesNotContain("null");
|
||||
|
||||
BatchIdentityCheckResponse identityCheckResponse = SystemMapper.getMapper()
|
||||
.readValue(responseJson, BatchIdentityCheckResponse.class);
|
||||
assertThat(identityCheckResponse).isNotNull();
|
||||
assertThat(identityCheckResponse.elements()).isNotNull().hasSize(2);
|
||||
assertThat(identityCheckResponse.elements()).element(0).isNotNull().is(isAnExpectedUuid);
|
||||
|
@ -1342,11 +1355,11 @@ class ProfileControllerTest {
|
|||
|
||||
static Stream<Arguments> testBatchIdentityCheckDeserializationBadRequest() {
|
||||
return Stream.of(
|
||||
Arguments.of( // aci and pni cannot both be null
|
||||
Arguments.of( // aci and uuid cannot both be null
|
||||
"""
|
||||
{
|
||||
"elements": [
|
||||
{ "aci": null, "pni": null, "fingerprint": "%s" }
|
||||
{ "aci": null, "uuid": null, "fingerprint": "%s" }
|
||||
]
|
||||
}
|
||||
"""),
|
||||
|
@ -1354,7 +1367,7 @@ class ProfileControllerTest {
|
|||
"""
|
||||
{
|
||||
"elements": [
|
||||
{ "aci": "", "pni": null, "fingerprint": "%s" }
|
||||
{ "aci": "", "uuid": null, "fingerprint": "%s" }
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
@ -1363,15 +1376,15 @@ class ProfileControllerTest {
|
|||
"""
|
||||
{
|
||||
"elements": [
|
||||
{ "aci": null, "pni": " ", "fingerprint": "%s" }
|
||||
{ "aci": null, "uuid": " ", "fingerprint": "%s" }
|
||||
]
|
||||
}
|
||||
"""),
|
||||
Arguments.of( // aci and pni cannot both be non-null
|
||||
Arguments.of( // aci and uuid cannot both be non-null
|
||||
String.format("""
|
||||
{
|
||||
"elements": [
|
||||
{ "aci": "%s", "pni": "%s", "fingerprint": "%s" }
|
||||
{ "aci": "%s", "uuid": "%s", "fingerprint": "%s" }
|
||||
]
|
||||
}
|
||||
""", AuthHelper.VALID_UUID, AuthHelper.VALID_PNI,
|
||||
|
|
Loading…
Reference in New Issue