diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/backup/BackupManager.java b/service/src/main/java/org/whispersystems/textsecuregcm/backup/BackupManager.java index 05fcdc761..dbc5b4ac9 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/backup/BackupManager.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/backup/BackupManager.java @@ -317,10 +317,14 @@ public class BackupManager { * Generate credentials that can be used to read from the backup CDN * * @param backupUser an already ZK authenticated backup user + * @param cdnNumber the cdn number to get backup credentials for * @return A map of headers to include with CDN requests */ - public Map generateReadAuth(final AuthenticatedBackupUser backupUser) { + public Map generateReadAuth(final AuthenticatedBackupUser backupUser, final int cdnNumber) { checkBackupTier(backupUser, BackupTier.MESSAGES); + if (cdnNumber != 3) { + throw Status.INVALID_ARGUMENT.withDescription("unknown cdn").asRuntimeException(); + } return cdn3BackupCredentialGenerator.readHeaders(backupUser.backupDir()); } diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArchiveController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArchiveController.java index 49186070a..fb7959f6f 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArchiveController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/ArchiveController.java @@ -280,12 +280,14 @@ public class ArchiveController { @Parameter(description = BackupAuthCredentialPresentationSignature.DESCRIPTION, schema = @Schema(implementation = String.class)) @NotNull - @HeaderParam(X_SIGNAL_ZK_AUTH_SIGNATURE) final BackupAuthCredentialPresentationSignature signature) { + @HeaderParam(X_SIGNAL_ZK_AUTH_SIGNATURE) final BackupAuthCredentialPresentationSignature signature, + + @NotNull @Parameter(description = "The number of the CDN to get credentials for") @QueryParam("cdn") final Integer cdn) { if (account.isPresent()) { throw new BadRequestException("must not use authenticated connection for anonymous operations"); } return backupManager.authenticateBackupUser(presentation.presentation, signature.signature) - .thenApply(backupManager::generateReadAuth) + .thenApply(user -> backupManager.generateReadAuth(user, cdn)) .thenApply(ReadAuthResponse::new); } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArchiveControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArchiveControllerTest.java index 977497c30..0c249c9a1 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArchiveControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/ArchiveControllerTest.java @@ -564,6 +564,44 @@ public class ArchiveControllerTest { assertThat(response.getStatus()).isEqualTo(429); } + @Test + public void readAuth() throws VerificationFailedException { + final BackupAuthCredentialPresentation presentation = + backupAuthTestUtil.getPresentation(BackupTier.MEDIA, backupKey, aci); + when(backupManager.authenticateBackupUser(any(), any())) + .thenReturn(CompletableFuture.completedFuture(backupUser(presentation.getBackupId(), BackupTier.MEDIA))); + when(backupManager.generateReadAuth(any(), eq(3))).thenReturn(Map.of("key", "value")); + final ArchiveController.ReadAuthResponse response = resources.getJerseyTest() + .target("v1/archives/auth/read") + .queryParam("cdn", 3) + .request() + .header("X-Signal-ZK-Auth", Base64.getEncoder().encodeToString(presentation.serialize())) + .header("X-Signal-ZK-Auth-Signature", "aaa") + .get(ArchiveController.ReadAuthResponse.class); + assertThat(response.headers()).containsExactlyEntriesOf(Map.of("key", "value")); + } + + @Test + public void readAuthInvalidParam() throws VerificationFailedException { + final BackupAuthCredentialPresentation presentation = + backupAuthTestUtil.getPresentation(BackupTier.MEDIA, backupKey, aci); + Response response = resources.getJerseyTest() + .target("v1/archives/auth/read") + .request() + .header("X-Signal-ZK-Auth", Base64.getEncoder().encodeToString(presentation.serialize())) + .header("X-Signal-ZK-Auth-Signature", "aaa") + .get(); + assertThat(response.getStatus()).isEqualTo(400); + + response = resources.getJerseyTest() + .target("v1/archives/auth/read") + .queryParam("abc") + .request() + .header("X-Signal-ZK-Auth", Base64.getEncoder().encodeToString(presentation.serialize())) + .header("X-Signal-ZK-Auth-Signature", "aaa") + .get(); + assertThat(response.getStatus()).isEqualTo(400); + } private static AuthenticatedBackupUser backupUser(byte[] backupId, BackupTier backupTier) { return new AuthenticatedBackupUser(backupId, backupTier, "myBackupDir", "myMediaDir");