mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-21 05:18:04 +01:00
Absorb DeletedAccounts into Accounts
This commit is contained in:
committed by
Jon Chambers
parent
9945367fa1
commit
1b9bf01ab1
@@ -176,7 +176,6 @@ import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ChangeNumberManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ClientReleases;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.IssuedReceiptsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysManager;
|
||||
@@ -299,9 +298,6 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
DynamoDbClient dynamoDbClient = DynamoDbFromConfig.client(config.getDynamoDbClientConfiguration(),
|
||||
AWSSDK_CREDENTIALS_PROVIDER);
|
||||
|
||||
DeletedAccounts deletedAccounts = new DeletedAccounts(dynamoDbClient,
|
||||
config.getDynamoDbTables().getDeletedAccounts().getTableName());
|
||||
|
||||
DynamicConfigurationManager<DynamicConfiguration> dynamicConfigurationManager =
|
||||
new DynamicConfigurationManager<>(config.getAppConfig().getApplication(),
|
||||
config.getAppConfig().getEnvironment(),
|
||||
@@ -325,6 +321,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
config.getDynamoDbTables().getAccounts().getPhoneNumberTableName(),
|
||||
config.getDynamoDbTables().getAccounts().getPhoneNumberIdentifierTableName(),
|
||||
config.getDynamoDbTables().getAccounts().getUsernamesTableName(),
|
||||
config.getDynamoDbTables().getDeletedAccounts().getTableName(),
|
||||
config.getDynamoDbTables().getAccounts().getScanPageSize());
|
||||
ClientReleases clientReleases = new ClientReleases(dynamoDbAsyncClient,
|
||||
config.getDynamoDbTables().getClientReleases().getTableName());
|
||||
@@ -514,7 +511,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
AccountLockManager accountLockManager = new AccountLockManager(dynamoDbClient,
|
||||
config.getDynamoDbTables().getDeletedAccountsLock().getTableName());
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
|
||||
accountLockManager, deletedAccounts, keys, messagesManager, profilesManager,
|
||||
accountLockManager, keys, messagesManager, profilesManager,
|
||||
secureStorageClient, secureBackupClient, secureValueRecovery2Client,
|
||||
clientPresenceManager,
|
||||
experimentEnrollmentManager, registrationRecoveryPasswordsManager, clock);
|
||||
@@ -764,7 +761,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
new DonationController(clock, zkReceiptOperations, redeemedReceiptsManager, accountsManager, config.getBadges(),
|
||||
ReceiptCredentialPresentation::new),
|
||||
new MessageController(rateLimiters, messageByteLimitCardinalityEstimator, messageSender, receiptSender,
|
||||
accountsManager, deletedAccounts, messagesManager, pushNotificationManager, reportMessageManager,
|
||||
accountsManager, messagesManager, pushNotificationManager, reportMessageManager,
|
||||
multiRecipientMessageExecutor, messageDeliveryScheduler, reportSpamTokenProvider, clientReleaseManager,
|
||||
dynamicConfigurationManager),
|
||||
new PaymentsController(currencyManager, paymentsCredentialsGenerator),
|
||||
|
||||
@@ -99,7 +99,6 @@ import org.whispersystems.textsecuregcm.spam.ReportSpamTokenProvider;
|
||||
import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.ClientReleaseManager;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||
import org.whispersystems.textsecuregcm.storage.Device;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesManager;
|
||||
@@ -123,7 +122,6 @@ public class MessageController {
|
||||
private final MessageSender messageSender;
|
||||
private final ReceiptSender receiptSender;
|
||||
private final AccountsManager accountsManager;
|
||||
private final DeletedAccounts deletedAccounts;
|
||||
private final MessagesManager messagesManager;
|
||||
private final PushNotificationManager pushNotificationManager;
|
||||
private final ReportMessageManager reportMessageManager;
|
||||
@@ -159,7 +157,6 @@ public class MessageController {
|
||||
MessageSender messageSender,
|
||||
ReceiptSender receiptSender,
|
||||
AccountsManager accountsManager,
|
||||
DeletedAccounts deletedAccounts,
|
||||
MessagesManager messagesManager,
|
||||
PushNotificationManager pushNotificationManager,
|
||||
ReportMessageManager reportMessageManager,
|
||||
@@ -173,7 +170,6 @@ public class MessageController {
|
||||
this.messageSender = messageSender;
|
||||
this.receiptSender = receiptSender;
|
||||
this.accountsManager = accountsManager;
|
||||
this.deletedAccounts = deletedAccounts;
|
||||
this.messagesManager = messagesManager;
|
||||
this.pushNotificationManager = pushNotificationManager;
|
||||
this.reportMessageManager = reportMessageManager;
|
||||
@@ -628,7 +624,7 @@ public class MessageController {
|
||||
sourceAci = maybeAccount.map(Account::getUuid);
|
||||
sourcePni = maybeAccount.map(Account::getPhoneNumberIdentifier);
|
||||
} else {
|
||||
sourceAci = deletedAccounts.findUuid(source);
|
||||
sourceAci = accountsManager.findRecentlyDeletedAccountIdentifier(source);
|
||||
sourcePni = Optional.ofNullable(accountsManager.getPhoneNumberIdentifier(source));
|
||||
}
|
||||
} else {
|
||||
@@ -638,7 +634,7 @@ public class MessageController {
|
||||
|
||||
if (sourceAccount.isEmpty()) {
|
||||
logger.warn("Could not find source: {}", sourceAci.get());
|
||||
sourceNumber = deletedAccounts.findE164(sourceAci.get());
|
||||
sourceNumber = accountsManager.findRecentlyDeletedE164(sourceAci.get());
|
||||
sourcePni = sourceNumber.map(accountsManager::getPhoneNumberIdentifier);
|
||||
} else {
|
||||
sourceNumber = sourceAccount.map(Account::getNumber);
|
||||
|
||||
@@ -15,10 +15,12 @@ public class AccountLockManager {
|
||||
|
||||
private final AmazonDynamoDBLockClient lockClient;
|
||||
|
||||
static final String KEY_ACCOUNT_E164 = "P";
|
||||
|
||||
public AccountLockManager(final DynamoDbClient lockDynamoDb, final String lockTableName) {
|
||||
this(new AmazonDynamoDBLockClient(
|
||||
AmazonDynamoDBLockClientOptions.builder(lockDynamoDb, lockTableName)
|
||||
.withPartitionKeyName(DeletedAccounts.KEY_ACCOUNT_E164)
|
||||
.withPartitionKeyName(KEY_ACCOUNT_E164)
|
||||
.withLeaseDuration(15L)
|
||||
.withHeartbeatPeriod(2L)
|
||||
.withTimeUnit(TimeUnit.SECONDS)
|
||||
|
||||
@@ -17,6 +17,7 @@ import java.io.IOException;
|
||||
import java.nio.ByteBuffer;
|
||||
import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
@@ -48,9 +49,11 @@ import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
|
||||
import software.amazon.awssdk.services.dynamodb.model.CancellationReason;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ConditionalCheckFailedException;
|
||||
import software.amazon.awssdk.services.dynamodb.model.Delete;
|
||||
import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GetItemResponse;
|
||||
import software.amazon.awssdk.services.dynamodb.model.Put;
|
||||
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
|
||||
import software.amazon.awssdk.services.dynamodb.model.ReturnValuesOnConditionCheckFailure;
|
||||
@@ -124,18 +127,23 @@ public class Accounts extends AbstractDynamoDbStore {
|
||||
// time to live; number
|
||||
static final String ATTR_TTL = "TTL";
|
||||
|
||||
static final String DELETED_ACCOUNTS_KEY_ACCOUNT_E164 = "P";
|
||||
static final String DELETED_ACCOUNTS_ATTR_ACCOUNT_UUID = "U";
|
||||
static final String DELETED_ACCOUNTS_ATTR_EXPIRES = "E";
|
||||
static final String DELETED_ACCOUNTS_UUID_TO_E164_INDEX_NAME = "u_to_p";
|
||||
|
||||
static final String USERNAME_LINK_TO_UUID_INDEX = "ul_to_u";
|
||||
|
||||
static final Duration DELETED_ACCOUNTS_TIME_TO_LIVE = Duration.ofDays(30);
|
||||
|
||||
private final Clock clock;
|
||||
|
||||
private final DynamoDbAsyncClient asyncClient;
|
||||
|
||||
private final String phoneNumberConstraintTableName;
|
||||
|
||||
private final String phoneNumberIdentifierConstraintTableName;
|
||||
|
||||
private final String usernamesConstraintTableName;
|
||||
|
||||
private final String deletedAccountsTableName;
|
||||
private final String accountsTableName;
|
||||
|
||||
private final int scanPageSize;
|
||||
@@ -150,6 +158,7 @@ public class Accounts extends AbstractDynamoDbStore {
|
||||
final String phoneNumberConstraintTableName,
|
||||
final String phoneNumberIdentifierConstraintTableName,
|
||||
final String usernamesConstraintTableName,
|
||||
final String deletedAccountsTableName,
|
||||
final int scanPageSize) {
|
||||
super(client);
|
||||
this.clock = clock;
|
||||
@@ -158,6 +167,7 @@ public class Accounts extends AbstractDynamoDbStore {
|
||||
this.phoneNumberIdentifierConstraintTableName = phoneNumberIdentifierConstraintTableName;
|
||||
this.accountsTableName = accountsTableName;
|
||||
this.usernamesConstraintTableName = usernamesConstraintTableName;
|
||||
this.deletedAccountsTableName = deletedAccountsTableName;
|
||||
this.scanPageSize = scanPageSize;
|
||||
}
|
||||
|
||||
@@ -168,10 +178,11 @@ public class Accounts extends AbstractDynamoDbStore {
|
||||
final String phoneNumberConstraintTableName,
|
||||
final String phoneNumberIdentifierConstraintTableName,
|
||||
final String usernamesConstraintTableName,
|
||||
final String deletedAccountsTableName,
|
||||
final int scanPageSize) {
|
||||
this(Clock.systemUTC(), client, asyncClient, accountsTableName,
|
||||
phoneNumberConstraintTableName, phoneNumberIdentifierConstraintTableName, usernamesConstraintTableName,
|
||||
scanPageSize);
|
||||
deletedAccountsTableName, scanPageSize);
|
||||
}
|
||||
|
||||
public boolean create(final Account account) {
|
||||
@@ -706,6 +717,23 @@ public class Accounts extends AbstractDynamoDbStore {
|
||||
.map(Accounts::fromItem)));
|
||||
}
|
||||
|
||||
public void putRecentlyDeletedAccount(final UUID uuid, final String e164) {
|
||||
db().putItem(PutItemRequest.builder()
|
||||
.tableName(deletedAccountsTableName)
|
||||
.item(Map.of(
|
||||
DELETED_ACCOUNTS_KEY_ACCOUNT_E164, AttributeValues.fromString(e164),
|
||||
DELETED_ACCOUNTS_ATTR_ACCOUNT_UUID, AttributeValues.fromUUID(uuid),
|
||||
DELETED_ACCOUNTS_ATTR_EXPIRES, AttributeValues.fromLong(Instant.now().plus(DELETED_ACCOUNTS_TIME_TO_LIVE).getEpochSecond())))
|
||||
.build());
|
||||
}
|
||||
|
||||
public void removeRecentlyDeletedAccount(final String e164) {
|
||||
db().deleteItem(DeleteItemRequest.builder()
|
||||
.tableName(deletedAccountsTableName)
|
||||
.key(Map.of(DELETED_ACCOUNTS_KEY_ACCOUNT_E164, AttributeValues.fromString(e164)))
|
||||
.build());
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
public CompletableFuture<Optional<Account>> getByAccountIdentifierAsync(final UUID uuid) {
|
||||
return AsyncTimerUtil.record(GET_BY_UUID_TIMER, () -> itemByKeyAsync(accountsTableName, KEY_ACCOUNT_UUID, AttributeValues.fromUUID(uuid))
|
||||
@@ -713,6 +741,37 @@ public class Accounts extends AbstractDynamoDbStore {
|
||||
.toCompletableFuture();
|
||||
}
|
||||
|
||||
public Optional<UUID> findRecentlyDeletedAccountIdentifier(final String e164) {
|
||||
final GetItemResponse response = db().getItem(GetItemRequest.builder()
|
||||
.tableName(deletedAccountsTableName)
|
||||
.consistentRead(true)
|
||||
.key(Map.of(DELETED_ACCOUNTS_KEY_ACCOUNT_E164, AttributeValues.fromString(e164)))
|
||||
.build());
|
||||
|
||||
return Optional.ofNullable(AttributeValues.getUUID(response.item(), DELETED_ACCOUNTS_ATTR_ACCOUNT_UUID, null));
|
||||
}
|
||||
|
||||
public Optional<String> findRecentlyDeletedE164(final UUID uuid) {
|
||||
final QueryResponse response = db().query(QueryRequest.builder()
|
||||
.tableName(deletedAccountsTableName)
|
||||
.indexName(DELETED_ACCOUNTS_UUID_TO_E164_INDEX_NAME)
|
||||
.keyConditionExpression("#uuid = :uuid")
|
||||
.projectionExpression("#e164")
|
||||
.expressionAttributeNames(Map.of("#uuid", DELETED_ACCOUNTS_ATTR_ACCOUNT_UUID,
|
||||
"#e164", DELETED_ACCOUNTS_KEY_ACCOUNT_E164))
|
||||
.expressionAttributeValues(Map.of(":uuid", AttributeValues.fromUUID(uuid))).build());
|
||||
|
||||
if (response.count() == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (response.count() > 1) {
|
||||
throw new RuntimeException("Impossible result: more than one phone number returned for UUID: " + uuid);
|
||||
}
|
||||
|
||||
return Optional.ofNullable(response.items().get(0).get(DELETED_ACCOUNTS_KEY_ACCOUNT_E164).s());
|
||||
}
|
||||
|
||||
public void delete(final UUID uuid) {
|
||||
DELETE_TIMER.record(() -> getByAccountIdentifier(uuid).ifPresent(account -> {
|
||||
|
||||
|
||||
@@ -101,7 +101,6 @@ public class AccountsManager {
|
||||
private final PhoneNumberIdentifiers phoneNumberIdentifiers;
|
||||
private final FaultTolerantRedisCluster cacheCluster;
|
||||
private final AccountLockManager accountLockManager;
|
||||
private final DeletedAccounts deletedAccounts;
|
||||
private final KeysManager keysManager;
|
||||
private final MessagesManager messagesManager;
|
||||
private final ProfilesManager profilesManager;
|
||||
@@ -147,7 +146,6 @@ public class AccountsManager {
|
||||
final PhoneNumberIdentifiers phoneNumberIdentifiers,
|
||||
final FaultTolerantRedisCluster cacheCluster,
|
||||
final AccountLockManager accountLockManager,
|
||||
final DeletedAccounts deletedAccounts,
|
||||
final KeysManager keysManager,
|
||||
final MessagesManager messagesManager,
|
||||
final ProfilesManager profilesManager,
|
||||
@@ -162,7 +160,6 @@ public class AccountsManager {
|
||||
this.phoneNumberIdentifiers = phoneNumberIdentifiers;
|
||||
this.cacheCluster = cacheCluster;
|
||||
this.accountLockManager = accountLockManager;
|
||||
this.deletedAccounts = deletedAccounts;
|
||||
this.keysManager = keysManager;
|
||||
this.messagesManager = messagesManager;
|
||||
this.profilesManager = profilesManager;
|
||||
@@ -201,7 +198,7 @@ public class AccountsManager {
|
||||
|
||||
// Reuse the ACI from any recently-deleted account with this number to cover cases where somebody is
|
||||
// re-registering.
|
||||
account.setUuid(deletedAccounts.findUuid(number).orElseGet(UUID::randomUUID));
|
||||
account.setUuid(accounts.findRecentlyDeletedAccountIdentifier(number).orElseGet(UUID::randomUUID));
|
||||
account.addDevice(device);
|
||||
account.setRegistrationLockFromAttributes(accountAttributes);
|
||||
account.setUnidentifiedAccessKey(accountAttributes.getUnidentifiedAccessKey());
|
||||
@@ -261,7 +258,7 @@ public class AccountsManager {
|
||||
|
||||
// Clear any "recently deleted account" record for this number since, if it existed, we've used its old ACI for
|
||||
// the newly-created account.
|
||||
deletedAccounts.remove(number);
|
||||
accounts.removeRecentlyDeletedAccount(number);
|
||||
});
|
||||
|
||||
return account;
|
||||
@@ -303,7 +300,7 @@ public class AccountsManager {
|
||||
// of the account changing its number (which facilitates ACI consistency in cases that a party is switching
|
||||
// back and forth between numbers).
|
||||
// 3. No account with the target number exists at all, in which case no additional action is needed.
|
||||
final Optional<UUID> recentlyDeletedAci = deletedAccounts.findUuid(targetNumber);
|
||||
final Optional<UUID> recentlyDeletedAci = accounts.findRecentlyDeletedAccountIdentifier(targetNumber);
|
||||
final Optional<Account> maybeExistingAccount = getByE164(targetNumber);
|
||||
final Optional<UUID> maybeDisplacedUuid;
|
||||
|
||||
@@ -314,7 +311,7 @@ public class AccountsManager {
|
||||
maybeDisplacedUuid = recentlyDeletedAci;
|
||||
}
|
||||
|
||||
maybeDisplacedUuid.ifPresent(displacedUuid -> deletedAccounts.put(displacedUuid, originalNumber));
|
||||
maybeDisplacedUuid.ifPresent(displacedUuid -> accounts.putRecentlyDeletedAccount(displacedUuid, originalNumber));
|
||||
|
||||
final UUID uuid = account.getUuid();
|
||||
final UUID phoneNumberIdentifier = phoneNumberIdentifiers.getPhoneNumberIdentifier(targetNumber);
|
||||
@@ -836,6 +833,14 @@ public class AccountsManager {
|
||||
return phoneNumberIdentifiers.getPhoneNumberIdentifier(e164);
|
||||
}
|
||||
|
||||
public Optional<UUID> findRecentlyDeletedAccountIdentifier(final String e164) {
|
||||
return accounts.findRecentlyDeletedAccountIdentifier(e164);
|
||||
}
|
||||
|
||||
public Optional<String> findRecentlyDeletedE164(final UUID uuid) {
|
||||
return accounts.findRecentlyDeletedE164(uuid);
|
||||
}
|
||||
|
||||
public AccountCrawlChunk getAllFromDynamo(int length) {
|
||||
return accounts.getAllFromStart(length);
|
||||
}
|
||||
@@ -856,7 +861,7 @@ public class AccountsManager {
|
||||
|
||||
delete(account);
|
||||
|
||||
deletedAccounts.put(accountIdentifier, e164);
|
||||
accounts.putRecentlyDeletedAccount(accountIdentifier, e164);
|
||||
});
|
||||
} catch (final RuntimeException | InterruptedException e) {
|
||||
logger.warn("Failed to delete account", e);
|
||||
|
||||
@@ -1,87 +0,0 @@
|
||||
/*
|
||||
* Copyright 2013-2021 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
import org.whispersystems.textsecuregcm.util.AttributeValues;
|
||||
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
|
||||
import software.amazon.awssdk.services.dynamodb.model.DeleteItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GetItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.GetItemResponse;
|
||||
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.QueryRequest;
|
||||
import software.amazon.awssdk.services.dynamodb.model.QueryResponse;
|
||||
|
||||
public class DeletedAccounts {
|
||||
|
||||
// e164, primary key
|
||||
static final String KEY_ACCOUNT_E164 = "P";
|
||||
static final String ATTR_ACCOUNT_UUID = "U";
|
||||
static final String ATTR_EXPIRES = "E";
|
||||
|
||||
static final String UUID_TO_E164_INDEX_NAME = "u_to_p";
|
||||
|
||||
static final Duration TIME_TO_LIVE = Duration.ofDays(30);
|
||||
|
||||
private final DynamoDbClient dynamoDbClient;
|
||||
private final String tableName;
|
||||
|
||||
public DeletedAccounts(final DynamoDbClient dynamoDbClient, final String tableName) {
|
||||
this.dynamoDbClient = dynamoDbClient;
|
||||
this.tableName = tableName;
|
||||
}
|
||||
|
||||
public void put(UUID uuid, String e164) {
|
||||
dynamoDbClient.putItem(PutItemRequest.builder()
|
||||
.tableName(tableName)
|
||||
.item(Map.of(
|
||||
KEY_ACCOUNT_E164, AttributeValues.fromString(e164),
|
||||
ATTR_ACCOUNT_UUID, AttributeValues.fromUUID(uuid),
|
||||
ATTR_EXPIRES, AttributeValues.fromLong(Instant.now().plus(TIME_TO_LIVE).getEpochSecond())))
|
||||
.build());
|
||||
}
|
||||
|
||||
public Optional<UUID> findUuid(final String e164) {
|
||||
final GetItemResponse response = dynamoDbClient.getItem(GetItemRequest.builder()
|
||||
.tableName(tableName)
|
||||
.consistentRead(true)
|
||||
.key(Map.of(KEY_ACCOUNT_E164, AttributeValues.fromString(e164)))
|
||||
.build());
|
||||
|
||||
return Optional.ofNullable(AttributeValues.getUUID(response.item(), ATTR_ACCOUNT_UUID, null));
|
||||
}
|
||||
|
||||
public Optional<String> findE164(final UUID uuid) {
|
||||
final QueryResponse response = dynamoDbClient.query(QueryRequest.builder()
|
||||
.tableName(tableName)
|
||||
.indexName(UUID_TO_E164_INDEX_NAME)
|
||||
.keyConditionExpression("#uuid = :uuid")
|
||||
.projectionExpression("#e164")
|
||||
.expressionAttributeNames(Map.of("#uuid", ATTR_ACCOUNT_UUID,
|
||||
"#e164", KEY_ACCOUNT_E164))
|
||||
.expressionAttributeValues(Map.of(":uuid", AttributeValues.fromUUID(uuid))).build());
|
||||
|
||||
if (response.count() == 0) {
|
||||
return Optional.empty();
|
||||
}
|
||||
|
||||
if (response.count() > 1) {
|
||||
throw new RuntimeException("Impossible result: more than one phone number returned for UUID: " + uuid);
|
||||
}
|
||||
|
||||
return Optional.ofNullable(response.items().get(0).get(KEY_ACCOUNT_E164).s());
|
||||
}
|
||||
|
||||
public void remove(final String e164) {
|
||||
dynamoDbClient.deleteItem(DeleteItemRequest.builder()
|
||||
.tableName(tableName)
|
||||
.key(Map.of(KEY_ACCOUNT_E164, AttributeValues.fromString(e164)))
|
||||
.build());
|
||||
}
|
||||
}
|
||||
@@ -38,7 +38,6 @@ import org.whispersystems.textsecuregcm.storage.Account;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountLockManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Accounts;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysManager;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||
@@ -141,8 +140,6 @@ public class AssignUsernameCommand extends EnvironmentCommand<WhisperServerConfi
|
||||
DynamoDbClient dynamoDbClient = DynamoDbFromConfig.client(configuration.getDynamoDbClientConfiguration(),
|
||||
WhisperServerService.AWSSDK_CREDENTIALS_PROVIDER);
|
||||
|
||||
DeletedAccounts deletedAccounts = new DeletedAccounts(dynamoDbClient,
|
||||
configuration.getDynamoDbTables().getDeletedAccounts().getTableName());
|
||||
RegistrationRecoveryPasswords registrationRecoveryPasswords = new RegistrationRecoveryPasswords(
|
||||
configuration.getDynamoDbTables().getRegistrationRecovery().getTableName(),
|
||||
configuration.getDynamoDbTables().getRegistrationRecovery().getExpiration(),
|
||||
@@ -159,6 +156,7 @@ public class AssignUsernameCommand extends EnvironmentCommand<WhisperServerConfi
|
||||
configuration.getDynamoDbTables().getAccounts().getPhoneNumberTableName(),
|
||||
configuration.getDynamoDbTables().getAccounts().getPhoneNumberIdentifierTableName(),
|
||||
configuration.getDynamoDbTables().getAccounts().getUsernamesTableName(),
|
||||
configuration.getDynamoDbTables().getDeletedAccounts().getTableName(),
|
||||
configuration.getDynamoDbTables().getAccounts().getScanPageSize());
|
||||
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(dynamoDbClient,
|
||||
configuration.getDynamoDbTables().getPhoneNumberIdentifiers().getTableName());
|
||||
@@ -206,7 +204,7 @@ public class AssignUsernameCommand extends EnvironmentCommand<WhisperServerConfi
|
||||
AccountLockManager accountLockManager = new AccountLockManager(dynamoDbClient,
|
||||
configuration.getDynamoDbTables().getDeletedAccountsLock().getTableName());
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
|
||||
accountLockManager, deletedAccounts, keys, messagesManager, profilesManager,
|
||||
accountLockManager, keys, messagesManager, profilesManager,
|
||||
secureStorageClient, secureBackupClient, secureValueRecovery2Client, clientPresenceManager,
|
||||
experimentEnrollmentManager, registrationRecoveryPasswordsManager, Clock.systemUTC());
|
||||
|
||||
|
||||
@@ -31,7 +31,6 @@ import org.whispersystems.textsecuregcm.securevaluerecovery.SecureValueRecovery2
|
||||
import org.whispersystems.textsecuregcm.storage.AccountLockManager;
|
||||
import org.whispersystems.textsecuregcm.storage.Accounts;
|
||||
import org.whispersystems.textsecuregcm.storage.AccountsManager;
|
||||
import org.whispersystems.textsecuregcm.storage.DeletedAccounts;
|
||||
import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
|
||||
import org.whispersystems.textsecuregcm.storage.KeysManager;
|
||||
import org.whispersystems.textsecuregcm.storage.MessagesCache;
|
||||
@@ -117,8 +116,6 @@ record CommandDependencies(
|
||||
DynamoDbClient dynamoDbClient = DynamoDbFromConfig.client(
|
||||
configuration.getDynamoDbClientConfiguration(), WhisperServerService.AWSSDK_CREDENTIALS_PROVIDER);
|
||||
|
||||
DeletedAccounts deletedAccounts = new DeletedAccounts(dynamoDbClient,
|
||||
configuration.getDynamoDbTables().getDeletedAccounts().getTableName());
|
||||
RegistrationRecoveryPasswords registrationRecoveryPasswords = new RegistrationRecoveryPasswords(
|
||||
configuration.getDynamoDbTables().getRegistrationRecovery().getTableName(),
|
||||
configuration.getDynamoDbTables().getRegistrationRecovery().getExpiration(),
|
||||
@@ -136,6 +133,7 @@ record CommandDependencies(
|
||||
configuration.getDynamoDbTables().getAccounts().getPhoneNumberTableName(),
|
||||
configuration.getDynamoDbTables().getAccounts().getPhoneNumberIdentifierTableName(),
|
||||
configuration.getDynamoDbTables().getAccounts().getUsernamesTableName(),
|
||||
configuration.getDynamoDbTables().getDeletedAccounts().getTableName(),
|
||||
configuration.getDynamoDbTables().getAccounts().getScanPageSize());
|
||||
PhoneNumberIdentifiers phoneNumberIdentifiers = new PhoneNumberIdentifiers(dynamoDbClient,
|
||||
configuration.getDynamoDbTables().getPhoneNumberIdentifiers().getTableName());
|
||||
@@ -184,7 +182,7 @@ record CommandDependencies(
|
||||
AccountLockManager accountLockManager = new AccountLockManager(dynamoDbClient,
|
||||
configuration.getDynamoDbTables().getDeletedAccountsLock().getTableName());
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
|
||||
accountLockManager, deletedAccounts, keys, messagesManager, profilesManager,
|
||||
accountLockManager, keys, messagesManager, profilesManager,
|
||||
secureStorageClient, secureBackupClient, secureValueRecovery2Client,
|
||||
clientPresenceManager,
|
||||
experimentEnrollmentManager, registrationRecoveryPasswordsManager, clock);
|
||||
|
||||
Reference in New Issue
Block a user