Allow max device limit to be configurable per-user
// FREEBIE
This commit is contained in:
parent
507d457900
commit
3d2f8a7ddb
|
@ -19,6 +19,7 @@ package org.whispersystems.textsecuregcm;
|
||||||
import com.fasterxml.jackson.annotation.JsonProperty;
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
import org.whispersystems.textsecuregcm.configuration.FederationConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.FederationConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.GraphiteConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.GraphiteConfiguration;
|
||||||
|
import org.whispersystems.textsecuregcm.configuration.MaxDeviceConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.PushConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.PushConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.RateLimitsConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.RateLimitsConfiguration;
|
||||||
import org.whispersystems.textsecuregcm.configuration.RedPhoneConfiguration;
|
import org.whispersystems.textsecuregcm.configuration.RedPhoneConfiguration;
|
||||||
|
@ -77,6 +78,11 @@ public class WhisperServerConfiguration extends Configuration {
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private List<TestDeviceConfiguration> testDevices = new LinkedList<>();
|
private List<TestDeviceConfiguration> testDevices = new LinkedList<>();
|
||||||
|
|
||||||
|
@Valid
|
||||||
|
@NotNull
|
||||||
|
@JsonProperty
|
||||||
|
private List<MaxDeviceConfiguration> maxDevices = new LinkedList<>();
|
||||||
|
|
||||||
@Valid
|
@Valid
|
||||||
@JsonProperty
|
@JsonProperty
|
||||||
private FederationConfiguration federation = new FederationConfiguration();
|
private FederationConfiguration federation = new FederationConfiguration();
|
||||||
|
@ -178,4 +184,15 @@ public class WhisperServerConfiguration extends Configuration {
|
||||||
|
|
||||||
return results;
|
return results;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Map<String, Integer> getMaxDevices() {
|
||||||
|
Map<String, Integer> results = new HashMap<>();
|
||||||
|
|
||||||
|
for (MaxDeviceConfiguration maxDeviceConfiguration : maxDevices) {
|
||||||
|
results.put(maxDeviceConfiguration.getNumber(),
|
||||||
|
maxDeviceConfiguration.getCount());
|
||||||
|
}
|
||||||
|
|
||||||
|
return results;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -212,7 +212,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||||
environment.jersey().register(new AuthValueFactoryProvider.Binder());
|
environment.jersey().register(new AuthValueFactoryProvider.Binder());
|
||||||
|
|
||||||
environment.jersey().register(new AccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender, messagesManager, new TimeProvider(), authorizationKey, turnTokenGenerator, config.getTestDevices()));
|
environment.jersey().register(new AccountController(pendingAccountsManager, accountsManager, rateLimiters, smsSender, messagesManager, new TimeProvider(), authorizationKey, turnTokenGenerator, config.getTestDevices()));
|
||||||
environment.jersey().register(new DeviceController(pendingDevicesManager, accountsManager, messagesManager, rateLimiters));
|
environment.jersey().register(new DeviceController(pendingDevicesManager, accountsManager, messagesManager, rateLimiters, config.getMaxDevices()));
|
||||||
environment.jersey().register(new DirectoryController(rateLimiters, directory));
|
environment.jersey().register(new DirectoryController(rateLimiters, directory));
|
||||||
environment.jersey().register(new FederationControllerV1(accountsManager, attachmentController, messageController));
|
environment.jersey().register(new FederationControllerV1(accountsManager, attachmentController, messageController));
|
||||||
environment.jersey().register(new FederationControllerV2(accountsManager, attachmentController, messageController, keysControllerV2));
|
environment.jersey().register(new FederationControllerV2(accountsManager, attachmentController, messageController, keysControllerV2));
|
||||||
|
|
|
@ -0,0 +1,27 @@
|
||||||
|
package org.whispersystems.textsecuregcm.configuration;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.annotation.JsonProperty;
|
||||||
|
|
||||||
|
import org.hibernate.validator.constraints.NotEmpty;
|
||||||
|
|
||||||
|
import javax.validation.constraints.NotNull;
|
||||||
|
|
||||||
|
public class MaxDeviceConfiguration {
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
@NotEmpty
|
||||||
|
private String number;
|
||||||
|
|
||||||
|
@JsonProperty
|
||||||
|
@NotNull
|
||||||
|
private int count;
|
||||||
|
|
||||||
|
public String getNumber() {
|
||||||
|
return number;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getCount() {
|
||||||
|
return count;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -54,6 +54,7 @@ import java.security.NoSuchAlgorithmException;
|
||||||
import java.security.SecureRandom;
|
import java.security.SecureRandom;
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import io.dropwizard.auth.Auth;
|
import io.dropwizard.auth.Auth;
|
||||||
|
|
||||||
|
@ -68,16 +69,19 @@ public class DeviceController {
|
||||||
private final AccountsManager accounts;
|
private final AccountsManager accounts;
|
||||||
private final MessagesManager messages;
|
private final MessagesManager messages;
|
||||||
private final RateLimiters rateLimiters;
|
private final RateLimiters rateLimiters;
|
||||||
|
private final Map<String, Integer> maxDeviceConfiguration;
|
||||||
|
|
||||||
public DeviceController(PendingDevicesManager pendingDevices,
|
public DeviceController(PendingDevicesManager pendingDevices,
|
||||||
AccountsManager accounts,
|
AccountsManager accounts,
|
||||||
MessagesManager messages,
|
MessagesManager messages,
|
||||||
RateLimiters rateLimiters)
|
RateLimiters rateLimiters,
|
||||||
|
Map<String, Integer> maxDeviceConfiguration)
|
||||||
{
|
{
|
||||||
this.pendingDevices = pendingDevices;
|
this.pendingDevices = pendingDevices;
|
||||||
this.accounts = accounts;
|
this.accounts = accounts;
|
||||||
this.messages = messages;
|
this.messages = messages;
|
||||||
this.rateLimiters = rateLimiters;
|
this.rateLimiters = rateLimiters;
|
||||||
|
this.maxDeviceConfiguration = maxDeviceConfiguration;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Timed
|
@Timed
|
||||||
|
@ -116,7 +120,13 @@ public class DeviceController {
|
||||||
{
|
{
|
||||||
rateLimiters.getAllocateDeviceLimiter().validate(account.getNumber());
|
rateLimiters.getAllocateDeviceLimiter().validate(account.getNumber());
|
||||||
|
|
||||||
if (account.getActiveDeviceCount() >= MAX_DEVICES) {
|
int maxDeviceLimit = MAX_DEVICES;
|
||||||
|
|
||||||
|
if (maxDeviceConfiguration.containsKey(account.getNumber())) {
|
||||||
|
maxDeviceLimit = maxDeviceConfiguration.get(account.getNumber());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account.getActiveDeviceCount() >= maxDeviceLimit) {
|
||||||
throw new DeviceLimitExceededException(account.getDevices().size(), MAX_DEVICES);
|
throw new DeviceLimitExceededException(account.getDevices().size(), MAX_DEVICES);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -40,6 +40,9 @@ import javax.ws.rs.client.Entity;
|
||||||
import javax.ws.rs.core.MediaType;
|
import javax.ws.rs.core.MediaType;
|
||||||
import javax.ws.rs.core.Response;
|
import javax.ws.rs.core.Response;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
import io.dropwizard.jersey.validation.ConstraintViolationExceptionMapper;
|
import io.dropwizard.jersey.validation.ConstraintViolationExceptionMapper;
|
||||||
import io.dropwizard.testing.junit.ResourceTestRule;
|
import io.dropwizard.testing.junit.ResourceTestRule;
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
@ -52,9 +55,10 @@ public class DeviceControllerTest {
|
||||||
public DumbVerificationDeviceController(PendingDevicesManager pendingDevices,
|
public DumbVerificationDeviceController(PendingDevicesManager pendingDevices,
|
||||||
AccountsManager accounts,
|
AccountsManager accounts,
|
||||||
MessagesManager messages,
|
MessagesManager messages,
|
||||||
RateLimiters rateLimiters)
|
RateLimiters rateLimiters,
|
||||||
|
Map<String, Integer> deviceConfiguration)
|
||||||
{
|
{
|
||||||
super(pendingDevices, accounts, messages, rateLimiters);
|
super(pendingDevices, accounts, messages, rateLimiters, deviceConfiguration);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -71,6 +75,10 @@ public class DeviceControllerTest {
|
||||||
private Account account = mock(Account.class );
|
private Account account = mock(Account.class );
|
||||||
private Account maxedAccount = mock(Account.class);
|
private Account maxedAccount = mock(Account.class);
|
||||||
|
|
||||||
|
private Map<String, Integer> deviceConfiguration = new HashMap<String, Integer>() {{
|
||||||
|
|
||||||
|
}};
|
||||||
|
|
||||||
@Rule
|
@Rule
|
||||||
public final ResourceTestRule resources = ResourceTestRule.builder()
|
public final ResourceTestRule resources = ResourceTestRule.builder()
|
||||||
.addProvider(AuthHelper.getAuthFilter())
|
.addProvider(AuthHelper.getAuthFilter())
|
||||||
|
@ -81,7 +89,8 @@ public class DeviceControllerTest {
|
||||||
.addResource(new DumbVerificationDeviceController(pendingDevicesManager,
|
.addResource(new DumbVerificationDeviceController(pendingDevicesManager,
|
||||||
accountsManager,
|
accountsManager,
|
||||||
messagesManager,
|
messagesManager,
|
||||||
rateLimiters))
|
rateLimiters,
|
||||||
|
deviceConfiguration))
|
||||||
.build();
|
.build();
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue