Add rate limiting
This commit is contained in:
parent
a3545ce551
commit
c6eb306691
|
@ -29,6 +29,9 @@ public class RateLimitsConfiguration {
|
|||
@JsonProperty
|
||||
private RateLimitConfiguration voiceDestinationDaily = new RateLimitConfiguration(10, 10.0 / (24.0 * 60.0));
|
||||
|
||||
@JsonProperty
|
||||
private RateLimitConfiguration smsVoiceIp = new RateLimitConfiguration(1000, 1000);
|
||||
|
||||
@JsonProperty
|
||||
private RateLimitConfiguration verifyNumber = new RateLimitConfiguration(2, 2);
|
||||
|
||||
|
@ -95,6 +98,10 @@ public class RateLimitsConfiguration {
|
|||
return voiceDestinationDaily;
|
||||
}
|
||||
|
||||
public RateLimitConfiguration getSmsVoiceIp() {
|
||||
return smsVoiceIp;
|
||||
}
|
||||
|
||||
public RateLimitConfiguration getVerifyNumber() {
|
||||
return verifyNumber;
|
||||
}
|
||||
|
|
|
@ -110,9 +110,10 @@ public class AccountController {
|
|||
@Timed
|
||||
@GET
|
||||
@Path("/{transport}/code/{number}")
|
||||
public Response createAccount(@PathParam("transport") String transport,
|
||||
@PathParam("number") String number,
|
||||
@QueryParam("client") Optional<String> client)
|
||||
public Response createAccount(@PathParam("transport") String transport,
|
||||
@PathParam("number") String number,
|
||||
@HeaderParam("X-Forwarded-For") String requester,
|
||||
@QueryParam("client") Optional<String> client)
|
||||
throws IOException, RateLimitExceededException
|
||||
{
|
||||
if (!Util.isValidNumber(number)) {
|
||||
|
@ -120,6 +121,13 @@ public class AccountController {
|
|||
throw new WebApplicationException(Response.status(400).build());
|
||||
}
|
||||
|
||||
try {
|
||||
rateLimiters.getSmsVoiceIpLimiter().validate(requester);
|
||||
} catch (RateLimitExceededException e) {
|
||||
logger.info("Rate limited exceeded: " + transport + ", " + number + ", " + requester);
|
||||
return Response.ok().build();
|
||||
}
|
||||
|
||||
switch (transport) {
|
||||
case "sms":
|
||||
rateLimiters.getSmsDestinationLimiter().validate(number);
|
||||
|
|
|
@ -25,6 +25,7 @@ public class RateLimiters {
|
|||
private final RateLimiter smsDestinationLimiter;
|
||||
private final RateLimiter voiceDestinationLimiter;
|
||||
private final RateLimiter voiceDestinationDailyLimiter;
|
||||
private final RateLimiter smsVoiceIpLimiter;
|
||||
private final RateLimiter verifyLimiter;
|
||||
private final RateLimiter pinLimiter;
|
||||
|
||||
|
@ -53,6 +54,10 @@ public class RateLimiters {
|
|||
config.getVoiceDestinationDaily().getBucketSize(),
|
||||
config.getVoiceDestinationDaily().getLeakRatePerMinute());
|
||||
|
||||
this.smsVoiceIpLimiter = new RateLimiter(cacheClient, "smsVoiceIp",
|
||||
config.getSmsVoiceIp().getBucketSize(),
|
||||
config.getSmsVoiceIp().getLeakRatePerMinute());
|
||||
|
||||
this.verifyLimiter = new RateLimiter(cacheClient, "verify",
|
||||
config.getVerifyNumber().getBucketSize(),
|
||||
config.getVerifyNumber().getLeakRatePerMinute());
|
||||
|
@ -122,6 +127,10 @@ public class RateLimiters {
|
|||
return smsDestinationLimiter;
|
||||
}
|
||||
|
||||
public RateLimiter getSmsVoiceIpLimiter() {
|
||||
return smsVoiceIpLimiter;
|
||||
}
|
||||
|
||||
public RateLimiter getVoiceDestinationLimiter() {
|
||||
return voiceDestinationLimiter;
|
||||
}
|
||||
|
|
|
@ -49,6 +49,7 @@ public class AccountControllerTest {
|
|||
private RateLimiters rateLimiters = mock(RateLimiters.class );
|
||||
private RateLimiter rateLimiter = mock(RateLimiter.class );
|
||||
private RateLimiter pinLimiter = mock(RateLimiter.class );
|
||||
private RateLimiter smsVoiceIpLimiter = mock(RateLimiter.class );
|
||||
private SmsSender smsSender = mock(SmsSender.class );
|
||||
private DirectoryQueue directoryQueue = mock(DirectoryQueue.class);
|
||||
private MessagesManager storedMessages = mock(MessagesManager.class );
|
||||
|
@ -80,6 +81,7 @@ public class AccountControllerTest {
|
|||
when(rateLimiters.getVoiceDestinationLimiter()).thenReturn(rateLimiter);
|
||||
when(rateLimiters.getVerifyLimiter()).thenReturn(rateLimiter);
|
||||
when(rateLimiters.getPinLimiter()).thenReturn(pinLimiter);
|
||||
when(rateLimiters.getSmsVoiceIpLimiter()).thenReturn(smsVoiceIpLimiter);
|
||||
|
||||
when(timeProvider.getCurrentTimeMillis()).thenReturn(System.currentTimeMillis());
|
||||
|
||||
|
@ -106,6 +108,7 @@ public class AccountControllerTest {
|
|||
resources.getJerseyTest()
|
||||
.target(String.format("/v1/accounts/sms/code/%s", SENDER))
|
||||
.request()
|
||||
.header("X-Forwarded-For", "127.0.0.1")
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
|
@ -120,6 +123,7 @@ public class AccountControllerTest {
|
|||
.target(String.format("/v1/accounts/sms/code/%s", SENDER))
|
||||
.queryParam("client", "ios")
|
||||
.request()
|
||||
.header("X-Forwarded-For", "127.0.0.1")
|
||||
.get();
|
||||
|
||||
assertThat(response.getStatus()).isEqualTo(200);
|
||||
|
|
Loading…
Reference in New Issue