mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 01:28:03 +01:00
Use UUIDs as rate limiter keys.
This commit is contained in:
committed by
Jon Chambers
parent
becf6afbdd
commit
a680639718
@@ -567,7 +567,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
smsSender, dynamicConfigurationManager, turnTokenGenerator, config.getTestDevices(),
|
||||
transitionalRecaptchaClient, gcmSender, apnSender, backupCredentialsGenerator,
|
||||
verifyExperimentEnrollmentManager));
|
||||
environment.jersey().register(new KeysController(rateLimiters, keysDynamoDb, accountsManager, preKeyRateLimiter, dynamicConfigurationManager, rateLimitChallengeManager));
|
||||
environment.jersey().register(new KeysController(rateLimiters, keysDynamoDb, accountsManager, preKeyRateLimiter, rateLimitChallengeManager));
|
||||
|
||||
final List<Object> commonControllers = List.of(
|
||||
new AttachmentControllerV1(rateLimiters, config.getAwsAttachmentsConfiguration().getAccessKey(), config.getAwsAttachmentsConfiguration().getAccessSecret(), config.getAwsAttachmentsConfiguration().getBucket()),
|
||||
|
||||
@@ -207,17 +207,17 @@ public class AccountController {
|
||||
throw new WebApplicationException(Response.status(400).build());
|
||||
}
|
||||
|
||||
String requester = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow();
|
||||
String sourceHost = ForwardedIpUtil.getMostRecentProxy(forwardedFor).orElseThrow();
|
||||
|
||||
Optional<StoredVerificationCode> storedChallenge = pendingAccounts.getCodeForNumber(number);
|
||||
CaptchaRequirement requirement = requiresCaptcha(number, transport, forwardedFor, requester, captcha, storedChallenge, pushChallenge);
|
||||
CaptchaRequirement requirement = requiresCaptcha(number, transport, forwardedFor, sourceHost, captcha, storedChallenge, pushChallenge);
|
||||
|
||||
if (requirement.isCaptchaRequired()) {
|
||||
captchaRequiredMeter.mark();
|
||||
|
||||
if (requirement.isAutoBlock() && shouldAutoBlock(requester)) {
|
||||
logger.info("Auto-block: " + requester);
|
||||
abusiveHostRules.setBlockedHost(requester, "Auto-Block");
|
||||
if (requirement.isAutoBlock() && shouldAutoBlock(sourceHost)) {
|
||||
logger.info("Auto-block: {}", sourceHost);
|
||||
abusiveHostRules.setBlockedHost(sourceHost, "Auto-Block");
|
||||
}
|
||||
|
||||
return Response.status(402).build();
|
||||
@@ -405,7 +405,7 @@ public class AccountController {
|
||||
@Path("/turn/")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public TurnToken getTurnToken(@Auth Account account) throws RateLimitExceededException {
|
||||
rateLimiters.getTurnLimiter().validate(account.getNumber());
|
||||
rateLimiters.getTurnLimiter().validate(account.getUuid());
|
||||
return turnTokenGenerator.generate();
|
||||
}
|
||||
|
||||
@@ -568,7 +568,7 @@ public class AccountController {
|
||||
@Path("/username/{username}")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
public Response setUsername(@Auth Account account, @PathParam("username") String username) throws RateLimitExceededException {
|
||||
rateLimiters.getUsernameSetLimiter().validate(account.getUuid().toString());
|
||||
rateLimiters.getUsernameSetLimiter().validate(account.getUuid());
|
||||
|
||||
if (username == null || username.isEmpty()) {
|
||||
return Response.status(Response.Status.BAD_REQUEST).build();
|
||||
@@ -588,14 +588,14 @@ public class AccountController {
|
||||
}
|
||||
|
||||
private CaptchaRequirement requiresCaptcha(String number, String transport, String forwardedFor,
|
||||
String requester,
|
||||
String sourceHost,
|
||||
Optional<String> captchaToken,
|
||||
Optional<StoredVerificationCode> storedVerificationCode,
|
||||
Optional<String> pushChallenge)
|
||||
{
|
||||
|
||||
if (captchaToken.isPresent()) {
|
||||
boolean validToken = recaptchaClient.verify(captchaToken.get(), requester);
|
||||
boolean validToken = recaptchaClient.verify(captchaToken.get(), sourceHost);
|
||||
|
||||
if (validToken) {
|
||||
captchaSuccessMeter.mark();
|
||||
@@ -633,18 +633,18 @@ public class AccountController {
|
||||
}
|
||||
}
|
||||
|
||||
List<AbusiveHostRule> abuseRules = abusiveHostRules.getAbusiveHostRulesFor(requester);
|
||||
List<AbusiveHostRule> abuseRules = abusiveHostRules.getAbusiveHostRulesFor(sourceHost);
|
||||
|
||||
for (AbusiveHostRule abuseRule : abuseRules) {
|
||||
if (abuseRule.isBlocked()) {
|
||||
logger.info("Blocked host: " + transport + ", " + number + ", " + requester + " (" + forwardedFor + ")");
|
||||
logger.info("Blocked host: {}, {}, {} ({})", transport, number, sourceHost, forwardedFor);
|
||||
blockedHostMeter.mark();
|
||||
return new CaptchaRequirement(true, false);
|
||||
}
|
||||
|
||||
if (!abuseRule.getRegions().isEmpty()) {
|
||||
if (abuseRule.getRegions().stream().noneMatch(number::startsWith)) {
|
||||
logger.info("Restricted host: " + transport + ", " + number + ", " + requester + " (" + forwardedFor + ")");
|
||||
logger.info("Restricted host: {}, {}, {} ({})", transport, number, sourceHost, forwardedFor);
|
||||
filteredHostMeter.mark();
|
||||
return new CaptchaRequirement(true, false);
|
||||
}
|
||||
@@ -652,9 +652,9 @@ public class AccountController {
|
||||
}
|
||||
|
||||
try {
|
||||
rateLimiters.getSmsVoiceIpLimiter().validate(requester);
|
||||
rateLimiters.getSmsVoiceIpLimiter().validate(sourceHost);
|
||||
} catch (RateLimitExceededException e) {
|
||||
logger.info("Rate limited exceeded: " + transport + ", " + number + ", " + requester + " (" + forwardedFor + ")");
|
||||
logger.info("Rate limit exceeded: {}, {}, {} ({})", transport, number, sourceHost, forwardedFor);
|
||||
rateLimitedHostMeter.mark();
|
||||
return new CaptchaRequirement(true, true);
|
||||
}
|
||||
@@ -662,7 +662,7 @@ public class AccountController {
|
||||
try {
|
||||
rateLimiters.getSmsVoicePrefixLimiter().validate(Util.getNumberPrefix(number));
|
||||
} catch (RateLimitExceededException e) {
|
||||
logger.info("Prefix rate limit exceeded: " + transport + ", " + number + ", (" + forwardedFor + ")");
|
||||
logger.info("Prefix rate limit exceeded: {}, {}, {} ({})", transport, number, sourceHost, forwardedFor);
|
||||
rateLimitedPrefixMeter.mark();
|
||||
return new CaptchaRequirement(true, true);
|
||||
}
|
||||
@@ -682,9 +682,9 @@ public class AccountController {
|
||||
accounts.delete(account, AccountsManager.DeletionReason.USER_REQUEST);
|
||||
}
|
||||
|
||||
private boolean shouldAutoBlock(String requester) {
|
||||
private boolean shouldAutoBlock(String sourceHost) {
|
||||
try {
|
||||
rateLimiters.getAutoBlockLimiter().validate(requester);
|
||||
rateLimiters.getAutoBlockLimiter().validate(sourceHost);
|
||||
} catch (RateLimitExceededException e) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class AttachmentControllerV1 extends AttachmentControllerBase {
|
||||
throws RateLimitExceededException
|
||||
{
|
||||
if (account.isRateLimited()) {
|
||||
rateLimiters.getAttachmentLimiter().validate(account.getNumber());
|
||||
rateLimiters.getAttachmentLimiter().validate(account.getUuid());
|
||||
}
|
||||
|
||||
long attachmentId = generateAttachmentId();
|
||||
|
||||
@@ -41,7 +41,7 @@ public class AttachmentControllerV2 extends AttachmentControllerBase {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/form/upload")
|
||||
public AttachmentDescriptorV2 getAttachmentUploadForm(@Auth Account account) throws RateLimitExceededException {
|
||||
rateLimiter.validate(account.getNumber());
|
||||
rateLimiter.validate(account.getUuid());
|
||||
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
long attachmentId = generateAttachmentId();
|
||||
|
||||
@@ -58,7 +58,7 @@ public class AttachmentControllerV3 extends AttachmentControllerBase {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/form/upload")
|
||||
public AttachmentDescriptorV3 getAttachmentUploadForm(@Auth Account account) throws RateLimitExceededException {
|
||||
rateLimiter.validate(account.getNumber());
|
||||
rateLimiter.validate(account.getUuid());
|
||||
|
||||
final ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
final String key = generateAttachmentKey();
|
||||
|
||||
@@ -112,7 +112,7 @@ public class DeviceController {
|
||||
public VerificationCode createDeviceToken(@Auth Account account)
|
||||
throws RateLimitExceededException, DeviceLimitExceededException
|
||||
{
|
||||
rateLimiters.getAllocateDeviceLimiter().validate(account.getNumber());
|
||||
rateLimiters.getAllocateDeviceLimiter().validate(account.getUuid());
|
||||
|
||||
int maxDeviceLimit = MAX_DEVICES;
|
||||
|
||||
|
||||
@@ -40,11 +40,9 @@ import org.whispersystems.textsecuregcm.limits.PreKeyRateLimiter;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeException;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimitChallengeManager;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.sqs.DirectoryQueue;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysDynamoDb;
|
||||
import org.whispersystems.textsecuregcm.util.Util;
|
||||
|
||||
@@ -57,7 +55,6 @@ public class KeysController {
|
||||
private final AccountsManager accounts;
|
||||
private final PreKeyRateLimiter preKeyRateLimiter;
|
||||
|
||||
private final DynamicConfigurationManager dynamicConfigurationManager;
|
||||
private final RateLimitChallengeManager rateLimitChallengeManager;
|
||||
|
||||
private static final String PREKEY_REQUEST_COUNTER_NAME = name(KeysController.class, "preKeyGet");
|
||||
@@ -69,15 +66,12 @@ public class KeysController {
|
||||
|
||||
public KeysController(RateLimiters rateLimiters, KeysDynamoDb keysDynamoDb, AccountsManager accounts,
|
||||
PreKeyRateLimiter preKeyRateLimiter,
|
||||
DynamicConfigurationManager dynamicConfigurationManager,
|
||||
RateLimitChallengeManager rateLimitChallengeManager) {
|
||||
this.rateLimiters = rateLimiters;
|
||||
this.keysDynamoDb = keysDynamoDb;
|
||||
this.accounts = accounts;
|
||||
this.preKeyRateLimiter = preKeyRateLimiter;
|
||||
|
||||
this.dynamicConfigurationManager = dynamicConfigurationManager;
|
||||
this.rateLimitChallengeManager = rateLimitChallengeManager;
|
||||
this.rateLimitChallengeManager = rateLimitChallengeManager;
|
||||
}
|
||||
|
||||
@GET
|
||||
@@ -152,7 +146,7 @@ public class KeysController {
|
||||
}
|
||||
|
||||
if (account.isPresent()) {
|
||||
rateLimiters.getPreKeysLimiter().validate(account.get().getNumber() + "." + account.get().getAuthenticatedDevice().get().getId() + "__" + target.get().getNumber() + "." + deviceId);
|
||||
rateLimiters.getPreKeysLimiter().validate(account.get().getUuid() + "." + account.get().getAuthenticatedDevice().get().getId() + "__" + target.get().getUuid() + "." + deviceId);
|
||||
|
||||
try {
|
||||
preKeyRateLimiter.validate(account.get());
|
||||
|
||||
@@ -257,7 +257,7 @@ public class MessageController {
|
||||
assert(destination.isPresent());
|
||||
|
||||
if (source.isPresent() && !source.get().isFor(destinationName)) {
|
||||
rateLimiters.getMessagesLimiter().validate(source.get().getNumber() + "__" + destination.get().getUuid());
|
||||
rateLimiters.getMessagesLimiter().validate(source.get().getUuid(), destination.get().getUuid());
|
||||
|
||||
final String senderCountryCode = Util.getCountryCode(source.get().getNumber());
|
||||
|
||||
|
||||
@@ -210,7 +210,7 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
if (requestAccount.isPresent()) {
|
||||
rateLimiters.getProfileLimiter().validate(requestAccount.get().getNumber());
|
||||
rateLimiters.getProfileLimiter().validate(requestAccount.get().getUuid());
|
||||
}
|
||||
|
||||
Optional<Account> accountProfile = accountsManager.get(uuid);
|
||||
@@ -260,7 +260,7 @@ public class ProfileController {
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Path("/username/{username}")
|
||||
public Profile getProfileByUsername(@Auth Account account, @PathParam("username") String username) throws RateLimitExceededException {
|
||||
rateLimiters.getUsernameLookupLimiter().validate(account.getUuid().toString());
|
||||
rateLimiters.getUsernameLookupLimiter().validate(account.getUuid());
|
||||
|
||||
username = username.toLowerCase();
|
||||
|
||||
@@ -341,7 +341,7 @@ public class ProfileController {
|
||||
}
|
||||
|
||||
if (requestAccount.isPresent()) {
|
||||
rateLimiters.getProfileLimiter().validate(requestAccount.get().getNumber());
|
||||
rateLimiters.getProfileLimiter().validate(requestAccount.get().getUuid());
|
||||
}
|
||||
|
||||
Optional<Account> accountProfile = accountsManager.get(identifier);
|
||||
|
||||
@@ -6,13 +6,8 @@
|
||||
package org.whispersystems.textsecuregcm.controllers;
|
||||
|
||||
import com.codahale.metrics.annotation.Timed;
|
||||
import org.whispersystems.textsecuregcm.entities.ProvisioningMessage;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.push.ProvisioningManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.websocket.InvalidWebsocketAddressException;
|
||||
import org.whispersystems.textsecuregcm.websocket.ProvisioningAddress;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
import java.util.Base64;
|
||||
import javax.validation.Valid;
|
||||
import javax.ws.rs.Consumes;
|
||||
import javax.ws.rs.PUT;
|
||||
@@ -22,10 +17,11 @@ import javax.ws.rs.Produces;
|
||||
import javax.ws.rs.WebApplicationException;
|
||||
import javax.ws.rs.core.MediaType;
|
||||
import javax.ws.rs.core.Response;
|
||||
import java.io.IOException;
|
||||
import java.util.Base64;
|
||||
|
||||
import io.dropwizard.auth.Auth;
|
||||
import org.whispersystems.textsecuregcm.entities.ProvisioningMessage;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.push.ProvisioningManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.websocket.ProvisioningAddress;
|
||||
|
||||
@Path("/v1/provisioning")
|
||||
public class ProvisioningController {
|
||||
@@ -46,9 +42,9 @@ public class ProvisioningController {
|
||||
public void sendProvisioningMessage(@Auth Account source,
|
||||
@PathParam("destination") String destinationName,
|
||||
@Valid ProvisioningMessage message)
|
||||
throws RateLimitExceededException, InvalidWebsocketAddressException, IOException
|
||||
{
|
||||
rateLimiters.getMessagesLimiter().validate(source.getNumber());
|
||||
throws RateLimitExceededException {
|
||||
|
||||
rateLimiters.getMessagesLimiter().validate(source.getUuid());
|
||||
|
||||
if (!provisioningManager.sendProvisioningMessage(new ProvisioningAddress(destinationName, 0),
|
||||
Base64.getDecoder().decode(message.getBody())))
|
||||
|
||||
@@ -49,7 +49,7 @@ public class StickerController {
|
||||
@PathParam("count") @Min(1) @Max(201) int stickerCount)
|
||||
throws RateLimitExceededException
|
||||
{
|
||||
rateLimiters.getStickerPackLimiter().validate(account.getNumber());
|
||||
rateLimiters.getStickerPackLimiter().validate(account.getUuid());
|
||||
|
||||
ZonedDateTime now = ZonedDateTime.now(ZoneOffset.UTC);
|
||||
String packId = generatePackId();
|
||||
|
||||
@@ -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