Rename "master device" to "primary device"
This commit is contained in:
parent
e8cebad27e
commit
f0ab52eb5d
|
@ -88,9 +88,9 @@ public final class Operations {
|
||||||
user.setPniUuid(registrationResponse.pni());
|
user.setPniUuid(registrationResponse.pni());
|
||||||
|
|
||||||
// upload pre-key
|
// upload pre-key
|
||||||
final TestUser.PreKeySetPublicView preKeySetPublicView = user.preKeys(Device.MASTER_ID, false);
|
final TestUser.PreKeySetPublicView preKeySetPublicView = user.preKeys(Device.PRIMARY_ID, false);
|
||||||
apiPut("/v2/keys", preKeySetPublicView)
|
apiPut("/v2/keys", preKeySetPublicView)
|
||||||
.authorized(user, Device.MASTER_ID)
|
.authorized(user, Device.PRIMARY_ID)
|
||||||
.executeExpectSuccess();
|
.executeExpectSuccess();
|
||||||
|
|
||||||
return user;
|
return user;
|
||||||
|
@ -233,7 +233,7 @@ public final class Operations {
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestBuilder authorized(final TestUser user) {
|
public RequestBuilder authorized(final TestUser user) {
|
||||||
return authorized(user, Device.MASTER_ID);
|
return authorized(user, Device.PRIMARY_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RequestBuilder authorized(final TestUser user, final long deviceId) {
|
public RequestBuilder authorized(final TestUser user, final long deviceId) {
|
||||||
|
|
|
@ -82,7 +82,7 @@ public class TestUser {
|
||||||
this.unidentifiedAccessKey = unidentifiedAccessKey;
|
this.unidentifiedAccessKey = unidentifiedAccessKey;
|
||||||
this.accountPassword = accountPassword;
|
this.accountPassword = accountPassword;
|
||||||
this.registrationPassword = registrationPassword;
|
this.registrationPassword = registrationPassword;
|
||||||
devices.put(Device.MASTER_ID, TestDevice.create(Device.MASTER_ID, aciIdentityKey, pniIdentityKey));
|
devices.put(Device.PRIMARY_ID, TestDevice.create(Device.PRIMARY_ID, aciIdentityKey, pniIdentityKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int registrationId() {
|
public int registrationId() {
|
||||||
|
|
|
@ -38,7 +38,7 @@ public class MessagingTest {
|
||||||
try {
|
try {
|
||||||
final byte[] expectedContent = "Hello, World!".getBytes(StandardCharsets.UTF_8);
|
final byte[] expectedContent = "Hello, World!".getBytes(StandardCharsets.UTF_8);
|
||||||
final String contentBase64 = Base64.getEncoder().encodeToString(expectedContent);
|
final String contentBase64 = Base64.getEncoder().encodeToString(expectedContent);
|
||||||
final IncomingMessage message = new IncomingMessage(1, Device.MASTER_ID, userB.registrationId(), contentBase64);
|
final IncomingMessage message = new IncomingMessage(1, Device.PRIMARY_ID, userB.registrationId(), contentBase64);
|
||||||
final IncomingMessageList messages = new IncomingMessageList(List.of(message), false, true, System.currentTimeMillis());
|
final IncomingMessageList messages = new IncomingMessageList(List.of(message), false, true, System.currentTimeMillis());
|
||||||
|
|
||||||
final Pair<Integer, SendMessageResponse> sendMessage = Operations
|
final Pair<Integer, SendMessageResponse> sendMessage = Operations
|
||||||
|
|
|
@ -60,7 +60,7 @@ public class BaseAccountAuthenticator {
|
||||||
|
|
||||||
if (deviceIdSeparatorIndex == -1) {
|
if (deviceIdSeparatorIndex == -1) {
|
||||||
identifier = basicUsername;
|
identifier = basicUsername;
|
||||||
deviceId = Device.MASTER_ID;
|
deviceId = Device.PRIMARY_ID;
|
||||||
} else {
|
} else {
|
||||||
identifier = basicUsername.substring(0, deviceIdSeparatorIndex);
|
identifier = basicUsername.substring(0, deviceIdSeparatorIndex);
|
||||||
deviceId = Long.parseLong(basicUsername.substring(deviceIdSeparatorIndex + 1));
|
deviceId = Long.parseLong(basicUsername.substring(deviceIdSeparatorIndex + 1));
|
||||||
|
@ -113,7 +113,7 @@ public class BaseAccountAuthenticator {
|
||||||
} else {
|
} else {
|
||||||
Metrics.counter(ENABLED_NOT_REQUIRED_AUTHENTICATION_COUNTER_NAME,
|
Metrics.counter(ENABLED_NOT_REQUIRED_AUTHENTICATION_COUNTER_NAME,
|
||||||
ENABLED_TAG_NAME, String.valueOf(device.get().isEnabled() && account.get().isEnabled()),
|
ENABLED_TAG_NAME, String.valueOf(device.get().isEnabled() && account.get().isEnabled()),
|
||||||
IS_PRIMARY_DEVICE_TAG, String.valueOf(device.get().isMaster()))
|
IS_PRIMARY_DEVICE_TAG, String.valueOf(device.get().isPrimary()))
|
||||||
.increment();
|
.increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,7 +162,7 @@ public class BaseAccountAuthenticator {
|
||||||
// (1) each account will only update last-seen at most once per day
|
// (1) each account will only update last-seen at most once per day
|
||||||
// (2) these updates will occur throughout the day rather than all occurring at UTC midnight.
|
// (2) these updates will occur throughout the day rather than all occurring at UTC midnight.
|
||||||
if (device.getLastSeen() < todayInMillisWithOffset) {
|
if (device.getLastSeen() < todayInMillisWithOffset) {
|
||||||
Metrics.summary(DAYS_SINCE_LAST_SEEN_DISTRIBUTION_NAME, IS_PRIMARY_DEVICE_TAG, String.valueOf(device.isMaster()))
|
Metrics.summary(DAYS_SINCE_LAST_SEEN_DISTRIBUTION_NAME, IS_PRIMARY_DEVICE_TAG, String.valueOf(device.isPrimary()))
|
||||||
.record(Duration.ofMillis(todayInMillisWithOffset - device.getLastSeen()).toDays());
|
.record(Duration.ofMillis(todayInMillisWithOffset - device.getLastSeen()).toDays());
|
||||||
|
|
||||||
return accountsManager.updateDeviceLastSeen(account, device, Util.todayInMillis(clock));
|
return accountsManager.updateDeviceLastSeen(account, device, Util.todayInMillis(clock));
|
||||||
|
|
|
@ -53,7 +53,7 @@ public class AuthenticationUtil {
|
||||||
public static AuthenticatedDevice requireAuthenticatedPrimaryDevice() {
|
public static AuthenticatedDevice requireAuthenticatedPrimaryDevice() {
|
||||||
final AuthenticatedDevice authenticatedDevice = requireAuthenticatedDevice();
|
final AuthenticatedDevice authenticatedDevice = requireAuthenticatedDevice();
|
||||||
|
|
||||||
if (authenticatedDevice.deviceId() != Device.MASTER_ID) {
|
if (authenticatedDevice.deviceId() != Device.PRIMARY_ID) {
|
||||||
throw Status.PERMISSION_DENIED.asRuntimeException();
|
throw Status.PERMISSION_DENIED.asRuntimeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ public class AccountControllerV2 {
|
||||||
@NotNull @Valid final ChangeNumberRequest request, @HeaderParam(HttpHeaders.USER_AGENT) final String userAgent)
|
@NotNull @Valid final ChangeNumberRequest request, @HeaderParam(HttpHeaders.USER_AGENT) final String userAgent)
|
||||||
throws RateLimitExceededException, InterruptedException {
|
throws RateLimitExceededException, InterruptedException {
|
||||||
|
|
||||||
if (!authenticatedAccount.getAuthenticatedDevice().isMaster()) {
|
if (!authenticatedAccount.getAuthenticatedDevice().isPrimary()) {
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -170,7 +170,7 @@ public class AccountControllerV2 {
|
||||||
public AccountIdentityResponse distributePhoneNumberIdentityKeys(@Auth final AuthenticatedAccount authenticatedAccount,
|
public AccountIdentityResponse distributePhoneNumberIdentityKeys(@Auth final AuthenticatedAccount authenticatedAccount,
|
||||||
@NotNull @Valid final PhoneNumberIdentityKeyDistributionRequest request) {
|
@NotNull @Valid final PhoneNumberIdentityKeyDistributionRequest request) {
|
||||||
|
|
||||||
if (!authenticatedAccount.getAuthenticatedDevice().isMaster()) {
|
if (!authenticatedAccount.getAuthenticatedDevice().isPrimary()) {
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -137,11 +137,11 @@ public class DeviceController {
|
||||||
@ChangesDeviceEnabledState
|
@ChangesDeviceEnabledState
|
||||||
public void removeDevice(@Auth AuthenticatedAccount auth, @PathParam("device_id") long deviceId) {
|
public void removeDevice(@Auth AuthenticatedAccount auth, @PathParam("device_id") long deviceId) {
|
||||||
Account account = auth.getAccount();
|
Account account = auth.getAccount();
|
||||||
if (auth.getAuthenticatedDevice().getId() != Device.MASTER_ID) {
|
if (auth.getAuthenticatedDevice().getId() != Device.PRIMARY_ID) {
|
||||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceId == Device.MASTER_ID) {
|
if (deviceId == Device.PRIMARY_ID) {
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ public class DeviceController {
|
||||||
throw new DeviceLimitExceededException(account.getDevices().size(), MAX_DEVICES);
|
throw new DeviceLimitExceededException(account.getDevices().size(), MAX_DEVICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (auth.getAuthenticatedDevice().getId() != Device.MASTER_ID) {
|
if (auth.getAuthenticatedDevice().getId() != Device.PRIMARY_ID) {
|
||||||
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
throw new WebApplicationException(Response.Status.UNAUTHORIZED);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -154,7 +154,7 @@ public class KeysController {
|
||||||
.and(HAS_IDENTITY_KEY_TAG_NAME, String.valueOf(hasIdentityKey))
|
.and(HAS_IDENTITY_KEY_TAG_NAME, String.valueOf(hasIdentityKey))
|
||||||
.and(IDENTITY_TYPE_TAG_NAME, usePhoneNumberIdentity ? "pni" : "aci");
|
.and(IDENTITY_TYPE_TAG_NAME, usePhoneNumberIdentity ? "pni" : "aci");
|
||||||
|
|
||||||
if (!device.isMaster()) {
|
if (!device.isPrimary()) {
|
||||||
Metrics.counter(IDENTITY_KEY_CHANGE_FORBIDDEN_COUNTER_NAME, tags).increment();
|
Metrics.counter(IDENTITY_KEY_CHANGE_FORBIDDEN_COUNTER_NAME, tags).increment();
|
||||||
|
|
||||||
throw new ForbiddenException();
|
throw new ForbiddenException();
|
||||||
|
|
|
@ -693,7 +693,7 @@ public class MessageController {
|
||||||
|
|
||||||
messageSender.sendMessage(destinationAccount, destinationDevice, envelope, online);
|
messageSender.sendMessage(destinationAccount, destinationDevice, envelope, online);
|
||||||
} catch (NotPushRegisteredException e) {
|
} catch (NotPushRegisteredException e) {
|
||||||
if (destinationDevice.isMaster()) throw new NoSuchUserException(e);
|
if (destinationDevice.isPrimary()) throw new NoSuchUserException(e);
|
||||||
else logger.debug("Not registered", e);
|
else logger.debug("Not registered", e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -727,7 +727,7 @@ public class MessageController {
|
||||||
|
|
||||||
messageSender.sendMessage(destinationAccount, destinationDevice, messageBuilder.build(), online);
|
messageSender.sendMessage(destinationAccount, destinationDevice, messageBuilder.build(), online);
|
||||||
} catch (NotPushRegisteredException e) {
|
} catch (NotPushRegisteredException e) {
|
||||||
if (destinationDevice.isMaster()) {
|
if (destinationDevice.isPrimary()) {
|
||||||
throw new NoSuchUserException(e);
|
throw new NoSuchUserException(e);
|
||||||
} else {
|
} else {
|
||||||
logger.debug("Not registered", e);
|
logger.debug("Not registered", e);
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class RegistrationController {
|
||||||
a.setIdentityKey(registrationRequest.aciIdentityKey().get());
|
a.setIdentityKey(registrationRequest.aciIdentityKey().get());
|
||||||
a.setPhoneNumberIdentityKey(registrationRequest.pniIdentityKey().get());
|
a.setPhoneNumberIdentityKey(registrationRequest.pniIdentityKey().get());
|
||||||
|
|
||||||
final Device device = a.getMasterDevice().orElseThrow();
|
final Device device = a.getPrimaryDevice().orElseThrow();
|
||||||
|
|
||||||
device.setSignedPreKey(registrationRequest.deviceActivationRequest().aciSignedPreKey().get());
|
device.setSignedPreKey(registrationRequest.deviceActivationRequest().aciSignedPreKey().get());
|
||||||
device.setPhoneNumberIdentitySignedPreKey(registrationRequest.deviceActivationRequest().pniSignedPreKey().get());
|
device.setPhoneNumberIdentitySignedPreKey(registrationRequest.deviceActivationRequest().pniSignedPreKey().get());
|
||||||
|
@ -173,13 +173,13 @@ public class RegistrationController {
|
||||||
|
|
||||||
CompletableFuture.allOf(
|
CompletableFuture.allOf(
|
||||||
keysManager.storeEcSignedPreKeys(a.getUuid(),
|
keysManager.storeEcSignedPreKeys(a.getUuid(),
|
||||||
Map.of(Device.MASTER_ID, registrationRequest.deviceActivationRequest().aciSignedPreKey().get())),
|
Map.of(Device.PRIMARY_ID, registrationRequest.deviceActivationRequest().aciSignedPreKey().get())),
|
||||||
keysManager.storePqLastResort(a.getUuid(),
|
keysManager.storePqLastResort(a.getUuid(),
|
||||||
Map.of(Device.MASTER_ID, registrationRequest.deviceActivationRequest().aciPqLastResortPreKey().get())),
|
Map.of(Device.PRIMARY_ID, registrationRequest.deviceActivationRequest().aciPqLastResortPreKey().get())),
|
||||||
keysManager.storeEcSignedPreKeys(a.getPhoneNumberIdentifier(),
|
keysManager.storeEcSignedPreKeys(a.getPhoneNumberIdentifier(),
|
||||||
Map.of(Device.MASTER_ID, registrationRequest.deviceActivationRequest().pniSignedPreKey().get())),
|
Map.of(Device.PRIMARY_ID, registrationRequest.deviceActivationRequest().pniSignedPreKey().get())),
|
||||||
keysManager.storePqLastResort(a.getPhoneNumberIdentifier(),
|
keysManager.storePqLastResort(a.getPhoneNumberIdentifier(),
|
||||||
Map.of(Device.MASTER_ID, registrationRequest.deviceActivationRequest().pniPqLastResortPreKey().get())))
|
Map.of(Device.PRIMARY_ID, registrationRequest.deviceActivationRequest().pniPqLastResortPreKey().get())))
|
||||||
.join();
|
.join();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,7 +75,7 @@ public class DevicesGrpcService extends ReactorDevicesGrpc.DevicesImplBase {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<RemoveDeviceResponse> removeDevice(final RemoveDeviceRequest request) {
|
public Mono<RemoveDeviceResponse> removeDevice(final RemoveDeviceRequest request) {
|
||||||
if (request.getId() == Device.MASTER_ID) {
|
if (request.getId() == Device.PRIMARY_ID) {
|
||||||
throw Status.INVALID_ARGUMENT.withDescription("Cannot remove primary device").asRuntimeException();
|
throw Status.INVALID_ARGUMENT.withDescription("Cannot remove primary device").asRuntimeException();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -181,7 +181,7 @@ public class DevicesGrpcService extends ReactorDevicesGrpc.DevicesImplBase {
|
||||||
.map(maybeAccount -> maybeAccount.orElseThrow(Status.UNAUTHENTICATED::asRuntimeException))
|
.map(maybeAccount -> maybeAccount.orElseThrow(Status.UNAUTHENTICATED::asRuntimeException))
|
||||||
.flatMap(account -> Mono.fromFuture(() -> accountsManager.updateDeviceAsync(account, authenticatedDevice.deviceId(), device -> {
|
.flatMap(account -> Mono.fromFuture(() -> accountsManager.updateDeviceAsync(account, authenticatedDevice.deviceId(), device -> {
|
||||||
if (StringUtils.isNotBlank(device.getApnId()) || StringUtils.isNotBlank(device.getVoipApnId())) {
|
if (StringUtils.isNotBlank(device.getApnId()) || StringUtils.isNotBlank(device.getVoipApnId())) {
|
||||||
device.setUserAgent(device.isMaster() ? "OWI" : "OWP");
|
device.setUserAgent(device.isPrimary() ? "OWI" : "OWP");
|
||||||
} else if (StringUtils.isNotBlank(device.getGcmId())) {
|
} else if (StringUtils.isNotBlank(device.getGcmId())) {
|
||||||
device.setUserAgent("OWA");
|
device.setUserAgent("OWA");
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,7 +45,7 @@ public class PushChallengeManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendChallenge(final Account account) throws NotPushRegisteredException {
|
public void sendChallenge(final Account account) throws NotPushRegisteredException {
|
||||||
final Device masterDevice = account.getMasterDevice().orElseThrow(NotPushRegisteredException::new);
|
final Device primaryDevice = account.getPrimaryDevice().orElseThrow(NotPushRegisteredException::new);
|
||||||
|
|
||||||
final byte[] token = new byte[CHALLENGE_TOKEN_LENGTH];
|
final byte[] token = new byte[CHALLENGE_TOKEN_LENGTH];
|
||||||
random.nextBytes(token);
|
random.nextBytes(token);
|
||||||
|
@ -58,9 +58,9 @@ public class PushChallengeManager {
|
||||||
|
|
||||||
sent = true;
|
sent = true;
|
||||||
|
|
||||||
if (StringUtils.isNotBlank(masterDevice.getGcmId())) {
|
if (StringUtils.isNotBlank(primaryDevice.getGcmId())) {
|
||||||
platform = ClientPlatform.ANDROID.name().toLowerCase();
|
platform = ClientPlatform.ANDROID.name().toLowerCase();
|
||||||
} else if (StringUtils.isNotBlank(masterDevice.getApnId())) {
|
} else if (StringUtils.isNotBlank(primaryDevice.getApnId())) {
|
||||||
platform = ClientPlatform.IOS.name().toLowerCase();
|
platform = ClientPlatform.IOS.name().toLowerCase();
|
||||||
} else {
|
} else {
|
||||||
// This should never happen; if the account has neither an APN nor FCM token, sending the challenge will result
|
// This should never happen; if the account has neither an APN nor FCM token, sending the challenge will result
|
||||||
|
@ -86,10 +86,10 @@ public class PushChallengeManager {
|
||||||
} catch (final IllegalArgumentException ignored) {
|
} catch (final IllegalArgumentException ignored) {
|
||||||
}
|
}
|
||||||
|
|
||||||
final String platform = account.getMasterDevice().map(masterDevice -> {
|
final String platform = account.getPrimaryDevice().map(primaryDevice -> {
|
||||||
if (StringUtils.isNotBlank(masterDevice.getGcmId())) {
|
if (StringUtils.isNotBlank(primaryDevice.getGcmId())) {
|
||||||
return ClientPlatform.IOS.name().toLowerCase();
|
return ClientPlatform.IOS.name().toLowerCase();
|
||||||
} else if (StringUtils.isNotBlank(masterDevice.getApnId())) {
|
} else if (StringUtils.isNotBlank(primaryDevice.getApnId())) {
|
||||||
return ClientPlatform.ANDROID.name().toLowerCase();
|
return ClientPlatform.ANDROID.name().toLowerCase();
|
||||||
} else {
|
} else {
|
||||||
return "unknown";
|
return "unknown";
|
||||||
|
|
|
@ -62,7 +62,7 @@ public class PushNotificationManager {
|
||||||
public void sendRateLimitChallengeNotification(final Account destination, final String challengeToken)
|
public void sendRateLimitChallengeNotification(final Account destination, final String challengeToken)
|
||||||
throws NotPushRegisteredException {
|
throws NotPushRegisteredException {
|
||||||
|
|
||||||
final Device device = destination.getDevice(Device.MASTER_ID).orElseThrow(NotPushRegisteredException::new);
|
final Device device = destination.getDevice(Device.PRIMARY_ID).orElseThrow(NotPushRegisteredException::new);
|
||||||
final Pair<String, PushNotification.TokenType> tokenAndType = getToken(device);
|
final Pair<String, PushNotification.TokenType> tokenAndType = getToken(device);
|
||||||
|
|
||||||
sendNotification(new PushNotification(tokenAndType.first(), tokenAndType.second(),
|
sendNotification(new PushNotification(tokenAndType.first(), tokenAndType.second(),
|
||||||
|
@ -70,7 +70,7 @@ public class PushNotificationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void sendAttemptLoginNotification(final Account destination, final String context) throws NotPushRegisteredException {
|
public void sendAttemptLoginNotification(final Account destination, final String context) throws NotPushRegisteredException {
|
||||||
final Device device = destination.getDevice(Device.MASTER_ID).orElseThrow(NotPushRegisteredException::new);
|
final Device device = destination.getDevice(Device.PRIMARY_ID).orElseThrow(NotPushRegisteredException::new);
|
||||||
final Pair<String, PushNotification.TokenType> tokenAndType = getToken(device);
|
final Pair<String, PushNotification.TokenType> tokenAndType = getToken(device);
|
||||||
|
|
||||||
sendNotification(new PushNotification(tokenAndType.first(), tokenAndType.second(),
|
sendNotification(new PushNotification(tokenAndType.first(), tokenAndType.second(),
|
||||||
|
|
|
@ -232,10 +232,10 @@ public class Account {
|
||||||
return devices;
|
return devices;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Device> getMasterDevice() {
|
public Optional<Device> getPrimaryDevice() {
|
||||||
requireNotStale();
|
requireNotStale();
|
||||||
|
|
||||||
return getDevice(Device.MASTER_ID);
|
return getDevice(Device.PRIMARY_ID);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Optional<Device> getDevice(final long deviceId) {
|
public Optional<Device> getDevice(final long deviceId) {
|
||||||
|
@ -253,7 +253,7 @@ public class Account {
|
||||||
public boolean isTransferSupported() {
|
public boolean isTransferSupported() {
|
||||||
requireNotStale();
|
requireNotStale();
|
||||||
|
|
||||||
return getMasterDevice().map(Device::getCapabilities).map(Device.DeviceCapabilities::transfer).orElse(false);
|
return getPrimaryDevice().map(Device::getCapabilities).map(Device.DeviceCapabilities::transfer).orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isPniSupported() {
|
public boolean isPniSupported() {
|
||||||
|
@ -275,13 +275,13 @@ public class Account {
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
requireNotStale();
|
requireNotStale();
|
||||||
|
|
||||||
return getMasterDevice().map(Device::isEnabled).orElse(false);
|
return getPrimaryDevice().map(Device::isEnabled).orElse(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long getNextDeviceId() {
|
public long getNextDeviceId() {
|
||||||
requireNotStale();
|
requireNotStale();
|
||||||
|
|
||||||
long candidateId = Device.MASTER_ID + 1;
|
long candidateId = Device.PRIMARY_ID + 1;
|
||||||
|
|
||||||
while (getDevice(candidateId).isPresent()) {
|
while (getDevice(candidateId).isPresent()) {
|
||||||
candidateId++;
|
candidateId++;
|
||||||
|
|
|
@ -186,7 +186,7 @@ public class AccountsManager {
|
||||||
|
|
||||||
accountLockManager.withLock(List.of(number), () -> {
|
accountLockManager.withLock(List.of(number), () -> {
|
||||||
Device device = new Device();
|
Device device = new Device();
|
||||||
device.setId(Device.MASTER_ID);
|
device.setId(Device.PRIMARY_ID);
|
||||||
device.setAuthTokenHash(SaltedTokenHash.generateFor(password));
|
device.setAuthTokenHash(SaltedTokenHash.generateFor(password));
|
||||||
device.setFetchesMessages(accountAttributes.getFetchesMessages());
|
device.setFetchesMessages(accountAttributes.getFetchesMessages());
|
||||||
device.setRegistrationId(accountAttributes.getRegistrationId());
|
device.setRegistrationId(accountAttributes.getRegistrationId());
|
||||||
|
@ -423,13 +423,13 @@ public class AccountsManager {
|
||||||
throw new IllegalArgumentException("Signed pre-keys and registration IDs must both be null or both be non-null");
|
throw new IllegalArgumentException("Signed pre-keys and registration IDs must both be null or both be non-null");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that all including master ID are in signed pre-keys
|
// Check that all including primary ID are in signed pre-keys
|
||||||
DestinationDeviceValidator.validateCompleteDeviceList(
|
DestinationDeviceValidator.validateCompleteDeviceList(
|
||||||
account,
|
account,
|
||||||
pniSignedPreKeys.keySet(),
|
pniSignedPreKeys.keySet(),
|
||||||
Collections.emptySet());
|
Collections.emptySet());
|
||||||
|
|
||||||
// Check that all including master ID are in Pq pre-keys
|
// Check that all including primary ID are in Pq pre-keys
|
||||||
if (pniPqLastResortPreKeys != null) {
|
if (pniPqLastResortPreKeys != null) {
|
||||||
DestinationDeviceValidator.validateCompleteDeviceList(
|
DestinationDeviceValidator.validateCompleteDeviceList(
|
||||||
account,
|
account,
|
||||||
|
|
|
@ -100,11 +100,11 @@ public class ChangeNumberManager {
|
||||||
|
|
||||||
private void validateDeviceMessages(final Account account,
|
private void validateDeviceMessages(final Account account,
|
||||||
final List<IncomingMessage> deviceMessages) throws MismatchedDevicesException, StaleDevicesException {
|
final List<IncomingMessage> deviceMessages) throws MismatchedDevicesException, StaleDevicesException {
|
||||||
// Check that all except master ID are in device messages
|
// Check that all except primary ID are in device messages
|
||||||
DestinationDeviceValidator.validateCompleteDeviceList(
|
DestinationDeviceValidator.validateCompleteDeviceList(
|
||||||
account,
|
account,
|
||||||
deviceMessages.stream().map(IncomingMessage::destinationDeviceId).collect(Collectors.toSet()),
|
deviceMessages.stream().map(IncomingMessage::destinationDeviceId).collect(Collectors.toSet()),
|
||||||
Set.of(Device.MASTER_ID));
|
Set.of(Device.PRIMARY_ID));
|
||||||
|
|
||||||
// check that all sync messages are to the current registration ID for the matching device
|
// check that all sync messages are to the current registration ID for the matching device
|
||||||
DestinationDeviceValidator.validateRegistrationIds(
|
DestinationDeviceValidator.validateRegistrationIds(
|
||||||
|
@ -140,7 +140,7 @@ public class ChangeNumberManager {
|
||||||
.setDestinationUuid(new AciServiceIdentifier(sourceAndDestinationAccount.getUuid()).toServiceIdentifierString())
|
.setDestinationUuid(new AciServiceIdentifier(sourceAndDestinationAccount.getUuid()).toServiceIdentifierString())
|
||||||
.setContent(ByteString.copyFrom(contents.get()))
|
.setContent(ByteString.copyFrom(contents.get()))
|
||||||
.setSourceUuid(new AciServiceIdentifier(sourceAndDestinationAccount.getUuid()).toServiceIdentifierString())
|
.setSourceUuid(new AciServiceIdentifier(sourceAndDestinationAccount.getUuid()).toServiceIdentifierString())
|
||||||
.setSourceDevice((int) Device.MASTER_ID)
|
.setSourceDevice((int) Device.PRIMARY_ID)
|
||||||
.setUpdatedPni(sourceAndDestinationAccount.getPhoneNumberIdentifier().toString())
|
.setUpdatedPni(sourceAndDestinationAccount.getPhoneNumberIdentifier().toString())
|
||||||
.setUrgent(true)
|
.setUrgent(true)
|
||||||
.build();
|
.build();
|
||||||
|
|
|
@ -19,7 +19,7 @@ import org.whispersystems.textsecuregcm.util.Util;
|
||||||
|
|
||||||
public class Device {
|
public class Device {
|
||||||
|
|
||||||
public static final long MASTER_ID = 1;
|
public static final long PRIMARY_ID = 1;
|
||||||
public static final int MAXIMUM_DEVICE_ID = 256;
|
public static final int MAXIMUM_DEVICE_ID = 256;
|
||||||
public static final int MAX_REGISTRATION_ID = 0x3FFF;
|
public static final int MAX_REGISTRATION_ID = 0x3FFF;
|
||||||
public static final List<Long> ALL_POSSIBLE_DEVICE_IDS = LongStream.range(1, MAXIMUM_DEVICE_ID).boxed().collect(Collectors.toList());
|
public static final List<Long> ALL_POSSIBLE_DEVICE_IDS = LongStream.range(1, MAXIMUM_DEVICE_ID).boxed().collect(Collectors.toList());
|
||||||
|
@ -199,8 +199,8 @@ public class Device {
|
||||||
public boolean isEnabled() {
|
public boolean isEnabled() {
|
||||||
boolean hasChannel = fetchesMessages || !Util.isEmpty(getApnId()) || !Util.isEmpty(getGcmId());
|
boolean hasChannel = fetchesMessages || !Util.isEmpty(getApnId()) || !Util.isEmpty(getGcmId());
|
||||||
|
|
||||||
return (id == MASTER_ID && hasChannel && signedPreKey != null) ||
|
return (id == PRIMARY_ID && hasChannel && signedPreKey != null) ||
|
||||||
(id != MASTER_ID && hasChannel && signedPreKey != null && lastSeen > (System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)));
|
(id != PRIMARY_ID && hasChannel && signedPreKey != null && lastSeen > (System.currentTimeMillis() - TimeUnit.DAYS.toMillis(30)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean getFetchesMessages() {
|
public boolean getFetchesMessages() {
|
||||||
|
@ -211,8 +211,8 @@ public class Device {
|
||||||
this.fetchesMessages = fetchesMessages;
|
this.fetchesMessages = fetchesMessages;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isMaster() {
|
public boolean isPrimary() {
|
||||||
return getId() == MASTER_ID;
|
return getId() == PRIMARY_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getRegistrationId() {
|
public int getRegistrationId() {
|
||||||
|
|
|
@ -256,7 +256,7 @@ public class WebSocketConnection implements MessageAvailabilityListener, Displac
|
||||||
public static void recordMessageDeliveryDuration(long timestamp, Device messageDestinationDevice) {
|
public static void recordMessageDeliveryDuration(long timestamp, Device messageDestinationDevice) {
|
||||||
final long messageDeliveryDuration = System.currentTimeMillis() - timestamp;
|
final long messageDeliveryDuration = System.currentTimeMillis() - timestamp;
|
||||||
messageTime.update(messageDeliveryDuration);
|
messageTime.update(messageDeliveryDuration);
|
||||||
if (messageDestinationDevice.isMaster()) {
|
if (messageDestinationDevice.isPrimary()) {
|
||||||
primaryDeviceMessageTime.update(messageDeliveryDuration);
|
primaryDeviceMessageTime.update(messageDeliveryDuration);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,7 +64,7 @@ public class UnlinkDeviceCommand extends EnvironmentCommand<WhisperServerConfigu
|
||||||
Account account = deps.accountsManager().getByAccountIdentifier(aci)
|
Account account = deps.accountsManager().getByAccountIdentifier(aci)
|
||||||
.orElseThrow(() -> new IllegalArgumentException("account id " + aci + " does not exist"));
|
.orElseThrow(() -> new IllegalArgumentException("account id " + aci + " does not exist"));
|
||||||
|
|
||||||
if (deviceIds.contains(Device.MASTER_ID)) {
|
if (deviceIds.contains(Device.PRIMARY_ID)) {
|
||||||
throw new IllegalArgumentException("cannot delete primary device");
|
throw new IllegalArgumentException("cannot delete primary device");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -171,7 +171,7 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
void testDeviceEnabledChanged(final Map<Long, Boolean> initialEnabled, final Map<Long, Boolean> finalEnabled) {
|
void testDeviceEnabledChanged(final Map<Long, Boolean> initialEnabled, final Map<Long, Boolean> finalEnabled) {
|
||||||
assert initialEnabled.size() == finalEnabled.size();
|
assert initialEnabled.size() == finalEnabled.size();
|
||||||
|
|
||||||
assert account.getMasterDevice().orElseThrow().isEnabled();
|
assert account.getPrimaryDevice().orElseThrow().isEnabled();
|
||||||
|
|
||||||
initialEnabled.forEach((deviceId, enabled) ->
|
initialEnabled.forEach((deviceId, enabled) ->
|
||||||
DevicesHelper.setEnabled(account.getDevice(deviceId).orElseThrow(), enabled));
|
DevicesHelper.setEnabled(account.getDevice(deviceId).orElseThrow(), enabled));
|
||||||
|
@ -211,7 +211,7 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDeviceAdded() {
|
void testDeviceAdded() {
|
||||||
assert account.getMasterDevice().orElseThrow().isEnabled();
|
assert account.getPrimaryDevice().orElseThrow().isEnabled();
|
||||||
|
|
||||||
final int initialDeviceCount = account.getDevices().size();
|
final int initialDeviceCount = account.getDevices().size();
|
||||||
|
|
||||||
|
@ -235,7 +235,7 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(ints = {1, 2})
|
@ValueSource(ints = {1, 2})
|
||||||
void testDeviceRemoved(final int removedDeviceCount) {
|
void testDeviceRemoved(final int removedDeviceCount) {
|
||||||
assert account.getMasterDevice().orElseThrow().isEnabled();
|
assert account.getPrimaryDevice().orElseThrow().isEnabled();
|
||||||
|
|
||||||
final List<Long> initialDeviceIds = account.getDevices().stream().map(Device::getId).collect(Collectors.toList());
|
final List<Long> initialDeviceIds = account.getDevices().stream().map(Device::getId).collect(Collectors.toList());
|
||||||
|
|
||||||
|
@ -266,8 +266,8 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testMasterDeviceDisabledAndDeviceRemoved() {
|
void testPrimaryDeviceDisabledAndDeviceRemoved() {
|
||||||
assert account.getMasterDevice().orElseThrow().isEnabled();
|
assert account.getPrimaryDevice().orElseThrow().isEnabled();
|
||||||
|
|
||||||
final Set<Long> initialDeviceIds = account.getDevices().stream().map(Device::getId).collect(Collectors.toSet());
|
final Set<Long> initialDeviceIds = account.getDevices().stream().map(Device::getId).collect(Collectors.toSet());
|
||||||
|
|
||||||
|
@ -275,7 +275,7 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
assertTrue(initialDeviceIds.remove(deletedDeviceId));
|
assertTrue(initialDeviceIds.remove(deletedDeviceId));
|
||||||
|
|
||||||
final Response response = resources.getJerseyTest()
|
final Response response = resources.getJerseyTest()
|
||||||
.target("/v1/test/account/disableMasterDeviceAndDeleteDevice/" + deletedDeviceId)
|
.target("/v1/test/account/disablePrimaryDeviceAndDeleteDevice/" + deletedDeviceId)
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization",
|
.header("Authorization",
|
||||||
"Basic " + Base64.getEncoder().encodeToString("user:pass".getBytes(StandardCharsets.UTF_8)))
|
"Basic " + Base64.getEncoder().encodeToString("user:pass".getBytes(StandardCharsets.UTF_8)))
|
||||||
|
@ -415,7 +415,7 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
@ChangesDeviceEnabledState
|
@ChangesDeviceEnabledState
|
||||||
public String setAccountEnabled(@Auth TestPrincipal principal, @PathParam("enabled") final boolean enabled) {
|
public String setAccountEnabled(@Auth TestPrincipal principal, @PathParam("enabled") final boolean enabled) {
|
||||||
|
|
||||||
final Device device = principal.getAccount().getMasterDevice().orElseThrow();
|
final Device device = principal.getAccount().getPrimaryDevice().orElseThrow();
|
||||||
|
|
||||||
DevicesHelper.setEnabled(device, enabled);
|
DevicesHelper.setEnabled(device, enabled);
|
||||||
|
|
||||||
|
@ -469,11 +469,11 @@ class AuthEnablementRefreshRequirementProviderTest {
|
||||||
}
|
}
|
||||||
|
|
||||||
@POST
|
@POST
|
||||||
@Path("/account/disableMasterDeviceAndDeleteDevice/{deviceId}")
|
@Path("/account/disablePrimaryDeviceAndDeleteDevice/{deviceId}")
|
||||||
@ChangesDeviceEnabledState
|
@ChangesDeviceEnabledState
|
||||||
public String disableMasterDeviceAndRemoveDevice(@Auth TestPrincipal auth, @PathParam("deviceId") long deviceId) {
|
public String disablePrimaryDeviceAndRemoveDevice(@Auth TestPrincipal auth, @PathParam("deviceId") long deviceId) {
|
||||||
|
|
||||||
DevicesHelper.setEnabled(auth.getAccount().getMasterDevice().orElseThrow(), false);
|
DevicesHelper.setEnabled(auth.getAccount().getPrimaryDevice().orElseThrow(), false);
|
||||||
|
|
||||||
auth.getAccount().removeDevice(deviceId);
|
auth.getAccount().removeDevice(deviceId);
|
||||||
|
|
||||||
|
|
|
@ -68,7 +68,7 @@ class BaseAccountAuthenticatorTest {
|
||||||
|
|
||||||
private static Device generateTestDevice(final long lastSeen) {
|
private static Device generateTestDevice(final long lastSeen) {
|
||||||
final Device device = new Device();
|
final Device device = new Device();
|
||||||
device.setId(Device.MASTER_ID);
|
device.setId(Device.PRIMARY_ID);
|
||||||
device.setLastSeen(lastSeen);
|
device.setLastSeen(lastSeen);
|
||||||
|
|
||||||
return device;
|
return device;
|
||||||
|
@ -374,8 +374,8 @@ class BaseAccountAuthenticatorTest {
|
||||||
|
|
||||||
private static Stream<Arguments> testGetIdentifierAndDeviceId() {
|
private static Stream<Arguments> testGetIdentifierAndDeviceId() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
Arguments.of("", "", Device.MASTER_ID),
|
Arguments.of("", "", Device.PRIMARY_ID),
|
||||||
Arguments.of("test", "test", Device.MASTER_ID),
|
Arguments.of("test", "test", Device.PRIMARY_ID),
|
||||||
Arguments.of("test.7", "test", 7));
|
Arguments.of("test.7", "test", 7));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,7 +26,7 @@ class BasicAuthorizationHeaderTest {
|
||||||
|
|
||||||
assertEquals("aladdin", header.getUsername());
|
assertEquals("aladdin", header.getUsername());
|
||||||
assertEquals("opensesame", header.getPassword());
|
assertEquals("opensesame", header.getPassword());
|
||||||
assertEquals(Device.MASTER_ID, header.getDeviceId());
|
assertEquals(Device.PRIMARY_ID, header.getDeviceId());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
|
|
|
@ -49,7 +49,7 @@ class PhoneNumberChangeRefreshRequirementProviderTest {
|
||||||
when(account.getUuid()).thenReturn(ACCOUNT_UUID);
|
when(account.getUuid()).thenReturn(ACCOUNT_UUID);
|
||||||
when(account.getNumber()).thenReturn(NUMBER);
|
when(account.getNumber()).thenReturn(NUMBER);
|
||||||
when(account.getDevices()).thenReturn(List.of(device));
|
when(account.getDevices()).thenReturn(List.of(device));
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
request = mock(ContainerRequest.class);
|
request = mock(ContainerRequest.class);
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ class PhoneNumberChangeRefreshRequirementProviderTest {
|
||||||
|
|
||||||
provider.handleRequestFiltered(requestEvent);
|
provider.handleRequestFiltered(requestEvent);
|
||||||
when(account.getNumber()).thenReturn(CHANGED_NUMBER);
|
when(account.getNumber()).thenReturn(CHANGED_NUMBER);
|
||||||
assertEquals(List.of(new Pair<>(ACCOUNT_UUID, Device.MASTER_ID)), provider.handleRequestFinished(requestEvent));
|
assertEquals(List.of(new Pair<>(ACCOUNT_UUID, Device.PRIMARY_ID)), provider.handleRequestFinished(requestEvent));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -69,7 +69,7 @@ class RegistrationLockVerificationManagerTest {
|
||||||
.thenReturn(mock(ExternalServiceCredentials.class));
|
.thenReturn(mock(ExternalServiceCredentials.class));
|
||||||
|
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
AccountsHelper.setupMockUpdate(accountsManager);
|
AccountsHelper.setupMockUpdate(accountsManager);
|
||||||
|
|
||||||
|
@ -104,7 +104,7 @@ class RegistrationLockVerificationManagerTest {
|
||||||
} else {
|
} else {
|
||||||
verify(registrationRecoveryPasswordsManager, never()).removeForNumber(account.getNumber());
|
verify(registrationRecoveryPasswordsManager, never()).removeForNumber(account.getNumber());
|
||||||
}
|
}
|
||||||
verify(clientPresenceManager).disconnectAllPresences(account.getUuid(), List.of(Device.MASTER_ID));
|
verify(clientPresenceManager).disconnectAllPresences(account.getUuid(), List.of(Device.PRIMARY_ID));
|
||||||
try {
|
try {
|
||||||
verify(pushNotificationManager).sendAttemptLoginNotification(any(), eq("failedRegistrationLock"));
|
verify(pushNotificationManager).sendAttemptLoginNotification(any(), eq("failedRegistrationLock"));
|
||||||
} catch (NotPushRegisteredException npre) {}
|
} catch (NotPushRegisteredException npre) {}
|
||||||
|
@ -127,7 +127,7 @@ class RegistrationLockVerificationManagerTest {
|
||||||
verify(pushNotificationManager, never()).sendAttemptLoginNotification(any(), eq("failedRegistrationLock"));
|
verify(pushNotificationManager, never()).sendAttemptLoginNotification(any(), eq("failedRegistrationLock"));
|
||||||
} catch (NotPushRegisteredException npre) {}
|
} catch (NotPushRegisteredException npre) {}
|
||||||
verify(registrationRecoveryPasswordsManager, never()).removeForNumber(account.getNumber());
|
verify(registrationRecoveryPasswordsManager, never()).removeForNumber(account.getNumber());
|
||||||
verify(clientPresenceManager, never()).disconnectAllPresences(account.getUuid(), List.of(Device.MASTER_ID));
|
verify(clientPresenceManager, never()).disconnectAllPresences(account.getUuid(), List.of(Device.PRIMARY_ID));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -165,7 +165,7 @@ class RegistrationLockVerificationManagerTest {
|
||||||
|
|
||||||
verify(account, never()).lockAuthTokenHash();
|
verify(account, never()).lockAuthTokenHash();
|
||||||
verify(registrationRecoveryPasswordsManager, never()).removeForNumber(account.getNumber());
|
verify(registrationRecoveryPasswordsManager, never()).removeForNumber(account.getNumber());
|
||||||
verify(clientPresenceManager, never()).disconnectAllPresences(account.getUuid(), List.of(Device.MASTER_ID));
|
verify(clientPresenceManager, never()).disconnectAllPresences(account.getUuid(), List.of(Device.PRIMARY_ID));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Stream<Arguments> testSuccess() {
|
static Stream<Arguments> testSuccess() {
|
||||||
|
|
|
@ -85,7 +85,7 @@ class BasicCredentialAuthenticationInterceptorTest {
|
||||||
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
when(account.getUuid()).thenReturn(UUID.randomUUID());
|
||||||
|
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
when(baseAccountAuthenticator.authenticate(any(), anyBoolean()))
|
when(baseAccountAuthenticator.authenticate(any(), anyBoolean()))
|
||||||
.thenReturn(Optional.of(new AuthenticatedAccount(() -> new Pair<>(account, device))));
|
.thenReturn(Optional.of(new AuthenticatedAccount(() -> new Pair<>(account, device))));
|
||||||
|
|
|
@ -92,7 +92,7 @@ class DeviceControllerTest {
|
||||||
private static RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
private static RedisAdvancedClusterCommands<String, String> commands = mock(RedisAdvancedClusterCommands.class);
|
||||||
private static Account account = mock(Account.class);
|
private static Account account = mock(Account.class);
|
||||||
private static Account maxedAccount = mock(Account.class);
|
private static Account maxedAccount = mock(Account.class);
|
||||||
private static Device masterDevice = mock(Device.class);
|
private static Device primaryDevice = mock(Device.class);
|
||||||
private static ClientPresenceManager clientPresenceManager = mock(ClientPresenceManager.class);
|
private static ClientPresenceManager clientPresenceManager = mock(ClientPresenceManager.class);
|
||||||
private static Map<String, Integer> deviceConfiguration = new HashMap<>();
|
private static Map<String, Integer> deviceConfiguration = new HashMap<>();
|
||||||
private static TestClock testClock = TestClock.now();
|
private static TestClock testClock = TestClock.now();
|
||||||
|
@ -132,7 +132,7 @@ class DeviceControllerTest {
|
||||||
when(rateLimiters.getAllocateDeviceLimiter()).thenReturn(rateLimiter);
|
when(rateLimiters.getAllocateDeviceLimiter()).thenReturn(rateLimiter);
|
||||||
when(rateLimiters.getVerifyDeviceLimiter()).thenReturn(rateLimiter);
|
when(rateLimiters.getVerifyDeviceLimiter()).thenReturn(rateLimiter);
|
||||||
|
|
||||||
when(masterDevice.getId()).thenReturn(1L);
|
when(primaryDevice.getId()).thenReturn(1L);
|
||||||
|
|
||||||
when(account.getNextDeviceId()).thenReturn(42L);
|
when(account.getNextDeviceId()).thenReturn(42L);
|
||||||
when(account.getNumber()).thenReturn(AuthHelper.VALID_NUMBER);
|
when(account.getNumber()).thenReturn(AuthHelper.VALID_NUMBER);
|
||||||
|
@ -165,7 +165,7 @@ class DeviceControllerTest {
|
||||||
commands,
|
commands,
|
||||||
account,
|
account,
|
||||||
maxedAccount,
|
maxedAccount,
|
||||||
masterDevice,
|
primaryDevice,
|
||||||
clientPresenceManager
|
clientPresenceManager
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -175,7 +175,7 @@ class DeviceControllerTest {
|
||||||
@Test
|
@Test
|
||||||
void validDeviceRegisterTest() {
|
void validDeviceRegisterTest() {
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(existingDevice.isEnabled()).thenReturn(true);
|
when(existingDevice.isEnabled()).thenReturn(true);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
|
@ -205,7 +205,7 @@ class DeviceControllerTest {
|
||||||
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
|
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
final String verificationToken = deviceController.generateVerificationToken(AuthHelper.VALID_UUID);
|
final String verificationToken = deviceController.generateVerificationToken(AuthHelper.VALID_UUID);
|
||||||
|
@ -228,7 +228,7 @@ class DeviceControllerTest {
|
||||||
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
VerificationCode deviceCode = resources.getJerseyTest()
|
VerificationCode deviceCode = resources.getJerseyTest()
|
||||||
|
@ -272,7 +272,7 @@ class DeviceControllerTest {
|
||||||
final Optional<String> expectedGcmToken) {
|
final Optional<String> expectedGcmToken) {
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
VerificationCode deviceCode = resources.getJerseyTest()
|
VerificationCode deviceCode = resources.getJerseyTest()
|
||||||
|
@ -358,7 +358,7 @@ class DeviceControllerTest {
|
||||||
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
|
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(account));
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
final Optional<ECSignedPreKey> aciSignedPreKey;
|
final Optional<ECSignedPreKey> aciSignedPreKey;
|
||||||
|
@ -405,7 +405,7 @@ class DeviceControllerTest {
|
||||||
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
VerificationCode deviceCode = resources.getJerseyTest()
|
VerificationCode deviceCode = resources.getJerseyTest()
|
||||||
|
@ -466,7 +466,7 @@ class DeviceControllerTest {
|
||||||
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
VerificationCode deviceCode = resources.getJerseyTest()
|
VerificationCode deviceCode = resources.getJerseyTest()
|
||||||
|
@ -524,7 +524,7 @@ class DeviceControllerTest {
|
||||||
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
when(accountsManager.getByAccountIdentifier(AuthHelper.VALID_UUID)).thenReturn(Optional.of(AuthHelper.VALID_ACCOUNT));
|
||||||
|
|
||||||
final Device existingDevice = mock(Device.class);
|
final Device existingDevice = mock(Device.class);
|
||||||
when(existingDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(existingDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
when(AuthHelper.VALID_ACCOUNT.getDevices()).thenReturn(List.of(existingDevice));
|
||||||
|
|
||||||
VerificationCode deviceCode = resources.getJerseyTest()
|
VerificationCode deviceCode = resources.getJerseyTest()
|
||||||
|
@ -765,7 +765,7 @@ class DeviceControllerTest {
|
||||||
|
|
||||||
try (final Response response = resources
|
try (final Response response = resources
|
||||||
.getJerseyTest()
|
.getJerseyTest()
|
||||||
.target("/v1/devices/" + Device.MASTER_ID)
|
.target("/v1/devices/" + Device.PRIMARY_ID)
|
||||||
.request()
|
.request()
|
||||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD))
|
||||||
.header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30")
|
.header(HttpHeaders.USER_AGENT, "Signal-Android/5.42.8675309 Android/30")
|
||||||
|
|
|
@ -285,7 +285,7 @@ class KeysControllerTest {
|
||||||
verify(AuthHelper.VALID_DEVICE).setSignedPreKey(eq(test));
|
verify(AuthHelper.VALID_DEVICE).setSignedPreKey(eq(test));
|
||||||
verify(AuthHelper.VALID_DEVICE, never()).setPhoneNumberIdentitySignedPreKey(any());
|
verify(AuthHelper.VALID_DEVICE, never()).setPhoneNumberIdentitySignedPreKey(any());
|
||||||
verify(accounts).updateDevice(eq(AuthHelper.VALID_ACCOUNT), anyLong(), any());
|
verify(accounts).updateDevice(eq(AuthHelper.VALID_ACCOUNT), anyLong(), any());
|
||||||
verify(KEYS).storeEcSignedPreKeys(AuthHelper.VALID_UUID, Map.of(Device.MASTER_ID, test));
|
verify(KEYS).storeEcSignedPreKeys(AuthHelper.VALID_UUID, Map.of(Device.PRIMARY_ID, test));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -304,7 +304,7 @@ class KeysControllerTest {
|
||||||
verify(AuthHelper.VALID_DEVICE).setPhoneNumberIdentitySignedPreKey(eq(replacementKey));
|
verify(AuthHelper.VALID_DEVICE).setPhoneNumberIdentitySignedPreKey(eq(replacementKey));
|
||||||
verify(AuthHelper.VALID_DEVICE, never()).setSignedPreKey(any());
|
verify(AuthHelper.VALID_DEVICE, never()).setSignedPreKey(any());
|
||||||
verify(accounts).updateDevice(eq(AuthHelper.VALID_ACCOUNT), anyLong(), any());
|
verify(accounts).updateDevice(eq(AuthHelper.VALID_ACCOUNT), anyLong(), any());
|
||||||
verify(KEYS).storeEcSignedPreKeys(AuthHelper.VALID_PNI, Map.of(Device.MASTER_ID, replacementKey));
|
verify(KEYS).storeEcSignedPreKeys(AuthHelper.VALID_PNI, Map.of(Device.PRIMARY_ID, replacementKey));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -684,7 +684,7 @@ class RegistrationControllerTest {
|
||||||
final Account account = MockUtils.buildMock(Account.class, a -> {
|
final Account account = MockUtils.buildMock(Account.class, a -> {
|
||||||
when(a.getUuid()).thenReturn(accountIdentifier);
|
when(a.getUuid()).thenReturn(accountIdentifier);
|
||||||
when(a.getPhoneNumberIdentifier()).thenReturn(phoneNumberIdentifier);
|
when(a.getPhoneNumberIdentifier()).thenReturn(phoneNumberIdentifier);
|
||||||
when(a.getMasterDevice()).thenReturn(Optional.of(device));
|
when(a.getPrimaryDevice()).thenReturn(Optional.of(device));
|
||||||
});
|
});
|
||||||
|
|
||||||
when(accountsManager.create(any(), any(), any(), any(), any())).thenReturn(account);
|
when(accountsManager.create(any(), any(), any(), any(), any())).thenReturn(account);
|
||||||
|
@ -715,10 +715,10 @@ class RegistrationControllerTest {
|
||||||
verify(device).setSignedPreKey(expectedAciSignedPreKey);
|
verify(device).setSignedPreKey(expectedAciSignedPreKey);
|
||||||
verify(device).setPhoneNumberIdentitySignedPreKey(expectedPniSignedPreKey);
|
verify(device).setPhoneNumberIdentitySignedPreKey(expectedPniSignedPreKey);
|
||||||
|
|
||||||
verify(keysManager).storeEcSignedPreKeys(accountIdentifier, Map.of(Device.MASTER_ID, expectedAciSignedPreKey));
|
verify(keysManager).storeEcSignedPreKeys(accountIdentifier, Map.of(Device.PRIMARY_ID, expectedAciSignedPreKey));
|
||||||
verify(keysManager).storeEcSignedPreKeys(phoneNumberIdentifier, Map.of(Device.MASTER_ID, expectedPniSignedPreKey));
|
verify(keysManager).storeEcSignedPreKeys(phoneNumberIdentifier, Map.of(Device.PRIMARY_ID, expectedPniSignedPreKey));
|
||||||
verify(keysManager).storePqLastResort(accountIdentifier, Map.of(Device.MASTER_ID, expectedAciPqLastResortPreKey));
|
verify(keysManager).storePqLastResort(accountIdentifier, Map.of(Device.PRIMARY_ID, expectedAciPqLastResortPreKey));
|
||||||
verify(keysManager).storePqLastResort(phoneNumberIdentifier, Map.of(Device.MASTER_ID, expectedPniPqLastResortPreKey));
|
verify(keysManager).storePqLastResort(phoneNumberIdentifier, Map.of(Device.PRIMARY_ID, expectedPniPqLastResortPreKey));
|
||||||
|
|
||||||
expectedApnsToken.ifPresentOrElse(expectedToken -> verify(device).setApnId(expectedToken),
|
expectedApnsToken.ifPresentOrElse(expectedToken -> verify(device).setApnId(expectedToken),
|
||||||
() -> verify(device, never()).setApnId(any()));
|
() -> verify(device, never()).setApnId(any()));
|
||||||
|
|
|
@ -40,7 +40,7 @@ class OutgoingMessageEntityTest {
|
||||||
MessageProtos.Envelope.Type.CIPHERTEXT_VALUE,
|
MessageProtos.Envelope.Type.CIPHERTEXT_VALUE,
|
||||||
messageTimestamp,
|
messageTimestamp,
|
||||||
sourceIdentifier,
|
sourceIdentifier,
|
||||||
sourceIdentifier != null ? (int) Device.MASTER_ID : 0,
|
sourceIdentifier != null ? (int) Device.PRIMARY_ID : 0,
|
||||||
destinationIdentifier,
|
destinationIdentifier,
|
||||||
updatedPni,
|
updatedPni,
|
||||||
messageContent,
|
messageContent,
|
||||||
|
|
|
@ -113,14 +113,14 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
|
||||||
final Instant linkedDeviceLastSeen = linkedDeviceCreated.plus(Duration.ofHours(7));
|
final Instant linkedDeviceLastSeen = linkedDeviceCreated.plus(Duration.ofHours(7));
|
||||||
|
|
||||||
final Device primaryDevice = mock(Device.class);
|
final Device primaryDevice = mock(Device.class);
|
||||||
when(primaryDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(primaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(primaryDevice.getCreated()).thenReturn(primaryDeviceCreated.toEpochMilli());
|
when(primaryDevice.getCreated()).thenReturn(primaryDeviceCreated.toEpochMilli());
|
||||||
when(primaryDevice.getLastSeen()).thenReturn(primaryDeviceLastSeen.toEpochMilli());
|
when(primaryDevice.getLastSeen()).thenReturn(primaryDeviceLastSeen.toEpochMilli());
|
||||||
|
|
||||||
final String linkedDeviceName = "A linked device";
|
final String linkedDeviceName = "A linked device";
|
||||||
|
|
||||||
final Device linkedDevice = mock(Device.class);
|
final Device linkedDevice = mock(Device.class);
|
||||||
when(linkedDevice.getId()).thenReturn(Device.MASTER_ID + 1);
|
when(linkedDevice.getId()).thenReturn(Device.PRIMARY_ID + 1);
|
||||||
when(linkedDevice.getCreated()).thenReturn(linkedDeviceCreated.toEpochMilli());
|
when(linkedDevice.getCreated()).thenReturn(linkedDeviceCreated.toEpochMilli());
|
||||||
when(linkedDevice.getLastSeen()).thenReturn(linkedDeviceLastSeen.toEpochMilli());
|
when(linkedDevice.getLastSeen()).thenReturn(linkedDeviceLastSeen.toEpochMilli());
|
||||||
when(linkedDevice.getName())
|
when(linkedDevice.getName())
|
||||||
|
@ -130,12 +130,12 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
|
||||||
|
|
||||||
final GetDevicesResponse expectedResponse = GetDevicesResponse.newBuilder()
|
final GetDevicesResponse expectedResponse = GetDevicesResponse.newBuilder()
|
||||||
.addDevices(GetDevicesResponse.LinkedDevice.newBuilder()
|
.addDevices(GetDevicesResponse.LinkedDevice.newBuilder()
|
||||||
.setId(Device.MASTER_ID)
|
.setId(Device.PRIMARY_ID)
|
||||||
.setCreated(primaryDeviceCreated.toEpochMilli())
|
.setCreated(primaryDeviceCreated.toEpochMilli())
|
||||||
.setLastSeen(primaryDeviceLastSeen.toEpochMilli())
|
.setLastSeen(primaryDeviceLastSeen.toEpochMilli())
|
||||||
.build())
|
.build())
|
||||||
.addDevices(GetDevicesResponse.LinkedDevice.newBuilder()
|
.addDevices(GetDevicesResponse.LinkedDevice.newBuilder()
|
||||||
.setId(Device.MASTER_ID + 1)
|
.setId(Device.PRIMARY_ID + 1)
|
||||||
.setCreated(linkedDeviceCreated.toEpochMilli())
|
.setCreated(linkedDeviceCreated.toEpochMilli())
|
||||||
.setLastSeen(linkedDeviceLastSeen.toEpochMilli())
|
.setLastSeen(linkedDeviceLastSeen.toEpochMilli())
|
||||||
.setName(ByteString.copyFrom(linkedDeviceName.getBytes(StandardCharsets.UTF_8)))
|
.setName(ByteString.copyFrom(linkedDeviceName.getBytes(StandardCharsets.UTF_8)))
|
||||||
|
@ -167,14 +167,14 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void removeDeviceNonPrimaryAuthenticated() {
|
void removeDeviceNonPrimaryAuthenticated() {
|
||||||
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, Device.MASTER_ID + 1);
|
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, Device.PRIMARY_ID + 1);
|
||||||
assertStatusException(Status.PERMISSION_DENIED, () -> authenticatedServiceStub().removeDevice(RemoveDeviceRequest.newBuilder()
|
assertStatusException(Status.PERMISSION_DENIED, () -> authenticatedServiceStub().removeDevice(RemoveDeviceRequest.newBuilder()
|
||||||
.setId(17)
|
.setId(17)
|
||||||
.build()));
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@ValueSource(longs = {Device.MASTER_ID, Device.MASTER_ID + 1})
|
@ValueSource(longs = {Device.PRIMARY_ID, Device.PRIMARY_ID + 1})
|
||||||
void setDeviceName(final long deviceId) {
|
void setDeviceName(final long deviceId) {
|
||||||
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, deviceId);
|
mockAuthenticationInterceptor().setAuthenticatedDevice(AUTHENTICATED_ACI, deviceId);
|
||||||
|
|
||||||
|
@ -238,7 +238,7 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
|
||||||
|
|
||||||
final Stream.Builder<Arguments> streamBuilder = Stream.builder();
|
final Stream.Builder<Arguments> streamBuilder = Stream.builder();
|
||||||
|
|
||||||
for (final long deviceId : new long[] { Device.MASTER_ID, Device.MASTER_ID + 1 }) {
|
for (final long deviceId : new long[] { Device.PRIMARY_ID, Device.PRIMARY_ID + 1 }) {
|
||||||
streamBuilder.add(Arguments.of(deviceId,
|
streamBuilder.add(Arguments.of(deviceId,
|
||||||
SetPushTokenRequest.newBuilder()
|
SetPushTokenRequest.newBuilder()
|
||||||
.setApnsTokenRequest(SetPushTokenRequest.ApnsTokenRequest.newBuilder()
|
.setApnsTokenRequest(SetPushTokenRequest.ApnsTokenRequest.newBuilder()
|
||||||
|
@ -352,7 +352,7 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
|
||||||
|
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
when(device.getId()).thenReturn(deviceId);
|
when(device.getId()).thenReturn(deviceId);
|
||||||
when(device.isMaster()).thenReturn(deviceId == Device.MASTER_ID);
|
when(device.isPrimary()).thenReturn(deviceId == Device.PRIMARY_ID);
|
||||||
when(device.getApnId()).thenReturn(apnsToken);
|
when(device.getApnId()).thenReturn(apnsToken);
|
||||||
when(device.getVoipApnId()).thenReturn(apnsVoipToken);
|
when(device.getVoipApnId()).thenReturn(apnsVoipToken);
|
||||||
when(device.getGcmId()).thenReturn(fcmToken);
|
when(device.getGcmId()).thenReturn(fcmToken);
|
||||||
|
@ -374,22 +374,22 @@ class DevicesGrpcServiceTest extends SimpleBaseGrpcTest<DevicesGrpcService, Devi
|
||||||
|
|
||||||
private static Stream<Arguments> clearPushToken() {
|
private static Stream<Arguments> clearPushToken() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
Arguments.of(Device.MASTER_ID, "apns-token", null, null, "OWI"),
|
Arguments.of(Device.PRIMARY_ID, "apns-token", null, null, "OWI"),
|
||||||
Arguments.of(Device.MASTER_ID, "apns-token", "apns-voip-token", null, "OWI"),
|
Arguments.of(Device.PRIMARY_ID, "apns-token", "apns-voip-token", null, "OWI"),
|
||||||
Arguments.of(Device.MASTER_ID, null, "apns-voip-token", null, "OWI"),
|
Arguments.of(Device.PRIMARY_ID, null, "apns-voip-token", null, "OWI"),
|
||||||
Arguments.of(Device.MASTER_ID, null, null, "fcm-token", "OWA"),
|
Arguments.of(Device.PRIMARY_ID, null, null, "fcm-token", "OWA"),
|
||||||
Arguments.of(Device.MASTER_ID, null, null, null, null),
|
Arguments.of(Device.PRIMARY_ID, null, null, null, null),
|
||||||
Arguments.of(Device.MASTER_ID + 1, "apns-token", null, null, "OWP"),
|
Arguments.of(Device.PRIMARY_ID + 1, "apns-token", null, null, "OWP"),
|
||||||
Arguments.of(Device.MASTER_ID + 1, "apns-token", "apns-voip-token", null, "OWP"),
|
Arguments.of(Device.PRIMARY_ID + 1, "apns-token", "apns-voip-token", null, "OWP"),
|
||||||
Arguments.of(Device.MASTER_ID + 1, null, "apns-voip-token", null, "OWP"),
|
Arguments.of(Device.PRIMARY_ID + 1, null, "apns-voip-token", null, "OWP"),
|
||||||
Arguments.of(Device.MASTER_ID + 1, null, null, "fcm-token", "OWA"),
|
Arguments.of(Device.PRIMARY_ID + 1, null, null, "fcm-token", "OWA"),
|
||||||
Arguments.of(Device.MASTER_ID + 1, null, null, null, null)
|
Arguments.of(Device.PRIMARY_ID + 1, null, null, null, null)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@CartesianTest
|
@CartesianTest
|
||||||
void setCapabilities(
|
void setCapabilities(
|
||||||
@CartesianTest.Values(longs = {Device.MASTER_ID, Device.MASTER_ID + 1}) final long deviceId,
|
@CartesianTest.Values(longs = {Device.PRIMARY_ID, Device.PRIMARY_ID + 1}) final long deviceId,
|
||||||
@CartesianTest.Values(booleans = {true, false}) final boolean storage,
|
@CartesianTest.Values(booleans = {true, false}) final boolean storage,
|
||||||
@CartesianTest.Values(booleans = {true, false}) final boolean transfer,
|
@CartesianTest.Values(booleans = {true, false}) final boolean transfer,
|
||||||
@CartesianTest.Values(booleans = {true, false}) final boolean pni,
|
@CartesianTest.Values(booleans = {true, false}) final boolean pni,
|
||||||
|
|
|
@ -83,9 +83,9 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
|
||||||
final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
|
final byte[] unidentifiedAccessKey = new byte[UnidentifiedAccessUtil.UNIDENTIFIED_ACCESS_KEY_LENGTH];
|
||||||
new SecureRandom().nextBytes(unidentifiedAccessKey);
|
new SecureRandom().nextBytes(unidentifiedAccessKey);
|
||||||
|
|
||||||
when(targetDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(targetDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(targetDevice.isEnabled()).thenReturn(true);
|
when(targetDevice.isEnabled()).thenReturn(true);
|
||||||
when(targetAccount.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(targetDevice));
|
when(targetAccount.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(targetDevice));
|
||||||
|
|
||||||
when(targetAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey));
|
when(targetAccount.getUnidentifiedAccessKey()).thenReturn(Optional.of(unidentifiedAccessKey));
|
||||||
when(targetAccount.getIdentifier(IdentityType.ACI)).thenReturn(identifier);
|
when(targetAccount.getIdentifier(IdentityType.ACI)).thenReturn(identifier);
|
||||||
|
@ -97,8 +97,8 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
|
||||||
final ECSignedPreKey ecSignedPreKey = KeysHelper.signedECPreKey(2, identityKeyPair);
|
final ECSignedPreKey ecSignedPreKey = KeysHelper.signedECPreKey(2, identityKeyPair);
|
||||||
final KEMSignedPreKey kemSignedPreKey = KeysHelper.signedKEMPreKey(3, identityKeyPair);
|
final KEMSignedPreKey kemSignedPreKey = KeysHelper.signedKEMPreKey(3, identityKeyPair);
|
||||||
|
|
||||||
when(keysManager.takeEC(identifier, Device.MASTER_ID)).thenReturn(CompletableFuture.completedFuture(Optional.of(ecPreKey)));
|
when(keysManager.takeEC(identifier, Device.PRIMARY_ID)).thenReturn(CompletableFuture.completedFuture(Optional.of(ecPreKey)));
|
||||||
when(keysManager.takePQ(identifier, Device.MASTER_ID)).thenReturn(CompletableFuture.completedFuture(Optional.of(kemSignedPreKey)));
|
when(keysManager.takePQ(identifier, Device.PRIMARY_ID)).thenReturn(CompletableFuture.completedFuture(Optional.of(kemSignedPreKey)));
|
||||||
when(targetDevice.getSignedPreKey(IdentityType.ACI)).thenReturn(ecSignedPreKey);
|
when(targetDevice.getSignedPreKey(IdentityType.ACI)).thenReturn(ecSignedPreKey);
|
||||||
|
|
||||||
final GetPreKeysResponse response = unauthenticatedServiceStub().getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
|
final GetPreKeysResponse response = unauthenticatedServiceStub().getPreKeys(GetPreKeysAnonymousRequest.newBuilder()
|
||||||
|
@ -108,13 +108,13 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
|
||||||
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
|
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
|
||||||
.setUuid(UUIDUtil.toByteString(identifier))
|
.setUuid(UUIDUtil.toByteString(identifier))
|
||||||
.build())
|
.build())
|
||||||
.setDeviceId(Device.MASTER_ID)
|
.setDeviceId(Device.PRIMARY_ID)
|
||||||
.build())
|
.build())
|
||||||
.build());
|
.build());
|
||||||
|
|
||||||
final GetPreKeysResponse expectedResponse = GetPreKeysResponse.newBuilder()
|
final GetPreKeysResponse expectedResponse = GetPreKeysResponse.newBuilder()
|
||||||
.setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
|
.setIdentityKey(ByteString.copyFrom(identityKey.serialize()))
|
||||||
.putPreKeys(Device.MASTER_ID, GetPreKeysResponse.PreKeyBundle.newBuilder()
|
.putPreKeys(Device.PRIMARY_ID, GetPreKeysResponse.PreKeyBundle.newBuilder()
|
||||||
.setEcOneTimePreKey(EcPreKey.newBuilder()
|
.setEcOneTimePreKey(EcPreKey.newBuilder()
|
||||||
.setKeyId(ecPreKey.keyId())
|
.setKeyId(ecPreKey.keyId())
|
||||||
.setPublicKey(ByteString.copyFrom(ecPreKey.serializedPublicKey()))
|
.setPublicKey(ByteString.copyFrom(ecPreKey.serializedPublicKey()))
|
||||||
|
@ -158,7 +158,7 @@ class KeysAnonymousGrpcServiceTest extends SimpleBaseGrpcTest<KeysAnonymousGrpcS
|
||||||
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
|
.setIdentityType(org.signal.chat.common.IdentityType.IDENTITY_TYPE_ACI)
|
||||||
.setUuid(UUIDUtil.toByteString(identifier))
|
.setUuid(UUIDUtil.toByteString(identifier))
|
||||||
.build())
|
.build())
|
||||||
.setDeviceId(Device.MASTER_ID)
|
.setDeviceId(Device.PRIMARY_ID)
|
||||||
.build())
|
.build())
|
||||||
.build()));
|
.build()));
|
||||||
}
|
}
|
||||||
|
|
|
@ -55,7 +55,7 @@ public abstract class SimpleBaseGrpcTest<SERVICE extends BindableService, STUB e
|
||||||
|
|
||||||
protected static final UUID AUTHENTICATED_ACI = UUID.randomUUID();
|
protected static final UUID AUTHENTICATED_ACI = UUID.randomUUID();
|
||||||
|
|
||||||
protected static final long AUTHENTICATED_DEVICE_ID = Device.MASTER_ID;
|
protected static final long AUTHENTICATED_DEVICE_ID = Device.PRIMARY_ID;
|
||||||
|
|
||||||
private AutoCloseable mocksCloseable;
|
private AutoCloseable mocksCloseable;
|
||||||
|
|
||||||
|
|
|
@ -60,14 +60,14 @@ class PushNotificationManagerTest {
|
||||||
|
|
||||||
final String deviceToken = "token";
|
final String deviceToken = "token";
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(device.getGcmId()).thenReturn(deviceToken);
|
when(device.getGcmId()).thenReturn(deviceToken);
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
when(fcmSender.sendNotification(any()))
|
when(fcmSender.sendNotification(any()))
|
||||||
.thenReturn(CompletableFuture.completedFuture(new SendPushNotificationResult(true, null, false)));
|
.thenReturn(CompletableFuture.completedFuture(new SendPushNotificationResult(true, null, false)));
|
||||||
|
|
||||||
pushNotificationManager.sendNewMessageNotification(account, Device.MASTER_ID, urgent);
|
pushNotificationManager.sendNewMessageNotification(account, Device.PRIMARY_ID, urgent);
|
||||||
verify(fcmSender).sendNotification(new PushNotification(deviceToken, PushNotification.TokenType.FCM, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent));
|
verify(fcmSender).sendNotification(new PushNotification(deviceToken, PushNotification.TokenType.FCM, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -91,9 +91,9 @@ class PushNotificationManagerTest {
|
||||||
final String deviceToken = "token";
|
final String deviceToken = "token";
|
||||||
final String challengeToken = "challenge";
|
final String challengeToken = "challenge";
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(device.getApnId()).thenReturn(deviceToken);
|
when(device.getApnId()).thenReturn(deviceToken);
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
when(apnSender.sendNotification(any()))
|
when(apnSender.sendNotification(any()))
|
||||||
.thenReturn(CompletableFuture.completedFuture(new SendPushNotificationResult(true, null, false)));
|
.thenReturn(CompletableFuture.completedFuture(new SendPushNotificationResult(true, null, false)));
|
||||||
|
@ -110,7 +110,7 @@ class PushNotificationManagerTest {
|
||||||
|
|
||||||
final String deviceToken = "token";
|
final String deviceToken = "token";
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
if (isApn) {
|
if (isApn) {
|
||||||
when(device.getApnId()).thenReturn(deviceToken);
|
when(device.getApnId()).thenReturn(deviceToken);
|
||||||
when(apnSender.sendNotification(any()))
|
when(apnSender.sendNotification(any()))
|
||||||
|
@ -122,7 +122,7 @@ class PushNotificationManagerTest {
|
||||||
when(fcmSender.sendNotification(any()))
|
when(fcmSender.sendNotification(any()))
|
||||||
.thenReturn(CompletableFuture.completedFuture(new SendPushNotificationResult(true, null, false)));
|
.thenReturn(CompletableFuture.completedFuture(new SendPushNotificationResult(true, null, false)));
|
||||||
}
|
}
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
pushNotificationManager.sendAttemptLoginNotification(account, "someContext");
|
pushNotificationManager.sendAttemptLoginNotification(account, "someContext");
|
||||||
|
|
||||||
|
@ -142,8 +142,8 @@ class PushNotificationManagerTest {
|
||||||
final Account account = mock(Account.class);
|
final Account account = mock(Account.class);
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
final PushNotification pushNotification = new PushNotification(
|
final PushNotification pushNotification = new PushNotification(
|
||||||
"token", PushNotification.TokenType.FCM, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent);
|
"token", PushNotification.TokenType.FCM, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent);
|
||||||
|
@ -155,7 +155,7 @@ class PushNotificationManagerTest {
|
||||||
|
|
||||||
verify(fcmSender).sendNotification(pushNotification);
|
verify(fcmSender).sendNotification(pushNotification);
|
||||||
verifyNoInteractions(apnSender);
|
verifyNoInteractions(apnSender);
|
||||||
verify(accountsManager, never()).updateDevice(eq(account), eq(Device.MASTER_ID), any());
|
verify(accountsManager, never()).updateDevice(eq(account), eq(Device.PRIMARY_ID), any());
|
||||||
verify(device, never()).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
verify(device, never()).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
||||||
verifyNoInteractions(apnPushNotificationScheduler);
|
verifyNoInteractions(apnPushNotificationScheduler);
|
||||||
}
|
}
|
||||||
|
@ -166,8 +166,8 @@ class PushNotificationManagerTest {
|
||||||
final Account account = mock(Account.class);
|
final Account account = mock(Account.class);
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
final PushNotification pushNotification = new PushNotification(
|
final PushNotification pushNotification = new PushNotification(
|
||||||
"token", PushNotification.TokenType.APN, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent);
|
"token", PushNotification.TokenType.APN, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent);
|
||||||
|
@ -199,8 +199,8 @@ class PushNotificationManagerTest {
|
||||||
final Account account = mock(Account.class);
|
final Account account = mock(Account.class);
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
final PushNotification pushNotification = new PushNotification(
|
final PushNotification pushNotification = new PushNotification(
|
||||||
"token", PushNotification.TokenType.APN_VOIP, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent);
|
"token", PushNotification.TokenType.APN_VOIP, PushNotification.NotificationType.NOTIFICATION, null, account, device, urgent);
|
||||||
|
@ -213,7 +213,7 @@ class PushNotificationManagerTest {
|
||||||
verify(apnSender).sendNotification(pushNotification);
|
verify(apnSender).sendNotification(pushNotification);
|
||||||
|
|
||||||
verifyNoInteractions(fcmSender);
|
verifyNoInteractions(fcmSender);
|
||||||
verify(accountsManager, never()).updateDevice(eq(account), eq(Device.MASTER_ID), any());
|
verify(accountsManager, never()).updateDevice(eq(account), eq(Device.PRIMARY_ID), any());
|
||||||
verify(device, never()).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
verify(device, never()).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
||||||
verify(apnPushNotificationScheduler).scheduleRecurringVoipNotification(account, device);
|
verify(apnPushNotificationScheduler).scheduleRecurringVoipNotification(account, device);
|
||||||
verify(apnPushNotificationScheduler, never()).scheduleBackgroundNotification(any(), any());
|
verify(apnPushNotificationScheduler, never()).scheduleBackgroundNotification(any(), any());
|
||||||
|
@ -224,9 +224,9 @@ class PushNotificationManagerTest {
|
||||||
final Account account = mock(Account.class);
|
final Account account = mock(Account.class);
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(device.getGcmId()).thenReturn("token");
|
when(device.getGcmId()).thenReturn("token");
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
final PushNotification pushNotification = new PushNotification(
|
final PushNotification pushNotification = new PushNotification(
|
||||||
"token", PushNotification.TokenType.FCM, PushNotification.NotificationType.NOTIFICATION, null, account, device, true);
|
"token", PushNotification.TokenType.FCM, PushNotification.NotificationType.NOTIFICATION, null, account, device, true);
|
||||||
|
@ -236,7 +236,7 @@ class PushNotificationManagerTest {
|
||||||
|
|
||||||
pushNotificationManager.sendNotification(pushNotification);
|
pushNotificationManager.sendNotification(pushNotification);
|
||||||
|
|
||||||
verify(accountsManager).updateDevice(eq(account), eq(Device.MASTER_ID), any());
|
verify(accountsManager).updateDevice(eq(account), eq(Device.PRIMARY_ID), any());
|
||||||
verify(device).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
verify(device).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
||||||
verifyNoInteractions(apnSender);
|
verifyNoInteractions(apnSender);
|
||||||
verifyNoInteractions(apnPushNotificationScheduler);
|
verifyNoInteractions(apnPushNotificationScheduler);
|
||||||
|
@ -247,8 +247,8 @@ class PushNotificationManagerTest {
|
||||||
final Account account = mock(Account.class);
|
final Account account = mock(Account.class);
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
|
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
final PushNotification pushNotification = new PushNotification(
|
final PushNotification pushNotification = new PushNotification(
|
||||||
"token", PushNotification.TokenType.APN_VOIP, PushNotification.NotificationType.NOTIFICATION, null, account, device, true);
|
"token", PushNotification.TokenType.APN_VOIP, PushNotification.NotificationType.NOTIFICATION, null, account, device, true);
|
||||||
|
@ -262,7 +262,7 @@ class PushNotificationManagerTest {
|
||||||
pushNotificationManager.sendNotification(pushNotification);
|
pushNotificationManager.sendNotification(pushNotification);
|
||||||
|
|
||||||
verifyNoInteractions(fcmSender);
|
verifyNoInteractions(fcmSender);
|
||||||
verify(accountsManager, never()).updateDevice(eq(account), eq(Device.MASTER_ID), any());
|
verify(accountsManager, never()).updateDevice(eq(account), eq(Device.PRIMARY_ID), any());
|
||||||
verify(device, never()).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
verify(device, never()).setUninstalledFeedbackTimestamp(Util.todayInMillis());
|
||||||
verify(apnPushNotificationScheduler).cancelScheduledNotifications(account, device);
|
verify(apnPushNotificationScheduler).cancelScheduledNotifications(account, device);
|
||||||
}
|
}
|
||||||
|
@ -275,14 +275,14 @@ class PushNotificationManagerTest {
|
||||||
final String userAgent = HttpHeaders.USER_AGENT;
|
final String userAgent = HttpHeaders.USER_AGENT;
|
||||||
|
|
||||||
when(account.getUuid()).thenReturn(accountIdentifier);
|
when(account.getUuid()).thenReturn(accountIdentifier);
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
when(apnPushNotificationScheduler.cancelScheduledNotifications(account, device))
|
when(apnPushNotificationScheduler.cancelScheduledNotifications(account, device))
|
||||||
.thenReturn(CompletableFuture.completedFuture(null));
|
.thenReturn(CompletableFuture.completedFuture(null));
|
||||||
|
|
||||||
pushNotificationManager.handleMessagesRetrieved(account, device, userAgent);
|
pushNotificationManager.handleMessagesRetrieved(account, device, userAgent);
|
||||||
|
|
||||||
verify(pushLatencyManager).recordQueueRead(accountIdentifier, Device.MASTER_ID, userAgent);
|
verify(pushLatencyManager).recordQueueRead(accountIdentifier, Device.PRIMARY_ID, userAgent);
|
||||||
verify(apnPushNotificationScheduler).cancelScheduledNotifications(account, device);
|
verify(apnPushNotificationScheduler).cancelScheduledNotifications(account, device);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -171,7 +171,7 @@ public class RedisClusterExtension implements BeforeAllCallback, BeforeEachCallb
|
||||||
final StatefulRedisConnection<String, String> connection = waitClient.connect()) {
|
final StatefulRedisConnection<String, String> connection = waitClient.connect()) {
|
||||||
// CLUSTER INFO gives us a big blob of key-value pairs, but the one we're interested in is `cluster_state`.
|
// CLUSTER INFO gives us a big blob of key-value pairs, but the one we're interested in is `cluster_state`.
|
||||||
// According to https://redis.io/commands/cluster-info, `cluster_state:ok` means that the node is ready to
|
// According to https://redis.io/commands/cluster-info, `cluster_state:ok` means that the node is ready to
|
||||||
// receive queries, all slots are assigned, and a majority of master nodes are reachable.
|
// receive queries, all slots are assigned, and a majority of leader nodes are reachable.
|
||||||
|
|
||||||
final int sleepMillis = 500;
|
final int sleepMillis = 500;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
|
|
|
@ -35,8 +35,8 @@ import org.whispersystems.textsecuregcm.util.TestClock;
|
||||||
|
|
||||||
class AccountTest {
|
class AccountTest {
|
||||||
|
|
||||||
private final Device oldMasterDevice = mock(Device.class);
|
private final Device oldPrimaryDevice = mock(Device.class);
|
||||||
private final Device recentMasterDevice = mock(Device.class);
|
private final Device recentPrimaryDevice = mock(Device.class);
|
||||||
private final Device agingSecondaryDevice = mock(Device.class);
|
private final Device agingSecondaryDevice = mock(Device.class);
|
||||||
private final Device recentSecondaryDevice = mock(Device.class);
|
private final Device recentSecondaryDevice = mock(Device.class);
|
||||||
private final Device oldSecondaryDevice = mock(Device.class);
|
private final Device oldSecondaryDevice = mock(Device.class);
|
||||||
|
@ -71,13 +71,13 @@ class AccountTest {
|
||||||
|
|
||||||
@BeforeEach
|
@BeforeEach
|
||||||
void setup() {
|
void setup() {
|
||||||
when(oldMasterDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
|
when(oldPrimaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(366));
|
||||||
when(oldMasterDevice.isEnabled()).thenReturn(true);
|
when(oldPrimaryDevice.isEnabled()).thenReturn(true);
|
||||||
when(oldMasterDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(oldPrimaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
when(recentMasterDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
|
when(recentPrimaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1));
|
||||||
when(recentMasterDevice.isEnabled()).thenReturn(true);
|
when(recentPrimaryDevice.isEnabled()).thenReturn(true);
|
||||||
when(recentMasterDevice.getId()).thenReturn(Device.MASTER_ID);
|
when(recentPrimaryDevice.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
when(agingSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31));
|
when(agingSecondaryDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31));
|
||||||
when(agingSecondaryDevice.isEnabled()).thenReturn(false);
|
when(agingSecondaryDevice.isEnabled()).thenReturn(false);
|
||||||
|
@ -178,69 +178,69 @@ class AccountTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIsEnabled() {
|
void testIsEnabled() {
|
||||||
final Device enabledMasterDevice = mock(Device.class);
|
final Device enabledPrimaryDevice = mock(Device.class);
|
||||||
final Device enabledLinkedDevice = mock(Device.class);
|
final Device enabledLinkedDevice = mock(Device.class);
|
||||||
final Device disabledMasterDevice = mock(Device.class);
|
final Device disabledPrimaryDevice = mock(Device.class);
|
||||||
final Device disabledLinkedDevice = mock(Device.class);
|
final Device disabledLinkedDevice = mock(Device.class);
|
||||||
|
|
||||||
when(enabledMasterDevice.isEnabled()).thenReturn(true);
|
when(enabledPrimaryDevice.isEnabled()).thenReturn(true);
|
||||||
when(enabledLinkedDevice.isEnabled()).thenReturn(true);
|
when(enabledLinkedDevice.isEnabled()).thenReturn(true);
|
||||||
when(disabledMasterDevice.isEnabled()).thenReturn(false);
|
when(disabledPrimaryDevice.isEnabled()).thenReturn(false);
|
||||||
when(disabledLinkedDevice.isEnabled()).thenReturn(false);
|
when(disabledLinkedDevice.isEnabled()).thenReturn(false);
|
||||||
|
|
||||||
when(enabledMasterDevice.getId()).thenReturn(1L);
|
when(enabledPrimaryDevice.getId()).thenReturn(1L);
|
||||||
when(enabledLinkedDevice.getId()).thenReturn(2L);
|
when(enabledLinkedDevice.getId()).thenReturn(2L);
|
||||||
when(disabledMasterDevice.getId()).thenReturn(1L);
|
when(disabledPrimaryDevice.getId()).thenReturn(1L);
|
||||||
when(disabledLinkedDevice.getId()).thenReturn(2L);
|
when(disabledLinkedDevice.getId()).thenReturn(2L);
|
||||||
|
|
||||||
assertTrue(AccountsHelper.generateTestAccount("+14151234567", List.of(enabledMasterDevice)).isEnabled());
|
assertTrue(AccountsHelper.generateTestAccount("+14151234567", List.of(enabledPrimaryDevice)).isEnabled());
|
||||||
assertTrue(AccountsHelper.generateTestAccount("+14151234567", List.of(enabledMasterDevice, enabledLinkedDevice)).isEnabled());
|
assertTrue(AccountsHelper.generateTestAccount("+14151234567", List.of(enabledPrimaryDevice, enabledLinkedDevice)).isEnabled());
|
||||||
assertTrue(AccountsHelper.generateTestAccount("+14151234567", List.of(enabledMasterDevice, disabledLinkedDevice)).isEnabled());
|
assertTrue(AccountsHelper.generateTestAccount("+14151234567", List.of(enabledPrimaryDevice, disabledLinkedDevice)).isEnabled());
|
||||||
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledMasterDevice)).isEnabled());
|
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledPrimaryDevice)).isEnabled());
|
||||||
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledMasterDevice, enabledLinkedDevice)).isEnabled());
|
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledPrimaryDevice, enabledLinkedDevice)).isEnabled());
|
||||||
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledMasterDevice, disabledLinkedDevice)).isEnabled());
|
assertFalse(AccountsHelper.generateTestAccount("+14151234567", List.of(disabledPrimaryDevice, disabledLinkedDevice)).isEnabled());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testIsTransferSupported() {
|
void testIsTransferSupported() {
|
||||||
final Device transferCapableMasterDevice = mock(Device.class);
|
final Device transferCapablePrimaryDevice = mock(Device.class);
|
||||||
final Device nonTransferCapableMasterDevice = mock(Device.class);
|
final Device nonTransferCapablePrimaryDevice = mock(Device.class);
|
||||||
final Device transferCapableLinkedDevice = mock(Device.class);
|
final Device transferCapableLinkedDevice = mock(Device.class);
|
||||||
|
|
||||||
final DeviceCapabilities transferCapabilities = mock(DeviceCapabilities.class);
|
final DeviceCapabilities transferCapabilities = mock(DeviceCapabilities.class);
|
||||||
final DeviceCapabilities nonTransferCapabilities = mock(DeviceCapabilities.class);
|
final DeviceCapabilities nonTransferCapabilities = mock(DeviceCapabilities.class);
|
||||||
|
|
||||||
when(transferCapableMasterDevice.getId()).thenReturn(1L);
|
when(transferCapablePrimaryDevice.getId()).thenReturn(1L);
|
||||||
when(transferCapableMasterDevice.isMaster()).thenReturn(true);
|
when(transferCapablePrimaryDevice.isPrimary()).thenReturn(true);
|
||||||
when(transferCapableMasterDevice.getCapabilities()).thenReturn(transferCapabilities);
|
when(transferCapablePrimaryDevice.getCapabilities()).thenReturn(transferCapabilities);
|
||||||
|
|
||||||
when(nonTransferCapableMasterDevice.getId()).thenReturn(1L);
|
when(nonTransferCapablePrimaryDevice.getId()).thenReturn(1L);
|
||||||
when(nonTransferCapableMasterDevice.isMaster()).thenReturn(true);
|
when(nonTransferCapablePrimaryDevice.isPrimary()).thenReturn(true);
|
||||||
when(nonTransferCapableMasterDevice.getCapabilities()).thenReturn(nonTransferCapabilities);
|
when(nonTransferCapablePrimaryDevice.getCapabilities()).thenReturn(nonTransferCapabilities);
|
||||||
|
|
||||||
when(transferCapableLinkedDevice.getId()).thenReturn(2L);
|
when(transferCapableLinkedDevice.getId()).thenReturn(2L);
|
||||||
when(transferCapableLinkedDevice.isMaster()).thenReturn(false);
|
when(transferCapableLinkedDevice.isPrimary()).thenReturn(false);
|
||||||
when(transferCapableLinkedDevice.getCapabilities()).thenReturn(transferCapabilities);
|
when(transferCapableLinkedDevice.getCapabilities()).thenReturn(transferCapabilities);
|
||||||
|
|
||||||
when(transferCapabilities.transfer()).thenReturn(true);
|
when(transferCapabilities.transfer()).thenReturn(true);
|
||||||
when(nonTransferCapabilities.transfer()).thenReturn(false);
|
when(nonTransferCapabilities.transfer()).thenReturn(false);
|
||||||
|
|
||||||
{
|
{
|
||||||
final Account transferableMasterAccount =
|
final Account transferablePrimaryAccount =
|
||||||
AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(transferCapableMasterDevice), "1234".getBytes());
|
AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(transferCapablePrimaryDevice), "1234".getBytes());
|
||||||
|
|
||||||
assertTrue(transferableMasterAccount.isTransferSupported());
|
assertTrue(transferablePrimaryAccount.isTransferSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
final Account nonTransferableMasterAccount =
|
final Account nonTransferablePrimaryAccount =
|
||||||
AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(nonTransferCapableMasterDevice), "1234".getBytes());
|
AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(nonTransferCapablePrimaryDevice), "1234".getBytes());
|
||||||
|
|
||||||
assertFalse(nonTransferableMasterAccount.isTransferSupported());
|
assertFalse(nonTransferablePrimaryAccount.isTransferSupported());
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
final Account transferableLinkedAccount = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(nonTransferCapableMasterDevice, transferCapableLinkedDevice), "1234".getBytes());
|
final Account transferableLinkedAccount = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(nonTransferCapablePrimaryDevice, transferCapableLinkedDevice), "1234".getBytes());
|
||||||
|
|
||||||
assertFalse(transferableLinkedAccount.isTransferSupported());
|
assertFalse(transferableLinkedAccount.isTransferSupported());
|
||||||
}
|
}
|
||||||
|
@ -248,7 +248,7 @@ class AccountTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDiscoverableByPhoneNumber() {
|
void testDiscoverableByPhoneNumber() {
|
||||||
final Account account = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(recentMasterDevice),
|
final Account account = AccountsHelper.generateTestAccount("+14152222222", UUID.randomUUID(), UUID.randomUUID(), List.of(recentPrimaryDevice),
|
||||||
"1234".getBytes());
|
"1234".getBytes());
|
||||||
|
|
||||||
assertTrue(account.isDiscoverableByPhoneNumber(),
|
assertTrue(account.isDiscoverableByPhoneNumber(),
|
||||||
|
@ -303,7 +303,7 @@ class AccountTest {
|
||||||
@Test
|
@Test
|
||||||
void getNextDeviceId() {
|
void getNextDeviceId() {
|
||||||
|
|
||||||
final List<Device> devices = List.of(createDevice(Device.MASTER_ID));
|
final List<Device> devices = List.of(createDevice(Device.PRIMARY_ID));
|
||||||
|
|
||||||
final Account account = AccountsHelper.generateTestAccount("+14151234567", UUID.randomUUID(), UUID.randomUUID(), devices, new byte[0]);
|
final Account account = AccountsHelper.generateTestAccount("+14151234567", UUID.randomUUID(), UUID.randomUUID(), devices, new byte[0]);
|
||||||
|
|
||||||
|
@ -326,8 +326,8 @@ class AccountTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void replaceDevice() {
|
void replaceDevice() {
|
||||||
final Device firstDevice = createDevice(Device.MASTER_ID);
|
final Device firstDevice = createDevice(Device.PRIMARY_ID);
|
||||||
final Device secondDevice = createDevice(Device.MASTER_ID);
|
final Device secondDevice = createDevice(Device.PRIMARY_ID);
|
||||||
final Account account = AccountsHelper.generateTestAccount("+14151234567", UUID.randomUUID(), UUID.randomUUID(), List.of(firstDevice), new byte[0]);
|
final Account account = AccountsHelper.generateTestAccount("+14151234567", UUID.randomUUID(), UUID.randomUUID(), List.of(firstDevice), new byte[0]);
|
||||||
|
|
||||||
assertEquals(List.of(firstDevice), account.getDevices());
|
assertEquals(List.of(firstDevice), account.getDevices());
|
||||||
|
@ -339,7 +339,7 @@ class AccountTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void addAndRemoveBadges() {
|
void addAndRemoveBadges() {
|
||||||
final Account account = AccountsHelper.generateTestAccount("+14151234567", UUID.randomUUID(), UUID.randomUUID(), List.of(createDevice(Device.MASTER_ID)), new byte[0]);
|
final Account account = AccountsHelper.generateTestAccount("+14151234567", UUID.randomUUID(), UUID.randomUUID(), List.of(createDevice(Device.PRIMARY_ID)), new byte[0]);
|
||||||
final Clock clock = TestClock.pinned(Instant.ofEpochSecond(40));
|
final Clock clock = TestClock.pinned(Instant.ofEpochSecond(40));
|
||||||
|
|
||||||
account.addBadge(clock, new AccountBadge("foo", Instant.ofEpochSecond(42), false));
|
account.addBadge(clock, new AccountBadge("foo", Instant.ofEpochSecond(42), false));
|
||||||
|
|
|
@ -175,14 +175,14 @@ class AccountsManagerChangeNumberIntegrationTest {
|
||||||
|
|
||||||
final AccountAttributes accountAttributes = new AccountAttributes(true, rotatedPniRegistrationId + 1, "test", null, true, new Device.DeviceCapabilities(false, false, false, false));
|
final AccountAttributes accountAttributes = new AccountAttributes(true, rotatedPniRegistrationId + 1, "test", null, true, new Device.DeviceCapabilities(false, false, false, false));
|
||||||
final Account account = accountsManager.create(originalNumber, "password", null, accountAttributes, new ArrayList<>());
|
final Account account = accountsManager.create(originalNumber, "password", null, accountAttributes, new ArrayList<>());
|
||||||
account.getMasterDevice().orElseThrow().setSignedPreKey(KeysHelper.signedECPreKey(1, pniIdentityKeyPair));
|
account.getPrimaryDevice().orElseThrow().setSignedPreKey(KeysHelper.signedECPreKey(1, pniIdentityKeyPair));
|
||||||
|
|
||||||
final UUID originalUuid = account.getUuid();
|
final UUID originalUuid = account.getUuid();
|
||||||
final UUID originalPni = account.getPhoneNumberIdentifier();
|
final UUID originalPni = account.getPhoneNumberIdentifier();
|
||||||
|
|
||||||
final IdentityKey pniIdentityKey = new IdentityKey(pniIdentityKeyPair.getPublicKey());
|
final IdentityKey pniIdentityKey = new IdentityKey(pniIdentityKeyPair.getPublicKey());
|
||||||
final Map<Long, ECSignedPreKey> preKeys = Map.of(Device.MASTER_ID, rotatedSignedPreKey);
|
final Map<Long, ECSignedPreKey> preKeys = Map.of(Device.PRIMARY_ID, rotatedSignedPreKey);
|
||||||
final Map<Long, Integer> registrationIds = Map.of(Device.MASTER_ID, rotatedPniRegistrationId);
|
final Map<Long, Integer> registrationIds = Map.of(Device.PRIMARY_ID, rotatedPniRegistrationId);
|
||||||
|
|
||||||
final Account updatedAccount = accountsManager.changeNumber(account, secondNumber, pniIdentityKey, preKeys, null, registrationIds);
|
final Account updatedAccount = accountsManager.changeNumber(account, secondNumber, pniIdentityKey, preKeys, null, registrationIds);
|
||||||
|
|
||||||
|
@ -200,9 +200,9 @@ class AccountsManagerChangeNumberIntegrationTest {
|
||||||
assertEquals(pniIdentityKey, updatedAccount.getIdentityKey(IdentityType.PNI));
|
assertEquals(pniIdentityKey, updatedAccount.getIdentityKey(IdentityType.PNI));
|
||||||
|
|
||||||
assertEquals(OptionalInt.of(rotatedPniRegistrationId),
|
assertEquals(OptionalInt.of(rotatedPniRegistrationId),
|
||||||
updatedAccount.getMasterDevice().orElseThrow().getPhoneNumberIdentityRegistrationId());
|
updatedAccount.getPrimaryDevice().orElseThrow().getPhoneNumberIdentityRegistrationId());
|
||||||
|
|
||||||
assertEquals(rotatedSignedPreKey, updatedAccount.getMasterDevice().orElseThrow().getSignedPreKey(IdentityType.PNI));
|
assertEquals(rotatedSignedPreKey, updatedAccount.getPrimaryDevice().orElseThrow().getSignedPreKey(IdentityType.PNI));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -249,7 +249,7 @@ class AccountsManagerChangeNumberIntegrationTest {
|
||||||
|
|
||||||
assertEquals(secondNumber, accountsManager.getByAccountIdentifier(originalUuid).map(Account::getNumber).orElseThrow());
|
assertEquals(secondNumber, accountsManager.getByAccountIdentifier(originalUuid).map(Account::getNumber).orElseThrow());
|
||||||
|
|
||||||
verify(clientPresenceManager).disconnectPresence(existingAccountUuid, Device.MASTER_ID);
|
verify(clientPresenceManager).disconnectPresence(existingAccountUuid, Device.PRIMARY_ID);
|
||||||
|
|
||||||
assertEquals(Optional.of(existingAccountUuid), accountsManager.findRecentlyDeletedAccountIdentifier(originalNumber));
|
assertEquals(Optional.of(existingAccountUuid), accountsManager.findRecentlyDeletedAccountIdentifier(originalNumber));
|
||||||
assertEquals(Optional.empty(), accountsManager.findRecentlyDeletedAccountIdentifier(secondNumber));
|
assertEquals(Optional.empty(), accountsManager.findRecentlyDeletedAccountIdentifier(secondNumber));
|
||||||
|
|
|
@ -168,8 +168,8 @@ class AccountsManagerConcurrentModificationIntegrationTest {
|
||||||
modifyAccount(uuid, account -> account.setUnidentifiedAccessKey(unidentifiedAccessKey)),
|
modifyAccount(uuid, account -> account.setUnidentifiedAccessKey(unidentifiedAccessKey)),
|
||||||
modifyAccount(uuid, account -> account.setRegistrationLock(credentials.hash(), credentials.salt())),
|
modifyAccount(uuid, account -> account.setRegistrationLock(credentials.hash(), credentials.salt())),
|
||||||
modifyAccount(uuid, account -> account.setUnrestrictedUnidentifiedAccess(unrestrictedUnidentifiedAccess)),
|
modifyAccount(uuid, account -> account.setUnrestrictedUnidentifiedAccess(unrestrictedUnidentifiedAccess)),
|
||||||
modifyDevice(uuid, Device.MASTER_ID, device -> device.setLastSeen(lastSeen)),
|
modifyDevice(uuid, Device.PRIMARY_ID, device -> device.setLastSeen(lastSeen)),
|
||||||
modifyDevice(uuid, Device.MASTER_ID, device -> device.setName("deviceName"))
|
modifyDevice(uuid, Device.PRIMARY_ID, device -> device.setName("deviceName"))
|
||||||
).join();
|
).join();
|
||||||
|
|
||||||
final Account managerAccount = accountsManager.getByAccountIdentifier(uuid).orElseThrow();
|
final Account managerAccount = accountsManager.getByAccountIdentifier(uuid).orElseThrow();
|
||||||
|
|
|
@ -1530,8 +1530,8 @@ class AccountsManagerTest {
|
||||||
|
|
||||||
assertEquals(originalAccount.getDevices().size(), parsedAccount.getDevices().size());
|
assertEquals(originalAccount.getDevices().size(), parsedAccount.getDevices().size());
|
||||||
|
|
||||||
final Device originalDevice = originalAccount.getMasterDevice().orElseThrow();
|
final Device originalDevice = originalAccount.getPrimaryDevice().orElseThrow();
|
||||||
final Device parsedDevice = parsedAccount.getMasterDevice().orElseThrow();
|
final Device parsedDevice = parsedAccount.getPrimaryDevice().orElseThrow();
|
||||||
|
|
||||||
assertEquals(originalDevice.getId(), parsedDevice.getId());
|
assertEquals(originalDevice.getId(), parsedDevice.getId());
|
||||||
assertEquals(originalDevice.getSignedPreKey(IdentityType.ACI), parsedDevice.getSignedPreKey(IdentityType.ACI));
|
assertEquals(originalDevice.getSignedPreKey(IdentityType.ACI), parsedDevice.getSignedPreKey(IdentityType.ACI));
|
||||||
|
@ -1549,7 +1549,7 @@ class AccountsManagerTest {
|
||||||
|
|
||||||
private static Device generateTestDevice(final long lastSeen) {
|
private static Device generateTestDevice(final long lastSeen) {
|
||||||
final Device device = new Device();
|
final Device device = new Device();
|
||||||
device.setId(Device.MASTER_ID);
|
device.setId(Device.PRIMARY_ID);
|
||||||
device.setFetchesMessages(true);
|
device.setFetchesMessages(true);
|
||||||
device.setSignedPreKey(KeysHelper.signedECPreKey(1, Curve.generateKeyPair()));
|
device.setSignedPreKey(KeysHelper.signedECPreKey(1, Curve.generateKeyPair()));
|
||||||
device.setLastSeen(lastSeen);
|
device.setLastSeen(lastSeen);
|
||||||
|
|
|
@ -158,7 +158,7 @@ public class ChangeNumberManagerTest {
|
||||||
|
|
||||||
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
||||||
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
||||||
assertEquals(Device.MASTER_ID, envelope.getSourceDevice());
|
assertEquals(Device.PRIMARY_ID, envelope.getSourceDevice());
|
||||||
assertEquals(updatedPhoneNumberIdentifiersByAccount.get(account), UUID.fromString(envelope.getUpdatedPni()));
|
assertEquals(updatedPhoneNumberIdentifiersByAccount.get(account), UUID.fromString(envelope.getUpdatedPni()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -203,7 +203,7 @@ public class ChangeNumberManagerTest {
|
||||||
|
|
||||||
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
||||||
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
||||||
assertEquals(Device.MASTER_ID, envelope.getSourceDevice());
|
assertEquals(Device.PRIMARY_ID, envelope.getSourceDevice());
|
||||||
assertEquals(updatedPhoneNumberIdentifiersByAccount.get(account), UUID.fromString(envelope.getUpdatedPni()));
|
assertEquals(updatedPhoneNumberIdentifiersByAccount.get(account), UUID.fromString(envelope.getUpdatedPni()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -246,7 +246,7 @@ public class ChangeNumberManagerTest {
|
||||||
|
|
||||||
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
||||||
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
||||||
assertEquals(Device.MASTER_ID, envelope.getSourceDevice());
|
assertEquals(Device.PRIMARY_ID, envelope.getSourceDevice());
|
||||||
assertFalse(updatedPhoneNumberIdentifiersByAccount.containsKey(account));
|
assertFalse(updatedPhoneNumberIdentifiersByAccount.containsKey(account));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -286,7 +286,7 @@ public class ChangeNumberManagerTest {
|
||||||
|
|
||||||
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
||||||
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
||||||
assertEquals(Device.MASTER_ID, envelope.getSourceDevice());
|
assertEquals(Device.PRIMARY_ID, envelope.getSourceDevice());
|
||||||
assertFalse(updatedPhoneNumberIdentifiersByAccount.containsKey(account));
|
assertFalse(updatedPhoneNumberIdentifiersByAccount.containsKey(account));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -327,7 +327,7 @@ public class ChangeNumberManagerTest {
|
||||||
|
|
||||||
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getDestinationUuid()));
|
||||||
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
assertEquals(aci, UUID.fromString(envelope.getSourceUuid()));
|
||||||
assertEquals(Device.MASTER_ID, envelope.getSourceDevice());
|
assertEquals(Device.PRIMARY_ID, envelope.getSourceDevice());
|
||||||
assertFalse(updatedPhoneNumberIdentifiersByAccount.containsKey(account));
|
assertFalse(updatedPhoneNumberIdentifiersByAccount.containsKey(account));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -19,13 +19,13 @@ class DeviceTest {
|
||||||
|
|
||||||
@ParameterizedTest
|
@ParameterizedTest
|
||||||
@MethodSource
|
@MethodSource
|
||||||
void testIsEnabled(final boolean master, final boolean fetchesMessages, final String apnId, final String gcmId,
|
void testIsEnabled(final boolean primary, final boolean fetchesMessages, final String apnId, final String gcmId,
|
||||||
final ECSignedPreKey signedPreKey, final Duration timeSinceLastSeen, final boolean expectEnabled) {
|
final ECSignedPreKey signedPreKey, final Duration timeSinceLastSeen, final boolean expectEnabled) {
|
||||||
|
|
||||||
final long lastSeen = System.currentTimeMillis() - timeSinceLastSeen.toMillis();
|
final long lastSeen = System.currentTimeMillis() - timeSinceLastSeen.toMillis();
|
||||||
|
|
||||||
final Device device = new Device();
|
final Device device = new Device();
|
||||||
device.setId(master ? Device.MASTER_ID : Device.MASTER_ID + 1);
|
device.setId(primary ? Device.PRIMARY_ID : Device.PRIMARY_ID + 1);
|
||||||
device.setFetchesMessages(fetchesMessages);
|
device.setFetchesMessages(fetchesMessages);
|
||||||
device.setApnId(apnId);
|
device.setApnId(apnId);
|
||||||
device.setGcmId(gcmId);
|
device.setGcmId(gcmId);
|
||||||
|
@ -38,7 +38,7 @@ class DeviceTest {
|
||||||
|
|
||||||
private static Stream<Arguments> testIsEnabled() {
|
private static Stream<Arguments> testIsEnabled() {
|
||||||
return Stream.of(
|
return Stream.of(
|
||||||
// master fetchesMessages apnId gcmId signedPreKey lastSeen expectEnabled
|
// primary fetchesMessages apnId gcmId signedPreKey lastSeen expectEnabled
|
||||||
Arguments.of(true, false, null, null, null, Duration.ofDays(60), false),
|
Arguments.of(true, false, null, null, null, Duration.ofDays(60), false),
|
||||||
Arguments.of(true, false, null, null, null, Duration.ofDays(1), false),
|
Arguments.of(true, false, null, null, null, Duration.ofDays(1), false),
|
||||||
Arguments.of(true, false, null, null, mock(ECSignedPreKey.class), Duration.ofDays(60), false),
|
Arguments.of(true, false, null, null, mock(ECSignedPreKey.class), Duration.ofDays(60), false),
|
||||||
|
|
|
@ -117,7 +117,7 @@ public class AccountsHelper {
|
||||||
case "getUsernameHash" -> when(updatedAccount.getUsernameHash()).thenAnswer(stubbing);
|
case "getUsernameHash" -> when(updatedAccount.getUsernameHash()).thenAnswer(stubbing);
|
||||||
case "getDevices" -> when(updatedAccount.getDevices()).thenAnswer(stubbing);
|
case "getDevices" -> when(updatedAccount.getDevices()).thenAnswer(stubbing);
|
||||||
case "getDevice" -> when(updatedAccount.getDevice(stubbing.getInvocation().getArgument(0))).thenAnswer(stubbing);
|
case "getDevice" -> when(updatedAccount.getDevice(stubbing.getInvocation().getArgument(0))).thenAnswer(stubbing);
|
||||||
case "getMasterDevice" -> when(updatedAccount.getMasterDevice()).thenAnswer(stubbing);
|
case "getPrimaryDevice" -> when(updatedAccount.getPrimaryDevice()).thenAnswer(stubbing);
|
||||||
case "isEnabled" -> when(updatedAccount.isEnabled()).thenAnswer(stubbing);
|
case "isEnabled" -> when(updatedAccount.isEnabled()).thenAnswer(stubbing);
|
||||||
case "isDiscoverableByPhoneNumber" -> when(updatedAccount.isDiscoverableByPhoneNumber()).thenAnswer(stubbing);
|
case "isDiscoverableByPhoneNumber" -> when(updatedAccount.isDiscoverableByPhoneNumber()).thenAnswer(stubbing);
|
||||||
case "getNextDeviceId" -> when(updatedAccount.getNextDeviceId()).thenAnswer(stubbing);
|
case "getNextDeviceId" -> when(updatedAccount.getNextDeviceId()).thenAnswer(stubbing);
|
||||||
|
|
|
@ -105,12 +105,12 @@ public class AuthHelper {
|
||||||
when(DISABLED_DEVICE.getAuthTokenHash()).thenReturn(DISABLED_CREDENTIALS);
|
when(DISABLED_DEVICE.getAuthTokenHash()).thenReturn(DISABLED_CREDENTIALS);
|
||||||
when(UNDISCOVERABLE_DEVICE.getAuthTokenHash()).thenReturn(UNDISCOVERABLE_CREDENTIALS);
|
when(UNDISCOVERABLE_DEVICE.getAuthTokenHash()).thenReturn(UNDISCOVERABLE_CREDENTIALS);
|
||||||
|
|
||||||
when(VALID_DEVICE.isMaster()).thenReturn(true);
|
when(VALID_DEVICE.isPrimary()).thenReturn(true);
|
||||||
when(VALID_DEVICE_TWO.isMaster()).thenReturn(true);
|
when(VALID_DEVICE_TWO.isPrimary()).thenReturn(true);
|
||||||
when(DISABLED_DEVICE.isMaster()).thenReturn(true);
|
when(DISABLED_DEVICE.isPrimary()).thenReturn(true);
|
||||||
when(UNDISCOVERABLE_DEVICE.isMaster()).thenReturn(true);
|
when(UNDISCOVERABLE_DEVICE.isPrimary()).thenReturn(true);
|
||||||
when(VALID_DEVICE_3_PRIMARY.isMaster()).thenReturn(true);
|
when(VALID_DEVICE_3_PRIMARY.isPrimary()).thenReturn(true);
|
||||||
when(VALID_DEVICE_3_LINKED.isMaster()).thenReturn(false);
|
when(VALID_DEVICE_3_LINKED.isPrimary()).thenReturn(false);
|
||||||
|
|
||||||
when(VALID_DEVICE.getId()).thenReturn(1L);
|
when(VALID_DEVICE.getId()).thenReturn(1L);
|
||||||
when(VALID_DEVICE_TWO.getId()).thenReturn(1L);
|
when(VALID_DEVICE_TWO.getId()).thenReturn(1L);
|
||||||
|
@ -122,20 +122,20 @@ public class AuthHelper {
|
||||||
when(VALID_DEVICE.isEnabled()).thenReturn(true);
|
when(VALID_DEVICE.isEnabled()).thenReturn(true);
|
||||||
when(VALID_DEVICE_TWO.isEnabled()).thenReturn(true);
|
when(VALID_DEVICE_TWO.isEnabled()).thenReturn(true);
|
||||||
when(DISABLED_DEVICE.isEnabled()).thenReturn(false);
|
when(DISABLED_DEVICE.isEnabled()).thenReturn(false);
|
||||||
when(UNDISCOVERABLE_DEVICE.isMaster()).thenReturn(true);
|
when(UNDISCOVERABLE_DEVICE.isPrimary()).thenReturn(true);
|
||||||
when(VALID_DEVICE_3_PRIMARY.isEnabled()).thenReturn(true);
|
when(VALID_DEVICE_3_PRIMARY.isEnabled()).thenReturn(true);
|
||||||
when(VALID_DEVICE_3_LINKED.isEnabled()).thenReturn(true);
|
when(VALID_DEVICE_3_LINKED.isEnabled()).thenReturn(true);
|
||||||
|
|
||||||
when(VALID_ACCOUNT.getDevice(1L)).thenReturn(Optional.of(VALID_DEVICE));
|
when(VALID_ACCOUNT.getDevice(1L)).thenReturn(Optional.of(VALID_DEVICE));
|
||||||
when(VALID_ACCOUNT.getMasterDevice()).thenReturn(Optional.of(VALID_DEVICE));
|
when(VALID_ACCOUNT.getPrimaryDevice()).thenReturn(Optional.of(VALID_DEVICE));
|
||||||
when(VALID_ACCOUNT_TWO.getDevice(eq(1L))).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
when(VALID_ACCOUNT_TWO.getDevice(eq(1L))).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
||||||
when(VALID_ACCOUNT_TWO.getMasterDevice()).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
when(VALID_ACCOUNT_TWO.getPrimaryDevice()).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
||||||
when(DISABLED_ACCOUNT.getDevice(eq(1L))).thenReturn(Optional.of(DISABLED_DEVICE));
|
when(DISABLED_ACCOUNT.getDevice(eq(1L))).thenReturn(Optional.of(DISABLED_DEVICE));
|
||||||
when(DISABLED_ACCOUNT.getMasterDevice()).thenReturn(Optional.of(DISABLED_DEVICE));
|
when(DISABLED_ACCOUNT.getPrimaryDevice()).thenReturn(Optional.of(DISABLED_DEVICE));
|
||||||
when(UNDISCOVERABLE_ACCOUNT.getDevice(eq(1L))).thenReturn(Optional.of(UNDISCOVERABLE_DEVICE));
|
when(UNDISCOVERABLE_ACCOUNT.getDevice(eq(1L))).thenReturn(Optional.of(UNDISCOVERABLE_DEVICE));
|
||||||
when(UNDISCOVERABLE_ACCOUNT.getMasterDevice()).thenReturn(Optional.of(UNDISCOVERABLE_DEVICE));
|
when(UNDISCOVERABLE_ACCOUNT.getPrimaryDevice()).thenReturn(Optional.of(UNDISCOVERABLE_DEVICE));
|
||||||
when(VALID_ACCOUNT_3.getDevice(1L)).thenReturn(Optional.of(VALID_DEVICE_3_PRIMARY));
|
when(VALID_ACCOUNT_3.getDevice(1L)).thenReturn(Optional.of(VALID_DEVICE_3_PRIMARY));
|
||||||
when(VALID_ACCOUNT_3.getMasterDevice()).thenReturn(Optional.of(VALID_DEVICE_3_PRIMARY));
|
when(VALID_ACCOUNT_3.getPrimaryDevice()).thenReturn(Optional.of(VALID_DEVICE_3_PRIMARY));
|
||||||
when(VALID_ACCOUNT_3.getDevice(2L)).thenReturn(Optional.of(VALID_DEVICE_3_LINKED));
|
when(VALID_ACCOUNT_3.getDevice(2L)).thenReturn(Optional.of(VALID_DEVICE_3_LINKED));
|
||||||
|
|
||||||
when(VALID_ACCOUNT_TWO.getEnabledDeviceCount()).thenReturn(6);
|
when(VALID_ACCOUNT_TWO.getEnabledDeviceCount()).thenReturn(6);
|
||||||
|
@ -250,11 +250,11 @@ public class AuthHelper {
|
||||||
private void setup(final AccountsManager accountsManager) {
|
private void setup(final AccountsManager accountsManager) {
|
||||||
when(saltedTokenHash.verify(password)).thenReturn(true);
|
when(saltedTokenHash.verify(password)).thenReturn(true);
|
||||||
when(device.getAuthTokenHash()).thenReturn(saltedTokenHash);
|
when(device.getAuthTokenHash()).thenReturn(saltedTokenHash);
|
||||||
when(device.isMaster()).thenReturn(true);
|
when(device.isPrimary()).thenReturn(true);
|
||||||
when(device.getId()).thenReturn(1L);
|
when(device.getId()).thenReturn(1L);
|
||||||
when(device.isEnabled()).thenReturn(true);
|
when(device.isEnabled()).thenReturn(true);
|
||||||
when(account.getDevice(1L)).thenReturn(Optional.of(device));
|
when(account.getDevice(1L)).thenReturn(Optional.of(device));
|
||||||
when(account.getMasterDevice()).thenReturn(Optional.of(device));
|
when(account.getPrimaryDevice()).thenReturn(Optional.of(device));
|
||||||
when(account.getNumber()).thenReturn(number);
|
when(account.getNumber()).thenReturn(number);
|
||||||
when(account.getUuid()).thenReturn(uuid);
|
when(account.getUuid()).thenReturn(uuid);
|
||||||
when(account.isEnabled()).thenReturn(true);
|
when(account.isEnabled()).thenReturn(true);
|
||||||
|
|
|
@ -192,24 +192,24 @@ class DestinationDeviceValidatorTest {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testDuplicateDeviceIds() {
|
void testDuplicateDeviceIds() {
|
||||||
final Account account = mockAccountWithDeviceAndRegId(Map.of(Device.MASTER_ID, 17));
|
final Account account = mockAccountWithDeviceAndRegId(Map.of(Device.PRIMARY_ID, 17));
|
||||||
try {
|
try {
|
||||||
DestinationDeviceValidator.validateRegistrationIds(account,
|
DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, 16), new Pair<>(Device.MASTER_ID, 17)), false);
|
Stream.of(new Pair<>(Device.PRIMARY_ID, 16), new Pair<>(Device.PRIMARY_ID, 17)), false);
|
||||||
Assertions.fail("duplicate devices should throw StaleDevicesException");
|
Assertions.fail("duplicate devices should throw StaleDevicesException");
|
||||||
} catch (StaleDevicesException e) {
|
} catch (StaleDevicesException e) {
|
||||||
Assertions.assertThat(e.getStaleDevices()).hasSameElementsAs(Collections.singletonList(Device.MASTER_ID));
|
Assertions.assertThat(e.getStaleDevices()).hasSameElementsAs(Collections.singletonList(Device.PRIMARY_ID));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void testValidatePniRegistrationIds() {
|
void testValidatePniRegistrationIds() {
|
||||||
final Device device = mock(Device.class);
|
final Device device = mock(Device.class);
|
||||||
when(device.getId()).thenReturn(Device.MASTER_ID);
|
when(device.getId()).thenReturn(Device.PRIMARY_ID);
|
||||||
|
|
||||||
final Account account = mock(Account.class);
|
final Account account = mock(Account.class);
|
||||||
when(account.getDevices()).thenReturn(List.of(device));
|
when(account.getDevices()).thenReturn(List.of(device));
|
||||||
when(account.getDevice(Device.MASTER_ID)).thenReturn(Optional.of(device));
|
when(account.getDevice(Device.PRIMARY_ID)).thenReturn(Optional.of(device));
|
||||||
|
|
||||||
final int aciRegistrationId = 17;
|
final int aciRegistrationId = 17;
|
||||||
final int pniRegistrationId = 89;
|
final int pniRegistrationId = 89;
|
||||||
|
@ -220,33 +220,33 @@ class DestinationDeviceValidatorTest {
|
||||||
|
|
||||||
assertDoesNotThrow(
|
assertDoesNotThrow(
|
||||||
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, aciRegistrationId)), false));
|
Stream.of(new Pair<>(Device.PRIMARY_ID, aciRegistrationId)), false));
|
||||||
assertDoesNotThrow(
|
assertDoesNotThrow(
|
||||||
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, pniRegistrationId)),
|
Stream.of(new Pair<>(Device.PRIMARY_ID, pniRegistrationId)),
|
||||||
true));
|
true));
|
||||||
assertThrows(StaleDevicesException.class,
|
assertThrows(StaleDevicesException.class,
|
||||||
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, aciRegistrationId)),
|
Stream.of(new Pair<>(Device.PRIMARY_ID, aciRegistrationId)),
|
||||||
true));
|
true));
|
||||||
assertThrows(StaleDevicesException.class,
|
assertThrows(StaleDevicesException.class,
|
||||||
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, pniRegistrationId)),
|
Stream.of(new Pair<>(Device.PRIMARY_ID, pniRegistrationId)),
|
||||||
false));
|
false));
|
||||||
|
|
||||||
when(device.getPhoneNumberIdentityRegistrationId()).thenReturn(OptionalInt.empty());
|
when(device.getPhoneNumberIdentityRegistrationId()).thenReturn(OptionalInt.empty());
|
||||||
|
|
||||||
assertDoesNotThrow(
|
assertDoesNotThrow(
|
||||||
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, aciRegistrationId)),
|
Stream.of(new Pair<>(Device.PRIMARY_ID, aciRegistrationId)),
|
||||||
false));
|
false));
|
||||||
assertDoesNotThrow(
|
assertDoesNotThrow(
|
||||||
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
() -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, aciRegistrationId)),
|
Stream.of(new Pair<>(Device.PRIMARY_ID, aciRegistrationId)),
|
||||||
true));
|
true));
|
||||||
assertThrows(StaleDevicesException.class, () -> DestinationDeviceValidator.validateRegistrationIds(account,
|
assertThrows(StaleDevicesException.class, () -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, incorrectRegistrationId)), true));
|
Stream.of(new Pair<>(Device.PRIMARY_ID, incorrectRegistrationId)), true));
|
||||||
assertThrows(StaleDevicesException.class, () -> DestinationDeviceValidator.validateRegistrationIds(account,
|
assertThrows(StaleDevicesException.class, () -> DestinationDeviceValidator.validateRegistrationIds(account,
|
||||||
Stream.of(new Pair<>(Device.MASTER_ID, incorrectRegistrationId)), false));
|
Stream.of(new Pair<>(Device.PRIMARY_ID, incorrectRegistrationId)), false));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue