Remove deprecated identity key and signed pre-key methods
This commit is contained in:
parent
2d1a979eba
commit
708f23a2ee
|
@ -13,6 +13,7 @@ import org.signal.libsignal.protocol.ecc.Curve;
|
|||
import org.signal.libsignal.protocol.ecc.ECPrivateKey;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.SenderCertificate;
|
||||
import org.whispersystems.textsecuregcm.entities.MessageProtos.ServerCertificate;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
|
||||
|
@ -32,11 +33,11 @@ public class CertificateGenerator {
|
|||
|
||||
public byte[] createFor(Account account, Device device, boolean includeE164) throws InvalidKeyException {
|
||||
SenderCertificate.Certificate.Builder builder = SenderCertificate.Certificate.newBuilder()
|
||||
.setSenderDevice(Math.toIntExact(device.getId()))
|
||||
.setExpires(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(expiresDays))
|
||||
.setIdentityKey(ByteString.copyFrom(account.getIdentityKey().serialize()))
|
||||
.setSigner(serverCertificate)
|
||||
.setSenderUuid(account.getUuid().toString());
|
||||
.setSenderDevice(Math.toIntExact(device.getId()))
|
||||
.setExpires(System.currentTimeMillis() + TimeUnit.DAYS.toMillis(expiresDays))
|
||||
.setIdentityKey(ByteString.copyFrom(account.getIdentityKey(IdentityType.ACI).serialize()))
|
||||
.setSigner(serverCertificate)
|
||||
.setSenderUuid(account.getUuid().toString());
|
||||
|
||||
if (includeE164) {
|
||||
builder.setSender(account.getNumber());
|
||||
|
|
|
@ -38,6 +38,7 @@ import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
|||
import org.whispersystems.textsecuregcm.auth.CertificateGenerator;
|
||||
import org.whispersystems.textsecuregcm.entities.DeliveryCertificate;
|
||||
import org.whispersystems.textsecuregcm.entities.GroupCredentials;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
|
||||
@SuppressWarnings("OptionalUsedAsFieldOrParameterType")
|
||||
@Path("/v1/certificate")
|
||||
|
@ -72,7 +73,7 @@ public class CertificateController {
|
|||
@QueryParam("includeE164") @DefaultValue("true") boolean includeE164)
|
||||
throws InvalidKeyException {
|
||||
|
||||
if (auth.getAccount().getIdentityKey() == null) {
|
||||
if (auth.getAccount().getIdentityKey(IdentityType.ACI) == null) {
|
||||
throw new WebApplicationException(Response.Status.BAD_REQUEST);
|
||||
}
|
||||
|
||||
|
|
|
@ -57,6 +57,7 @@ import org.whispersystems.textsecuregcm.entities.DeviceInfoList;
|
|||
import org.whispersystems.textsecuregcm.entities.DeviceResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.LinkDeviceRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKeySignatureValidator;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
|
@ -359,9 +360,10 @@ public class DeviceController {
|
|||
assert deviceActivationRequest.aciPqLastResortPreKey().isPresent();
|
||||
assert deviceActivationRequest.pniPqLastResortPreKey().isPresent();
|
||||
|
||||
final boolean allKeysValid = PreKeySignatureValidator.validatePreKeySignatures(account.getIdentityKey(),
|
||||
final boolean allKeysValid = PreKeySignatureValidator.validatePreKeySignatures(account.getIdentityKey(
|
||||
IdentityType.ACI),
|
||||
List.of(deviceActivationRequest.aciSignedPreKey().get(), deviceActivationRequest.aciPqLastResortPreKey().get()))
|
||||
&& PreKeySignatureValidator.validatePreKeySignatures(account.getPhoneNumberIdentityKey(),
|
||||
&& PreKeySignatureValidator.validatePreKeySignatures(account.getIdentityKey(IdentityType.PNI),
|
||||
List.of(deviceActivationRequest.pniSignedPreKey().get(), deviceActivationRequest.pniPqLastResortPreKey().get()));
|
||||
|
||||
if (!allKeysValid) {
|
||||
|
|
|
@ -56,6 +56,7 @@ import org.whispersystems.textsecuregcm.entities.PreKeyResponse;
|
|||
import org.whispersystems.textsecuregcm.entities.PreKeyResponseItem;
|
||||
import org.whispersystems.textsecuregcm.entities.PreKeyState;
|
||||
import org.whispersystems.textsecuregcm.experiment.Experiment;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||
|
@ -137,11 +138,13 @@ public class KeysController {
|
|||
final boolean usePhoneNumberIdentity = usePhoneNumberIdentity(identityType);
|
||||
|
||||
if (preKeys.getSignedPreKey() != null &&
|
||||
!preKeys.getSignedPreKey().equals(usePhoneNumberIdentity ? device.getPhoneNumberIdentitySignedPreKey() : device.getSignedPreKey())) {
|
||||
!preKeys.getSignedPreKey().equals(usePhoneNumberIdentity ? device.getSignedPreKey(IdentityType.PNI)
|
||||
: device.getSignedPreKey(IdentityType.ACI))) {
|
||||
updateAccount = true;
|
||||
}
|
||||
|
||||
final IdentityKey oldIdentityKey = usePhoneNumberIdentity ? account.getPhoneNumberIdentityKey() : account.getIdentityKey();
|
||||
final IdentityKey oldIdentityKey =
|
||||
usePhoneNumberIdentity ? account.getIdentityKey(IdentityType.PNI) : account.getIdentityKey(IdentityType.ACI);
|
||||
if (!Objects.equals(preKeys.getIdentityKey(), oldIdentityKey)) {
|
||||
updateAccount = true;
|
||||
|
||||
|
@ -242,10 +245,7 @@ public class KeysController {
|
|||
List<PreKeyResponseItem> responseItems = new ArrayList<>(devices.size());
|
||||
|
||||
for (Device device : devices) {
|
||||
ECSignedPreKey signedECPreKey = switch (targetIdentifier.identityType()) {
|
||||
case ACI -> device.getSignedPreKey();
|
||||
case PNI -> device.getPhoneNumberIdentitySignedPreKey();
|
||||
};
|
||||
ECSignedPreKey signedECPreKey = device.getSignedPreKey(targetIdentifier.identityType());
|
||||
|
||||
ECPreKey unsignedECPreKey = keys.takeEC(targetIdentifier.uuid(), device.getId()).join().orElse(null);
|
||||
KEMSignedPreKey pqPreKey = returnPqKey ? keys.takePQ(targetIdentifier.uuid(), device.getId()).join().orElse(null) : null;
|
||||
|
@ -263,10 +263,7 @@ public class KeysController {
|
|||
}
|
||||
}
|
||||
|
||||
final IdentityKey identityKey = switch (targetIdentifier.identityType()) {
|
||||
case ACI -> target.getIdentityKey();
|
||||
case PNI -> target.getPhoneNumberIdentityKey();
|
||||
};
|
||||
final IdentityKey identityKey = target.getIdentityKey(targetIdentifier.identityType());
|
||||
|
||||
if (responseItems.isEmpty()) {
|
||||
throw new WebApplicationException(Response.Status.NOT_FOUND);
|
||||
|
|
|
@ -87,6 +87,7 @@ import org.whispersystems.textsecuregcm.entities.UserCapabilities;
|
|||
import org.whispersystems.textsecuregcm.entities.VersionedProfileResponse;
|
||||
import org.whispersystems.textsecuregcm.grpc.ProfileHelper;
|
||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.identity.PniServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
|
@ -430,7 +431,7 @@ public class ProfileController {
|
|||
final boolean isSelf,
|
||||
final ContainerRequestContext containerRequestContext) {
|
||||
|
||||
return new BaseProfileResponse(account.getIdentityKey(),
|
||||
return new BaseProfileResponse(account.getIdentityKey(IdentityType.ACI),
|
||||
UnidentifiedAccessChecksum.generateFor(account.getUnidentifiedAccessKey()),
|
||||
account.isUnrestrictedUnidentifiedAccess(),
|
||||
UserCapabilities.createForAccount(account),
|
||||
|
@ -442,7 +443,7 @@ public class ProfileController {
|
|||
}
|
||||
|
||||
private BaseProfileResponse buildBaseProfileResponseForPhoneNumberIdentity(final Account account) {
|
||||
return new BaseProfileResponse(account.getPhoneNumberIdentityKey(),
|
||||
return new BaseProfileResponse(account.getIdentityKey(IdentityType.PNI),
|
||||
null,
|
||||
false,
|
||||
UserCapabilities.createForAccount(account),
|
||||
|
|
|
@ -317,24 +317,6 @@ public class Account {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link #getIdentityKey(IdentityType)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public IdentityKey getIdentityKey() {
|
||||
requireNotStale();
|
||||
|
||||
return identityKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link #getIdentityKey(IdentityType)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public IdentityKey getPhoneNumberIdentityKey() {
|
||||
return phoneNumberIdentityKey;
|
||||
}
|
||||
|
||||
public void setPhoneNumberIdentityKey(final IdentityKey phoneNumberIdentityKey) {
|
||||
this.phoneNumberIdentityKey = phoneNumberIdentityKey;
|
||||
}
|
||||
|
|
|
@ -52,6 +52,7 @@ import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
|||
import org.whispersystems.textsecuregcm.entities.ECSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.entities.KEMSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.identity.ServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
||||
|
@ -397,8 +398,8 @@ public class AccountsManager {
|
|||
throw new IllegalArgumentException("PNI identity key, signed pre-keys, and registration IDs must be all null or all non-null");
|
||||
}
|
||||
|
||||
boolean changed = !Objects.equals(pniIdentityKey, account.getPhoneNumberIdentityKey());
|
||||
|
||||
boolean changed = !Objects.equals(pniIdentityKey, account.getIdentityKey(IdentityType.PNI));
|
||||
|
||||
for (Device device : account.getDevices()) {
|
||||
if (!device.isEnabled()) {
|
||||
continue;
|
||||
|
@ -406,11 +407,11 @@ public class AccountsManager {
|
|||
ECSignedPreKey signedPreKey = pniSignedPreKeys.get(device.getId());
|
||||
int registrationId = pniRegistrationIds.get(device.getId());
|
||||
changed = changed ||
|
||||
!signedPreKey.equals(device.getPhoneNumberIdentitySignedPreKey()) ||
|
||||
!signedPreKey.equals(device.getSignedPreKey(IdentityType.PNI)) ||
|
||||
device.getRegistrationId() != registrationId;
|
||||
device.setPhoneNumberIdentitySignedPreKey(signedPreKey);
|
||||
device.setPhoneNumberIdentityRegistrationId(registrationId);
|
||||
}
|
||||
}
|
||||
|
||||
account.setPhoneNumberIdentityKey(pniIdentityKey);
|
||||
|
||||
|
|
|
@ -238,26 +238,10 @@ public class Device {
|
|||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link #getSignedPreKey(IdentityType)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public ECSignedPreKey getSignedPreKey() {
|
||||
return signedPreKey;
|
||||
}
|
||||
|
||||
public void setSignedPreKey(ECSignedPreKey signedPreKey) {
|
||||
this.signedPreKey = signedPreKey;
|
||||
}
|
||||
|
||||
/**
|
||||
* @deprecated Please use {@link #getSignedPreKey(IdentityType)} instead.
|
||||
*/
|
||||
@Deprecated
|
||||
public ECSignedPreKey getPhoneNumberIdentitySignedPreKey() {
|
||||
return phoneNumberIdentitySignedPreKey;
|
||||
}
|
||||
|
||||
public void setPhoneNumberIdentitySignedPreKey(final ECSignedPreKey phoneNumberIdentitySignedPreKey) {
|
||||
this.phoneNumberIdentitySignedPreKey = phoneNumberIdentitySignedPreKey;
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import java.util.ArrayList;
|
|||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import org.whispersystems.textsecuregcm.entities.ECSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysManager;
|
||||
|
@ -42,12 +43,13 @@ public class MigrateSignedECPreKeysCommand extends AbstractSinglePassCrawlAccoun
|
|||
.flatMap(device -> {
|
||||
final List<Tuple3<UUID, Long, ECSignedPreKey>> keys = new ArrayList<>(2);
|
||||
|
||||
if (device.getSignedPreKey() != null) {
|
||||
keys.add(Tuples.of(account.getUuid(), device.getId(), device.getSignedPreKey()));
|
||||
if (device.getSignedPreKey(IdentityType.ACI) != null) {
|
||||
keys.add(Tuples.of(account.getUuid(), device.getId(), device.getSignedPreKey(IdentityType.ACI)));
|
||||
}
|
||||
|
||||
if (device.getPhoneNumberIdentitySignedPreKey() != null) {
|
||||
keys.add(Tuples.of(account.getPhoneNumberIdentifier(), device.getId(), device.getPhoneNumberIdentitySignedPreKey()));
|
||||
if (device.getSignedPreKey(IdentityType.PNI) != null) {
|
||||
keys.add(Tuples.of(account.getPhoneNumberIdentifier(), device.getId(),
|
||||
device.getSignedPreKey(IdentityType.PNI)));
|
||||
}
|
||||
|
||||
return Flux.fromIterable(keys);
|
||||
|
|
|
@ -17,6 +17,7 @@ import org.junit.jupiter.api.Test;
|
|||
import org.signal.libsignal.protocol.IdentityKey;
|
||||
import org.signal.libsignal.protocol.ecc.Curve;
|
||||
import org.signal.libsignal.protocol.ecc.ECPublicKey;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
|
||||
|
@ -32,7 +33,7 @@ class CertificateGeneratorTest {
|
|||
final Device device = mock(Device.class);
|
||||
final CertificateGenerator certificateGenerator = new CertificateGenerator(Base64.getDecoder().decode(SIGNING_CERTIFICATE), Curve.decodePrivatePoint(Base64.getDecoder().decode(SIGNING_KEY)), 1);
|
||||
|
||||
when(account.getIdentityKey()).thenReturn(IDENTITY_KEY);
|
||||
when(account.getIdentityKey(IdentityType.ACI)).thenReturn(IDENTITY_KEY);
|
||||
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
||||
when(account.getNumber()).thenReturn("+18005551234");
|
||||
when(device.getId()).thenReturn(4L);
|
||||
|
|
|
@ -75,6 +75,7 @@ import org.whispersystems.textsecuregcm.entities.AccountIdentityResponse;
|
|||
import org.whispersystems.textsecuregcm.entities.ChangeNumberRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.PhoneNumberDiscoverabilityRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.RegistrationServiceSession;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.mappers.ImpossiblePhoneNumberExceptionMapper;
|
||||
|
@ -151,7 +152,7 @@ class AccountControllerV2Test {
|
|||
final Account updatedAccount = mock(Account.class);
|
||||
when(updatedAccount.getUuid()).thenReturn(uuid);
|
||||
when(updatedAccount.getNumber()).thenReturn(number);
|
||||
when(updatedAccount.getPhoneNumberIdentityKey()).thenReturn(pniIdentityKey);
|
||||
when(updatedAccount.getIdentityKey(IdentityType.PNI)).thenReturn(pniIdentityKey);
|
||||
if (number.equals(account.getNumber())) {
|
||||
when(updatedAccount.getPhoneNumberIdentifier()).thenReturn(AuthHelper.VALID_PNI);
|
||||
} else {
|
||||
|
@ -205,7 +206,7 @@ class AccountControllerV2Test {
|
|||
.header(HttpHeaders.AUTHORIZATION,
|
||||
AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.put(Entity.entity(
|
||||
new ChangeNumberRequest(encodeSessionId("session"), null, AuthHelper.VALID_NUMBER, null,
|
||||
new ChangeNumberRequest(encodeSessionId("session"), null, AuthHelper.VALID_NUMBER, null,
|
||||
new IdentityKey(Curve.generateKeyPair().getPublicKey()),
|
||||
Collections.emptyList(),
|
||||
Collections.emptyMap(), null, Collections.emptyMap()),
|
||||
|
@ -476,7 +477,7 @@ class AccountControllerV2Test {
|
|||
final Account updatedAccount = mock(Account.class);
|
||||
when(updatedAccount.getUuid()).thenReturn(uuid);
|
||||
when(updatedAccount.getNumber()).thenReturn(number);
|
||||
when(updatedAccount.getPhoneNumberIdentityKey()).thenReturn(pniIdentityKey);
|
||||
when(updatedAccount.getIdentityKey(IdentityType.PNI)).thenReturn(pniIdentityKey);
|
||||
when(updatedAccount.getPhoneNumberIdentifier()).thenReturn(pni);
|
||||
when(updatedAccount.getDevices()).thenReturn(devices);
|
||||
|
||||
|
@ -487,12 +488,12 @@ class AccountControllerV2Test {
|
|||
|
||||
return updatedAccount;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
void pniKeyDistributionSuccess() throws Exception {
|
||||
when(AuthHelper.VALID_ACCOUNT.isPniSupported()).thenReturn(true);
|
||||
|
||||
|
||||
final AccountIdentityResponse accountIdentityResponse =
|
||||
resources.getJerseyTest()
|
||||
.target("/v2/accounts/phone_number_identity_key_distribution")
|
||||
|
@ -506,8 +507,8 @@ class AccountControllerV2Test {
|
|||
assertEquals(AuthHelper.VALID_UUID, accountIdentityResponse.uuid());
|
||||
assertEquals(AuthHelper.VALID_NUMBER, accountIdentityResponse.number());
|
||||
assertEquals(AuthHelper.VALID_PNI, accountIdentityResponse.pni());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Test
|
||||
void unprocessableRequestJson() {
|
||||
final Invocation.Builder request = resources.getJerseyTest()
|
||||
|
@ -552,7 +553,7 @@ class AccountControllerV2Test {
|
|||
assertEquals(422, response.getStatus());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Valid request JSON for a {@link org.whispersystems.textsecuregcm.entities.PhoneNumberIdentityKeyDistributionRequest}
|
||||
*/
|
||||
|
@ -596,7 +597,7 @@ class AccountControllerV2Test {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
@Nested
|
||||
class PhoneNumberDiscoverability {
|
||||
|
||||
|
|
|
@ -4,12 +4,40 @@
|
|||
*/
|
||||
package org.whispersystems.textsecuregcm.controllers;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.anyString;
|
||||
import static org.mockito.Mockito.clearInvocations;
|
||||
import static org.mockito.Mockito.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.reset;
|
||||
import static org.mockito.Mockito.times;
|
||||
import static org.mockito.Mockito.verify;
|
||||
import static org.mockito.Mockito.verifyNoMoreInteractions;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.net.HttpHeaders;
|
||||
import io.dropwizard.auth.PolymorphicAuthValueFactoryProvider;
|
||||
import io.dropwizard.testing.junit5.DropwizardExtensionsSupport;
|
||||
import io.dropwizard.testing.junit5.ResourceExtension;
|
||||
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Stream;
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory;
|
||||
import org.junit.jupiter.api.AfterEach;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
|
@ -26,12 +54,22 @@ import org.signal.libsignal.protocol.ecc.ECKeyPair;
|
|||
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.WebsocketRefreshApplicationEventListener;
|
||||
import org.whispersystems.textsecuregcm.entities.*;
|
||||
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.ApnRegistrationId;
|
||||
import org.whispersystems.textsecuregcm.entities.DeviceActivationRequest;
|
||||
import org.whispersystems.textsecuregcm.entities.DeviceResponse;
|
||||
import org.whispersystems.textsecuregcm.entities.ECSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.entities.GcmRegistrationId;
|
||||
import org.whispersystems.textsecuregcm.entities.KEMSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.entities.LinkDeviceRequest;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.mappers.DeviceLimitExceededExceptionMapper;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.storage.*;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.Device.DeviceCapabilities;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysManager;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||
|
@ -42,23 +80,6 @@ import org.whispersystems.textsecuregcm.tests.util.RedisClusterHelper;
|
|||
import org.whispersystems.textsecuregcm.util.TestClock;
|
||||
import org.whispersystems.textsecuregcm.util.VerificationCode;
|
||||
|
||||
import javax.ws.rs.client.Entity;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.SecureRandom;
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
import static org.junit.jupiter.api.Assertions.assertNull;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.ArgumentMatchers.anyLong;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
@ExtendWith(DropwizardExtensionsSupport.class)
|
||||
class DeviceControllerTest {
|
||||
|
||||
|
@ -272,8 +293,8 @@ class DeviceControllerTest {
|
|||
aciPqLastResortPreKey = Optional.of(KeysHelper.signedKEMPreKey(3, aciIdentityKeyPair));
|
||||
pniPqLastResortPreKey = Optional.of(KeysHelper.signedKEMPreKey(4, pniIdentityKeyPair));
|
||||
|
||||
when(account.getIdentityKey()).thenReturn(new IdentityKey(aciIdentityKeyPair.getPublicKey()));
|
||||
when(account.getPhoneNumberIdentityKey()).thenReturn(new IdentityKey(pniIdentityKeyPair.getPublicKey()));
|
||||
when(account.getIdentityKey(IdentityType.ACI)).thenReturn(new IdentityKey(aciIdentityKeyPair.getPublicKey()));
|
||||
when(account.getIdentityKey(IdentityType.PNI)).thenReturn(new IdentityKey(pniIdentityKeyPair.getPublicKey()));
|
||||
|
||||
when(keysManager.storeEcSignedPreKeys(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(keysManager.storePqLastResort(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
@ -295,8 +316,8 @@ class DeviceControllerTest {
|
|||
|
||||
final Device device = deviceCaptor.getValue();
|
||||
|
||||
assertEquals(aciSignedPreKey.get(), device.getSignedPreKey());
|
||||
assertEquals(pniSignedPreKey.get(), device.getPhoneNumberIdentitySignedPreKey());
|
||||
assertEquals(aciSignedPreKey.get(), device.getSignedPreKey(IdentityType.ACI));
|
||||
assertEquals(pniSignedPreKey.get(), device.getSignedPreKey(IdentityType.PNI));
|
||||
assertEquals(fetchesMessages, device.getFetchesMessages());
|
||||
|
||||
expectedApnsToken.ifPresentOrElse(expectedToken -> assertEquals(expectedToken, device.getApnId()),
|
||||
|
@ -352,8 +373,8 @@ class DeviceControllerTest {
|
|||
aciPqLastResortPreKey = Optional.of(KeysHelper.signedKEMPreKey(3, aciIdentityKeyPair));
|
||||
pniPqLastResortPreKey = Optional.of(KeysHelper.signedKEMPreKey(4, pniIdentityKeyPair));
|
||||
|
||||
when(account.getIdentityKey()).thenReturn(new IdentityKey(aciIdentityKeyPair.getPublicKey()));
|
||||
when(account.getPhoneNumberIdentityKey()).thenReturn(new IdentityKey(pniIdentityKeyPair.getPublicKey()));
|
||||
when(account.getIdentityKey(IdentityType.ACI)).thenReturn(new IdentityKey(aciIdentityKeyPair.getPublicKey()));
|
||||
when(account.getIdentityKey(IdentityType.PNI)).thenReturn(new IdentityKey(pniIdentityKeyPair.getPublicKey()));
|
||||
|
||||
when(keysManager.storeEcSignedPreKeys(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(keysManager.storePqLastResort(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
@ -405,8 +426,8 @@ class DeviceControllerTest {
|
|||
aciPqLastResortPreKey = Optional.of(KeysHelper.signedKEMPreKey(3, aciIdentityKeyPair));
|
||||
pniPqLastResortPreKey = Optional.of(KeysHelper.signedKEMPreKey(4, pniIdentityKeyPair));
|
||||
|
||||
when(account.getIdentityKey()).thenReturn(new IdentityKey(aciIdentityKeyPair.getPublicKey()));
|
||||
when(account.getPhoneNumberIdentityKey()).thenReturn(new IdentityKey(pniIdentityKeyPair.getPublicKey()));
|
||||
when(account.getIdentityKey(IdentityType.ACI)).thenReturn(new IdentityKey(aciIdentityKeyPair.getPublicKey()));
|
||||
when(account.getIdentityKey(IdentityType.PNI)).thenReturn(new IdentityKey(pniIdentityKeyPair.getPublicKey()));
|
||||
|
||||
final LinkDeviceRequest request = new LinkDeviceRequest(deviceCode.verificationCode(),
|
||||
new AccountAttributes(fetchesMessages, 1234, null, null, true, null),
|
||||
|
@ -453,8 +474,8 @@ class DeviceControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(VerificationCode.class);
|
||||
|
||||
when(account.getIdentityKey()).thenReturn(aciIdentityKey);
|
||||
when(account.getPhoneNumberIdentityKey()).thenReturn(pniIdentityKey);
|
||||
when(account.getIdentityKey(IdentityType.ACI)).thenReturn(aciIdentityKey);
|
||||
when(account.getIdentityKey(IdentityType.PNI)).thenReturn(pniIdentityKey);
|
||||
|
||||
final LinkDeviceRequest request = new LinkDeviceRequest(deviceCode.verificationCode(),
|
||||
new AccountAttributes(true, 1234, null, null, true, null),
|
||||
|
@ -511,8 +532,8 @@ class DeviceControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(VerificationCode.class);
|
||||
|
||||
when(account.getIdentityKey()).thenReturn(aciIdentityKey);
|
||||
when(account.getPhoneNumberIdentityKey()).thenReturn(pniIdentityKey);
|
||||
when(account.getIdentityKey(IdentityType.ACI)).thenReturn(aciIdentityKey);
|
||||
when(account.getIdentityKey(IdentityType.PNI)).thenReturn(pniIdentityKey);
|
||||
|
||||
final LinkDeviceRequest request = new LinkDeviceRequest(deviceCode.verificationCode(),
|
||||
new AccountAttributes(true, 1234, null, null, true, null),
|
||||
|
|
|
@ -58,6 +58,7 @@ import org.whispersystems.textsecuregcm.entities.PreKeyResponse;
|
|||
import org.whispersystems.textsecuregcm.entities.PreKeyState;
|
||||
import org.whispersystems.textsecuregcm.entities.SignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.identity.PniServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
|
@ -89,10 +90,10 @@ class KeysControllerTest {
|
|||
|
||||
private final ECKeyPair IDENTITY_KEY_PAIR = Curve.generateKeyPair();
|
||||
private final IdentityKey IDENTITY_KEY = new IdentityKey(IDENTITY_KEY_PAIR.getPublicKey());
|
||||
|
||||
|
||||
private final ECKeyPair PNI_IDENTITY_KEY_PAIR = Curve.generateKeyPair();
|
||||
private final IdentityKey PNI_IDENTITY_KEY = new IdentityKey(PNI_IDENTITY_KEY_PAIR.getPublicKey());
|
||||
|
||||
|
||||
private final ECPreKey SAMPLE_KEY = KeysHelper.ecPreKey(1234);
|
||||
private final ECPreKey SAMPLE_KEY2 = KeysHelper.ecPreKey(5667);
|
||||
private final ECPreKey SAMPLE_KEY3 = KeysHelper.ecPreKey(334);
|
||||
|
@ -186,14 +187,14 @@ class KeysControllerTest {
|
|||
when(sampleDevice2.isEnabled()).thenReturn(true);
|
||||
when(sampleDevice3.isEnabled()).thenReturn(false);
|
||||
when(sampleDevice4.isEnabled()).thenReturn(true);
|
||||
when(sampleDevice.getSignedPreKey()).thenReturn(SAMPLE_SIGNED_KEY);
|
||||
when(sampleDevice2.getSignedPreKey()).thenReturn(SAMPLE_SIGNED_KEY2);
|
||||
when(sampleDevice3.getSignedPreKey()).thenReturn(SAMPLE_SIGNED_KEY3);
|
||||
when(sampleDevice4.getSignedPreKey()).thenReturn(null);
|
||||
when(sampleDevice.getPhoneNumberIdentitySignedPreKey()).thenReturn(SAMPLE_SIGNED_PNI_KEY);
|
||||
when(sampleDevice2.getPhoneNumberIdentitySignedPreKey()).thenReturn(SAMPLE_SIGNED_PNI_KEY2);
|
||||
when(sampleDevice3.getPhoneNumberIdentitySignedPreKey()).thenReturn(SAMPLE_SIGNED_PNI_KEY3);
|
||||
when(sampleDevice4.getPhoneNumberIdentitySignedPreKey()).thenReturn(null);
|
||||
when(sampleDevice.getSignedPreKey(IdentityType.ACI)).thenReturn(SAMPLE_SIGNED_KEY);
|
||||
when(sampleDevice2.getSignedPreKey(IdentityType.ACI)).thenReturn(SAMPLE_SIGNED_KEY2);
|
||||
when(sampleDevice3.getSignedPreKey(IdentityType.ACI)).thenReturn(SAMPLE_SIGNED_KEY3);
|
||||
when(sampleDevice4.getSignedPreKey(IdentityType.ACI)).thenReturn(null);
|
||||
when(sampleDevice.getSignedPreKey(IdentityType.PNI)).thenReturn(SAMPLE_SIGNED_PNI_KEY);
|
||||
when(sampleDevice2.getSignedPreKey(IdentityType.PNI)).thenReturn(SAMPLE_SIGNED_PNI_KEY2);
|
||||
when(sampleDevice3.getSignedPreKey(IdentityType.PNI)).thenReturn(SAMPLE_SIGNED_PNI_KEY3);
|
||||
when(sampleDevice4.getSignedPreKey(IdentityType.PNI)).thenReturn(null);
|
||||
when(sampleDevice.getId()).thenReturn(1L);
|
||||
when(sampleDevice2.getId()).thenReturn(2L);
|
||||
when(sampleDevice3.getId()).thenReturn(3L);
|
||||
|
@ -208,8 +209,8 @@ class KeysControllerTest {
|
|||
when(existsAccount.getDevice(22L)).thenReturn(Optional.empty());
|
||||
when(existsAccount.getDevices()).thenReturn(allDevices);
|
||||
when(existsAccount.isEnabled()).thenReturn(true);
|
||||
when(existsAccount.getIdentityKey()).thenReturn(IDENTITY_KEY);
|
||||
when(existsAccount.getPhoneNumberIdentityKey()).thenReturn(PNI_IDENTITY_KEY);
|
||||
when(existsAccount.getIdentityKey(IdentityType.ACI)).thenReturn(IDENTITY_KEY);
|
||||
when(existsAccount.getIdentityKey(IdentityType.PNI)).thenReturn(PNI_IDENTITY_KEY);
|
||||
when(existsAccount.getNumber()).thenReturn(EXISTS_NUMBER);
|
||||
when(existsAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of("1337".getBytes()));
|
||||
|
||||
|
@ -232,9 +233,9 @@ class KeysControllerTest {
|
|||
when(KEYS.getEcCount(AuthHelper.VALID_UUID, 1)).thenReturn(CompletableFuture.completedFuture(5));
|
||||
when(KEYS.getPqCount(AuthHelper.VALID_UUID, 1)).thenReturn(CompletableFuture.completedFuture(5));
|
||||
|
||||
when(AuthHelper.VALID_DEVICE.getSignedPreKey()).thenReturn(VALID_DEVICE_SIGNED_KEY);
|
||||
when(AuthHelper.VALID_DEVICE.getPhoneNumberIdentitySignedPreKey()).thenReturn(VALID_DEVICE_PNI_SIGNED_KEY);
|
||||
when(AuthHelper.VALID_ACCOUNT.getIdentityKey()).thenReturn(null);
|
||||
when(AuthHelper.VALID_DEVICE.getSignedPreKey(IdentityType.ACI)).thenReturn(VALID_DEVICE_SIGNED_KEY);
|
||||
when(AuthHelper.VALID_DEVICE.getSignedPreKey(IdentityType.PNI)).thenReturn(VALID_DEVICE_PNI_SIGNED_KEY);
|
||||
when(AuthHelper.VALID_ACCOUNT.getIdentityKey(IdentityType.ACI)).thenReturn(null);
|
||||
}
|
||||
|
||||
@AfterEach
|
||||
|
@ -322,12 +323,13 @@ class KeysControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.ACI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY, result.getDevice(1).getPreKey());
|
||||
assertThat(result.getDevice(1).getPqPreKey()).isNull();
|
||||
assertThat(result.getDevice(1).getRegistrationId()).isEqualTo(SAMPLE_REGISTRATION_ID);
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.ACI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_UUID, 1);
|
||||
verify(KEYS).getEcSignedPreKey(EXISTS_UUID, 1);
|
||||
|
@ -345,12 +347,13 @@ class KeysControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.ACI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY, result.getDevice(1).getPreKey());
|
||||
assertThat(result.getDevice(1).getPqPreKey()).isNull();
|
||||
assertThat(result.getDevice(1).getRegistrationId()).isEqualTo(SAMPLE_REGISTRATION_ID);
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.ACI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_UUID, 1);
|
||||
verify(KEYS).takePQ(EXISTS_UUID, 1);
|
||||
|
@ -367,12 +370,13 @@ class KeysControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.ACI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY, result.getDevice(1).getPreKey());
|
||||
assertEquals(SAMPLE_PQ_KEY, result.getDevice(1).getPqPreKey());
|
||||
assertThat(result.getDevice(1).getRegistrationId()).isEqualTo(SAMPLE_REGISTRATION_ID);
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.ACI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_UUID, 1);
|
||||
verify(KEYS).takePQ(EXISTS_UUID, 1);
|
||||
|
@ -388,12 +392,13 @@ class KeysControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getPhoneNumberIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.PNI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY_PNI, result.getDevice(1).getPreKey());
|
||||
assertThat(result.getDevice(1).getPqPreKey()).isNull();
|
||||
assertThat(result.getDevice(1).getRegistrationId()).isEqualTo(SAMPLE_PNI_REGISTRATION_ID);
|
||||
assertEquals(existsAccount.getDevice(1).get().getPhoneNumberIdentitySignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.PNI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_PNI, 1);
|
||||
verify(KEYS).getEcSignedPreKey(EXISTS_PNI, 1);
|
||||
|
@ -409,12 +414,13 @@ class KeysControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getPhoneNumberIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.PNI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY_PNI, result.getDevice(1).getPreKey());
|
||||
assertThat(result.getDevice(1).getPqPreKey()).isEqualTo(SAMPLE_PQ_KEY_PNI);
|
||||
assertThat(result.getDevice(1).getRegistrationId()).isEqualTo(SAMPLE_PNI_REGISTRATION_ID);
|
||||
assertEquals(existsAccount.getDevice(1).get().getPhoneNumberIdentitySignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.PNI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_PNI, 1);
|
||||
verify(KEYS).takePQ(EXISTS_PNI, 1);
|
||||
|
@ -432,12 +438,13 @@ class KeysControllerTest {
|
|||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getPhoneNumberIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.PNI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY_PNI, result.getDevice(1).getPreKey());
|
||||
assertThat(result.getDevice(1).getPqPreKey()).isNull();
|
||||
assertThat(result.getDevice(1).getRegistrationId()).isEqualTo(SAMPLE_REGISTRATION_ID);
|
||||
assertEquals(existsAccount.getDevice(1).get().getPhoneNumberIdentitySignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.PNI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_PNI, 1);
|
||||
verify(KEYS).getEcSignedPreKey(EXISTS_PNI, 1);
|
||||
|
@ -468,11 +475,12 @@ class KeysControllerTest {
|
|||
.header(OptionalAccess.UNIDENTIFIED, AuthHelper.getUnidentifiedAccessHeader("1337".getBytes()))
|
||||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(result.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.ACI));
|
||||
assertThat(result.getDevicesCount()).isEqualTo(1);
|
||||
assertEquals(SAMPLE_KEY, result.getDevice(1).getPreKey());
|
||||
assertEquals(SAMPLE_PQ_KEY, result.getDevice(1).getPqPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(), result.getDevice(1).getSignedPreKey());
|
||||
assertEquals(existsAccount.getDevice(1).get().getSignedPreKey(IdentityType.ACI),
|
||||
result.getDevice(1).getSignedPreKey());
|
||||
|
||||
verify(KEYS).takeEC(EXISTS_UUID, 1);
|
||||
verify(KEYS).takePQ(EXISTS_UUID, 1);
|
||||
|
@ -534,7 +542,7 @@ class KeysControllerTest {
|
|||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(results.getDevicesCount()).isEqualTo(3);
|
||||
assertThat(results.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(results.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.ACI));
|
||||
|
||||
ECSignedPreKey signedPreKey = results.getDevice(1).getSignedPreKey();
|
||||
ECPreKey preKey = results.getDevice(1).getPreKey();
|
||||
|
@ -595,7 +603,7 @@ class KeysControllerTest {
|
|||
.get(PreKeyResponse.class);
|
||||
|
||||
assertThat(results.getDevicesCount()).isEqualTo(3);
|
||||
assertThat(results.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey());
|
||||
assertThat(results.getIdentityKey()).isEqualTo(existsAccount.getIdentityKey(IdentityType.ACI));
|
||||
|
||||
ECSignedPreKey signedPreKey = results.getDevice(1).getSignedPreKey();
|
||||
ECPreKey preKey = results.getDevice(1).getPreKey();
|
||||
|
|
|
@ -193,9 +193,7 @@ class ProfileControllerTest {
|
|||
|
||||
profileAccount = mock(Account.class);
|
||||
|
||||
when(profileAccount.getIdentityKey()).thenReturn(ACCOUNT_TWO_IDENTITY_KEY);
|
||||
when(profileAccount.getIdentityKey(IdentityType.ACI)).thenReturn(ACCOUNT_TWO_IDENTITY_KEY);
|
||||
when(profileAccount.getPhoneNumberIdentityKey()).thenReturn(ACCOUNT_TWO_PHONE_NUMBER_IDENTITY_KEY);
|
||||
when(profileAccount.getIdentityKey(IdentityType.PNI)).thenReturn(ACCOUNT_TWO_PHONE_NUMBER_IDENTITY_KEY);
|
||||
when(profileAccount.getUuid()).thenReturn(AuthHelper.VALID_UUID_TWO);
|
||||
when(profileAccount.getPhoneNumberIdentifier()).thenReturn(AuthHelper.VALID_PNI_TWO);
|
||||
|
@ -207,9 +205,7 @@ class ProfileControllerTest {
|
|||
Account capabilitiesAccount = mock(Account.class);
|
||||
|
||||
when(capabilitiesAccount.getUuid()).thenReturn(AuthHelper.VALID_UUID);
|
||||
when(capabilitiesAccount.getIdentityKey()).thenReturn(ACCOUNT_IDENTITY_KEY);
|
||||
when(capabilitiesAccount.getIdentityKey(IdentityType.ACI)).thenReturn(ACCOUNT_IDENTITY_KEY);
|
||||
when(capabilitiesAccount.getPhoneNumberIdentityKey()).thenReturn(ACCOUNT_PHONE_NUMBER_IDENTITY_KEY);
|
||||
when(capabilitiesAccount.getIdentityKey(IdentityType.PNI)).thenReturn(ACCOUNT_PHONE_NUMBER_IDENTITY_KEY);
|
||||
when(capabilitiesAccount.isEnabled()).thenReturn(true);
|
||||
|
||||
|
|
|
@ -31,6 +31,7 @@ import org.whispersystems.textsecuregcm.controllers.MismatchedDevicesException;
|
|||
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.ECSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.redis.RedisClusterExtension;
|
||||
import org.whispersystems.textsecuregcm.securebackup.SecureBackupClient;
|
||||
|
@ -180,12 +181,12 @@ class AccountsManagerChangeNumberIntegrationTest {
|
|||
assertEquals(Optional.empty(), deletedAccounts.findUuid(originalNumber));
|
||||
assertEquals(Optional.empty(), deletedAccounts.findUuid(secondNumber));
|
||||
|
||||
assertEquals(pniIdentityKey, updatedAccount.getPhoneNumberIdentityKey());
|
||||
assertEquals(pniIdentityKey, updatedAccount.getIdentityKey(IdentityType.PNI));
|
||||
|
||||
assertEquals(OptionalInt.of(rotatedPniRegistrationId),
|
||||
updatedAccount.getMasterDevice().orElseThrow().getPhoneNumberIdentityRegistrationId());
|
||||
|
||||
assertEquals(rotatedSignedPreKey, updatedAccount.getMasterDevice().orElseThrow().getPhoneNumberIdentitySignedPreKey());
|
||||
assertEquals(rotatedSignedPreKey, updatedAccount.getMasterDevice().orElseThrow().getSignedPreKey(IdentityType.PNI));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
|
|||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.securebackup.SecureBackupClient;
|
||||
import org.whispersystems.textsecuregcm.securestorage.SecureStorageClient;
|
||||
|
@ -194,7 +195,7 @@ class AccountsManagerConcurrentModificationIntegrationTest {
|
|||
assertAll(name,
|
||||
() -> assertEquals(discoverableByPhoneNumber, account.isDiscoverableByPhoneNumber()),
|
||||
() -> assertEquals(currentProfileVersion, account.getCurrentProfileVersion().orElseThrow()),
|
||||
() -> assertEquals(identityKey, account.getIdentityKey()),
|
||||
() -> assertEquals(identityKey, account.getIdentityKey(IdentityType.ACI)),
|
||||
() -> assertArrayEquals(unidentifiedAccessKey, account.getUnidentifiedAccessKey().orElseThrow()),
|
||||
() -> assertTrue(account.getRegistrationLock().verify(clientRegistrationLock)),
|
||||
() -> assertEquals(unrestrictedUnidentifiedAccess, account.isUnrestrictedUnidentifiedAccess())
|
||||
|
|
|
@ -63,6 +63,7 @@ import org.whispersystems.textsecuregcm.entities.ECSignedPreKey;
|
|||
import org.whispersystems.textsecuregcm.entities.KEMSignedPreKey;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.identity.PniServiceIdentifier;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.securebackup.SecureBackupClient;
|
||||
|
@ -790,7 +791,7 @@ class AccountsManagerTest {
|
|||
account = accountsManager.update(account, a -> a.setIdentityKey(identityKey));
|
||||
|
||||
assertEquals(1, account.getVersion());
|
||||
assertEquals(identityKey, account.getIdentityKey());
|
||||
assertEquals(identityKey, account.getIdentityKey(IdentityType.ACI));
|
||||
|
||||
verify(accounts, times(1)).getByAccountIdentifier(uuid);
|
||||
verify(accounts, times(2)).update(any());
|
||||
|
@ -817,7 +818,7 @@ class AccountsManagerTest {
|
|||
account = accountsManager.updateAsync(account, a -> a.setIdentityKey(identityKey)).join();
|
||||
|
||||
assertEquals(1, account.getVersion());
|
||||
assertEquals(identityKey, account.getIdentityKey());
|
||||
assertEquals(identityKey, account.getIdentityKey(IdentityType.ACI));
|
||||
|
||||
verify(accounts, times(1)).getByAccountIdentifierAsync(uuid);
|
||||
verify(accounts, times(2)).updateAsync(any());
|
||||
|
@ -1146,7 +1147,8 @@ class AccountsManagerTest {
|
|||
|
||||
UUID oldUuid = account.getUuid();
|
||||
UUID oldPni = account.getPhoneNumberIdentifier();
|
||||
Map<Long, ECSignedPreKey> oldSignedPreKeys = account.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getSignedPreKey));
|
||||
Map<Long, ECSignedPreKey> oldSignedPreKeys = account.getDevices().stream()
|
||||
.collect(Collectors.toMap(Device::getId, d -> d.getSignedPreKey(IdentityType.ACI)));
|
||||
|
||||
final IdentityKey pniIdentityKey = new IdentityKey(Curve.generateKeyPair().getPublicKey());
|
||||
|
||||
|
@ -1159,15 +1161,17 @@ class AccountsManagerTest {
|
|||
assertEquals(oldUuid, updatedAccount.getUuid());
|
||||
assertEquals(number, updatedAccount.getNumber());
|
||||
assertEquals(oldPni, updatedAccount.getPhoneNumberIdentifier());
|
||||
assertNull(updatedAccount.getIdentityKey());
|
||||
assertEquals(oldSignedPreKeys, updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getSignedPreKey)));
|
||||
assertNull(updatedAccount.getIdentityKey(IdentityType.ACI));
|
||||
assertEquals(oldSignedPreKeys, updatedAccount.getDevices().stream()
|
||||
.collect(Collectors.toMap(Device::getId, d -> d.getSignedPreKey(IdentityType.ACI))));
|
||||
assertEquals(Map.of(1L, 101, 2L, 102),
|
||||
updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getRegistrationId)));
|
||||
|
||||
// PNI stuff should
|
||||
assertEquals(pniIdentityKey, updatedAccount.getPhoneNumberIdentityKey());
|
||||
assertEquals(pniIdentityKey, updatedAccount.getIdentityKey(IdentityType.PNI));
|
||||
assertEquals(newSignedKeys,
|
||||
updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getPhoneNumberIdentitySignedPreKey)));
|
||||
updatedAccount.getDevices().stream()
|
||||
.collect(Collectors.toMap(Device::getId, d -> d.getSignedPreKey(IdentityType.PNI))));
|
||||
assertEquals(newRegistrationIds,
|
||||
updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, d -> d.getPhoneNumberIdentityRegistrationId().getAsInt())));
|
||||
|
||||
|
@ -1199,7 +1203,8 @@ class AccountsManagerTest {
|
|||
when(keysManager.storeEcSignedPreKeys(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
when(keysManager.storePqLastResort(any(), any())).thenReturn(CompletableFuture.completedFuture(null));
|
||||
|
||||
Map<Long, ECSignedPreKey> oldSignedPreKeys = account.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getSignedPreKey));
|
||||
Map<Long, ECSignedPreKey> oldSignedPreKeys = account.getDevices().stream()
|
||||
.collect(Collectors.toMap(Device::getId, d -> d.getSignedPreKey(IdentityType.ACI)));
|
||||
|
||||
final IdentityKey pniIdentityKey = new IdentityKey(Curve.generateKeyPair().getPublicKey());
|
||||
|
||||
|
@ -1210,15 +1215,17 @@ class AccountsManagerTest {
|
|||
assertEquals(oldUuid, updatedAccount.getUuid());
|
||||
assertEquals(number, updatedAccount.getNumber());
|
||||
assertEquals(oldPni, updatedAccount.getPhoneNumberIdentifier());
|
||||
assertNull(updatedAccount.getIdentityKey());
|
||||
assertEquals(oldSignedPreKeys, updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getSignedPreKey)));
|
||||
assertNull(updatedAccount.getIdentityKey(IdentityType.ACI));
|
||||
assertEquals(oldSignedPreKeys, updatedAccount.getDevices().stream()
|
||||
.collect(Collectors.toMap(Device::getId, d -> d.getSignedPreKey(IdentityType.ACI))));
|
||||
assertEquals(Map.of(1L, 101, 2L, 102),
|
||||
updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getRegistrationId)));
|
||||
|
||||
// PNI keys should
|
||||
assertEquals(pniIdentityKey, updatedAccount.getPhoneNumberIdentityKey());
|
||||
assertEquals(pniIdentityKey, updatedAccount.getIdentityKey(IdentityType.PNI));
|
||||
assertEquals(newSignedKeys,
|
||||
updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, Device::getPhoneNumberIdentitySignedPreKey)));
|
||||
updatedAccount.getDevices().stream()
|
||||
.collect(Collectors.toMap(Device::getId, d -> d.getSignedPreKey(IdentityType.PNI))));
|
||||
assertEquals(newRegistrationIds,
|
||||
updatedAccount.getDevices().stream().collect(Collectors.toMap(Device::getId, d -> d.getPhoneNumberIdentityRegistrationId().getAsInt())));
|
||||
|
||||
|
|
|
@ -48,6 +48,7 @@ import org.junit.jupiter.params.ParameterizedTest;
|
|||
import org.junit.jupiter.params.provider.ValueSource;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.push.ClientPresenceManager;
|
||||
import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisCluster;
|
||||
import org.whispersystems.textsecuregcm.securebackup.SecureBackupClient;
|
||||
|
@ -746,7 +747,7 @@ class AccountsTest {
|
|||
accounts.reserveUsernameHash(account, USERNAME_HASH_1, Duration.ofDays(1));
|
||||
accounts.confirmUsernameHash(account, USERNAME_HASH_1, ENCRYPTED_USERNAME_1);
|
||||
final UUID oldHandle = account.getUsernameLinkHandle();
|
||||
|
||||
|
||||
{
|
||||
final Optional<Account> maybeAccount = accounts.getByUsernameHash(USERNAME_HASH_1);
|
||||
|
||||
|
@ -1116,7 +1117,8 @@ class AccountsTest {
|
|||
assertThat(resultDevice.getApnId()).isEqualTo(expectingDevice.getApnId());
|
||||
assertThat(resultDevice.getGcmId()).isEqualTo(expectingDevice.getGcmId());
|
||||
assertThat(resultDevice.getLastSeen()).isEqualTo(expectingDevice.getLastSeen());
|
||||
assertThat(resultDevice.getSignedPreKey()).isEqualTo(expectingDevice.getSignedPreKey());
|
||||
assertThat(resultDevice.getSignedPreKey(IdentityType.ACI)).isEqualTo(
|
||||
expectingDevice.getSignedPreKey(IdentityType.ACI));
|
||||
assertThat(resultDevice.getFetchesMessages()).isEqualTo(expectingDevice.getFetchesMessages());
|
||||
assertThat(resultDevice.getUserAgent()).isEqualTo(expectingDevice.getUserAgent());
|
||||
assertThat(resultDevice.getName()).isEqualTo(expectingDevice.getName());
|
||||
|
|
|
@ -125,8 +125,8 @@ public class AccountsHelper {
|
|||
case "isPaymentActivationSupported" -> when(updatedAccount.isPaymentActivationSupported()).thenAnswer(stubbing);
|
||||
case "getEnabledDeviceCount" -> when(updatedAccount.getEnabledDeviceCount()).thenAnswer(stubbing);
|
||||
case "getRegistrationLock" -> when(updatedAccount.getRegistrationLock()).thenAnswer(stubbing);
|
||||
case "getIdentityKey" -> when(updatedAccount.getIdentityKey()).thenAnswer(stubbing);
|
||||
case "getPhoneNumberIdentityKey" -> when(updatedAccount.getPhoneNumberIdentityKey()).thenAnswer(stubbing);
|
||||
case "getIdentityKey" ->
|
||||
when(updatedAccount.getIdentityKey(stubbing.getInvocation().getArgument(0))).thenAnswer(stubbing);
|
||||
case "getBadges" -> when(updatedAccount.getBadges()).thenAnswer(stubbing);
|
||||
case "getLastSeen" -> when(updatedAccount.getLastSeen()).thenAnswer(stubbing);
|
||||
case "hasLockedCredentials" -> when(updatedAccount.hasLockedCredentials()).thenAnswer(stubbing);
|
||||
|
|
|
@ -27,6 +27,7 @@ import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
|
|||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccountAuthenticator;
|
||||
import org.whispersystems.textsecuregcm.auth.DisabledPermittedAuthenticatedAccount;
|
||||
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
|
||||
import org.whispersystems.textsecuregcm.identity.IdentityType;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
|
@ -165,7 +166,7 @@ public class AuthHelper {
|
|||
when(UNDISCOVERABLE_ACCOUNT.isDiscoverableByPhoneNumber()).thenReturn(false);
|
||||
when(VALID_ACCOUNT_3.isDiscoverableByPhoneNumber()).thenReturn(true);
|
||||
|
||||
when(VALID_ACCOUNT.getIdentityKey()).thenReturn(VALID_IDENTITY);
|
||||
when(VALID_ACCOUNT.getIdentityKey(IdentityType.ACI)).thenReturn(VALID_IDENTITY);
|
||||
|
||||
reset(ACCOUNTS_MANAGER);
|
||||
|
||||
|
|
Loading…
Reference in New Issue