Discard the Redis-backed "used token" system

This commit is contained in:
Jon Chambers 2024-10-04 15:49:37 -04:00 committed by Jon Chambers
parent 961d6d0a5c
commit 63e45563ec
9 changed files with 4 additions and 28 deletions

View File

@ -638,7 +638,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
ClientPublicKeysManager clientPublicKeysManager = ClientPublicKeysManager clientPublicKeysManager =
new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor); new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor);
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster, AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
rateLimitersCluster, accountLockManager, keysManager, messagesManager, profilesManager, accountLockManager, keysManager, messagesManager, profilesManager,
secureStorageClient, secureValueRecovery2Client, secureStorageClient, secureValueRecovery2Client,
clientPresenceManager, clientPresenceManager,
registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, clientPresenceExecutor, registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, clientPresenceExecutor,

View File

@ -13,7 +13,6 @@ import com.fasterxml.jackson.databind.ObjectWriter;
import com.google.common.annotations.VisibleForTesting; import com.google.common.annotations.VisibleForTesting;
import com.google.common.base.Preconditions; import com.google.common.base.Preconditions;
import io.lettuce.core.RedisException; import io.lettuce.core.RedisException;
import io.lettuce.core.SetArgs;
import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands; import io.lettuce.core.cluster.api.sync.RedisAdvancedClusterCommands;
import io.micrometer.core.instrument.Metrics; import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Tag; import io.micrometer.core.instrument.Tag;
@ -109,7 +108,6 @@ public class AccountsManager {
private final Accounts accounts; private final Accounts accounts;
private final PhoneNumberIdentifiers phoneNumberIdentifiers; private final PhoneNumberIdentifiers phoneNumberIdentifiers;
private final FaultTolerantRedisCluster cacheCluster; private final FaultTolerantRedisCluster cacheCluster;
private final FaultTolerantRedisCluster rateLimitCluster;
private final AccountLockManager accountLockManager; private final AccountLockManager accountLockManager;
private final KeysManager keysManager; private final KeysManager keysManager;
private final MessagesManager messagesManager; private final MessagesManager messagesManager;
@ -160,7 +158,6 @@ public class AccountsManager {
public AccountsManager(final Accounts accounts, public AccountsManager(final Accounts accounts,
final PhoneNumberIdentifiers phoneNumberIdentifiers, final PhoneNumberIdentifiers phoneNumberIdentifiers,
final FaultTolerantRedisCluster cacheCluster, final FaultTolerantRedisCluster cacheCluster,
final FaultTolerantRedisCluster rateLimitCluster,
final AccountLockManager accountLockManager, final AccountLockManager accountLockManager,
final KeysManager keysManager, final KeysManager keysManager,
final MessagesManager messagesManager, final MessagesManager messagesManager,
@ -178,7 +175,6 @@ public class AccountsManager {
this.accounts = accounts; this.accounts = accounts;
this.phoneNumberIdentifiers = phoneNumberIdentifiers; this.phoneNumberIdentifiers = phoneNumberIdentifiers;
this.cacheCluster = cacheCluster; this.cacheCluster = cacheCluster;
this.rateLimitCluster = rateLimitCluster;
this.accountLockManager = accountLockManager; this.accountLockManager = accountLockManager;
this.keysManager = keysManager; this.keysManager = keysManager;
this.messagesManager = messagesManager; this.messagesManager = messagesManager;
@ -345,9 +341,6 @@ public class AccountsManager {
return accounts.updateTransactionallyAsync(account, additionalWriteItems) return accounts.updateTransactionallyAsync(account, additionalWriteItems)
.thenApply(ignored -> new Pair<>(account, account.getDevice(nextDeviceId).orElseThrow())); .thenApply(ignored -> new Pair<>(account, account.getDevice(nextDeviceId).orElseThrow()));
}) })
.thenCompose(updatedAccountAndDevice -> rateLimitCluster.withCluster(connection ->
connection.async().set(getUsedTokenKey(linkDeviceToken), "", new SetArgs().ex(LINK_DEVICE_TOKEN_EXPIRATION_DURATION)))
.thenApply(ignored -> updatedAccountAndDevice))
.thenCompose(updatedAccountAndDevice -> redisDeleteAsync(updatedAccountAndDevice.first()) .thenCompose(updatedAccountAndDevice -> redisDeleteAsync(updatedAccountAndDevice.first())
.thenApply(ignored -> updatedAccountAndDevice)) .thenApply(ignored -> updatedAccountAndDevice))
.exceptionallyCompose(throwable -> { .exceptionallyCompose(throwable -> {
@ -412,20 +405,13 @@ public class AccountsManager {
/** /**
* Checks that a device-linking token is valid and returns the account identifier from the token if so, or empty if * Checks that a device-linking token is valid and returns the account identifier from the token if so, or empty if
* the token was invalid or has already been used * the token was invalid
* *
* @param token the device-linking token to check * @param token the device-linking token to check
* *
* @return the account identifier from a valid token or empty if the token was invalid or already used * @return the account identifier from a valid token or empty if the token was invalid
*/ */
public Optional<UUID> checkDeviceLinkingToken(final String token) { public Optional<UUID> checkDeviceLinkingToken(final String token) {
final boolean tokenUsed = rateLimitCluster.withCluster(connection ->
connection.sync().get(getUsedTokenKey(token)) != null);
if (tokenUsed) {
return Optional.empty();
}
final String[] claimsAndSignature = token.split(":", 2); final String[] claimsAndSignature = token.split(":", 2);
if (claimsAndSignature.length != 2) { if (claimsAndSignature.length != 2) {
@ -476,10 +462,6 @@ public class AccountsManager {
return Optional.of(aci); return Optional.of(aci);
} }
private static String getUsedTokenKey(final String token) {
return "usedToken::" + token;
}
public CompletableFuture<Account> removeDevice(final Account account, final byte deviceId) { public CompletableFuture<Account> removeDevice(final Account account, final byte deviceId) {
if (deviceId == Device.PRIMARY_ID) { if (deviceId == Device.PRIMARY_ID) {
throw new IllegalArgumentException("Cannot remove primary device"); throw new IllegalArgumentException("Cannot remove primary device");

View File

@ -226,7 +226,7 @@ record CommandDependencies(
ClientPublicKeysManager clientPublicKeysManager = ClientPublicKeysManager clientPublicKeysManager =
new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor); new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor);
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster, AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
rateLimitersCluster, accountLockManager, keys, messagesManager, profilesManager, accountLockManager, keys, messagesManager, profilesManager,
secureStorageClient, secureValueRecovery2Client, clientPresenceManager, secureStorageClient, secureValueRecovery2Client, clientPresenceManager,
registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, clientPresenceExecutor, registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, clientPresenceExecutor,
clock, configuration.getLinkDeviceSecretConfiguration().secret().value(), dynamicConfigurationManager); clock, configuration.getLinkDeviceSecretConfiguration().secret().value(), dynamicConfigurationManager);

View File

@ -142,7 +142,6 @@ public class AccountCreationDeletionIntegrationTest {
accounts, accounts,
phoneNumberIdentifiers, phoneNumberIdentifiers,
CACHE_CLUSTER_EXTENSION.getRedisCluster(), CACHE_CLUSTER_EXTENSION.getRedisCluster(),
CACHE_CLUSTER_EXTENSION.getRedisCluster(),
accountLockManager, accountLockManager,
keysManager, keysManager,
messagesManager, messagesManager,

View File

@ -137,7 +137,6 @@ class AccountsManagerChangeNumberIntegrationTest {
accounts, accounts,
phoneNumberIdentifiers, phoneNumberIdentifiers,
CACHE_CLUSTER_EXTENSION.getRedisCluster(), CACHE_CLUSTER_EXTENSION.getRedisCluster(),
CACHE_CLUSTER_EXTENSION.getRedisCluster(),
accountLockManager, accountLockManager,
keysManager, keysManager,
messagesManager, messagesManager,

View File

@ -124,7 +124,6 @@ class AccountsManagerConcurrentModificationIntegrationTest {
accounts, accounts,
phoneNumberIdentifiers, phoneNumberIdentifiers,
RedisClusterHelper.builder().stringCommands(commands).build(), RedisClusterHelper.builder().stringCommands(commands).build(),
RedisClusterHelper.builder().stringCommands(commands).build(),
accountLockManager, accountLockManager,
mock(KeysManager.class), mock(KeysManager.class),
mock(MessagesManager.class), mock(MessagesManager.class),

View File

@ -239,7 +239,6 @@ class AccountsManagerTest {
accounts, accounts,
phoneNumberIdentifiers, phoneNumberIdentifiers,
redisCluster, redisCluster,
redisCluster,
accountLockManager, accountLockManager,
keysManager, keysManager,
messagesManager, messagesManager,

View File

@ -137,7 +137,6 @@ class AccountsManagerUsernameIntegrationTest {
accounts, accounts,
phoneNumberIdentifiers, phoneNumberIdentifiers,
CACHE_CLUSTER_EXTENSION.getRedisCluster(), CACHE_CLUSTER_EXTENSION.getRedisCluster(),
CACHE_CLUSTER_EXTENSION.getRedisCluster(),
accountLockManager, accountLockManager,
keysManager, keysManager,
messageManager, messageManager,

View File

@ -132,7 +132,6 @@ public class AddRemoveDeviceIntegrationTest {
accounts, accounts,
phoneNumberIdentifiers, phoneNumberIdentifiers,
CACHE_CLUSTER_EXTENSION.getRedisCluster(), CACHE_CLUSTER_EXTENSION.getRedisCluster(),
CACHE_CLUSTER_EXTENSION.getRedisCluster(),
accountLockManager, accountLockManager,
keysManager, keysManager,
messagesManager, messagesManager,