diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index cfadf7035..429071581 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -144,16 +144,14 @@ import org.whispersystems.textsecuregcm.grpc.AccountsAnonymousGrpcService; import org.whispersystems.textsecuregcm.grpc.AccountsGrpcService; import org.whispersystems.textsecuregcm.grpc.CallQualitySurveyGrpcService; import org.whispersystems.textsecuregcm.grpc.ErrorConformanceInterceptor; -import org.whispersystems.textsecuregcm.grpc.GrpcAllowListInterceptor; import org.whispersystems.textsecuregcm.grpc.ErrorMappingInterceptor; import org.whispersystems.textsecuregcm.grpc.ExternalServiceCredentialsAnonymousGrpcService; import org.whispersystems.textsecuregcm.grpc.ExternalServiceCredentialsGrpcService; +import org.whispersystems.textsecuregcm.grpc.GrpcAllowListInterceptor; import org.whispersystems.textsecuregcm.grpc.KeysAnonymousGrpcService; import org.whispersystems.textsecuregcm.grpc.KeysGrpcService; import org.whispersystems.textsecuregcm.grpc.MetricServerInterceptor; import org.whispersystems.textsecuregcm.grpc.PaymentsGrpcService; -import org.whispersystems.textsecuregcm.grpc.ProfileAnonymousGrpcService; -import org.whispersystems.textsecuregcm.grpc.ProfileGrpcService; import org.whispersystems.textsecuregcm.grpc.RequestAttributesInterceptor; import org.whispersystems.textsecuregcm.grpc.ValidatingInterceptor; import org.whispersystems.textsecuregcm.grpc.net.ManagedGrpcServer; @@ -219,8 +217,6 @@ import org.whispersystems.textsecuregcm.storage.AccountLockManager; import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.ChangeNumberManager; -import org.whispersystems.textsecuregcm.storage.ClientPublicKeys; -import org.whispersystems.textsecuregcm.storage.ClientPublicKeysManager; import org.whispersystems.textsecuregcm.storage.ClientReleaseManager; import org.whispersystems.textsecuregcm.storage.ClientReleases; import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; @@ -257,8 +253,8 @@ import org.whispersystems.textsecuregcm.subscriptions.AppleAppStoreClient; import org.whispersystems.textsecuregcm.subscriptions.AppleAppStoreManager; import org.whispersystems.textsecuregcm.subscriptions.BankMandateTranslator; import org.whispersystems.textsecuregcm.subscriptions.BraintreeManager; -import org.whispersystems.textsecuregcm.subscriptions.PayPalDonationsTranslator; import org.whispersystems.textsecuregcm.subscriptions.GooglePlayBillingManager; +import org.whispersystems.textsecuregcm.subscriptions.PayPalDonationsTranslator; import org.whispersystems.textsecuregcm.subscriptions.StripeManager; import org.whispersystems.textsecuregcm.telephony.CarrierDataProvider; import org.whispersystems.textsecuregcm.telephony.hlrlookup.HlrLookupCarrierDataProvider; @@ -499,8 +495,6 @@ public class WhisperServerService extends Application maxDeviceConfiguration; @@ -122,13 +117,11 @@ public class DeviceController { static final int MAX_TOKEN_IDENTIFIER_LENGTH = 64; public DeviceController(final AccountsManager accounts, - final ClientPublicKeysManager clientPublicKeysManager, final RateLimiters rateLimiters, final PersistentTimer persistentTimer, final Map maxDeviceConfiguration) { this.accounts = accounts; - this.clientPublicKeysManager = clientPublicKeysManager; this.rateLimiters = rateLimiters; this.persistentTimer = persistentTimer; this.maxDeviceConfiguration = maxDeviceConfiguration; @@ -419,29 +412,6 @@ public class DeviceController { d -> d.setCapabilities(DeviceCapabilityAdapter.mapToSet(capabilities))); } - @PUT - @Produces(MediaType.APPLICATION_JSON) - @Path("/public_key") - @Operation( - summary = "Sets a public key for authentication", - description = """ - Sets the authentication public key for the authenticated device. The public key will be used for - authentication in the nascent gRPC-over-Noise API. Existing devices must upload a public key before they can - use the gRPC-over-Noise API, and this endpoint exists to facilitate migration to the new API. - """ - ) - @ApiResponse(responseCode = "200", description = "Public key stored successfully") - @ApiResponse(responseCode = "401", description = "Account authentication check failed") - @ApiResponse(responseCode = "422", description = "Invalid request format") - public CompletableFuture setPublicKey(@Auth final AuthenticatedDevice auth, - final SetPublicKeyRequest setPublicKeyRequest) { - - final Account account = accounts.getByAccountIdentifier(auth.accountIdentifier()) - .orElseThrow(() -> new WebApplicationException(Response.Status.UNAUTHORIZED)); - - return clientPublicKeysManager.setPublicKey(account, auth.deviceId(), setPublicKeyRequest.publicKey()); - } - private static boolean isCapabilityDowngrade(final Account account, final Set capabilities) { final Set requiredCapabilities = Arrays.stream(DeviceCapability.values()) // `ALWAYS_CAPABLE` capabilities are always assumed to be present, so we don't require callers to specify them diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java index c6ccd6425..cc21f137a 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/storage/AccountsManager.java @@ -5,8 +5,8 @@ package org.whispersystems.textsecuregcm.storage; -import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name; import static java.util.Objects.requireNonNull; +import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectWriter; @@ -134,7 +134,6 @@ public class AccountsManager extends RedisPubSubAdapter implemen private final SecureValueRecoveryClient secureValueRecovery2Client; private final DisconnectionRequestManager disconnectionRequestManager; private final RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager; - private final ClientPublicKeysManager clientPublicKeysManager; private final Executor accountLockExecutor; private final ScheduledExecutorService messagesPollExecutor; private final ScheduledExecutorService retryExecutor; @@ -218,7 +217,6 @@ public class AccountsManager extends RedisPubSubAdapter implemen final SecureValueRecoveryClient secureValueRecovery2Client, final DisconnectionRequestManager disconnectionRequestManager, final RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager, - final ClientPublicKeysManager clientPublicKeysManager, final Executor accountLockExecutor, final ScheduledExecutorService messagesPollExecutor, final ScheduledExecutorService retryExecutor, final Clock clock, @@ -236,7 +234,6 @@ public class AccountsManager extends RedisPubSubAdapter implemen this.secureValueRecovery2Client = secureValueRecovery2Client; this.disconnectionRequestManager = disconnectionRequestManager; this.registrationRecoveryPasswordsManager = requireNonNull(registrationRecoveryPasswordsManager); - this.clientPublicKeysManager = clientPublicKeysManager; this.accountLockExecutor = accountLockExecutor; this.messagesPollExecutor = messagesPollExecutor; this.retryExecutor = retryExecutor; @@ -663,8 +660,6 @@ public class AccountsManager extends RedisPubSubAdapter implemen account.getIdentifier(IdentityType.PNI), deviceId)); - additionalWriteItems.add(clientPublicKeysManager.buildTransactWriteItemForDeletion(account.getIdentifier(IdentityType.ACI), deviceId)); - return accounts.updateTransactionallyAsync(account, additionalWriteItems) .thenApply(ignored -> account); }) @@ -1238,18 +1233,15 @@ public class AccountsManager extends RedisPubSubAdapter implemen } private CompletableFuture delete(final Account account) { - final List additionalWriteItems = Stream.concat( - account.getDevices().stream() - .flatMap(device -> keysManager.buildWriteItemsForRemovedDevice( - account.getIdentifier(IdentityType.ACI), - account.getIdentifier(IdentityType.PNI), - device.getId()) - .stream()), - account.getDevices().stream() - .map(device -> clientPublicKeysManager.buildTransactWriteItemForDeletion( + final List additionalWriteItems = + account.getDevices().stream() + .flatMap(device -> keysManager.buildWriteItemsForRemovedDevice( account.getIdentifier(IdentityType.ACI), - device.getId()))) - .toList(); + account.getIdentifier(IdentityType.PNI), + device.getId()) + .stream()) + .toList(); + return CompletableFuture.allOf( secureStorageClient.deleteStoredData(account.getUuid()), secureValueRecovery2Client.removeData(account.getUuid()), diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeys.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeys.java deleted file mode 100644 index 857795792..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeys.java +++ /dev/null @@ -1,145 +0,0 @@ -package org.whispersystems.textsecuregcm.storage; - -import java.util.Map; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import org.signal.libsignal.protocol.InvalidKeyException; -import org.signal.libsignal.protocol.ecc.ECPublicKey; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.whispersystems.textsecuregcm.util.AttributeValues; -import org.whispersystems.textsecuregcm.util.Util; -import software.amazon.awssdk.services.dynamodb.DynamoDbAsyncClient; -import software.amazon.awssdk.services.dynamodb.model.AttributeValue; -import software.amazon.awssdk.services.dynamodb.model.Delete; -import software.amazon.awssdk.services.dynamodb.model.GetItemRequest; -import software.amazon.awssdk.services.dynamodb.model.Put; -import software.amazon.awssdk.services.dynamodb.model.PutItemRequest; -import software.amazon.awssdk.services.dynamodb.model.TransactWriteItem; - -/** - * Stores clients' public keys for transport-level authentication/encryption in a DynamoDB table. - */ -public class ClientPublicKeys { - - private final DynamoDbAsyncClient dynamoDbAsyncClient; - private final String tableName; - - static final String KEY_ACCOUNT_UUID = "U"; - static final String KEY_DEVICE_ID = "D"; - static final String ATTR_PUBLIC_KEY = "K"; - - private static final Logger log = LoggerFactory.getLogger(ClientPublicKeys.class); - - public ClientPublicKeys(final DynamoDbAsyncClient dynamoDbAsyncClient, final String tableName) { - this.dynamoDbAsyncClient = dynamoDbAsyncClient; - this.tableName = tableName; - } - - /** - * Stores the given public key for the given account/device, overwriting any previously-stored public key. This method - * is intended for use for adding public keys to existing accounts/devices as a migration step. Callers should use - * {@link #buildTransactWriteItemForInsertion(UUID, byte, ECPublicKey)} instead when creating new accounts/devices. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * @param publicKey the public key to store for the target account/device - - * @return a future that completes when the given key has been stored - */ - CompletableFuture setPublicKey(final UUID accountIdentifier, final byte deviceId, final ECPublicKey publicKey) { - return dynamoDbAsyncClient.putItem(PutItemRequest.builder() - .tableName(tableName) - .item(Map.of( - KEY_ACCOUNT_UUID, getPartitionKey(accountIdentifier), - KEY_DEVICE_ID, getSortKey(deviceId), - ATTR_PUBLIC_KEY, AttributeValues.fromByteArray(publicKey.serialize()))) - .build()) - .thenRun(Util.NOOP); - } - - /** - * Builds a {@link TransactWriteItem} that will store a public key for the given account/device. Intended for use when - * adding devices to accounts or creating new accounts. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * @param publicKey the public key to store for the target account/device - * - * @return a {@code TransactWriteItem} that will store the given public key for the given account/device - */ - TransactWriteItem buildTransactWriteItemForInsertion(final UUID accountIdentifier, - final byte deviceId, - final ECPublicKey publicKey) { - - return TransactWriteItem.builder() - .put(Put.builder() - .tableName(tableName) - .item(Map.of( - KEY_ACCOUNT_UUID, getPartitionKey(accountIdentifier), - KEY_DEVICE_ID, getSortKey(deviceId), - ATTR_PUBLIC_KEY, AttributeValues.fromByteArray(publicKey.serialize()))) - .build()) - .build(); - } - - /** - * Builds a {@link TransactWriteItem} that will remove the public key for the given account/device. Intended for - * use when removing devices from accounts or deleting/re-creating accounts. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * - * @return a {@code TransactWriteItem} that will remove the public key for the given account/device - */ - TransactWriteItem buildTransactWriteItemForDeletion(final UUID accountIdentifier, final byte deviceId) { - return TransactWriteItem.builder() - .delete(Delete.builder() - .tableName(tableName) - .key(getPrimaryKey(accountIdentifier, deviceId)) - .build()) - .build(); - } - - /** - * Finds the public key for the given account/device. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * - * @return a future that yields the Ed25519 public key for the given account/device, or empty if no public key was - * found - */ - CompletableFuture> findPublicKey(final UUID accountIdentifier, final byte deviceId) { - return dynamoDbAsyncClient.getItem(GetItemRequest.builder() - .tableName(tableName) - .consistentRead(true) - .key(getPrimaryKey(accountIdentifier, deviceId)) - .build()) - .thenApply(response -> Optional.of(response.item()) - .filter(item -> response.hasItem()) - .map(item -> { - try { - return new ECPublicKey(item.get(ATTR_PUBLIC_KEY).b().asByteArray()); - } catch (final InvalidKeyException e) { - log.warn("Invalid public key for {}:{}", accountIdentifier, deviceId, e); - return null; - } - })); - } - - private static Map getPrimaryKey(final UUID identifier, final byte deviceId) { - return Map.of( - KEY_ACCOUNT_UUID, getPartitionKey(identifier), - KEY_DEVICE_ID, getSortKey(deviceId)); - } - - private static AttributeValue getPartitionKey(final UUID accountUuid) { - return AttributeValues.fromUUID(accountUuid); - } - - private static AttributeValue getSortKey(final byte deviceId) { - return AttributeValues.fromInt(deviceId); - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeysManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeysManager.java deleted file mode 100644 index 478f28597..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeysManager.java +++ /dev/null @@ -1,92 +0,0 @@ -package org.whispersystems.textsecuregcm.storage; - -import java.util.List; -import java.util.Optional; -import java.util.Set; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.Executor; -import org.signal.libsignal.protocol.ecc.ECPublicKey; -import org.whispersystems.textsecuregcm.identity.IdentityType; -import software.amazon.awssdk.services.dynamodb.model.TransactWriteItem; - -/** - * A client public key manager provides access to clients' public keys for use in transport-level authentication and - * encryption. - */ -public class ClientPublicKeysManager { - - private final ClientPublicKeys clientPublicKeys; - - private final AccountLockManager accountLockManager; - private final Executor accountLockExecutor; - - public ClientPublicKeysManager(final ClientPublicKeys clientPublicKeys, - final AccountLockManager accountLockManager, - final Executor accountLockExecutor) { - - this.clientPublicKeys = clientPublicKeys; - this.accountLockManager = accountLockManager; - this.accountLockExecutor = accountLockExecutor; - } - - /** - * Stores the given public key for the given account/device, overwriting any previously-stored public key. This method - * is intended for use for adding public keys to existing accounts/devices as a migration step. Callers should use - * {@link #buildTransactWriteItemForInsertion(UUID, byte, ECPublicKey)} instead when creating new accounts/devices. - * - * @param account the target account - * @param deviceId the identifier for the target device - * @param publicKey the public key to store for the target account/device - - * @return a future that completes when the given key has been stored - */ - public CompletableFuture setPublicKey(final Account account, final byte deviceId, final ECPublicKey publicKey) { - return accountLockManager.withLockAsync(Set.of(account.getPhoneNumberIdentifier()), - () -> clientPublicKeys.setPublicKey(account.getIdentifier(IdentityType.ACI), deviceId, publicKey), - accountLockExecutor); - } - - /** - * Builds a {@link TransactWriteItem} that will store a public key for the given account/device. Intended for use when - * adding devices to accounts or creating new accounts. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * @param publicKey the public key to store for the target account/device - * - * @return a {@code TransactWriteItem} that will store the given public key for the given account/device - */ - public TransactWriteItem buildTransactWriteItemForInsertion(final UUID accountIdentifier, - final byte deviceId, - final ECPublicKey publicKey) { - - return clientPublicKeys.buildTransactWriteItemForInsertion(accountIdentifier, deviceId, publicKey); - } - - /** - * Builds a {@link TransactWriteItem} that will remove the public key for the given account/device. Intended for use - * when removing devices from accounts or deleting/re-creating accounts. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * - * @return a {@code TransactWriteItem} that will remove the public key for the given account/device - */ - public TransactWriteItem buildTransactWriteItemForDeletion(final UUID accountIdentifier, final byte deviceId) { - return clientPublicKeys.buildTransactWriteItemForDeletion(accountIdentifier, deviceId); - } - - /** - * Finds the public key for the given account/device. - * - * @param accountIdentifier the identifier for the target account - * @param deviceId the identifier for the target device - * - * @return a future that yields the Ed25519 public key for the given account/device, or empty if no public key was - * found - */ - public CompletableFuture> findPublicKey(final UUID accountIdentifier, final byte deviceId) { - return clientPublicKeys.findPublicKey(accountIdentifier, deviceId); - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CommandDependencies.java b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CommandDependencies.java index 0a45ac89d..735281ae0 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/workers/CommandDependencies.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/workers/CommandDependencies.java @@ -52,8 +52,6 @@ import org.whispersystems.textsecuregcm.securevaluerecovery.SecureValueRecoveryC import org.whispersystems.textsecuregcm.storage.AccountLockManager; import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.AccountsManager; -import org.whispersystems.textsecuregcm.storage.ClientPublicKeys; -import org.whispersystems.textsecuregcm.storage.ClientPublicKeysManager; import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager; import org.whispersystems.textsecuregcm.storage.DynamoDbRecoveryManager; import org.whispersystems.textsecuregcm.storage.IssuedReceiptsManager; @@ -210,9 +208,6 @@ public record CommandDependencies( dynamoDbAsyncClient, clock); - ClientPublicKeys clientPublicKeys = - new ClientPublicKeys(dynamoDbAsyncClient, configuration.getDynamoDbTables().getClientPublicKeys().getTableName()); - Accounts accounts = new Accounts( clock, dynamoDbClient, @@ -281,14 +276,12 @@ public record CommandDependencies( reportMessageManager, messageDeletionExecutor, Clock.systemUTC()); AccountLockManager accountLockManager = new AccountLockManager(dynamoDbClient, configuration.getDynamoDbTables().getDeletedAccountsLock().getTableName()); - ClientPublicKeysManager clientPublicKeysManager = - new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor); RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager = new RegistrationRecoveryPasswordsManager(registrationRecoveryPasswords); AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster, pubsubClient, accountLockManager, keys, messagesManager, profilesManager, secureStorageClient, secureValueRecovery2Client, disconnectionRequestManager, - registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, messagePollExecutor, + registrationRecoveryPasswordsManager, accountLockExecutor, messagePollExecutor, retryExecutor, clock, configuration.getLinkDeviceSecretConfiguration().secret().value(), dynamicConfigurationManager); RateLimiters rateLimiters = RateLimiters.create(dynamicConfigurationManager, rateLimitersCluster, retryExecutor); diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/DeviceControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/DeviceControllerTest.java index 0ac5a136b..94f1ff667 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/DeviceControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/DeviceControllerTest.java @@ -73,7 +73,6 @@ import org.whispersystems.textsecuregcm.entities.LinkDeviceResponse; import org.whispersystems.textsecuregcm.entities.RemoteAttachment; import org.whispersystems.textsecuregcm.entities.RemoteAttachmentError; import org.whispersystems.textsecuregcm.entities.RestoreAccountRequest; -import org.whispersystems.textsecuregcm.entities.SetPublicKeyRequest; import org.whispersystems.textsecuregcm.entities.TransferArchiveUploadedRequest; import org.whispersystems.textsecuregcm.identity.IdentityType; import org.whispersystems.textsecuregcm.limits.RateLimiter; @@ -82,7 +81,6 @@ import org.whispersystems.textsecuregcm.mappers.DeviceLimitExceededExceptionMapp import org.whispersystems.textsecuregcm.mappers.RateLimitExceededExceptionMapper; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.AccountsManager; -import org.whispersystems.textsecuregcm.storage.ClientPublicKeysManager; import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.DeviceCapability; import org.whispersystems.textsecuregcm.storage.DeviceSpec; @@ -101,7 +99,6 @@ import org.whispersystems.textsecuregcm.util.TestRandomUtil; class DeviceControllerTest { private static final AccountsManager accountsManager = mock(AccountsManager.class); - private static final ClientPublicKeysManager clientPublicKeysManager = mock(ClientPublicKeysManager.class); private static final PersistentTimer persistentTimer = mock(PersistentTimer.class); private static final RateLimiters rateLimiters = mock(RateLimiters.class); private static final RateLimiter rateLimiter = mock(RateLimiter.class); @@ -119,7 +116,6 @@ class DeviceControllerTest { private static final DeviceController deviceController = new DeviceController( accountsManager, - clientPublicKeysManager, rateLimiters, persistentTimer, deviceConfiguration); @@ -160,9 +156,6 @@ class DeviceControllerTest { when(accountsManager.getByE164(AuthHelper.VALID_NUMBER)).thenReturn(Optional.of(account)); when(accountsManager.getByE164(AuthHelper.VALID_NUMBER_TWO)).thenReturn(Optional.of(maxedAccount)); - when(clientPublicKeysManager.setPublicKey(any(), anyByte(), any())) - .thenReturn(CompletableFuture.completedFuture(null)); - when(persistentTimer.start(anyString(), anyString())) .thenReturn(CompletableFuture.completedFuture(mock(PersistentTimer.Sample.class))); @@ -978,22 +971,6 @@ class DeviceControllerTest { } } - @Test - void setPublicKey() { - final SetPublicKeyRequest request = new SetPublicKeyRequest(ECKeyPair.generate().getPublicKey()); - - try (final Response response = resources.getJerseyTest() - .target("/v1/devices/public_key") - .request() - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .put(Entity.entity(request, MediaType.APPLICATION_JSON_TYPE))) { - - assertEquals(204, response.getStatus()); - } - - verify(clientPublicKeysManager).setPublicKey(account, AuthHelper.VALID_DEVICE.getId(), request.publicKey()); - } - @Test void waitForLinkedDevice() { final DeviceInfo deviceInfo = new DeviceInfo(Device.PRIMARY_ID, diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCreationDeletionIntegrationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCreationDeletionIntegrationTest.java index 99eb111b8..e0b3ea1b9 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCreationDeletionIntegrationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountCreationDeletionIntegrationTest.java @@ -59,7 +59,6 @@ public class AccountCreationDeletionIntegrationTest { @RegisterExtension static final DynamoDbExtension DYNAMO_DB_EXTENSION = new DynamoDbExtension( DynamoDbExtensionSchema.Tables.ACCOUNTS, - DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS, DynamoDbExtensionSchema.Tables.DELETED_ACCOUNTS, DynamoDbExtensionSchema.Tables.DELETED_ACCOUNTS_LOCK, DynamoDbExtensionSchema.Tables.NUMBERS, @@ -83,7 +82,6 @@ public class AccountCreationDeletionIntegrationTest { private AccountsManager accountsManager; private KeysManager keysManager; - private ClientPublicKeysManager clientPublicKeysManager; private DisconnectionRequestManager disconnectionRequestManager; record DeliveryChannels(boolean fetchesMessages, String apnsToken, String fcmToken) {} @@ -108,9 +106,6 @@ public class AccountCreationDeletionIntegrationTest { new RepeatedUseKEMSignedPreKeyStore(dynamoDbAsyncClient, DynamoDbExtensionSchema.Tables.REPEATED_USE_KEM_SIGNED_PRE_KEYS.tableName())); - final ClientPublicKeys clientPublicKeys = new ClientPublicKeys(DYNAMO_DB_EXTENSION.getDynamoDbAsyncClient(), - DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS.tableName()); - final Accounts accounts = new Accounts( CLOCK, DYNAMO_DB_EXTENSION.getDynamoDbClient(), @@ -127,8 +122,6 @@ public class AccountCreationDeletionIntegrationTest { final AccountLockManager accountLockManager = new AccountLockManager(DYNAMO_DB_EXTENSION.getDynamoDbClient(), DynamoDbExtensionSchema.Tables.DELETED_ACCOUNTS_LOCK.tableName()); - clientPublicKeysManager = new ClientPublicKeysManager(clientPublicKeys, accountLockManager, executor); - final SecureStorageClient secureStorageClient = mock(SecureStorageClient.class); when(secureStorageClient.deleteStoredData(any())).thenReturn(CompletableFuture.completedFuture(null)); @@ -167,7 +160,6 @@ public class AccountCreationDeletionIntegrationTest { svr2Client, disconnectionRequestManager, registrationRecoveryPasswordsManager, - clientPublicKeysManager, executor, executor, executor, @@ -475,8 +467,6 @@ public class AccountCreationDeletionIntegrationTest { pniPqLastResortPreKey), null); - clientPublicKeysManager.setPublicKey(account, Device.PRIMARY_ID, ECKeyPair.generate().getPublicKey()).join(); - final UUID aci = account.getIdentifier(IdentityType.ACI); assertTrue(accountsManager.getByAccountIdentifier(aci).isPresent()); @@ -488,7 +478,6 @@ public class AccountCreationDeletionIntegrationTest { assertFalse(keysManager.getEcSignedPreKey(account.getPhoneNumberIdentifier(), Device.PRIMARY_ID).join().isPresent()); assertFalse(keysManager.getLastResort(account.getUuid(), Device.PRIMARY_ID).join().isPresent()); assertFalse(keysManager.getLastResort(account.getPhoneNumberIdentifier(), Device.PRIMARY_ID).join().isPresent()); - assertFalse(clientPublicKeysManager.findPublicKey(account.getUuid(), Device.PRIMARY_ID).join().isPresent()); verify(disconnectionRequestManager).requestDisconnection(account); } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerChangeNumberIntegrationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerChangeNumberIntegrationTest.java index e66b7e16c..baa932d6f 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerChangeNumberIntegrationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerChangeNumberIntegrationTest.java @@ -52,7 +52,6 @@ class AccountsManagerChangeNumberIntegrationTest { @RegisterExtension static final DynamoDbExtension DYNAMO_DB_EXTENSION = new DynamoDbExtension( Tables.ACCOUNTS, - Tables.CLIENT_PUBLIC_KEYS, Tables.DELETED_ACCOUNTS, Tables.DELETED_ACCOUNTS_LOCK, Tables.NUMBERS, @@ -98,9 +97,6 @@ class AccountsManagerChangeNumberIntegrationTest { new RepeatedUseKEMSignedPreKeyStore(dynamoDbAsyncClient, DynamoDbExtensionSchema.Tables.REPEATED_USE_KEM_SIGNED_PRE_KEYS.tableName())); - final ClientPublicKeys clientPublicKeys = new ClientPublicKeys(DYNAMO_DB_EXTENSION.getDynamoDbAsyncClient(), - DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS.tableName()); - final Accounts accounts = new Accounts( Clock.systemUTC(), DYNAMO_DB_EXTENSION.getDynamoDbClient(), @@ -117,9 +113,6 @@ class AccountsManagerChangeNumberIntegrationTest { final AccountLockManager accountLockManager = new AccountLockManager(DYNAMO_DB_EXTENSION.getDynamoDbClient(), Tables.DELETED_ACCOUNTS_LOCK.tableName()); - final ClientPublicKeysManager clientPublicKeysManager = - new ClientPublicKeysManager(clientPublicKeys, accountLockManager, executor); - final SecureStorageClient secureStorageClient = mock(SecureStorageClient.class); when(secureStorageClient.deleteStoredData(any())).thenReturn(CompletableFuture.completedFuture(null)); @@ -156,7 +149,6 @@ class AccountsManagerChangeNumberIntegrationTest { svr2Client, disconnectionRequestManager, registrationRecoveryPasswordsManager, - clientPublicKeysManager, executor, executor, executor, diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerConcurrentModificationIntegrationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerConcurrentModificationIntegrationTest.java index 2bc0e52a9..2fdcb961d 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerConcurrentModificationIntegrationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerConcurrentModificationIntegrationTest.java @@ -136,7 +136,6 @@ class AccountsManagerConcurrentModificationIntegrationTest { mock(SecureValueRecoveryClient.class), mock(DisconnectionRequestManager.class), mock(RegistrationRecoveryPasswordsManager.class), - mock(ClientPublicKeysManager.class), mock(Executor.class), mock(ScheduledExecutorService.class), mock(ScheduledExecutorService.class), diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerDeviceTransferIntegrationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerDeviceTransferIntegrationTest.java index 367a98d6c..35f0ba02b 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerDeviceTransferIntegrationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerDeviceTransferIntegrationTest.java @@ -5,19 +5,31 @@ package org.whispersystems.textsecuregcm.storage; +import static org.junit.jupiter.api.Assertions.assertArrayEquals; +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import java.nio.charset.StandardCharsets; +import java.time.Clock; +import java.time.Duration; +import java.util.Base64; +import java.util.Optional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.ScheduledExecutorService; import org.apache.commons.lang3.RandomStringUtils; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Timeout; import org.junit.jupiter.api.extension.RegisterExtension; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; import org.whispersystems.textsecuregcm.auth.DisconnectionRequestManager; +import org.whispersystems.textsecuregcm.entities.RemoteAttachment; import org.whispersystems.textsecuregcm.entities.RemoteAttachmentError; import org.whispersystems.textsecuregcm.entities.RestoreAccountRequest; -import org.whispersystems.textsecuregcm.entities.RemoteAttachment; import org.whispersystems.textsecuregcm.entities.TransferArchiveResult; import org.whispersystems.textsecuregcm.identity.IdentityType; import org.whispersystems.textsecuregcm.redis.FaultTolerantRedisClusterClient; @@ -26,23 +38,6 @@ import org.whispersystems.textsecuregcm.securestorage.SecureStorageClient; import org.whispersystems.textsecuregcm.securevaluerecovery.SecureValueRecoveryClient; import org.whispersystems.textsecuregcm.util.TestRandomUtil; -import java.nio.charset.StandardCharsets; -import java.time.Clock; -import java.time.Duration; -import java.util.Base64; -import java.util.List; -import java.util.Optional; -import java.util.UUID; -import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.ScheduledExecutorService; - -import static org.junit.jupiter.api.Assertions.assertArrayEquals; -import static org.junit.jupiter.api.Assertions.assertEquals; -import static org.junit.jupiter.api.Assertions.assertTrue; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; - // ThreadMode.SEPARATE_THREAD protects against hangs in the remote Redis calls, as this mode allows the test code to be // preempted by the timeout check @Timeout(value = 5, threadMode = Timeout.ThreadMode.SEPARATE_THREAD) @@ -74,7 +69,6 @@ public class AccountsManagerDeviceTransferIntegrationTest { mock(SecureValueRecoveryClient.class), mock(DisconnectionRequestManager.class), mock(RegistrationRecoveryPasswordsManager.class), - mock(ClientPublicKeysManager.class), mock(ExecutorService.class), mock(ScheduledExecutorService.class), mock(ScheduledExecutorService.class), diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerTest.java index d047b901f..5aea36233 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerTest.java @@ -57,7 +57,6 @@ import java.util.concurrent.Callable; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; import java.util.function.Consumer; import java.util.function.Supplier; import java.util.stream.Stream; @@ -84,8 +83,6 @@ import org.whispersystems.textsecuregcm.controllers.MismatchedDevicesException; import org.whispersystems.textsecuregcm.entities.AccountAttributes; import org.whispersystems.textsecuregcm.entities.ECSignedPreKey; import org.whispersystems.textsecuregcm.entities.KEMSignedPreKey; -import org.whispersystems.textsecuregcm.entities.RemoteAttachment; -import org.whispersystems.textsecuregcm.entities.TransferArchiveResult; import org.whispersystems.textsecuregcm.identity.AciServiceIdentifier; import org.whispersystems.textsecuregcm.identity.IdentityType; import org.whispersystems.textsecuregcm.identity.PniServiceIdentifier; @@ -126,7 +123,6 @@ class AccountsManagerTest { private MessagesManager messagesManager; private ProfilesManager profilesManager; private DisconnectionRequestManager disconnectionRequestManager; - private ClientPublicKeysManager clientPublicKeysManager; private Map phoneNumberIdentifiersByE164; @@ -161,7 +157,6 @@ class AccountsManagerTest { messagesManager = mock(MessagesManager.class); profilesManager = mock(ProfilesManager.class); disconnectionRequestManager = mock(DisconnectionRequestManager.class); - clientPublicKeysManager = mock(ClientPublicKeysManager.class); dynamicConfiguration = mock(DynamicConfiguration.class); //noinspection unchecked @@ -258,7 +253,6 @@ class AccountsManagerTest { svr2Client, disconnectionRequestManager, registrationRecoveryPasswordsManager, - clientPublicKeysManager, mock(Executor.class), mock(ScheduledExecutorService.class), mock(ScheduledExecutorService.class), @@ -791,7 +785,6 @@ class AccountsManagerTest { verify(messagesManager, times(2)).clear(account.getUuid(), linkedDevice.getId()); verify(keysManager, times(2)).deleteSingleUsePreKeys(account.getUuid(), linkedDevice.getId()); verify(keysManager).buildWriteItemsForRemovedDevice(account.getUuid(), account.getPhoneNumberIdentifier(), linkedDevice.getId()); - verify(clientPublicKeysManager).buildTransactWriteItemForDeletion(account.getUuid(), linkedDevice.getId()); verify(disconnectionRequestManager).requestDisconnection(account.getUuid(), List.of(linkedDevice.getId())); } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerUsernameIntegrationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerUsernameIntegrationTest.java index 05e313136..3a93dd3f8 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerUsernameIntegrationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AccountsManagerUsernameIntegrationTest.java @@ -160,7 +160,6 @@ class AccountsManagerUsernameIntegrationTest { mock(SecureValueRecoveryClient.class), disconnectionRequestManager, mock(RegistrationRecoveryPasswordsManager.class), - mock(ClientPublicKeysManager.class), Executors.newSingleThreadExecutor(), Executors.newSingleThreadScheduledExecutor(), Executors.newSingleThreadScheduledExecutor(), diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AddRemoveDeviceIntegrationTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AddRemoveDeviceIntegrationTest.java index e5db47fff..a40c4ffa5 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/AddRemoveDeviceIntegrationTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/AddRemoveDeviceIntegrationTest.java @@ -53,7 +53,6 @@ public class AddRemoveDeviceIntegrationTest { @RegisterExtension static final DynamoDbExtension DYNAMO_DB_EXTENSION = new DynamoDbExtension( DynamoDbExtensionSchema.Tables.ACCOUNTS, - DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS, DynamoDbExtensionSchema.Tables.DELETED_ACCOUNTS, DynamoDbExtensionSchema.Tables.DELETED_ACCOUNTS_LOCK, DynamoDbExtensionSchema.Tables.USED_LINK_DEVICE_TOKENS, @@ -79,7 +78,6 @@ public class AddRemoveDeviceIntegrationTest { private ScheduledExecutorService scheduledExecutorService; private KeysManager keysManager; - private ClientPublicKeysManager clientPublicKeysManager; private MessagesManager messagesManager; private AccountsManager accountsManager; private TestClock clock; @@ -106,9 +104,6 @@ public class AddRemoveDeviceIntegrationTest { new RepeatedUseKEMSignedPreKeyStore(dynamoDbAsyncClient, DynamoDbExtensionSchema.Tables.REPEATED_USE_KEM_SIGNED_PRE_KEYS.tableName())); - final ClientPublicKeys clientPublicKeys = new ClientPublicKeys(DYNAMO_DB_EXTENSION.getDynamoDbAsyncClient(), - DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS.tableName()); - final Accounts accounts = new Accounts( clock, DYNAMO_DB_EXTENSION.getDynamoDbClient(), @@ -126,8 +121,6 @@ public class AddRemoveDeviceIntegrationTest { final AccountLockManager accountLockManager = new AccountLockManager(DYNAMO_DB_EXTENSION.getDynamoDbClient(), DynamoDbExtensionSchema.Tables.DELETED_ACCOUNTS_LOCK.tableName()); - clientPublicKeysManager = new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor); - final SecureStorageClient secureStorageClient = mock(SecureStorageClient.class); when(secureStorageClient.deleteStoredData(any())).thenReturn(CompletableFuture.completedFuture(null)); @@ -168,7 +161,6 @@ public class AddRemoveDeviceIntegrationTest { svr2Client, mock(DisconnectionRequestManager.class), mock(RegistrationRecoveryPasswordsManager.class), - clientPublicKeysManager, accountLockExecutor, scheduledExecutorService, scheduledExecutorService, @@ -331,9 +323,6 @@ public class AddRemoveDeviceIntegrationTest { final byte addedDeviceId = updatedAccountAndDevice.second().getId(); - clientPublicKeysManager.setPublicKey(account, Device.PRIMARY_ID, ECKeyPair.generate().getPublicKey()).join(); - clientPublicKeysManager.setPublicKey(account, addedDeviceId, ECKeyPair.generate().getPublicKey()).join(); - final Account updatedAccount = accountsManager.removeDevice(updatedAccountAndDevice.first(), addedDeviceId).join(); assertEquals(1, updatedAccount.getDevices().size()); @@ -343,7 +332,6 @@ public class AddRemoveDeviceIntegrationTest { keysManager.getEcSignedPreKey(updatedAccount.getPhoneNumberIdentifier(), addedDeviceId).join().isPresent()); assertFalse(keysManager.getLastResort(updatedAccount.getUuid(), addedDeviceId).join().isPresent()); assertFalse(keysManager.getLastResort(updatedAccount.getPhoneNumberIdentifier(), addedDeviceId).join().isPresent()); - assertFalse(clientPublicKeysManager.findPublicKey(updatedAccount.getUuid(), addedDeviceId).join().isPresent()); assertTrue(keysManager.getEcSignedPreKey(updatedAccount.getUuid(), Device.PRIMARY_ID).join().isPresent()); assertTrue( @@ -351,7 +339,6 @@ public class AddRemoveDeviceIntegrationTest { assertTrue(keysManager.getLastResort(updatedAccount.getUuid(), Device.PRIMARY_ID).join().isPresent()); assertTrue( keysManager.getLastResort(updatedAccount.getPhoneNumberIdentifier(), Device.PRIMARY_ID).join().isPresent()); - assertTrue(clientPublicKeysManager.findPublicKey(updatedAccount.getUuid(), Device.PRIMARY_ID).join().isPresent()); } @Test @@ -396,11 +383,6 @@ public class AddRemoveDeviceIntegrationTest { final Account retrievedAccount = accountsManager.getByAccountIdentifierAsync(aci).join().orElseThrow(); - clientPublicKeysManager.setPublicKey(retrievedAccount, Device.PRIMARY_ID, ECKeyPair.generate().getPublicKey()) - .join(); - clientPublicKeysManager.setPublicKey(retrievedAccount, addedDeviceId, ECKeyPair.generate().getPublicKey()) - .join(); - assertEquals(2, retrievedAccount.getDevices().size()); assertTrue(keysManager.getEcSignedPreKey(retrievedAccount.getUuid(), addedDeviceId).join().isPresent()); @@ -409,7 +391,6 @@ public class AddRemoveDeviceIntegrationTest { assertTrue(keysManager.getLastResort(retrievedAccount.getUuid(), addedDeviceId).join().isPresent()); assertTrue( keysManager.getLastResort(retrievedAccount.getPhoneNumberIdentifier(), addedDeviceId).join().isPresent()); - assertTrue(clientPublicKeysManager.findPublicKey(retrievedAccount.getUuid(), addedDeviceId).join().isPresent()); assertTrue(keysManager.getEcSignedPreKey(retrievedAccount.getUuid(), Device.PRIMARY_ID).join().isPresent()); assertTrue(keysManager.getEcSignedPreKey(retrievedAccount.getPhoneNumberIdentifier(), Device.PRIMARY_ID).join() @@ -417,7 +398,6 @@ public class AddRemoveDeviceIntegrationTest { assertTrue(keysManager.getLastResort(retrievedAccount.getUuid(), Device.PRIMARY_ID).join().isPresent()); assertTrue( keysManager.getLastResort(retrievedAccount.getPhoneNumberIdentifier(), Device.PRIMARY_ID).join().isPresent()); - assertTrue(clientPublicKeysManager.findPublicKey(retrievedAccount.getUuid(), Device.PRIMARY_ID).join().isPresent()); } @Test diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeysTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeysTest.java deleted file mode 100644 index c0e93273e..000000000 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/ClientPublicKeysTest.java +++ /dev/null @@ -1,61 +0,0 @@ -package org.whispersystems.textsecuregcm.storage; - -import static org.junit.jupiter.api.Assertions.assertEquals; - -import java.util.Optional; -import java.util.UUID; -import org.junit.jupiter.api.BeforeEach; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.RegisterExtension; -import org.signal.libsignal.protocol.ecc.ECKeyPair; -import org.signal.libsignal.protocol.ecc.ECPublicKey; -import software.amazon.awssdk.services.dynamodb.model.TransactWriteItemsRequest; - -class ClientPublicKeysTest { - - private ClientPublicKeys clientPublicKeys; - - @RegisterExtension - static final DynamoDbExtension DYNAMO_DB_EXTENSION = - new DynamoDbExtension(DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS); - - @BeforeEach - void setUp() { - clientPublicKeys = new ClientPublicKeys(DYNAMO_DB_EXTENSION.getDynamoDbAsyncClient(), - DynamoDbExtensionSchema.Tables.CLIENT_PUBLIC_KEYS.tableName()); - } - - @Test - void buildTransactWriteItemForInsertionAndDeletion() { - final UUID accountIdentifier = UUID.randomUUID(); - final byte deviceId = Device.PRIMARY_ID; - final ECPublicKey publicKey = ECKeyPair.generate().getPublicKey(); - - assertEquals(Optional.empty(), clientPublicKeys.findPublicKey(accountIdentifier, deviceId).join()); - - DYNAMO_DB_EXTENSION.getDynamoDbClient().transactWriteItems(TransactWriteItemsRequest.builder() - .transactItems(clientPublicKeys.buildTransactWriteItemForInsertion(accountIdentifier, deviceId, publicKey)) - .build()); - - assertEquals(Optional.of(publicKey), clientPublicKeys.findPublicKey(accountIdentifier, deviceId).join()); - - DYNAMO_DB_EXTENSION.getDynamoDbClient().transactWriteItems(TransactWriteItemsRequest.builder() - .transactItems(clientPublicKeys.buildTransactWriteItemForDeletion(accountIdentifier, deviceId)) - .build()); - - assertEquals(Optional.empty(), clientPublicKeys.findPublicKey(accountIdentifier, deviceId).join()); - } - - @Test - void setPublicKey() { - final UUID accountIdentifier = UUID.randomUUID(); - final byte deviceId = Device.PRIMARY_ID; - final ECPublicKey publicKey = ECKeyPair.generate().getPublicKey(); - - assertEquals(Optional.empty(), clientPublicKeys.findPublicKey(accountIdentifier, deviceId).join()); - - clientPublicKeys.setPublicKey(accountIdentifier, deviceId, publicKey).join(); - - assertEquals(Optional.of(publicKey), clientPublicKeys.findPublicKey(accountIdentifier, deviceId).join()); - } -} diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamoDbExtensionSchema.java b/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamoDbExtensionSchema.java index ccf2132f1..ac171007a 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamoDbExtensionSchema.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/storage/DynamoDbExtensionSchema.java @@ -346,21 +346,6 @@ public final class DynamoDbExtensionSchema { .build()), List.of()), - CLIENT_PUBLIC_KEYS("client_public_keys_test", - ClientPublicKeys.KEY_ACCOUNT_UUID, - ClientPublicKeys.KEY_DEVICE_ID, - List.of( - AttributeDefinition.builder() - .attributeName(ClientPublicKeys.KEY_ACCOUNT_UUID) - .attributeType(ScalarAttributeType.B) - .build(), - AttributeDefinition.builder() - .attributeName(ClientPublicKeys.KEY_DEVICE_ID) - .attributeType(ScalarAttributeType.N) - .build()), - List.of(), - List.of()), - USED_LINK_DEVICE_TOKENS("used_link_device_tokens_test", Accounts.KEY_LINK_DEVICE_TOKEN_HASH, null,