mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-27 06:13:27 +01:00
Enhance device management API.
1. Put a limit on the number of registered devices per account. 2. Support removing devices. 3. Support device names and created dates. 4. Support enumerating devices. // FREEBIE
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
package org.whispersystems.textsecuregcm.tests.controllers;
|
||||
|
||||
import com.google.common.base.Optional;
|
||||
import com.sun.jersey.api.client.ClientResponse;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
@@ -25,6 +26,7 @@ import org.whispersystems.textsecuregcm.entities.AccountAttributes;
|
||||
import org.whispersystems.textsecuregcm.entities.DeviceResponse;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.mappers.DeviceLimitExceededExceptionMapper;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.PendingDevicesManager;
|
||||
@@ -34,8 +36,10 @@ import org.whispersystems.textsecuregcm.util.VerificationCode;
|
||||
import javax.ws.rs.Path;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
|
||||
import io.dropwizard.jersey.validation.ConstraintViolationExceptionMapper;
|
||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||
import static org.fest.assertions.api.Assertions.assertThat;
|
||||
import static org.junit.Assert.assertEquals;
|
||||
import static org.mockito.Mockito.*;
|
||||
|
||||
public class DeviceControllerTest {
|
||||
@@ -56,10 +60,13 @@ public class DeviceControllerTest {
|
||||
private RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private Account account = mock(Account.class );
|
||||
private Account maxedAccount = mock(Account.class);
|
||||
|
||||
@Rule
|
||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||
.addProvider(AuthHelper.getAuthenticator())
|
||||
.addProvider(new DeviceLimitExceededExceptionMapper())
|
||||
.addProvider(new ConstraintViolationExceptionMapper())
|
||||
.addResource(new DumbVerificationDeviceController(pendingDevicesManager,
|
||||
accountsManager,
|
||||
rateLimiters))
|
||||
@@ -75,9 +82,12 @@ public class DeviceControllerTest {
|
||||
when(rateLimiters.getVerifyDeviceLimiter()).thenReturn(rateLimiter);
|
||||
|
||||
when(account.getNextDeviceId()).thenReturn(42L);
|
||||
when(maxedAccount.getActiveDeviceCount()).thenReturn(3);
|
||||
|
||||
when(pendingDevicesManager.getCodeForNumber(AuthHelper.VALID_NUMBER)).thenReturn(Optional.of("5678901"));
|
||||
when(pendingDevicesManager.getCodeForNumber(AuthHelper.VALID_NUMBER_TWO)).thenReturn(Optional.of("1112223"));
|
||||
when(accountsManager.get(AuthHelper.VALID_NUMBER)).thenReturn(Optional.of(account));
|
||||
when(accountsManager.get(AuthHelper.VALID_NUMBER_TWO)).thenReturn(Optional.of(maxedAccount));
|
||||
}
|
||||
|
||||
@Test
|
||||
@@ -98,4 +108,24 @@ public class DeviceControllerTest {
|
||||
|
||||
verify(pendingDevicesManager).remove(AuthHelper.VALID_NUMBER);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void maxDevicesTest() throws Exception {
|
||||
ClientResponse response = resources.client().resource("/v1/devices/provisioning/code")
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER_TWO, AuthHelper.VALID_PASSWORD_TWO))
|
||||
.get(ClientResponse.class);
|
||||
|
||||
assertEquals(response.getStatus(), 411);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void longNameTest() throws Exception {
|
||||
ClientResponse response = resources.client().resource("/v1/devices/5678901")
|
||||
.header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_NUMBER, "password1"))
|
||||
.entity(new AccountAttributes("keykeykeykey", false, 1234, "this is a really long name that is longer than 80 characters"))
|
||||
.type(MediaType.APPLICATION_JSON_TYPE)
|
||||
.put(ClientResponse.class);
|
||||
|
||||
assertEquals(response.getStatus(), 422);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -74,12 +74,12 @@ public class FederatedControllerTest {
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Set<Device> singleDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, "foo", "bar", "baz", "isgcm", null, null, false, 111, null, System.currentTimeMillis()));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
}};
|
||||
|
||||
Set<Device> multiDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, "foo", "bar", "baz", "isgcm", null, null, false, 222, null, System.currentTimeMillis()));
|
||||
add(new Device(2, "foo", "bar", "baz", "isgcm", null, null, false, 333, null, System.currentTimeMillis()));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
}};
|
||||
|
||||
Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, singleDeviceList);
|
||||
|
||||
@@ -69,13 +69,13 @@ public class MessageControllerTest {
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Set<Device> singleDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, "foo", "bar", "baz", "isgcm", null, null, false, 111, null, System.currentTimeMillis()));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
}};
|
||||
|
||||
Set<Device> multiDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis()));
|
||||
add(new Device(2, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis()));
|
||||
add(new Device(3, "foo", "bar", "baz", "isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31)));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, new SignedPreKey(111, "foo", "bar"), System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, new SignedPreKey(222, "oof", "rab"), System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
add(new Device(3, null, "foo", "bar", "baz", "isgcm", null, null, false, 444, null, System.currentTimeMillis() - TimeUnit.DAYS.toMillis(31), System.currentTimeMillis()));
|
||||
}};
|
||||
|
||||
Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, singleDeviceList);
|
||||
|
||||
@@ -47,12 +47,12 @@ public class ReceiptControllerTest {
|
||||
@Before
|
||||
public void setup() throws Exception {
|
||||
Set<Device> singleDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, "foo", "bar", "baz", "isgcm", null, null, false, 111, null, System.currentTimeMillis()));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 111, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
}};
|
||||
|
||||
Set<Device> multiDeviceList = new HashSet<Device>() {{
|
||||
add(new Device(1, "foo", "bar", "baz", "isgcm", null, null, false, 222, null, System.currentTimeMillis()));
|
||||
add(new Device(2, "foo", "bar", "baz", "isgcm", null, null, false, 333, null, System.currentTimeMillis()));
|
||||
add(new Device(1, null, "foo", "bar", "baz", "isgcm", null, null, false, 222, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
add(new Device(2, null, "foo", "bar", "baz", "isgcm", null, null, false, 333, null, System.currentTimeMillis(), System.currentTimeMillis()));
|
||||
}};
|
||||
|
||||
Account singleDeviceAccount = new Account(SINGLE_DEVICE_RECIPIENT, singleDeviceList);
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
|
||||
import static org.mockito.Matchers.anyLong;
|
||||
import static org.mockito.Matchers.eq;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
@@ -24,23 +25,38 @@ public class AuthHelper {
|
||||
public static final String VALID_NUMBER = "+14150000000";
|
||||
public static final String VALID_PASSWORD = "foo";
|
||||
|
||||
public static final String VALID_NUMBER_TWO = "+14151111111";
|
||||
public static final String VALID_PASSWORD_TWO = "baz";
|
||||
|
||||
public static final String INVVALID_NUMBER = "+14151111111";
|
||||
public static final String INVALID_PASSWORD = "bar";
|
||||
|
||||
public static AccountsManager ACCOUNTS_MANAGER = mock(AccountsManager.class );
|
||||
public static Account VALID_ACCOUNT = mock(Account.class );
|
||||
public static Account VALID_ACCOUNT_TWO = mock(Account.class);
|
||||
public static Device VALID_DEVICE = mock(Device.class );
|
||||
public static AuthenticationCredentials VALID_CREDENTIALS = mock(AuthenticationCredentials.class);
|
||||
public static Device VALID_DEVICE_TWO = mock(Device.class);
|
||||
private static AuthenticationCredentials VALID_CREDENTIALS = mock(AuthenticationCredentials.class);
|
||||
private static AuthenticationCredentials VALID_CREDENTIALS_TWO = mock(AuthenticationCredentials.class);
|
||||
|
||||
public static MultiBasicAuthProvider<FederatedPeer, Account> getAuthenticator() {
|
||||
when(VALID_CREDENTIALS.verify("foo")).thenReturn(true);
|
||||
when(VALID_CREDENTIALS_TWO.verify("baz")).thenReturn(true);
|
||||
when(VALID_DEVICE.getAuthenticationCredentials()).thenReturn(VALID_CREDENTIALS);
|
||||
when(VALID_DEVICE_TWO.getAuthenticationCredentials()).thenReturn(VALID_CREDENTIALS_TWO);
|
||||
when(VALID_DEVICE.getId()).thenReturn(1L);
|
||||
when(VALID_DEVICE_TWO.getId()).thenReturn(1L);
|
||||
when(VALID_ACCOUNT.getDevice(anyLong())).thenReturn(Optional.of(VALID_DEVICE));
|
||||
when(VALID_ACCOUNT_TWO.getDevice(eq(1L))).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
||||
when(VALID_ACCOUNT_TWO.getActiveDeviceCount()).thenReturn(3);
|
||||
when(VALID_ACCOUNT.getNumber()).thenReturn(VALID_NUMBER);
|
||||
when(VALID_ACCOUNT_TWO.getNumber()).thenReturn(VALID_NUMBER_TWO);
|
||||
when(VALID_ACCOUNT.getAuthenticatedDevice()).thenReturn(Optional.of(VALID_DEVICE));
|
||||
when(VALID_ACCOUNT_TWO.getAuthenticatedDevice()).thenReturn(Optional.of(VALID_DEVICE_TWO));
|
||||
when(VALID_ACCOUNT.getRelay()).thenReturn(Optional.<String>absent());
|
||||
when(VALID_ACCOUNT_TWO.getRelay()).thenReturn(Optional.<String>absent());
|
||||
when(ACCOUNTS_MANAGER.get(VALID_NUMBER)).thenReturn(Optional.of(VALID_ACCOUNT));
|
||||
when(ACCOUNTS_MANAGER.get(VALID_NUMBER_TWO)).thenReturn(Optional.of(VALID_ACCOUNT_TWO));
|
||||
|
||||
List<FederatedPeer> peer = new LinkedList<FederatedPeer>() {{
|
||||
add(new FederatedPeer("cyanogen", "https://foo", "foofoo", "bazzzzz"));
|
||||
|
||||
Reference in New Issue
Block a user