mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-19 14:48:12 +01:00
Move /v1/svrb/auth to /v1/archives/auth/svrb
This commit is contained in:
@@ -93,6 +93,7 @@ import org.whispersystems.textsecuregcm.backup.BackupManager;
|
||||
import org.whispersystems.textsecuregcm.backup.BackupsDb;
|
||||
import org.whispersystems.textsecuregcm.backup.Cdn3BackupCredentialGenerator;
|
||||
import org.whispersystems.textsecuregcm.backup.Cdn3RemoteStorageManager;
|
||||
import org.whispersystems.textsecuregcm.backup.SecureValueRecoveryBCredentialsGeneratorFactory;
|
||||
import org.whispersystems.textsecuregcm.badges.ConfiguredProfileBadgeConverter;
|
||||
import org.whispersystems.textsecuregcm.captcha.CaptchaChecker;
|
||||
import org.whispersystems.textsecuregcm.captcha.CaptchaClient;
|
||||
@@ -126,7 +127,6 @@ import org.whispersystems.textsecuregcm.controllers.RemoteConfigController;
|
||||
import org.whispersystems.textsecuregcm.controllers.RemoteConfigControllerV1;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureStorageController;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureValueRecovery2Controller;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureValueRecoveryBController;
|
||||
import org.whispersystems.textsecuregcm.controllers.StickerController;
|
||||
import org.whispersystems.textsecuregcm.controllers.SubscriptionController;
|
||||
import org.whispersystems.textsecuregcm.controllers.VerificationController;
|
||||
@@ -595,9 +595,9 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
ExternalServiceCredentialsGenerator paymentsCredentialsGenerator = PaymentsController.credentialsGenerator(
|
||||
config.getPaymentsServiceConfiguration());
|
||||
ExternalServiceCredentialsGenerator svr2CredentialsGenerator = SecureValueRecovery2Controller.credentialsGenerator(
|
||||
config.getSvr2Configuration());
|
||||
ExternalServiceCredentialsGenerator svrbCredentialsGenerator = SecureValueRecoveryBController.credentialsGenerator(
|
||||
config.getSvrbConfiguration());
|
||||
config.getSvr2Configuration());
|
||||
ExternalServiceCredentialsGenerator svrbCredentialsGenerator =
|
||||
SecureValueRecoveryBCredentialsGeneratorFactory.svrbCredentialsGenerator(config.getSvrbConfiguration());
|
||||
|
||||
RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager =
|
||||
new RegistrationRecoveryPasswordsManager(registrationRecoveryPasswords);
|
||||
@@ -644,7 +644,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
new ClientPublicKeysManager(clientPublicKeys, accountLockManager, accountLockExecutor);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
|
||||
pubsubClient, accountLockManager, keysManager, messagesManager, profilesManager,
|
||||
secureStorageClient, secureValueRecovery2Client, secureValueRecoveryBClient, disconnectionRequestManager,
|
||||
secureStorageClient, secureValueRecovery2Client, disconnectionRequestManager,
|
||||
registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, messagePollExecutor,
|
||||
clock, config.getLinkDeviceSecretConfiguration().secret().value(), dynamicConfigurationManager);
|
||||
RemoteConfigsManager remoteConfigsManager = new RemoteConfigsManager(remoteConfigs);
|
||||
@@ -798,6 +798,8 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
tusAttachmentGenerator,
|
||||
cdn3BackupCredentialGenerator,
|
||||
cdn3RemoteStorageManager,
|
||||
svrbCredentialsGenerator,
|
||||
secureValueRecoveryBClient,
|
||||
clock);
|
||||
|
||||
final AppleDeviceChecks appleDeviceChecks = new AppleDeviceChecks(
|
||||
@@ -1115,7 +1117,6 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
new RemoteConfigController(remoteConfigsManager, config.getRemoteConfigConfiguration().globalConfig(), clock),
|
||||
new SecureStorageController(storageCredentialsGenerator),
|
||||
new SecureValueRecovery2Controller(svr2CredentialsGenerator, accountsManager),
|
||||
new SecureValueRecoveryBController(svrbCredentialsGenerator),
|
||||
new StickerController(rateLimiters, config.getCdnConfiguration().credentials().accessKeyId().value(),
|
||||
config.getCdnConfiguration().credentials().secretAccessKey().value(), config.getCdnConfiguration().region(),
|
||||
config.getCdnConfiguration().bucket()),
|
||||
|
||||
@@ -8,7 +8,6 @@ package org.whispersystems.textsecuregcm.backup;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.dropwizard.util.DataSize;
|
||||
import io.grpc.Status;
|
||||
import io.grpc.StatusRuntimeException;
|
||||
import io.micrometer.core.instrument.DistributionSummary;
|
||||
import io.micrometer.core.instrument.Metrics;
|
||||
import io.micrometer.core.instrument.Tag;
|
||||
@@ -19,6 +18,7 @@ import java.time.Clock;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Base64;
|
||||
import java.util.HexFormat;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Optional;
|
||||
@@ -38,9 +38,12 @@ import org.slf4j.LoggerFactory;
|
||||
import org.whispersystems.textsecuregcm.attachments.AttachmentGenerator;
|
||||
import org.whispersystems.textsecuregcm.attachments.TusAttachmentGenerator;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedBackupUser;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
import org.whispersystems.textsecuregcm.metrics.MetricsUtil;
|
||||
import org.whispersystems.textsecuregcm.metrics.UserAgentTagUtil;
|
||||
import org.whispersystems.textsecuregcm.securevaluerecovery.SecureValueRecoveryClient;
|
||||
import org.whispersystems.textsecuregcm.util.AsyncTimerUtil;
|
||||
import org.whispersystems.textsecuregcm.util.ExceptionUtils;
|
||||
import org.whispersystems.textsecuregcm.util.Pair;
|
||||
@@ -94,9 +97,10 @@ public class BackupManager {
|
||||
private final Cdn3BackupCredentialGenerator cdn3BackupCredentialGenerator;
|
||||
private final RemoteStorageManager remoteStorageManager;
|
||||
private final SecureRandom secureRandom = new SecureRandom();
|
||||
private final ExternalServiceCredentialsGenerator secureValueRecoveryBCredentialsGenerator;
|
||||
private final SecureValueRecoveryClient secureValueRecoveryBClient;
|
||||
private final Clock clock;
|
||||
|
||||
|
||||
public BackupManager(
|
||||
final BackupsDb backupsDb,
|
||||
final GenericServerSecretParams serverSecretParams,
|
||||
@@ -104,6 +108,8 @@ public class BackupManager {
|
||||
final TusAttachmentGenerator tusAttachmentGenerator,
|
||||
final Cdn3BackupCredentialGenerator cdn3BackupCredentialGenerator,
|
||||
final RemoteStorageManager remoteStorageManager,
|
||||
final ExternalServiceCredentialsGenerator secureValueRecoveryBCredentialsGenerator,
|
||||
final SecureValueRecoveryClient secureValueRecoveryBClient,
|
||||
final Clock clock) {
|
||||
this.backupsDb = backupsDb;
|
||||
this.serverSecretParams = serverSecretParams;
|
||||
@@ -111,7 +117,9 @@ public class BackupManager {
|
||||
this.tusAttachmentGenerator = tusAttachmentGenerator;
|
||||
this.cdn3BackupCredentialGenerator = cdn3BackupCredentialGenerator;
|
||||
this.remoteStorageManager = remoteStorageManager;
|
||||
this.secureValueRecoveryBClient = secureValueRecoveryBClient;
|
||||
this.clock = clock;
|
||||
this.secureValueRecoveryBCredentialsGenerator = secureValueRecoveryBCredentialsGenerator;
|
||||
}
|
||||
|
||||
|
||||
@@ -387,6 +395,26 @@ public class BackupManager {
|
||||
return cdn3BackupCredentialGenerator.readHeaders(backupUser.backupDir());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate credentials that can be used with SVRB
|
||||
*
|
||||
* @param backupUser an already ZK authenticated backup user
|
||||
* @return the credential that may be used with SVRB
|
||||
*/
|
||||
public ExternalServiceCredentials generateSvrbAuth(final AuthenticatedBackupUser backupUser) {
|
||||
checkBackupLevel(backupUser, BackupLevel.FREE);
|
||||
// Clients may only use SVRB with their messages backup-id
|
||||
checkBackupCredentialType(backupUser, BackupCredentialType.MESSAGES);
|
||||
return secureValueRecoveryBCredentialsGenerator.generateFor(svrbIdentifier(backupUser));
|
||||
}
|
||||
|
||||
private static String svrbIdentifier(final AuthenticatedBackupUser backupUser) {
|
||||
return svrbIdentifier(BackupsDb.hashedBackupId(backupUser.backupId()));
|
||||
}
|
||||
|
||||
private static String svrbIdentifier(final byte[] hashedBackupId) {
|
||||
return HexFormat.of().formatHex(hashedBackupId);
|
||||
}
|
||||
|
||||
/**
|
||||
* List of media stored for a particular backup id
|
||||
@@ -427,13 +455,19 @@ public class BackupManager {
|
||||
|
||||
public CompletableFuture<Void> deleteEntireBackup(final AuthenticatedBackupUser backupUser) {
|
||||
checkBackupLevel(backupUser, BackupLevel.FREE);
|
||||
return backupsDb
|
||||
|
||||
// Clients only include SVRB data with their messages backup-id
|
||||
final CompletableFuture<Void> svrbRemoval = switch(backupUser.credentialType()) {
|
||||
case BackupCredentialType.MESSAGES -> secureValueRecoveryBClient.removeData(svrbIdentifier(backupUser));
|
||||
case BackupCredentialType.MEDIA -> CompletableFuture.completedFuture(null);
|
||||
};
|
||||
return svrbRemoval.thenCompose(_ -> backupsDb
|
||||
// Try to swap out the backupDir for the user
|
||||
.scheduleBackupDeletion(backupUser)
|
||||
// If there was already a pending swap, try to delete the cdn objects directly
|
||||
.exceptionallyCompose(ExceptionUtils.exceptionallyHandler(BackupsDb.PendingDeletionException.class, e ->
|
||||
AsyncTimerUtil.record(SYNCHRONOUS_DELETE_TIMER, () ->
|
||||
deletePrefix(backupUser.backupDir(), DELETION_CONCURRENCY))));
|
||||
deletePrefix(backupUser.backupDir(), DELETION_CONCURRENCY)))));
|
||||
}
|
||||
|
||||
|
||||
@@ -617,12 +651,17 @@ public class BackupManager {
|
||||
* @return A stage that completes when the deletion operation is finished
|
||||
*/
|
||||
public CompletableFuture<Void> expireBackup(final ExpiredBackup expiredBackup) {
|
||||
return backupsDb.startExpiration(expiredBackup)
|
||||
// Clients only include SVRB data with their messages backup-id
|
||||
final CompletableFuture<Void> svrbRemoval = switch(expiredBackup.expirationType()) {
|
||||
case ALL -> secureValueRecoveryBClient.removeData(svrbIdentifier(expiredBackup.hashedBackupId()));
|
||||
case MEDIA, GARBAGE_COLLECTION -> CompletableFuture.completedFuture(null);
|
||||
};
|
||||
return svrbRemoval.thenCompose(_ -> backupsDb.startExpiration(expiredBackup)
|
||||
// the deletion operation is effectively single threaded -- it's expected that the caller can increase
|
||||
// concurrency by deleting more backups at once, rather than increasing concurrency deleting an individual
|
||||
// backup
|
||||
.thenCompose(ignored -> deletePrefix(expiredBackup.prefixToDelete(), 1))
|
||||
.thenCompose(ignored -> backupsDb.finishExpiration(expiredBackup));
|
||||
.thenCompose(ignored -> backupsDb.finishExpiration(expiredBackup)));
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.backup;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator;
|
||||
import org.whispersystems.textsecuregcm.configuration.SecureValueRecoveryConfiguration;
|
||||
import java.time.Clock;
|
||||
|
||||
public class SecureValueRecoveryBCredentialsGeneratorFactory {
|
||||
private SecureValueRecoveryBCredentialsGeneratorFactory() {}
|
||||
|
||||
|
||||
@VisibleForTesting
|
||||
static ExternalServiceCredentialsGenerator svrbCredentialsGenerator(
|
||||
final SecureValueRecoveryConfiguration cfg,
|
||||
final Clock clock) {
|
||||
return ExternalServiceCredentialsGenerator
|
||||
.builder(cfg.userAuthenticationTokenSharedSecret())
|
||||
.withUserDerivationKey(cfg.userIdTokenSharedSecret().value())
|
||||
.prependUsername(false)
|
||||
.withDerivedUsernameTruncateLength(16)
|
||||
.withClock(clock)
|
||||
.build();
|
||||
}
|
||||
|
||||
public static ExternalServiceCredentialsGenerator svrbCredentialsGenerator(final SecureValueRecoveryConfiguration cfg) {
|
||||
return svrbCredentialsGenerator(cfg, Clock.systemUTC());
|
||||
}
|
||||
}
|
||||
@@ -64,6 +64,7 @@ import org.signal.libsignal.zkgroup.backups.BackupAuthCredentialRequest;
|
||||
import org.signal.libsignal.zkgroup.backups.BackupCredentialType;
|
||||
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
|
||||
import org.whispersystems.textsecuregcm.backup.BackupAuthManager;
|
||||
import org.whispersystems.textsecuregcm.backup.BackupManager;
|
||||
import org.whispersystems.textsecuregcm.backup.CopyParameters;
|
||||
@@ -389,6 +390,35 @@ public class ArchiveController {
|
||||
.thenApply(ReadAuthResponse::new);
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/auth/svrb")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Generate credentials for SVRB",
|
||||
description = """
|
||||
Generate SVRB service credentials. Generated credentials have an expiration time of 1 day (subject to change)
|
||||
""")
|
||||
@ApiResponse(responseCode = "200", description = "`JSON` with generated credentials.", useReturnTypeSchema = true)
|
||||
@ApiResponseZkAuth
|
||||
public CompletionStage<ExternalServiceCredentials> svrbAuth(
|
||||
@Auth final Optional<AuthenticatedDevice> account,
|
||||
@HeaderParam(HttpHeaders.USER_AGENT) final String userAgent,
|
||||
|
||||
@Parameter(description = BackupAuthCredentialPresentationHeader.DESCRIPTION, schema = @Schema(implementation = String.class))
|
||||
@NotNull
|
||||
@HeaderParam(X_SIGNAL_ZK_AUTH) final ArchiveController.BackupAuthCredentialPresentationHeader presentation,
|
||||
|
||||
@Parameter(description = BackupAuthCredentialPresentationSignature.DESCRIPTION, schema = @Schema(implementation = String.class))
|
||||
@NotNull
|
||||
@HeaderParam(X_SIGNAL_ZK_AUTH_SIGNATURE) final BackupAuthCredentialPresentationSignature signature) {
|
||||
if (account.isPresent()) {
|
||||
throw new BadRequestException("must not use authenticated connection for anonymous operations");
|
||||
}
|
||||
return backupManager
|
||||
.authenticateBackupUser(presentation.presentation, signature.signature, userAgent)
|
||||
.thenApply(backupManager::generateSvrbAuth);
|
||||
}
|
||||
|
||||
public record BackupInfoResponse(
|
||||
@Schema(description = "The CDN type where the message backup is stored. Media may be stored elsewhere.")
|
||||
int cdn,
|
||||
|
||||
@@ -1,63 +0,0 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
package org.whispersystems.textsecuregcm.controllers;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import io.dropwizard.auth.Auth;
|
||||
import io.swagger.v3.oas.annotations.Operation;
|
||||
import io.swagger.v3.oas.annotations.responses.ApiResponse;
|
||||
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.time.Clock;
|
||||
import org.whispersystems.textsecuregcm.auth.AuthenticatedDevice;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentials;
|
||||
import org.whispersystems.textsecuregcm.auth.ExternalServiceCredentialsGenerator;
|
||||
import org.whispersystems.textsecuregcm.configuration.SecureValueRecoveryConfiguration;
|
||||
|
||||
@Path("/v1/svrb")
|
||||
@Tag(name = "Secure Value Recovery B")
|
||||
public class SecureValueRecoveryBController {
|
||||
|
||||
public static ExternalServiceCredentialsGenerator credentialsGenerator(final SecureValueRecoveryConfiguration cfg) {
|
||||
return credentialsGenerator(cfg, Clock.systemUTC());
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public static ExternalServiceCredentialsGenerator credentialsGenerator(final SecureValueRecoveryConfiguration cfg,
|
||||
final Clock clock) {
|
||||
return ExternalServiceCredentialsGenerator
|
||||
.builder(cfg.userAuthenticationTokenSharedSecret())
|
||||
.withUserDerivationKey(cfg.userIdTokenSharedSecret().value())
|
||||
.prependUsername(false)
|
||||
.withDerivedUsernameTruncateLength(16)
|
||||
.withClock(clock)
|
||||
.build();
|
||||
}
|
||||
|
||||
private final ExternalServiceCredentialsGenerator svrbCredentialGenerator;
|
||||
|
||||
public SecureValueRecoveryBController(final ExternalServiceCredentialsGenerator svrbCredentialGenerator) {
|
||||
this.svrbCredentialGenerator = svrbCredentialGenerator;
|
||||
}
|
||||
|
||||
@GET
|
||||
@Path("/auth")
|
||||
@Produces(MediaType.APPLICATION_JSON)
|
||||
@Operation(
|
||||
summary = "Generate credentials for SVRB",
|
||||
description = """
|
||||
Generate SVRB service credentials. Generated credentials have an expiration time of 1 day (subject to change)
|
||||
"""
|
||||
)
|
||||
@ApiResponse(responseCode = "200", description = "`JSON` with generated credentials.", useReturnTypeSchema = true)
|
||||
@ApiResponse(responseCode = "401", description = "Account authentication check failed.")
|
||||
public ExternalServiceCredentials getAuth(@Auth final AuthenticatedDevice auth) {
|
||||
return svrbCredentialGenerator.generateFor(auth.accountIdentifier().toString());
|
||||
}
|
||||
}
|
||||
@@ -21,6 +21,8 @@ import org.signal.chat.backup.GetBackupInfoRequest;
|
||||
import org.signal.chat.backup.GetBackupInfoResponse;
|
||||
import org.signal.chat.backup.GetCdnCredentialsRequest;
|
||||
import org.signal.chat.backup.GetCdnCredentialsResponse;
|
||||
import org.signal.chat.backup.GetSvrBCredentialsRequest;
|
||||
import org.signal.chat.backup.GetSvrBCredentialsResponse;
|
||||
import org.signal.chat.backup.GetUploadFormRequest;
|
||||
import org.signal.chat.backup.GetUploadFormResponse;
|
||||
import org.signal.chat.backup.ListMediaRequest;
|
||||
@@ -64,6 +66,16 @@ public class BackupsAnonymousGrpcService extends ReactorBackupsAnonymousGrpc.Bac
|
||||
.map(credentials -> GetCdnCredentialsResponse.newBuilder().putAllHeaders(credentials).build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<GetSvrBCredentialsResponse> getSvrBCredentials(final GetSvrBCredentialsRequest request) {
|
||||
return authenticateBackupUserMono(request.getSignedPresentation())
|
||||
.map(backupManager::generateSvrbAuth)
|
||||
.map(credentials -> GetSvrBCredentialsResponse.newBuilder()
|
||||
.setUsername(credentials.username())
|
||||
.setPassword(credentials.password())
|
||||
.build());
|
||||
}
|
||||
|
||||
@Override
|
||||
public Mono<GetBackupInfoResponse> getBackupInfo(final GetBackupInfoRequest request) {
|
||||
return Mono.fromFuture(() ->
|
||||
|
||||
@@ -47,16 +47,6 @@ enum ExternalServiceDefinitions {
|
||||
.withClock(clock)
|
||||
.build();
|
||||
}),
|
||||
SVRB(ExternalServiceType.EXTERNAL_SERVICE_TYPE_SVRB, (chatConfig, clock) -> {
|
||||
final SecureValueRecoveryConfiguration cfg = chatConfig.getSvrbConfiguration();
|
||||
return ExternalServiceCredentialsGenerator
|
||||
.builder(cfg.userAuthenticationTokenSharedSecret())
|
||||
.withUserDerivationKey(cfg.userIdTokenSharedSecret().value())
|
||||
.prependUsername(false)
|
||||
.withDerivedUsernameTruncateLength(16)
|
||||
.withClock(clock)
|
||||
.build();
|
||||
}),
|
||||
STORAGE(ExternalServiceType.EXTERNAL_SERVICE_TYPE_STORAGE, (chatConfig, clock) -> {
|
||||
final PaymentsServiceConfiguration cfg = chatConfig.getPaymentsServiceConfiguration();
|
||||
return ExternalServiceCredentialsGenerator
|
||||
|
||||
@@ -30,9 +30,10 @@ import org.whispersystems.textsecuregcm.http.FaultTolerantHttpClient;
|
||||
import org.whispersystems.textsecuregcm.util.HttpUtils;
|
||||
|
||||
/**
|
||||
* A client for sending requests to Signal's secure value recovery v2 service on behalf of authenticated users.
|
||||
* A client for sending requests to Signal's secure value recovery service on behalf of authenticated users.
|
||||
*/
|
||||
public class SecureValueRecoveryClient {
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(SecureValueRecoveryClient.class);
|
||||
|
||||
private final ExternalServiceCredentialsGenerator secureValueRecoveryCredentialsGenerator;
|
||||
@@ -67,8 +68,12 @@ public class SecureValueRecoveryClient {
|
||||
}
|
||||
|
||||
public CompletableFuture<Void> removeData(final UUID accountUuid) {
|
||||
return removeData(accountUuid.toString());
|
||||
}
|
||||
|
||||
final ExternalServiceCredentials credentials = secureValueRecoveryCredentialsGenerator.generateForUuid(accountUuid);
|
||||
public CompletableFuture<Void> removeData(final String userIdentifier) {
|
||||
|
||||
final ExternalServiceCredentials credentials = secureValueRecoveryCredentialsGenerator.generateFor(userIdentifier);
|
||||
|
||||
final HttpRequest request = HttpRequest.newBuilder()
|
||||
.uri(deleteUri)
|
||||
@@ -83,11 +88,11 @@ public class SecureValueRecoveryClient {
|
||||
|
||||
final List<Integer> allowedErrors = allowedDeletionErrorStatusCodes.get();
|
||||
if (allowedErrors.contains(response.statusCode())) {
|
||||
logger.warn("Ignoring failure to delete svr entry for account {} with status {}",
|
||||
accountUuid, response.statusCode());
|
||||
logger.warn("Ignoring failure to delete svr entry for identifier {} with status {}",
|
||||
userIdentifier, response.statusCode());
|
||||
return null;
|
||||
}
|
||||
logger.warn("Failed to delete svr entry for account {} with status {}", accountUuid, response.statusCode());
|
||||
logger.warn("Failed to delete svr entry for identifier {} with status {}", userIdentifier, response.statusCode());
|
||||
throw new SecureValueRecoveryException("Failed to delete backup", String.valueOf(response.statusCode()));
|
||||
});
|
||||
}
|
||||
|
||||
@@ -128,7 +128,6 @@ public class AccountsManager extends RedisPubSubAdapter<String, String> implemen
|
||||
private final ProfilesManager profilesManager;
|
||||
private final SecureStorageClient secureStorageClient;
|
||||
private final SecureValueRecoveryClient secureValueRecovery2Client;
|
||||
private final SecureValueRecoveryClient secureValueRecoveryBClient;
|
||||
private final DisconnectionRequestManager disconnectionRequestManager;
|
||||
private final RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager;
|
||||
private final ClientPublicKeysManager clientPublicKeysManager;
|
||||
@@ -219,7 +218,6 @@ public class AccountsManager extends RedisPubSubAdapter<String, String> implemen
|
||||
final ProfilesManager profilesManager,
|
||||
final SecureStorageClient secureStorageClient,
|
||||
final SecureValueRecoveryClient secureValueRecovery2Client,
|
||||
final SecureValueRecoveryClient secureValueRecoveryBClient,
|
||||
final DisconnectionRequestManager disconnectionRequestManager,
|
||||
final RegistrationRecoveryPasswordsManager registrationRecoveryPasswordsManager,
|
||||
final ClientPublicKeysManager clientPublicKeysManager,
|
||||
@@ -238,7 +236,6 @@ public class AccountsManager extends RedisPubSubAdapter<String, String> implemen
|
||||
this.profilesManager = profilesManager;
|
||||
this.secureStorageClient = secureStorageClient;
|
||||
this.secureValueRecovery2Client = secureValueRecovery2Client;
|
||||
this.secureValueRecoveryBClient = secureValueRecoveryBClient;
|
||||
this.disconnectionRequestManager = disconnectionRequestManager;
|
||||
this.registrationRecoveryPasswordsManager = requireNonNull(registrationRecoveryPasswordsManager);
|
||||
this.clientPublicKeysManager = clientPublicKeysManager;
|
||||
@@ -1232,7 +1229,6 @@ public class AccountsManager extends RedisPubSubAdapter<String, String> implemen
|
||||
return CompletableFuture.allOf(
|
||||
secureStorageClient.deleteStoredData(account.getUuid()),
|
||||
secureValueRecovery2Client.removeData(account.getUuid()),
|
||||
secureValueRecoveryBClient.removeData(account.getUuid()),
|
||||
keysManager.deleteSingleUsePreKeys(account.getUuid()),
|
||||
keysManager.deleteSingleUsePreKeys(account.getPhoneNumberIdentifier()),
|
||||
messagesManager.clear(account.getUuid()),
|
||||
|
||||
@@ -30,11 +30,11 @@ import org.whispersystems.textsecuregcm.backup.BackupManager;
|
||||
import org.whispersystems.textsecuregcm.backup.BackupsDb;
|
||||
import org.whispersystems.textsecuregcm.backup.Cdn3BackupCredentialGenerator;
|
||||
import org.whispersystems.textsecuregcm.backup.Cdn3RemoteStorageManager;
|
||||
import org.whispersystems.textsecuregcm.backup.SecureValueRecoveryBCredentialsGeneratorFactory;
|
||||
import org.whispersystems.textsecuregcm.configuration.dynamic.DynamicConfiguration;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureStorageController;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureValueRecovery2Controller;
|
||||
import org.whispersystems.textsecuregcm.experiment.ExperimentEnrollmentManager;
|
||||
import org.whispersystems.textsecuregcm.controllers.SecureValueRecoveryBController;
|
||||
import org.whispersystems.textsecuregcm.experiment.PushNotificationExperimentSamples;
|
||||
import org.whispersystems.textsecuregcm.grpc.net.GrpcClientConnectionManager;
|
||||
import org.whispersystems.textsecuregcm.limits.RateLimiters;
|
||||
@@ -174,8 +174,8 @@ record CommandDependencies(
|
||||
configuration.getSecureStorageServiceConfiguration());
|
||||
ExternalServiceCredentialsGenerator secureValueRecovery2CredentialsGenerator = SecureValueRecovery2Controller.credentialsGenerator(
|
||||
configuration.getSvr2Configuration());
|
||||
ExternalServiceCredentialsGenerator secureValueRecoveryBCredentialsGenerator = SecureValueRecoveryBController.credentialsGenerator(
|
||||
configuration.getSvrbConfiguration());
|
||||
ExternalServiceCredentialsGenerator secureValueRecoveryBCredentialsGenerator =
|
||||
SecureValueRecoveryBCredentialsGeneratorFactory.svrbCredentialsGenerator(configuration.getSvrbConfiguration());
|
||||
|
||||
final ExecutorService awsSdkMetricsExecutor = environment.lifecycle()
|
||||
.virtualExecutorService(MetricRegistry.name(WhisperServerService.class, "awsSdkMetrics-%d"));
|
||||
@@ -276,7 +276,7 @@ record CommandDependencies(
|
||||
new RegistrationRecoveryPasswordsManager(registrationRecoveryPasswords);
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, phoneNumberIdentifiers, cacheCluster,
|
||||
pubsubClient, accountLockManager, keys, messagesManager, profilesManager,
|
||||
secureStorageClient, secureValueRecovery2Client, secureValueRecoveryBClient, disconnectionRequestManager,
|
||||
secureStorageClient, secureValueRecovery2Client, disconnectionRequestManager,
|
||||
registrationRecoveryPasswordsManager, clientPublicKeysManager, accountLockExecutor, messagePollExecutor,
|
||||
clock, configuration.getLinkDeviceSecretConfiguration().secret().value(), dynamicConfigurationManager);
|
||||
RateLimiters rateLimiters = RateLimiters.create(dynamicConfigurationManager, rateLimitersCluster);
|
||||
@@ -299,6 +299,8 @@ record CommandDependencies(
|
||||
remoteStorageHttpExecutor,
|
||||
remoteStorageRetryExecutor,
|
||||
configuration.getCdn3StorageManagerConfiguration()),
|
||||
secureValueRecoveryBCredentialsGenerator,
|
||||
secureValueRecoveryBClient,
|
||||
clock);
|
||||
|
||||
final IssuedReceiptsManager issuedReceiptsManager = new IssuedReceiptsManager(
|
||||
|
||||
Reference in New Issue
Block a user