diff --git a/service/config/sample-secrets-bundle.yml b/service/config/sample-secrets-bundle.yml index 9c56b6857..a5fe057cc 100644 --- a/service/config/sample-secrets-bundle.yml +++ b/service/config/sample-secrets-bundle.yml @@ -89,9 +89,6 @@ paymentsService.userAuthenticationTokenSharedSecret: AAAAAAAAAAAAAAAAAAAAAAAAAAA paymentsService.fixerApiKey: unset paymentsService.coinMarketCapApiKey: unset -artService.userAuthenticationTokenSharedSecret: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= # base64-encoded 32-byte secret not shared with any external service, but used in ArtController -artService.userAuthenticationTokenUserIdSecret: AAAAAAAAAAA= # base64-encoded secret to obscure user phone numbers from Sticker Creator - currentReportingKey.secret: AAAAAAAAAAA= currentReportingKey.salt: AAAAAAAAAAA= diff --git a/service/config/sample.yml b/service/config/sample.yml index 1e4575d9b..5a3f1e762 100644 --- a/service/config/sample.yml +++ b/service/config/sample.yml @@ -331,10 +331,6 @@ paymentsService: coinMarketCapCurrencyIds: MOB: 7878 -artService: - userAuthenticationTokenSharedSecret: secret://artService.userAuthenticationTokenSharedSecret - userAuthenticationTokenUserIdSecret: secret://artService.userAuthenticationTokenUserIdSecret - badges: badges: - id: TEST diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java index fb99adb77..a0ccee336 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerConfiguration.java @@ -17,7 +17,6 @@ import org.whispersystems.textsecuregcm.configuration.ApnConfiguration; import org.whispersystems.textsecuregcm.configuration.AppleAppStoreConfiguration; import org.whispersystems.textsecuregcm.configuration.AppleDeviceCheckConfiguration; -import org.whispersystems.textsecuregcm.configuration.ArtServiceConfiguration; import org.whispersystems.textsecuregcm.configuration.AwsCredentialsProviderFactory; import org.whispersystems.textsecuregcm.configuration.BadgesConfiguration; import org.whispersystems.textsecuregcm.configuration.BraintreeConfiguration; @@ -217,11 +216,6 @@ public class WhisperServerConfiguration extends Configuration { @JsonProperty private PaymentsServiceConfiguration paymentsService; - @Valid - @NotNull - @JsonProperty - private ArtServiceConfiguration artService; - @Valid @NotNull @JsonProperty @@ -469,10 +463,6 @@ public PaymentsServiceConfiguration getPaymentsServiceConfiguration() { return paymentsService; } - public ArtServiceConfiguration getArtServiceConfiguration() { - return artService; - } - public ZkConfig getZkConfig() { return zkConfig; } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java index bb8fe712b..911a10c7d 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/WhisperServerService.java @@ -108,7 +108,6 @@ import org.whispersystems.textsecuregcm.controllers.AccountController; import org.whispersystems.textsecuregcm.controllers.AccountControllerV2; import org.whispersystems.textsecuregcm.controllers.ArchiveController; -import org.whispersystems.textsecuregcm.controllers.ArtController; import org.whispersystems.textsecuregcm.controllers.AttachmentControllerV4; import org.whispersystems.textsecuregcm.controllers.CallLinkController; import org.whispersystems.textsecuregcm.controllers.CallRoutingController; @@ -214,9 +213,6 @@ import org.whispersystems.textsecuregcm.storage.AccountPrincipalSupplier; import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.AccountsManager; -import org.whispersystems.textsecuregcm.storage.devicecheck.AppleDeviceCheckManager; -import org.whispersystems.textsecuregcm.storage.devicecheck.AppleDeviceCheckTrustAnchor; -import org.whispersystems.textsecuregcm.storage.devicecheck.AppleDeviceChecks; import org.whispersystems.textsecuregcm.storage.ChangeNumberManager; import org.whispersystems.textsecuregcm.storage.ClientPublicKeys; import org.whispersystems.textsecuregcm.storage.ClientPublicKeysManager; @@ -244,6 +240,9 @@ import org.whispersystems.textsecuregcm.storage.Subscriptions; import org.whispersystems.textsecuregcm.storage.VerificationSessionManager; import org.whispersystems.textsecuregcm.storage.VerificationSessions; +import org.whispersystems.textsecuregcm.storage.devicecheck.AppleDeviceCheckManager; +import org.whispersystems.textsecuregcm.storage.devicecheck.AppleDeviceCheckTrustAnchor; +import org.whispersystems.textsecuregcm.storage.devicecheck.AppleDeviceChecks; import org.whispersystems.textsecuregcm.subscriptions.AppleAppStoreManager; import org.whispersystems.textsecuregcm.subscriptions.BankMandateTranslator; import org.whispersystems.textsecuregcm.subscriptions.BraintreeManager; @@ -582,8 +581,6 @@ public void run(WhisperServerConfiguration config, Environment environment) thro config.getSecureStorageServiceConfiguration()); ExternalServiceCredentialsGenerator paymentsCredentialsGenerator = PaymentsController.credentialsGenerator( config.getPaymentsServiceConfiguration()); - ExternalServiceCredentialsGenerator artCredentialsGenerator = ArtController.credentialsGenerator( - config.getArtServiceConfiguration()); ExternalServiceCredentialsGenerator svr2CredentialsGenerator = SecureValueRecovery2Controller.credentialsGenerator( config.getSvr2Configuration()); @@ -1101,7 +1098,6 @@ protected void configureServer(final ServerBuilder serverBuilder) { usernameHashZkProofVerifier), new AccountControllerV2(accountsManager, changeNumberManager, phoneVerificationTokenManager, registrationLockVerificationManager, rateLimiters), - new ArtController(rateLimiters, artCredentialsGenerator), new AttachmentControllerV4(rateLimiters, gcsAttachmentGenerator, tusAttachmentGenerator, experimentEnrollmentManager), new ArchiveController(backupAuthManager, backupManager), diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java b/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java deleted file mode 100644 index 9e1a450bf..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/configuration/ArtServiceConfiguration.java +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright 2022 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.configuration; - -import static org.apache.commons.lang3.ObjectUtils.firstNonNull; - -import jakarta.validation.constraints.NotNull; -import java.time.Duration; -import org.whispersystems.textsecuregcm.configuration.secrets.SecretBytes; -import org.whispersystems.textsecuregcm.util.ExactlySize; - -public record ArtServiceConfiguration(@ExactlySize(32) SecretBytes userAuthenticationTokenSharedSecret, - @NotNull SecretBytes userAuthenticationTokenUserIdSecret, - @NotNull Duration tokenExpiration) { - public ArtServiceConfiguration { - tokenExpiration = firstNonNull(tokenExpiration, Duration.ofDays(1)); - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java deleted file mode 100644 index e41f344eb..000000000 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArtController.java +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2013 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.controllers; - -import io.dropwizard.auth.Auth; -import io.swagger.v3.oas.annotations.tags.Tag; -import jakarta.ws.rs.GET; -import jakarta.ws.rs.Path; -import jakarta.ws.rs.Produces; -import jakarta.ws.rs.core.MediaType; -import java.util.UUID; -import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice; -import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; -import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; -import org.whispersystems.textsecuregcm.configuration.ArtServiceConfiguration; -import org.whispersystems.textsecuregcm.limits.RateLimiters; -import org.whispersystems.websocket.auth.ReadOnly; - -@Path("/v1/art") -@Tag(name = "Art") -public class ArtController { - private final ExternalServiceCredentialsGenerator artServiceCredentialsGenerator; - private final RateLimiters rateLimiters; - - public static ExternalServiceCredentialsGenerator credentialsGenerator(final ArtServiceConfiguration cfg) { - return ExternalServiceCredentialsGenerator - .builder(cfg.userAuthenticationTokenSharedSecret()) - .withUserDerivationKey(cfg.userAuthenticationTokenUserIdSecret()) - .prependUsername(false) - .truncateSignature(false) - .build(); - } - - public ArtController(final RateLimiters rateLimiters, - final ExternalServiceCredentialsGenerator artServiceCredentialsGenerator) { - this.artServiceCredentialsGenerator = artServiceCredentialsGenerator; - this.rateLimiters = rateLimiters; - } - - @GET - @Path("/auth") - @Produces(MediaType.APPLICATION_JSON) - public ExternalServiceCredentials getAuth(final @ReadOnly @Auth AuthenticatedDevice auth) - throws RateLimitExceededException { - final UUID uuid = auth.getAccount().getUuid(); - rateLimiters.forDescriptor(RateLimiters.For.EXTERNAL_SERVICE_CREDENTIALS).validate(uuid); - return artServiceCredentialsGenerator.generateForUuid(uuid); - } -} diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceDefinitions.java b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceDefinitions.java index dcf285a3a..60645a502 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceDefinitions.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceDefinitions.java @@ -16,21 +16,11 @@ import org.signal.chat.credentials.ExternalServiceType; import org.whispersystems.textsecuregcm.WhisperServerConfiguration; import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; -import org.whispersystems.textsecuregcm.configuration.ArtServiceConfiguration; import org.whispersystems.textsecuregcm.configuration.DirectoryV2ClientConfiguration; import org.whispersystems.textsecuregcm.configuration.PaymentsServiceConfiguration; import org.whispersystems.textsecuregcm.configuration.SecureValueRecovery2Configuration; enum ExternalServiceDefinitions { - ART(ExternalServiceType.EXTERNAL_SERVICE_TYPE_ART, (chatConfig, clock) -> { - final ArtServiceConfiguration cfg = chatConfig.getArtServiceConfiguration(); - return ExternalServiceCredentialsGenerator - .builder(cfg.userAuthenticationTokenSharedSecret()) - .withUserDerivationKey(cfg.userAuthenticationTokenUserIdSecret()) - .prependUsername(false) - .truncateSignature(false) - .build(); - }), DIRECTORY(ExternalServiceType.EXTERNAL_SERVICE_TYPE_DIRECTORY, (chatConfig, clock) -> { final DirectoryV2ClientConfiguration cfg = chatConfig.getDirectoryV2Configuration().getDirectoryV2ClientConfiguration(); return ExternalServiceCredentialsGenerator diff --git a/service/src/main/proto/org/signal/chat/credentials.proto b/service/src/main/proto/org/signal/chat/credentials.proto index 136d5463e..d35086026 100644 --- a/service/src/main/proto/org/signal/chat/credentials.proto +++ b/service/src/main/proto/org/signal/chat/credentials.proto @@ -49,11 +49,10 @@ service ExternalServiceCredentialsAnonymous { enum ExternalServiceType { EXTERNAL_SERVICE_TYPE_UNSPECIFIED = 0; - EXTERNAL_SERVICE_TYPE_ART = 1; - EXTERNAL_SERVICE_TYPE_DIRECTORY = 2; - EXTERNAL_SERVICE_TYPE_PAYMENTS = 3; - EXTERNAL_SERVICE_TYPE_STORAGE = 4; - EXTERNAL_SERVICE_TYPE_SVR = 5; + EXTERNAL_SERVICE_TYPE_DIRECTORY = 1; + EXTERNAL_SERVICE_TYPE_PAYMENTS = 2; + EXTERNAL_SERVICE_TYPE_STORAGE = 3; + EXTERNAL_SERVICE_TYPE_SVR = 4; } message GetExternalServiceCredentialsRequest { diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArtControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArtControllerTest.java deleted file mode 100644 index d5441930f..000000000 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArtControllerTest.java +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright 2013 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.textsecuregcm.controllers; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Mockito.mock; -import static org.whispersystems.textsecuregcm.util.MockUtils.randomSecretBytes; - -import io.dropwizard.auth.AuthValueFactoryProvider; -import io.dropwizard.testing.junit5.DropwizardExtensionsSupport; -import io.dropwizard.testing.junit5.ResourceExtension; -import java.time.Duration; -import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; -import org.junit.jupiter.api.Test; -import org.junit.jupiter.api.extension.ExtendWith; -import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice; -import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials; -import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator; -import org.whispersystems.textsecuregcm.configuration.ArtServiceConfiguration; -import org.whispersystems.textsecuregcm.limits.RateLimiters; -import org.whispersystems.textsecuregcm.tests.util.AuthHelper; -import org.whispersystems.textsecuregcm.util.MockUtils; -import org.whispersystems.textsecuregcm.util.SystemMapper; - -@ExtendWith(DropwizardExtensionsSupport.class) -class ArtControllerTest { - private static final ArtServiceConfiguration ART_SERVICE_CONFIGURATION = new ArtServiceConfiguration( - randomSecretBytes(32), randomSecretBytes(32), Duration.ofDays(1)); - private static final ExternalServiceCredentialsGenerator artCredentialsGenerator = ArtController.credentialsGenerator(ART_SERVICE_CONFIGURATION); - private static final RateLimiters rateLimiters = mock(RateLimiters.class); - - private static final ResourceExtension resources = ResourceExtension.builder() - .addProvider(AuthHelper.getAuthFilter()) - .addProvider(new AuthValueFactoryProvider.Binder<>(AuthenticatedDevice.class)) - .setMapper(SystemMapper.jsonMapper()) - .setTestContainerFactory(new GrizzlyWebTestContainerFactory()) - .addResource(new ArtController(rateLimiters, artCredentialsGenerator)) - .build(); - - @Test - void testGetAuthToken() { - MockUtils.updateRateLimiterResponseToAllow(rateLimiters, RateLimiters.For.EXTERNAL_SERVICE_CREDENTIALS, AuthHelper.VALID_UUID); - final ExternalServiceCredentials token = - resources.getJerseyTest() - .target("/v1/art/auth") - .request() - .header("Authorization", AuthHelper.getAuthHeader(AuthHelper.VALID_UUID, AuthHelper.VALID_PASSWORD)) - .get(ExternalServiceCredentials.class); - - assertThat(token.password()).isNotEmpty(); - assertThat(token.username()).isNotEmpty(); - } -} diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceCredentialsGrpcServiceTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceCredentialsGrpcServiceTest.java index e4fa24732..e2498cb3e 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceCredentialsGrpcServiceTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/grpc/ExternalServiceCredentialsGrpcServiceTest.java @@ -43,7 +43,7 @@ public class ExternalServiceCredentialsGrpcServiceTest extends SimpleBaseGrpcTest { - private static final ExternalServiceCredentialsGenerator ART_CREDENTIALS_GENERATOR = Mockito.spy(ExternalServiceCredentialsGenerator + private static final ExternalServiceCredentialsGenerator DIRECTORY_CREDENTIALS_GENERATOR = Mockito.spy(ExternalServiceCredentialsGenerator .builder(TestRandomUtil.nextBytes(32)) .withUserDerivationKey(TestRandomUtil.nextBytes(32)) .prependUsername(false) @@ -62,14 +62,14 @@ public class ExternalServiceCredentialsGrpcServiceTest @Override protected ExternalServiceCredentialsGrpcService createServiceBeforeEachTest() { return new ExternalServiceCredentialsGrpcService(Map.of( - ExternalServiceType.EXTERNAL_SERVICE_TYPE_ART, ART_CREDENTIALS_GENERATOR, + ExternalServiceType.EXTERNAL_SERVICE_TYPE_DIRECTORY, DIRECTORY_CREDENTIALS_GENERATOR, ExternalServiceType.EXTERNAL_SERVICE_TYPE_PAYMENTS, PAYMENTS_CREDENTIALS_GENERATOR ), rateLimiters); } static Stream testSuccess() { return Stream.of( - Arguments.of(ExternalServiceType.EXTERNAL_SERVICE_TYPE_ART, ART_CREDENTIALS_GENERATOR), + Arguments.of(ExternalServiceType.EXTERNAL_SERVICE_TYPE_DIRECTORY, DIRECTORY_CREDENTIALS_GENERATOR), Arguments.of(ExternalServiceType.EXTERNAL_SERVICE_TYPE_PAYMENTS, PAYMENTS_CREDENTIALS_GENERATOR) ); } @@ -111,14 +111,14 @@ public void testInvalidRequest() throws Exception { public void testRateLimitExceeded() throws Exception { final Duration retryAfter = MockUtils.updateRateLimiterResponseToFail( rateLimiters, RateLimiters.For.EXTERNAL_SERVICE_CREDENTIALS, AUTHENTICATED_ACI, Duration.ofSeconds(100)); - Mockito.reset(ART_CREDENTIALS_GENERATOR); + Mockito.reset(DIRECTORY_CREDENTIALS_GENERATOR); assertRateLimitExceeded( retryAfter, () -> authenticatedServiceStub().getExternalServiceCredentials( GetExternalServiceCredentialsRequest.newBuilder() - .setExternalService(ExternalServiceType.EXTERNAL_SERVICE_TYPE_ART) + .setExternalService(ExternalServiceType.EXTERNAL_SERVICE_TYPE_DIRECTORY) .build()), - ART_CREDENTIALS_GENERATOR + DIRECTORY_CREDENTIALS_GENERATOR ); } @@ -126,7 +126,7 @@ public void testRateLimitExceeded() throws Exception { public void testUnauthenticatedCall() throws Exception { assertStatusUnauthenticated(() -> unauthenticatedServiceStub().getExternalServiceCredentials( GetExternalServiceCredentialsRequest.newBuilder() - .setExternalService(ExternalServiceType.EXTERNAL_SERVICE_TYPE_ART) + .setExternalService(ExternalServiceType.EXTERNAL_SERVICE_TYPE_DIRECTORY) .build())); } diff --git a/service/src/test/resources/config/test-secrets-bundle.yml b/service/src/test/resources/config/test-secrets-bundle.yml index 7d2932157..545cbf7c7 100644 --- a/service/src/test/resources/config/test-secrets-bundle.yml +++ b/service/src/test/resources/config/test-secrets-bundle.yml @@ -159,9 +159,6 @@ paymentsService.userAuthenticationTokenSharedSecret: AAAAAAAAAAAAAAAAAAAAAAAAAAA paymentsService.fixerApiKey: unset paymentsService.coinMarketCapApiKey: unset -artService.userAuthenticationTokenSharedSecret: AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA= # base64-encoded 32-byte secret not shared with any external service, but used in ArtController -artService.userAuthenticationTokenUserIdSecret: AAAAAAAAAAA= # base64-encoded secret to obscure user phone numbers from Sticker Creator - currentReportingKey.secret: AAAAAAAAAAA= currentReportingKey.salt: AAAAAAAAAAA= diff --git a/service/src/test/resources/config/test.yml b/service/src/test/resources/config/test.yml index 58f56f527..9590ff89e 100644 --- a/service/src/test/resources/config/test.yml +++ b/service/src/test/resources/config/test.yml @@ -326,10 +326,6 @@ paymentsService: externalClients: type: stub -artService: - userAuthenticationTokenSharedSecret: secret://artService.userAuthenticationTokenSharedSecret - userAuthenticationTokenUserIdSecret: secret://artService.userAuthenticationTokenUserIdSecret - badges: badges: - id: TEST