From c048074c317fa2cd0edc44398943cb03a7580135 Mon Sep 17 00:00:00 2001 From: Jon Chambers Date: Wed, 16 Mar 2022 14:38:02 -0400 Subject: [PATCH] Tag captcha attempt metrics with UA platform --- .../controllers/ChallengeController.java | 2 +- .../limits/RateLimitChallengeManager.java | 16 ++++++++++++---- .../controllers/ChallengeControllerTest.java | 6 ++++-- .../limits/RateLimitChallengeManagerTest.java | 2 +- 4 files changed, 18 insertions(+), 8 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java index 861a31be7..7a12e42e8 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ChallengeController.java @@ -68,7 +68,7 @@ public class ChallengeController { final String mostRecentProxy = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow(); rateLimitChallengeManager.answerRecaptchaChallenge(auth.getAccount(), recaptchaChallengeRequest.getCaptcha(), - mostRecentProxy); + mostRecentProxy, userAgent); } catch (final NoSuchElementException e) { return Response.status(400).build(); diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManager.java index 3ca7e361a..69aaea9b0 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManager.java @@ -6,12 +6,16 @@ import io.micrometer.core.instrument.Metrics; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import io.micrometer.core.instrument.Tag; +import io.micrometer.core.instrument.Tags; import org.whispersystems.textsecuregcm.abuse.RateLimitChallengeListener; import org.whispersystems.textsecuregcm.controllers.RateLimitExceededException; +import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil; import org.whispersystems.textsecuregcm.push.NotPushRegisteredException; import org.whispersystems.textsecuregcm.recaptcha.RecaptchaClient; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.util.Util; +import org.whispersystems.textsecuregcm.util.ua.ClientPlatform; public class RateLimitChallengeManager { @@ -54,16 +58,20 @@ public class RateLimitChallengeManager { } } - public void answerRecaptchaChallenge(final Account account, final String captcha, final String mostRecentProxyIp) + public void answerRecaptchaChallenge(final Account account, final String captcha, final String mostRecentProxyIp, final String userAgent) throws RateLimitExceededException { rateLimiters.getRecaptchaChallengeAttemptLimiter().validate(account.getUuid()); final boolean challengeSuccess = recaptchaClient.verify(captcha, mostRecentProxyIp); - Metrics.counter(RECAPTCHA_ATTEMPT_COUNTER_NAME, - SOURCE_COUNTRY_TAG_NAME, Util.getCountryCode(account.getNumber()), - SUCCESS_TAG_NAME, String.valueOf(challengeSuccess)).increment(); + final Tags tags = Tags.of( + Tag.of(SOURCE_COUNTRY_TAG_NAME, Util.getCountryCode(account.getNumber())), + Tag.of(SUCCESS_TAG_NAME, String.valueOf(challengeSuccess)), + UserAgentTagUtil.getPlatformTag(userAgent) + ); + + Metrics.counter(RECAPTCHA_ATTEMPT_COUNTER_NAME, tags).increment(); if (challengeSuccess) { rateLimiters.getRecaptchaChallengeSuccessLimiter().validate(account.getUuid()); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java index f28c9d553..a49c534fb 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ChallengeControllerTest.java @@ -7,6 +7,8 @@ package org.whispersystems.textsecuregcm.controllers; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyString; +import static org.mockito.ArgumentMatchers.eq; import static org.mockito.Mockito.doThrow; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.reset; @@ -110,7 +112,7 @@ class ChallengeControllerTest { .put(Entity.json(recaptchaChallengeJson)); assertEquals(200, response.getStatus()); - verify(rateLimitChallengeManager).answerRecaptchaChallenge(AuthHelper.VALID_ACCOUNT, "The value of the solved captcha token", "10.0.0.1"); + verify(rateLimitChallengeManager).answerRecaptchaChallenge(eq(AuthHelper.VALID_ACCOUNT), eq("The value of the solved captcha token"), eq("10.0.0.1"), anyString()); } @Test @@ -124,7 +126,7 @@ class ChallengeControllerTest { """; final Duration retryAfter = Duration.ofMinutes(17); - doThrow(new RateLimitExceededException(retryAfter)).when(rateLimitChallengeManager).answerRecaptchaChallenge(any(), any(), any()); + doThrow(new RateLimitExceededException(retryAfter)).when(rateLimitChallengeManager).answerRecaptchaChallenge(any(), any(), any(), any()); final Response response = EXTENSION.target("/v1/challenge") .request() diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManagerTest.java index f3de728da..4c980eced 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/limits/RateLimitChallengeManagerTest.java @@ -75,7 +75,7 @@ class RateLimitChallengeManagerTest { when(rateLimiters.getRecaptchaChallengeSuccessLimiter()).thenReturn(mock(RateLimiter.class)); when(rateLimiters.getRateLimitResetLimiter()).thenReturn(mock(RateLimiter.class)); - rateLimitChallengeManager.answerRecaptchaChallenge(account, "captcha", "10.0.0.1"); + rateLimitChallengeManager.answerRecaptchaChallenge(account, "captcha", "10.0.0.1", "Test User-Agent"); if (successfulChallenge) { verify(rateLimitChallengeListener).handleRateLimitChallengeAnswered(account);