Measure rate limit challenge responses by platform
This commit is contained in:
		
							parent
							
								
									a6182acc9c
								
							
						
					
					
						commit
						99eda80a78
					
				| 
						 | 
					@ -15,21 +15,31 @@ import javax.ws.rs.POST;
 | 
				
			||||||
import javax.ws.rs.PUT;
 | 
					import javax.ws.rs.PUT;
 | 
				
			||||||
import javax.ws.rs.Path;
 | 
					import javax.ws.rs.Path;
 | 
				
			||||||
import javax.ws.rs.Produces;
 | 
					import javax.ws.rs.Produces;
 | 
				
			||||||
 | 
					import javax.ws.rs.core.HttpHeaders;
 | 
				
			||||||
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 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.auth.AuthenticatedAccount;
 | 
				
			||||||
import org.whispersystems.textsecuregcm.entities.AnswerChallengeRequest;
 | 
					import org.whispersystems.textsecuregcm.entities.AnswerChallengeRequest;
 | 
				
			||||||
import org.whispersystems.textsecuregcm.entities.AnswerPushChallengeRequest;
 | 
					import org.whispersystems.textsecuregcm.entities.AnswerPushChallengeRequest;
 | 
				
			||||||
import org.whispersystems.textsecuregcm.entities.AnswerRecaptchaChallengeRequest;
 | 
					import org.whispersystems.textsecuregcm.entities.AnswerRecaptchaChallengeRequest;
 | 
				
			||||||
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
 | 
					import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
 | 
				
			||||||
 | 
					import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
 | 
				
			||||||
import org.whispersystems.textsecuregcm.push.NotPushRegisteredException;
 | 
					import org.whispersystems.textsecuregcm.push.NotPushRegisteredException;
 | 
				
			||||||
import org.whispersystems.textsecuregcm.util.ForwardedIpUtil;
 | 
					import org.whispersystems.textsecuregcm.util.ForwardedIpUtil;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@Path("/v1/challenge")
 | 
					@Path("/v1/challenge")
 | 
				
			||||||
public class ChallengeController {
 | 
					public class ChallengeController {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
  private final RateLimitChallengeManager rateLimitChallengeManager;
 | 
					  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) {
 | 
					  public ChallengeController(final RateLimitChallengeManager rateLimitChallengeManager) {
 | 
				
			||||||
    this.rateLimitChallengeManager = rateLimitChallengeManager;
 | 
					    this.rateLimitChallengeManager = rateLimitChallengeManager;
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
| 
						 | 
					@ -40,16 +50,20 @@ public class ChallengeController {
 | 
				
			||||||
  @Consumes(MediaType.APPLICATION_JSON)
 | 
					  @Consumes(MediaType.APPLICATION_JSON)
 | 
				
			||||||
  public Response handleChallengeResponse(@Auth final AuthenticatedAccount auth,
 | 
					  public Response handleChallengeResponse(@Auth final AuthenticatedAccount auth,
 | 
				
			||||||
      @Valid final AnswerChallengeRequest answerRequest,
 | 
					      @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 {
 | 
					    try {
 | 
				
			||||||
      if (answerRequest instanceof AnswerPushChallengeRequest) {
 | 
					      if (answerRequest instanceof final AnswerPushChallengeRequest pushChallengeRequest) {
 | 
				
			||||||
        final AnswerPushChallengeRequest pushChallengeRequest = (AnswerPushChallengeRequest) answerRequest;
 | 
					        tags = tags.and(CHALLENGE_TYPE_TAG, "push");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        rateLimitChallengeManager.answerPushChallenge(auth.getAccount(), pushChallengeRequest.getChallenge());
 | 
					        rateLimitChallengeManager.answerPushChallenge(auth.getAccount(), pushChallengeRequest.getChallenge());
 | 
				
			||||||
      } else if (answerRequest instanceof AnswerRecaptchaChallengeRequest) {
 | 
					      } else if (answerRequest instanceof AnswerRecaptchaChallengeRequest) {
 | 
				
			||||||
        try {
 | 
					        tags = tags.and(CHALLENGE_TYPE_TAG, "recaptcha");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        try {
 | 
				
			||||||
          final AnswerRecaptchaChallengeRequest recaptchaChallengeRequest = (AnswerRecaptchaChallengeRequest) answerRequest;
 | 
					          final AnswerRecaptchaChallengeRequest recaptchaChallengeRequest = (AnswerRecaptchaChallengeRequest) answerRequest;
 | 
				
			||||||
          final String mostRecentProxy = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow();
 | 
					          final String mostRecentProxy = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -59,9 +73,13 @@ public class ChallengeController {
 | 
				
			||||||
        } catch (final NoSuchElementException e) {
 | 
					        } catch (final NoSuchElementException e) {
 | 
				
			||||||
          return Response.status(400).build();
 | 
					          return Response.status(400).build();
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					      } else {
 | 
				
			||||||
 | 
					        tags = tags.and(CHALLENGE_TYPE_TAG, "unrecognized");
 | 
				
			||||||
      }
 | 
					      }
 | 
				
			||||||
    } catch (final RateLimitExceededException e) {
 | 
					    } catch (final RateLimitExceededException e) {
 | 
				
			||||||
      throw new RetryLaterException(e);
 | 
					      throw new RetryLaterException(e);
 | 
				
			||||||
 | 
					    } finally {
 | 
				
			||||||
 | 
					      Metrics.counter(CHALLENGE_RESPONSE_COUNTER_NAME, tags).increment();
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return Response.status(200).build();
 | 
					    return Response.status(200).build();
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue