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