Measure rate limit challenge responses by platform

This commit is contained in:
Jon Chambers 2022-01-27 11:47:15 -05:00 committed by Jon Chambers
parent a6182acc9c
commit 99eda80a78
1 changed files with 22 additions and 4 deletions

View File

@ -15,21 +15,31 @@ import javax.ws.rs.POST;
import javax.ws.rs.PUT;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.HttpHeaders;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag;
import io.micrometer.core.instrument.Tags;
import org.whispersystems.textsecuregcm.auth.AuthenticatedAccount;
import org.whispersystems.textsecuregcm.entities.AnswerChallengeRequest;
import org.whispersystems.textsecuregcm.entities.AnswerPushChallengeRequest;
import org.whispersystems.textsecuregcm.entities.AnswerRecaptchaChallengeRequest;
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
import org.whispersystems.textsecuregcm.push.NotPushRegisteredException;
import org.whispersystems.textsecuregcm.util.ForwardedIpUtil;
import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
@Path("/v1/challenge")
public class ChallengeController {
private final RateLimitChallengeManager rateLimitChallengeManager;
private static final String CHALLENGE_RESPONSE_COUNTER_NAME = name(ChallengeController.class, "challengeResponse");
private static final String CHALLENGE_TYPE_TAG = "type";
public ChallengeController(final RateLimitChallengeManager rateLimitChallengeManager) {
this.rateLimitChallengeManager = rateLimitChallengeManager;
}
@ -40,16 +50,20 @@ public class ChallengeController {
@Consumes(MediaType.APPLICATION_JSON)
public Response handleChallengeResponse(@Auth final AuthenticatedAccount auth,
@Valid final AnswerChallengeRequest answerRequest,
@HeaderParam("X-Forwarded-For") String forwardedFor) throws RetryLaterException {
@HeaderParam("X-Forwarded-For") final String forwardedFor,
@HeaderParam(HttpHeaders.USER_AGENT) final String userAgent) throws RetryLaterException {
Tags tags = Tags.of(UserAgentTagUtil.getPlatformTag(userAgent));
try {
if (answerRequest instanceof AnswerPushChallengeRequest) {
final AnswerPushChallengeRequest pushChallengeRequest = (AnswerPushChallengeRequest) answerRequest;
if (answerRequest instanceof final AnswerPushChallengeRequest pushChallengeRequest) {
tags = tags.and(CHALLENGE_TYPE_TAG, "push");
rateLimitChallengeManager.answerPushChallenge(auth.getAccount(), pushChallengeRequest.getChallenge());
} else if (answerRequest instanceof AnswerRecaptchaChallengeRequest) {
try {
tags = tags.and(CHALLENGE_TYPE_TAG, "recaptcha");
try {
final AnswerRecaptchaChallengeRequest recaptchaChallengeRequest = (AnswerRecaptchaChallengeRequest) answerRequest;
final String mostRecentProxy = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow();
@ -59,9 +73,13 @@ public class ChallengeController {
} catch (final NoSuchElementException e) {
return Response.status(400).build();
}
} else {
tags = tags.and(CHALLENGE_TYPE_TAG, "unrecognized");
}
} catch (final RateLimitExceededException e) {
throw new RetryLaterException(e);
} finally {
Metrics.counter(CHALLENGE_RESPONSE_COUNTER_NAME, tags).increment();
}
return Response.status(200).build();