mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 19:18:03 +01:00
Use UUIDs as rate limiter keys.
This commit is contained in:
committed by
Jon Chambers
parent
becf6afbdd
commit
a680639718
@@ -49,7 +49,7 @@ public class PreKeyRateLimiter {
|
||||
public void validate(final Account account) throws RateLimitExceededException {
|
||||
|
||||
try {
|
||||
rateLimiters.getDailyPreKeysLimiter().validate(account.getNumber());
|
||||
rateLimiters.getDailyPreKeysLimiter().validate(account.getUuid());
|
||||
} catch (final RateLimitExceededException e) {
|
||||
|
||||
final boolean enforceLimit = dynamicConfigurationManager.getConfiguration()
|
||||
@@ -70,7 +70,7 @@ public class PreKeyRateLimiter {
|
||||
|
||||
public void handleRateLimitReset(final Account account) {
|
||||
|
||||
rateLimiters.getDailyPreKeysLimiter().clear(account.getNumber());
|
||||
rateLimiters.getDailyPreKeysLimiter().clear(account.getUuid());
|
||||
|
||||
Metrics.counter(RATE_LIMIT_RESET_COUNTER_NAME, "countryCode", Util.getCountryCode(account.getNumber()))
|
||||
.increment();
|
||||
|
||||
@@ -54,12 +54,12 @@ public class RateLimitChallengeManager {
|
||||
}
|
||||
|
||||
public void answerPushChallenge(final Account account, final String challenge) throws RateLimitExceededException {
|
||||
rateLimiters.getPushChallengeAttemptLimiter().validate(account.getNumber());
|
||||
rateLimiters.getPushChallengeAttemptLimiter().validate(account.getUuid());
|
||||
|
||||
final boolean challengeSuccess = pushChallengeManager.answerChallenge(account, challenge);
|
||||
|
||||
if (challengeSuccess) {
|
||||
rateLimiters.getPushChallengeSuccessLimiter().validate(account.getNumber());
|
||||
rateLimiters.getPushChallengeSuccessLimiter().validate(account.getUuid());
|
||||
resetRateLimits(account);
|
||||
}
|
||||
}
|
||||
@@ -67,7 +67,7 @@ public class RateLimitChallengeManager {
|
||||
public void answerRecaptchaChallenge(final Account account, final String captcha, final String mostRecentProxyIp)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
rateLimiters.getRecaptchaChallengeAttemptLimiter().validate(account.getNumber());
|
||||
rateLimiters.getRecaptchaChallengeAttemptLimiter().validate(account.getUuid());
|
||||
|
||||
final boolean challengeSuccess = recaptchaClient.verify(captcha, mostRecentProxyIp);
|
||||
|
||||
@@ -76,14 +76,14 @@ public class RateLimitChallengeManager {
|
||||
SUCCESS_TAG_NAME, String.valueOf(challengeSuccess)).increment();
|
||||
|
||||
if (challengeSuccess) {
|
||||
rateLimiters.getRecaptchaChallengeSuccessLimiter().validate(account.getNumber());
|
||||
rateLimiters.getRecaptchaChallengeSuccessLimiter().validate(account.getUuid());
|
||||
resetRateLimits(account);
|
||||
}
|
||||
}
|
||||
|
||||
private void resetRateLimits(final Account account) throws RateLimitExceededException {
|
||||
try {
|
||||
rateLimiters.getRateLimitResetLimiter().validate(account.getNumber());
|
||||
rateLimiters.getRateLimitResetLimiter().validate(account.getUuid());
|
||||
} catch (final RateLimitExceededException e) {
|
||||
Metrics.counter(RESET_RATE_LIMIT_EXCEEDED_COUNTER_NAME,
|
||||
SOURCE_COUNTRY_TAG_NAME, Util.getCountryCode(account.getNumber())).increment();
|
||||
@@ -112,16 +112,14 @@ public class RateLimitChallengeManager {
|
||||
public List<String> getChallengeOptions(final Account account) {
|
||||
final List<String> options = new ArrayList<>(2);
|
||||
|
||||
final String key = account.getNumber();
|
||||
|
||||
if (rateLimiters.getRecaptchaChallengeAttemptLimiter().hasAvailablePermits(key, 1) &&
|
||||
rateLimiters.getRecaptchaChallengeSuccessLimiter().hasAvailablePermits(key, 1)) {
|
||||
if (rateLimiters.getRecaptchaChallengeAttemptLimiter().hasAvailablePermits(account.getUuid(), 1) &&
|
||||
rateLimiters.getRecaptchaChallengeSuccessLimiter().hasAvailablePermits(account.getUuid(), 1)) {
|
||||
|
||||
options.add(OPTION_RECAPTCHA);
|
||||
}
|
||||
|
||||
if (rateLimiters.getPushChallengeAttemptLimiter().hasAvailablePermits(key, 1) &&
|
||||
rateLimiters.getPushChallengeSuccessLimiter().hasAvailablePermits(key, 1)) {
|
||||
if (rateLimiters.getPushChallengeAttemptLimiter().hasAvailablePermits(account.getUuid(), 1) &&
|
||||
rateLimiters.getPushChallengeSuccessLimiter().hasAvailablePermits(account.getUuid(), 1)) {
|
||||
|
||||
options.add(OPTION_PUSH_CHALLENGE);
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import com.fasterxml.jackson.core.JsonProcessingException;
|
||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
||||
import java.io.IOException;
|
||||
import java.time.Duration;
|
||||
import java.util.UUID;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.configuration.RateLimitsConfiguration.RateLimitConfiguration;
|
||||
@@ -61,14 +62,32 @@ public class RateLimiter {
|
||||
}
|
||||
}
|
||||
|
||||
public void validate(final UUID accountUuid) throws RateLimitExceededException {
|
||||
validate(accountUuid.toString());
|
||||
}
|
||||
|
||||
public void validate(final UUID sourceAccountUuid, final UUID destinationAccountUuid)
|
||||
throws RateLimitExceededException {
|
||||
|
||||
validate(sourceAccountUuid.toString() + "__" + destinationAccountUuid.toString());
|
||||
}
|
||||
|
||||
public void validate(String key) throws RateLimitExceededException {
|
||||
validate(key, 1);
|
||||
}
|
||||
|
||||
public boolean hasAvailablePermits(final UUID accountUuid, final int permits) {
|
||||
return hasAvailablePermits(accountUuid.toString(), permits);
|
||||
}
|
||||
|
||||
public boolean hasAvailablePermits(final String key, final int permits) {
|
||||
return getBucket(key).getTimeUntilSpaceAvailable(permits).equals(Duration.ZERO);
|
||||
}
|
||||
|
||||
public void clear(final UUID accountUuid) {
|
||||
clear(accountUuid.toString());
|
||||
}
|
||||
|
||||
public void clear(String key) {
|
||||
cacheCluster.useCluster(connection -> connection.sync().del(getBucketName(key)));
|
||||
}
|
||||
|
||||
@@ -65,7 +65,7 @@ public class UnsealedSenderRateLimiter {
|
||||
|
||||
try {
|
||||
rateLimiters.getUnsealedSenderCardinalityLimiter()
|
||||
.validate(sender.getNumber(), destination.getUuid().toString(), maxCardinality);
|
||||
.validate(sender.getUuid().toString(), destination.getUuid().toString(), maxCardinality);
|
||||
} catch (final RateLimitExceededException e) {
|
||||
|
||||
final boolean enforceLimit = dynamicConfigurationManager.getConfiguration()
|
||||
@@ -91,7 +91,7 @@ public class UnsealedSenderRateLimiter {
|
||||
|
||||
final long ttl;
|
||||
{
|
||||
final long remainingTtl = unsealedSenderCardinalityLimiter.getRemainingTtl(account.getNumber());
|
||||
final long remainingTtl = unsealedSenderCardinalityLimiter.getRemainingTtl(account.getUuid().toString());
|
||||
ttl = remainingTtl > 0 ? remainingTtl : unsealedSenderCardinalityLimiter.getInitialTtl().toSeconds();
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user