Treat missing backup after authentication as an authentication failure

This commit is contained in:
Ravi Khadiwala
2026-02-13 13:37:03 -06:00
committed by ravi-signal
parent 225e756e38
commit d6a0129c5a
6 changed files with 10 additions and 11 deletions

View File

@@ -230,13 +230,12 @@ public class BackupManager {
* @param backupUser an already ZK authenticated backup user
* @return Information about the existing backup
* @throws BackupPermissionException if the credential does not have the correct level
* @throws BackupNotFoundException if the provided backupuser does not exist
* @throws BackupFailedZkAuthenticationException if the provided backupuser does not exist
*/
public BackupInfo backupInfo(final AuthenticatedBackupUser backupUser)
throws BackupNotFoundException, BackupPermissionException {
public BackupInfo backupInfo(final AuthenticatedBackupUser backupUser) throws BackupPermissionException, BackupFailedZkAuthenticationException {
checkBackupLevel(backupUser, BackupLevel.FREE);
final BackupsDb.BackupDescription backupDescription = ExceptionUtils.unwrapSupply(
BackupNotFoundException.class,
BackupFailedZkAuthenticationException.class,
() -> backupsDb.describeBackup(backupUser).join());
return new BackupInfo(
backupDescription.cdn(),

View File

@@ -331,7 +331,9 @@ public class BackupsDb {
.build())
.thenApply(response -> {
if (!response.hasItem()) {
throw ExceptionUtils.wrap(new BackupNotFoundException("Backup ID not found"));
// At this point, the user has already authenticated against this backup record, so we must have raced
// with a deletion. Just throw the same error we would have thrown if authentication had failed
throw ExceptionUtils.wrap(new BackupFailedZkAuthenticationException("Backup ID not found"));
}
// If the client hasn't already uploaded a backup, return the cdn we would return if they did create one
final int cdn = AttributeValues.getInt(response.item(), ATTR_CDN, BACKUP_CDN);

View File

@@ -486,7 +486,6 @@ public class ArchiveController {
summary = "Fetch backup info",
description = "Retrieve information about the currently stored backup")
@ApiResponse(responseCode = "200", content = @Content(schema = @Schema(implementation = BackupInfoResponse.class)))
@ApiResponse(responseCode = "404", description = "No existing backups found")
@ApiResponse(responseCode = "429", description = "Rate limited.")
@ApiResponseZkAuth
@ManagedAsync
@@ -501,7 +500,7 @@ public class ArchiveController {
@Parameter(description = BackupAuthCredentialPresentationSignature.DESCRIPTION, schema = @Schema(implementation = String.class))
@NotNull
@HeaderParam(X_SIGNAL_ZK_AUTH_SIGNATURE) final BackupAuthCredentialPresentationSignature signature)
throws BackupFailedZkAuthenticationException, BackupNotFoundException, BackupPermissionException {
throws BackupFailedZkAuthenticationException, BackupPermissionException {
if (account.isPresent()) {
throw new BadRequestException("must not use authenticated connection for anonymous operations");
}

View File

@@ -99,8 +99,7 @@ public class BackupsAnonymousGrpcService extends SimpleBackupsAnonymousGrpc.Back
}
@Override
public GetBackupInfoResponse getBackupInfo(final GetBackupInfoRequest request)
throws BackupNotFoundException, BackupPermissionException {
public GetBackupInfoResponse getBackupInfo(final GetBackupInfoRequest request) throws BackupPermissionException {
try {
final AuthenticatedBackupUser backupUser = authenticateBackupUser(request.getSignedPresentation());
final BackupManager.BackupInfo info = backupManager.backupInfo(backupUser);