Refresh registration recovery password expirations before retrying an insertion

This commit is contained in:
Jon Chambers
2024-11-25 16:22:49 -05:00
committed by Jon Chambers
parent ffed19d198
commit ff4e2bdfb7
3 changed files with 30 additions and 9 deletions

View File

@@ -17,6 +17,7 @@ import java.util.concurrent.CompletableFuture;
import org.whispersystems.textsecuregcm.auth.SaltedTokenHash;
import org.whispersystems.textsecuregcm.util.AttributeValues;
import org.whispersystems.textsecuregcm.util.ExceptionUtils;
import org.whispersystems.textsecuregcm.util.Pair;
import org.whispersystems.textsecuregcm.util.Util;
import reactor.core.publisher.Flux;
import reactor.core.scheduler.Scheduler;
@@ -65,13 +66,26 @@ public class RegistrationRecoveryPasswords {
.tableName(tableName)
.key(Map.of(KEY_E164, AttributeValues.fromString(number)))
.consistentRead(true)
.build())
.build())
.thenApply(getItemResponse -> Optional.ofNullable(getItemResponse.item())
.filter(item -> item.containsKey(ATTR_SALT))
.filter(item -> item.containsKey(ATTR_HASH))
.map(RegistrationRecoveryPasswords::saltedTokenHashFromItem));
}
CompletableFuture<Optional<Pair<SaltedTokenHash, Long>>> lookupWithExpiration(final String key) {
return asyncClient.getItem(GetItemRequest.builder()
.tableName(tableName)
.key(Map.of(KEY_E164, AttributeValues.fromString(key)))
.consistentRead(true)
.build())
.thenApply(getItemResponse -> Optional.ofNullable(getItemResponse.item())
.filter(item -> item.containsKey(ATTR_SALT))
.filter(item -> item.containsKey(ATTR_HASH))
.filter(item -> item.containsKey(ATTR_EXP))
.map(item -> new Pair<>(saltedTokenHashFromItem(item), Long.parseLong(item.get(ATTR_EXP).n()))));
}
public CompletableFuture<Optional<SaltedTokenHash>> lookup(final UUID phoneNumberIdentifier) {
return lookup(phoneNumberIdentifier.toString());
}

View File

@@ -95,9 +95,9 @@ public class RegistrationRecoveryPasswordsManager {
.exceptionallyCompose(throwable -> {
if (ExceptionUtils.unwrap(throwable) instanceof ContestedOptimisticLockException) {
// Something about the original record changed; refresh and retry
return registrationRecoveryPasswords.lookup(number)
.thenCompose(maybeSaltedTokenHash -> maybeSaltedTokenHash
.map(refreshedSaltedTokenHash -> migrateE164Record(number, phoneNumberIdentifier, refreshedSaltedTokenHash, expirationSeconds, remainingAttempts - 1))
return registrationRecoveryPasswords.lookupWithExpiration(number)
.thenCompose(maybePair -> maybePair
.map(pair -> migrateE164Record(number, phoneNumberIdentifier, pair.first(), pair.second(), remainingAttempts - 1))
.orElseGet(() -> {
// The original record was deleted, and we can declare victory
return CompletableFuture.completedFuture(false);