diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/auth/StoredRegistrationLock.java b/service/src/main/java/org/whispersystems/textsecuregcm/auth/StoredRegistrationLock.java new file mode 100644 index 000000000..208aaf190 --- /dev/null +++ b/service/src/main/java/org/whispersystems/textsecuregcm/auth/StoredRegistrationLock.java @@ -0,0 +1,59 @@ +package org.whispersystems.textsecuregcm.auth; + +import com.google.common.annotations.VisibleForTesting; +import org.whispersystems.textsecuregcm.util.Util; + +import javax.annotation.Nullable; +import java.security.MessageDigest; +import java.util.Optional; +import java.util.concurrent.TimeUnit; + +@SuppressWarnings("OptionalUsedAsFieldOrParameterType") +public class StoredRegistrationLock { + + private final Optional registrationLock; + + private final Optional registrationLockSalt; + + private final Optional deprecatedPin; + + private final long lastSeen; + + public StoredRegistrationLock(Optional registrationLock, Optional registrationLockSalt, Optional deprecatedPin, long lastSeen) { + this.registrationLock = registrationLock; + this.registrationLockSalt = registrationLockSalt; + this.deprecatedPin = deprecatedPin; + this.lastSeen = lastSeen; + } + + public boolean requiresClientRegistrationLock() { + return ((registrationLock.isPresent() && registrationLockSalt.isPresent()) || deprecatedPin.isPresent()) && System.currentTimeMillis() - lastSeen < TimeUnit.DAYS.toMillis(7); + } + + public boolean needsFailureCredentials() { + return registrationLock.isPresent() && registrationLockSalt.isPresent(); + } + + public long getTimeRemaining() { + return TimeUnit.DAYS.toMillis(7) - (System.currentTimeMillis() - lastSeen); + } + + public boolean verify(@Nullable String clientRegistrationLock, @Nullable String clientDeprecatedPin) { + if (Util.isEmpty(clientRegistrationLock) && Util.isEmpty(clientDeprecatedPin)) { + return false; + } + + if (registrationLock.isPresent() && registrationLockSalt.isPresent() && !Util.isEmpty(clientRegistrationLock)) { + return new AuthenticationCredentials(registrationLock.get(), registrationLockSalt.get()).verify(clientRegistrationLock); + } else if (deprecatedPin.isPresent() && !Util.isEmpty(clientDeprecatedPin)) { + return MessageDigest.isEqual(deprecatedPin.get().getBytes(), clientDeprecatedPin.getBytes()); + } else { + return false; + } + } + + @VisibleForTesting + public StoredRegistrationLock forTime(long timestamp) { + return new StoredRegistrationLock(registrationLock, registrationLockSalt, deprecatedPin, timestamp); + } +} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java index 35cc5caa5..37da991c6 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java @@ -29,6 +29,7 @@ import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; import org.whispersystems.textsecuregcm.auth.InvalidAuthorizationHeaderException; +import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock; import org.whispersystems.textsecuregcm.auth.StoredVerificationCode; import org.whispersystems.textsecuregcm.auth.TurnToken; import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator; @@ -74,14 +75,12 @@ import javax.ws.rs.QueryParam; import javax.ws.rs.WebApplicationException; import javax.ws.rs.core.MediaType; import javax.ws.rs.core.Response; -import java.security.MessageDigest; import java.security.SecureRandom; import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.UUID; -import java.util.concurrent.TimeUnit; import static com.codahale.metrics.MetricRegistry.name; import io.dropwizard.auth.Auth; @@ -270,48 +269,26 @@ public class AccountController { Optional storedVerificationCode = pendingAccounts.getCodeForNumber(number); - if (!storedVerificationCode.isPresent() || !storedVerificationCode.get().isValid(verificationCode)) { + if (storedVerificationCode.isEmpty() || !storedVerificationCode.get().isValid(verificationCode)) { throw new WebApplicationException(Response.status(403).build()); } - Optional existingAccount = accounts.get(number); + Optional existingAccount = accounts.get(number); + Optional existingRegistrationLock = existingAccount.map(Account::getRegistrationLock); + Optional existingBackupCredentials = existingAccount.map(Account::getUuid) + .map(uuid -> backupServiceCredentialGenerator.generateFor(uuid.toString())); - if (existingAccount.isPresent() && - (existingAccount.get().getPin().isPresent() || existingAccount.get().getRegistrationLock().isPresent()) && - System.currentTimeMillis() - existingAccount.get().getLastSeen() < TimeUnit.DAYS.toMillis(7)) - { + if (existingRegistrationLock.isPresent() && existingRegistrationLock.get().requiresClientRegistrationLock()) { rateLimiters.getVerifyLimiter().clear(number); - long timeRemaining = TimeUnit.DAYS.toMillis(7) - (System.currentTimeMillis() - existingAccount.get().getLastSeen()); - Optional credentials = existingAccount.get().getRegistrationLock().isPresent() && - existingAccount.get().getRegistrationLockSalt().isPresent() ? - Optional.of(backupServiceCredentialGenerator.generateFor(existingAccount.get().getUuid().toString())) : - Optional.empty(); - - if (Util.isEmpty(accountAttributes.getPin()) && - Util.isEmpty(accountAttributes.getRegistrationLock())) - { - throw new WebApplicationException(Response.status(423) - .entity(new RegistrationLockFailure(timeRemaining, credentials.orElse(null))) - .build()); + if (!Util.isEmpty(accountAttributes.getRegistrationLock()) || !Util.isEmpty(accountAttributes.getPin())) { + rateLimiters.getPinLimiter().validate(number); } - rateLimiters.getPinLimiter().validate(number); - - boolean pinMatches; - - if (existingAccount.get().getRegistrationLock().isPresent() && existingAccount.get().getRegistrationLockSalt().isPresent()) { - pinMatches = new AuthenticationCredentials(existingAccount.get().getRegistrationLock().get(), - existingAccount.get().getRegistrationLockSalt().get()).verify(accountAttributes.getRegistrationLock()); - } else if (existingAccount.get().getPin().isPresent()) { - pinMatches = MessageDigest.isEqual(existingAccount.get().getPin().get().getBytes(), accountAttributes.getPin().getBytes()); - } else { - throw new AssertionError("Invalid registration lock state"); - } - - if (!pinMatches) { + if (!existingRegistrationLock.get().verify(accountAttributes.getRegistrationLock(), accountAttributes.getPin())) { throw new WebApplicationException(Response.status(423) - .entity(new RegistrationLockFailure(timeRemaining, credentials.orElse(null))) + .entity(new RegistrationLockFailure(existingRegistrationLock.get().getTimeRemaining(), + existingRegistrationLock.get().needsFailureCredentials() ? existingBackupCredentials.orElseThrow() : null)) .build()); } @@ -322,7 +299,7 @@ public class AccountController { metricRegistry.meter(name(AccountController.class, "verify", Util.getCountryCode(number))).mark(); - return new AccountCreationResult(account.getUuid()); + return new AccountCreationResult(account.getUuid(), existingAccount.map(Account::isStorageSupported).orElse(false) ? existingBackupCredentials.orElse(null) : null); } catch (InvalidAuthorizationHeaderException e) { logger.info("Bad Authorization Header", e); throw new WebApplicationException(Response.status(401).build()); @@ -423,8 +400,7 @@ public class AccountController { @Path("/registration_lock") public void setRegistrationLock(@Auth Account account, @Valid RegistrationLock accountLock) { AuthenticationCredentials credentials = new AuthenticationCredentials(accountLock.getRegistrationLock()); - account.setRegistrationLock(credentials.getHashedAuthenticationToken()); - account.setRegistrationLockSalt(credentials.getSalt()); + account.setRegistrationLock(credentials.getHashedAuthenticationToken(), credentials.getSalt()); account.setPin(null); accounts.update(account); @@ -434,8 +410,7 @@ public class AccountController { @DELETE @Path("/registration_lock") public void removeRegistrationLock(@Auth Account account) { - account.setRegistrationLock(null); - account.setRegistrationLockSalt(null); + account.setRegistrationLock(null, null); accounts.update(account); } @@ -445,8 +420,7 @@ public class AccountController { @Path("/pin/") public void setPin(@Auth Account account, @Valid DeprecatedPin accountLock) { account.setPin(accountLock.getPin()); - account.setRegistrationLock(null); - account.setRegistrationLockSalt(null); + account.setRegistrationLock(null, null); accounts.update(account); } @@ -500,12 +474,10 @@ public class AccountController { account.setPin(attributes.getPin()); } else if (!Util.isEmpty(attributes.getRegistrationLock())) { AuthenticationCredentials credentials = new AuthenticationCredentials(attributes.getRegistrationLock()); - account.setRegistrationLock(credentials.getHashedAuthenticationToken()); - account.setRegistrationLockSalt(credentials.getSalt()); + account.setRegistrationLock(credentials.getHashedAuthenticationToken(), credentials.getSalt()); } else { account.setPin(null); - account.setRegistrationLock(null); - account.setRegistrationLockSalt(null); + account.setRegistrationLock(null, null); } account.setUnidentifiedAccessKey(attributes.getUnidentifiedAccessKey()); @@ -518,7 +490,7 @@ public class AccountController { @Path("/whoami") @Produces(MediaType.APPLICATION_JSON) public AccountCreationResult whoAmI(@Auth Account account) { - return new AccountCreationResult(account.getUuid()); + return new AccountCreationResult(account.getUuid(), backupServiceCredentialGenerator.generateFor(account.getUuid().toString())); } @DELETE diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountCreationResult.java b/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountCreationResult.java index 06625d388..10811cfbf 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountCreationResult.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/entities/AccountCreationResult.java @@ -2,6 +2,8 @@ package org.whispersystems.textsecuregcm.entities; import com.fasterxml.jackson.annotation.JsonProperty; +import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; + import java.util.UUID; public class AccountCreationResult { @@ -9,13 +11,21 @@ public class AccountCreationResult { @JsonProperty private UUID uuid; + @JsonProperty + private ExternalServiceCredentials backupCredentials; + public AccountCreationResult() {} - public AccountCreationResult(UUID uuid) { - this.uuid = uuid; + public AccountCreationResult(UUID uuid, ExternalServiceCredentials backupCredentials) { + this.uuid = uuid; + this.backupCredentials = backupCredentials; } public UUID getUuid() { return uuid; } + + public ExternalServiceCredentials getBackupCredentials() { + return backupCredentials; + } } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java index 1881c7d33..cea68157a 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Account.java @@ -21,6 +21,7 @@ import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonProperty; import com.google.common.annotations.VisibleForTesting; import org.whispersystems.textsecuregcm.auth.AmbiguousIdentifier; +import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock; import javax.security.auth.Subject; import java.security.Principal; @@ -144,6 +145,10 @@ public class Account implements Principal { .allMatch(device -> device.getCapabilities() != null && device.getCapabilities().isGv2()); } + public boolean isStorageSupported() { + return devices.stream().anyMatch(device -> device.getCapabilities() != null && device.getCapabilities().isStorage()); + } + public boolean isEnabled() { return getMasterDevice().isPresent() && @@ -227,30 +232,19 @@ public class Account implements Principal { this.avatarDigest = avatarDigest; } - public Optional getPin() { - return Optional.ofNullable(pin); - } - public void setPin(String pin) { this.pin = pin; } - public void setRegistrationLock(String registrationLock) { - this.registrationLock = registrationLock; - } - - public Optional getRegistrationLock() { - return Optional.ofNullable(registrationLock); - } - - public void setRegistrationLockSalt(String registrationLockSalt) { + public void setRegistrationLock(String registrationLock, String registrationLockSalt) { + this.registrationLock = registrationLock; this.registrationLockSalt = registrationLockSalt; } - public Optional getRegistrationLockSalt() { - return Optional.ofNullable(registrationLockSalt); + public StoredRegistrationLock getRegistrationLock() { + return new StoredRegistrationLock(Optional.ofNullable(registrationLock), Optional.ofNullable(registrationLockSalt), Optional.ofNullable(pin), getLastSeen()); } - + public Optional getUnidentifiedAccessKey() { return Optional.ofNullable(unidentifiedAccessKey); } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java index 676c005d9..74102629f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/Device.java @@ -273,11 +273,15 @@ public class Device { @JsonProperty private boolean gv2; + @JsonProperty + private boolean storage; + public DeviceCapabilities() {} - public DeviceCapabilities(boolean uuid, boolean gv2) { - this.uuid = uuid; - this.gv2 = gv2; + public DeviceCapabilities(boolean uuid, boolean gv2, boolean storage) { + this.uuid = uuid; + this.gv2 = gv2; + this.storage = storage; } public boolean isUuid() { @@ -287,6 +291,10 @@ public class Device { public boolean isGv2() { return gv2; } + + public boolean isStorage() { + return storage; + } } } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java index 75626153b..b6578bcf2 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java @@ -9,6 +9,7 @@ import org.mockito.ArgumentCaptor; import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials; import org.whispersystems.textsecuregcm.auth.DisabledPermittedAccount; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialGenerator; +import org.whispersystems.textsecuregcm.auth.StoredRegistrationLock; import org.whispersystems.textsecuregcm.auth.StoredVerificationCode; import org.whispersystems.textsecuregcm.auth.TurnTokenGenerator; import org.whispersystems.textsecuregcm.controllers.AccountController; @@ -68,6 +69,7 @@ public class AccountControllerTest { private static final String SENDER_OVER_PREFIX = "+14156666666"; private static final String SENDER_PREAUTH = "+14157777777"; private static final String SENDER_REG_LOCK = "+14158888888"; + private static final String SENDER_HAS_STORAGE = "+14159999999"; private static final UUID SENDER_REG_LOCK_UUID = UUID.randomUUID(); @@ -98,6 +100,7 @@ public class AccountControllerTest { private TurnTokenGenerator turnTokenGenerator = mock(TurnTokenGenerator.class); private Account senderPinAccount = mock(Account.class); private Account senderRegLockAccount = mock(Account.class); + private Account senderHasStorage = mock(Account.class); private RecaptchaClient recaptchaClient = mock(RecaptchaClient.class); private GCMSender gcmSender = mock(GCMSender.class); private APNSender apnSender = mock(APNSender.class); @@ -146,12 +149,14 @@ public class AccountControllerTest { when(timeProvider.getCurrentTimeMillis()).thenReturn(System.currentTimeMillis()); - when(senderPinAccount.getPin()).thenReturn(Optional.of("31337")); when(senderPinAccount.getLastSeen()).thenReturn(System.currentTimeMillis()); + when(senderPinAccount.getRegistrationLock()).thenReturn(new StoredRegistrationLock(Optional.empty(), Optional.empty(), Optional.of("31337"), System.currentTimeMillis())); - when(senderRegLockAccount.getPin()).thenReturn(Optional.empty()); - when(senderRegLockAccount.getRegistrationLock()).thenReturn(Optional.of(registrationLockCredentials.getHashedAuthenticationToken())); - when(senderRegLockAccount.getRegistrationLockSalt()).thenReturn(Optional.of(registrationLockCredentials.getSalt())); + when(senderHasStorage.getUuid()).thenReturn(UUID.randomUUID()); + when(senderHasStorage.isStorageSupported()).thenReturn(true); + when(senderHasStorage.getRegistrationLock()).thenReturn(new StoredRegistrationLock(Optional.empty(), Optional.empty(), Optional.empty(), System.currentTimeMillis())); + + when(senderRegLockAccount.getRegistrationLock()).thenReturn(new StoredRegistrationLock(Optional.of(registrationLockCredentials.getHashedAuthenticationToken()), Optional.of(registrationLockCredentials.getSalt()), Optional.empty(), System.currentTimeMillis())); when(senderRegLockAccount.getLastSeen()).thenReturn(System.currentTimeMillis()); when(senderRegLockAccount.getUuid()).thenReturn(SENDER_REG_LOCK_UUID); @@ -161,6 +166,7 @@ public class AccountControllerTest { when(pendingAccountsManager.getCodeForNumber(SENDER_REG_LOCK)).thenReturn(Optional.of(new StoredVerificationCode("666666", System.currentTimeMillis(), null))); when(pendingAccountsManager.getCodeForNumber(SENDER_OVER_PIN)).thenReturn(Optional.of(new StoredVerificationCode("444444", System.currentTimeMillis(), null))); when(pendingAccountsManager.getCodeForNumber(SENDER_PREAUTH)).thenReturn(Optional.of(new StoredVerificationCode("555555", System.currentTimeMillis(), "validchallenge"))); + when(pendingAccountsManager.getCodeForNumber(SENDER_HAS_STORAGE)).thenReturn(Optional.of(new StoredVerificationCode("666666", System.currentTimeMillis(), null))); when(accountsManager.get(eq(SENDER_PIN))).thenReturn(Optional.of(senderPinAccount)); when(accountsManager.get(eq(SENDER_REG_LOCK))).thenReturn(Optional.of(senderRegLockAccount)); @@ -168,6 +174,7 @@ public class AccountControllerTest { when(accountsManager.get(eq(SENDER))).thenReturn(Optional.empty()); when(accountsManager.get(eq(SENDER_OLD))).thenReturn(Optional.empty()); when(accountsManager.get(eq(SENDER_PREAUTH))).thenReturn(Optional.empty()); + when(accountsManager.get(eq(SENDER_HAS_STORAGE))).thenReturn(Optional.of(senderHasStorage)); when(usernamesManager.put(eq(AuthHelper.VALID_UUID), eq("n00bkiller"))).thenReturn(true); when(usernamesManager.put(eq(AuthHelper.VALID_UUID), eq("takenusername"))).thenReturn(false); @@ -485,11 +492,29 @@ public class AccountControllerTest { MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); assertThat(result.getUuid()).isNotNull(); + assertThat(result.getBackupCredentials()).isNull(); verify(accountsManager, times(1)).create(isA(Account.class)); verify(directoryQueue, times(1)).deleteRegisteredUser(notNull(), eq(SENDER)); } + @Test + public void testVerifySupportsStorage() throws Exception { + AccountCreationResult result = + resources.getJerseyTest() + .target(String.format("/v1/accounts/code/%s", "666666")) + .request() + .header("Authorization", AuthHelper.getAuthHeader(SENDER_HAS_STORAGE, "bar")) + .put(Entity.entity(new AccountAttributes("keykeykeykey", false, 2222, null), + MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); + + assertThat(result.getUuid()).isNotNull(); + assertThat(result.getBackupCredentials()).isNotNull(); + + verify(accountsManager, times(1)).create(isA(Account.class)); + verify(directoryQueue, times(1)).deleteRegisteredUser(notNull(), eq(SENDER_HAS_STORAGE)); + } + @Test public void testVerifyCodeOld() throws Exception { Response response = @@ -550,6 +575,29 @@ public class AccountControllerTest { verify(pinLimiter).validate(eq(SENDER_REG_LOCK)); } + @Test + public void testVerifyRegistrationLockOld() throws Exception { + StoredRegistrationLock lock = senderRegLockAccount.getRegistrationLock(); + + try { + when(senderRegLockAccount.getRegistrationLock()).thenReturn(lock.forTime(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))); + + AccountCreationResult result = + resources.getJerseyTest() + .target(String.format("/v1/accounts/code/%s", "666666")) + .request() + .header("Authorization", AuthHelper.getAuthHeader(SENDER_REG_LOCK, "bar")) + .put(Entity.entity(new AccountAttributes("keykeykeykey", false, 3333, null, null, null), + MediaType.APPLICATION_JSON_TYPE), AccountCreationResult.class); + + assertThat(result.getUuid()).isNotNull(); + + verifyNoMoreInteractions(pinLimiter); + } finally { + when(senderRegLockAccount.getRegistrationLock()).thenReturn(lock); + } + } + @Test public void testVerifyWrongPin() throws Exception { Response response = @@ -639,7 +687,7 @@ public class AccountControllerTest { @Test public void testVerifyOldPin() throws Exception { try { - when(senderPinAccount.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7)); + when(senderPinAccount.getRegistrationLock()).thenReturn(new StoredRegistrationLock(Optional.empty(), Optional.empty(), Optional.of("31337"), System.currentTimeMillis() - TimeUnit.DAYS.toMillis(7))); AccountCreationResult result = resources.getJerseyTest() @@ -652,7 +700,7 @@ public class AccountControllerTest { assertThat(result.getUuid()).isNotNull(); } finally { - when(senderPinAccount.getLastSeen()).thenReturn(System.currentTimeMillis()); + when(senderPinAccount.getRegistrationLock()).thenReturn(new StoredRegistrationLock(Optional.empty(), Optional.empty(), Optional.of("31337"), System.currentTimeMillis())); } } @@ -669,8 +717,7 @@ public class AccountControllerTest { assertThat(response.getStatus()).isEqualTo(204); verify(AuthHelper.VALID_ACCOUNT).setPin(eq("31337")); - verify(AuthHelper.VALID_ACCOUNT).setRegistrationLock(eq(null)); - verify(AuthHelper.VALID_ACCOUNT).setRegistrationLockSalt(eq(null)); + verify(AuthHelper.VALID_ACCOUNT).setRegistrationLock(eq(null), eq(null)); } @Test @@ -688,8 +735,7 @@ public class AccountControllerTest { ArgumentCaptor pinSaltCapture = ArgumentCaptor.forClass(String.class); verify(AuthHelper.VALID_ACCOUNT, times(1)).setPin(eq(null)); - verify(AuthHelper.VALID_ACCOUNT, times(1)).setRegistrationLock(pinCapture.capture()); - verify(AuthHelper.VALID_ACCOUNT, times(1)).setRegistrationLockSalt(pinSaltCapture.capture()); + verify(AuthHelper.VALID_ACCOUNT, times(1)).setRegistrationLock(pinCapture.capture(), pinSaltCapture.capture()); assertThat(pinCapture.getValue()).isNotEmpty(); assertThat(pinSaltCapture.getValue()).isNotEmpty(); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java index 385865e75..9e5d0f3bc 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/MessageControllerTest.java @@ -85,13 +85,13 @@ public class MessageControllerTest { @Before public void setup() throws Exception { Set singleDeviceList = new HashSet() {{ - add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, new SignedPreKey(333, "baz", "boop"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, true))); + add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, new SignedPreKey(333, "baz", "boop"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, true, true))); }}; Set multiDeviceList = new HashSet() {{ - add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, true))); - add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, true))); - add(new Device(3, null, "foo", "bar", "baz", "isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(false, false))); + add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, true, true))); + add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(true, true, true))); + add(new Device(3, null, "foo", "bar", "baz", "isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31), System.currentTimeMillis(), "Test", 0, new Device.DeviceCapabilities(false, false, false))); }}; Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, SINGLE_DEVICE_UUID, singleDeviceList, "1234".getBytes()); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountTest.java index 0647acf40..af0be15fc 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountTest.java @@ -49,15 +49,15 @@ public class AccountTest { when(oldSecondaryDevice.isEnabled()).thenReturn(false); when(oldSecondaryDevice.getId()).thenReturn(2L); - when(uuidCapableDevice.getCapabilities()).thenReturn(new Device.DeviceCapabilities(true, true)); + when(uuidCapableDevice.getCapabilities()).thenReturn(new Device.DeviceCapabilities(true, true, true)); when(uuidCapableDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1)); when(uuidCapableDevice.isEnabled()).thenReturn(true); - when(uuidIncapableDevice.getCapabilities()).thenReturn(new Device.DeviceCapabilities(false, false)); + when(uuidIncapableDevice.getCapabilities()).thenReturn(new Device.DeviceCapabilities(false, false, false)); when(uuidIncapableDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(1)); when(uuidIncapableDevice.isEnabled()).thenReturn(true); - when(uuidIncapableExpiredDevice.getCapabilities()).thenReturn(new Device.DeviceCapabilities(false, false)); + when(uuidIncapableExpiredDevice.getCapabilities()).thenReturn(new Device.DeviceCapabilities(false, false, false)); when(uuidIncapableExpiredDevice.getLastSeen()).thenReturn(System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31)); when(uuidIncapableExpiredDevice.isEnabled()).thenReturn(false); } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountsTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountsTest.java index 4e24969a8..969bdb804 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountsTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/storage/AccountsTest.java @@ -270,7 +270,7 @@ public class AccountsTest { private Device generateDevice(long id) { Random random = new Random(System.currentTimeMillis()); SignedPreKey signedPreKey = new SignedPreKey(random.nextInt(), "testPublicKey-" + random.nextInt(), "testSignature-" + random.nextInt()); - return new Device(id, "testName-" + random.nextInt(), "testAuthToken-" + random.nextInt(), "testSalt-" + random.nextInt(), null, "testGcmId-" + random.nextInt(), "testApnId-" + random.nextInt(), "testVoipApnId-" + random.nextInt(), random.nextBoolean(), random.nextInt(), signedPreKey, random.nextInt(), random.nextInt(), "testUserAgent-" + random.nextInt() , 0, new Device.DeviceCapabilities(random.nextBoolean(), random.nextBoolean())); + return new Device(id, "testName-" + random.nextInt(), "testAuthToken-" + random.nextInt(), "testSalt-" + random.nextInt(), null, "testGcmId-" + random.nextInt(), "testApnId-" + random.nextInt(), "testVoipApnId-" + random.nextInt(), random.nextBoolean(), random.nextInt(), signedPreKey, random.nextInt(), random.nextInt(), "testUserAgent-" + random.nextInt() , 0, new Device.DeviceCapabilities(random.nextBoolean(), random.nextBoolean(), random.nextBoolean())); } private Account generateAccount(String number, UUID uuid) {