diff --git a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt index 306fd573bd..bd410915a4 100644 --- a/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt +++ b/app/src/androidTest/java/org/thoughtcrime/securesms/dependencies/InstrumentationApplicationDependencyProvider.kt @@ -34,6 +34,7 @@ import org.whispersystems.signalservice.internal.configuration.SignalServiceConf import org.whispersystems.signalservice.internal.configuration.SignalServiceUrl import org.whispersystems.signalservice.internal.configuration.SignalStorageUrl import org.whispersystems.signalservice.internal.configuration.SignalSvr2Url +import org.whispersystems.signalservice.internal.push.PushServiceSocket import java.util.Optional /** @@ -112,10 +113,10 @@ class InstrumentationApplicationDependencyProvider(val application: Application, override fun provideSignalServiceMessageSender( signalWebSocket: SignalWebSocket, protocolStore: SignalServiceDataStore, - signalServiceConfiguration: SignalServiceConfiguration + pushServiceSocket: PushServiceSocket ): SignalServiceMessageSender { if (signalServiceMessageSender == null) { - signalServiceMessageSender = spyk(objToCopy = default.provideSignalServiceMessageSender(signalWebSocket, protocolStore, signalServiceConfiguration)) + signalServiceMessageSender = spyk(objToCopy = default.provideSignalServiceMessageSender(signalWebSocket, protocolStore, pushServiceSocket)) } return signalServiceMessageSender!! } diff --git a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt index 587d11f584..e567779c2f 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/backup/v2/BackupRepository.kt @@ -56,6 +56,7 @@ import org.thoughtcrime.securesms.groups.GroupId import org.thoughtcrime.securesms.jobs.RequestGroupV2InfoJob import org.thoughtcrime.securesms.keyvalue.KeyValueStore import org.thoughtcrime.securesms.keyvalue.SignalStore +import org.thoughtcrime.securesms.net.SignalNetwork import org.thoughtcrime.securesms.recipients.RecipientId import org.thoughtcrime.securesms.util.toMillis import org.whispersystems.signalservice.api.NetworkResult @@ -471,33 +472,30 @@ object BackupRepository { } fun listRemoteMediaObjects(limit: Int, cursor: String? = null): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getArchiveMediaItemsPage(backupKey, SignalStore.account.requireAci(), credential, limit, cursor) + SignalNetwork.archive.getArchiveMediaItemsPage(backupKey, SignalStore.account.requireAci(), credential, limit, cursor) } } fun getRemoteBackupUsedSpace(): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) .map { it.usedSpace } } } - private fun getBackupTier(): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi + private fun getBackupTier(aci: ACI): NetworkResult { val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .map { credential -> - val zkCredential = api.getZkCredential(backupKey, credential) + val zkCredential = SignalNetwork.archive.getZkCredential(backupKey, aci, credential) if (zkCredential.backupLevel == BackupLevel.MEDIA) { MessageBackupTier.PAID } else { @@ -510,17 +508,16 @@ object BackupRepository { * Returns an object with details about the remote backup state. */ fun getRemoteBackupState(): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) .map { it to credential } } .then { pair -> val (info, credential) = pair - api.debugGetUploadedMediaItemMetadata(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.debugGetUploadedMediaItemMetadata(backupKey, SignalStore.account.requireAci(), credential) .also { Log.i(TAG, "MediaItemMetadataResult: $it") } .map { mediaObjects -> BackupMetadata( @@ -537,34 +534,32 @@ object BackupRepository { * @return True if successful, otherwise false. */ fun uploadBackupFile(backupStream: InputStream, backupStreamLength: Long): Boolean { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getMessageBackupUploadForm(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.getMessageBackupUploadForm(backupKey, SignalStore.account.requireAci(), credential) .also { Log.i(TAG, "UploadFormResult: $it") } } .then { form -> - api.getBackupResumableUploadUrl(form) + SignalNetwork.archive.getBackupResumableUploadUrl(form) .also { Log.i(TAG, "ResumableUploadUrlResult: $it") } .map { form to it } } .then { formAndUploadUrl -> val (form, resumableUploadUrl) = formAndUploadUrl - api.uploadBackupFile(form, resumableUploadUrl, backupStream, backupStreamLength) + SignalNetwork.archive.uploadBackupFile(form, resumableUploadUrl, backupStream, backupStreamLength) .also { Log.i(TAG, "UploadBackupFileResult: $it") } } .also { Log.i(TAG, "OverallResult: $it") } is NetworkResult.Success } fun downloadBackupFile(destination: File, listener: ProgressListener? = null): Boolean { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) } .then { info -> getCdnReadCredentials(info.cdn ?: Cdn.CDN_3.cdnNumber).map { it.headers to info } } .map { pair -> @@ -575,12 +570,11 @@ object BackupRepository { } fun getBackupFileLastModified(): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential) } .then { info -> getCdnReadCredentials(info.cdn ?: Cdn.CDN_3.cdnNumber).map { it.headers to info } } .then { pair -> @@ -596,12 +590,11 @@ object BackupRepository { * Returns an object with details about the remote backup state. */ fun debugGetArchivedMediaState(): NetworkResult> { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.debugGetUploadedMediaItemMetadata(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.debugGetUploadedMediaItemMetadata(backupKey, SignalStore.account.requireAci(), credential) } } @@ -609,26 +602,24 @@ object BackupRepository { * Retrieves an upload spec that can be used to upload attachment media. */ fun getMediaUploadSpec(secretKey: ByteArray? = null): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getMediaUploadForm(backupKey, SignalStore.account.requireAci(), credential) + SignalNetwork.archive.getMediaUploadForm(backupKey, SignalStore.account.requireAci(), credential) } .then { form -> - api.getResumableUploadSpec(form, secretKey) + SignalNetwork.archive.getResumableUploadSpec(form, secretKey) } } fun archiveThumbnail(thumbnailAttachment: Attachment, parentAttachment: DatabaseAttachment): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() val request = thumbnailAttachment.toArchiveMediaRequest(parentAttachment.getThumbnailMediaName(), backupKey) return initBackupAndFetchAuth(backupKey) .then { credential -> - api.archiveAttachmentMedia( + SignalNetwork.archive.archiveAttachmentMedia( backupKey = backupKey, aci = SignalStore.account.requireAci(), serviceCredential = credential, @@ -638,14 +629,13 @@ object BackupRepository { } fun archiveMedia(attachment: DatabaseAttachment): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> val mediaName = attachment.getMediaName() val request = attachment.toArchiveMediaRequest(mediaName, backupKey) - api + SignalNetwork.archive .archiveAttachmentMedia( backupKey = backupKey, aci = SignalStore.account.requireAci(), @@ -662,7 +652,6 @@ object BackupRepository { } fun archiveMedia(databaseAttachments: List): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) @@ -679,7 +668,7 @@ object BackupRepository { attachmentIdToMediaName[it.attachmentId] = mediaName.name } - api + SignalNetwork.archive .archiveAttachmentMedia( backupKey = backupKey, aci = SignalStore.account.requireAci(), @@ -703,7 +692,6 @@ object BackupRepository { } fun deleteArchivedMedia(attachments: List): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() val mediaToDelete = attachments @@ -722,7 +710,7 @@ object BackupRepository { return initBackupAndFetchAuth(backupKey) .then { credential -> - api.deleteArchivedMedia( + SignalNetwork.archive.deleteArchivedMedia( backupKey = backupKey, aci = SignalStore.account.requireAci(), serviceCredential = credential, @@ -736,7 +724,6 @@ object BackupRepository { } fun deleteAbandonedMediaObjects(mediaObjects: Collection): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() val mediaToDelete = mediaObjects @@ -754,7 +741,7 @@ object BackupRepository { return initBackupAndFetchAuth(backupKey) .then { credential -> - api.deleteArchivedMedia( + SignalNetwork.archive.deleteArchivedMedia( backupKey = backupKey, aci = SignalStore.account.requireAci(), serviceCredential = credential, @@ -765,7 +752,6 @@ object BackupRepository { } fun debugDeleteAllArchivedMedia(): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return debugGetArchivedMediaState() @@ -784,7 +770,7 @@ object BackupRepository { } else { getAuthCredential() .then { credential -> - api.deleteArchivedMedia( + SignalNetwork.archive.deleteArchivedMedia( backupKey = backupKey, aci = SignalStore.account.requireAci(), serviceCredential = credential, @@ -808,12 +794,11 @@ object BackupRepository { return NetworkResult.Success(cached) } - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getCdnReadCredentials( + SignalNetwork.archive.getCdnReadCredentials( cdnNumber = cdnNumber, backupKey = backupKey, aci = SignalStore.account.requireAci(), @@ -828,7 +813,7 @@ object BackupRepository { .also { Log.i(TAG, "getCdnReadCredentialsResult: $it") } } - fun restoreBackupTier(): MessageBackupTier? { + fun restoreBackupTier(aci: ACI): MessageBackupTier? { // TODO: more complete error handling try { val lastModified = getBackupFileLastModified().successOrThrow() @@ -841,7 +826,7 @@ object BackupRepository { return null } SignalStore.backup.backupTier = try { - getBackupTier().successOrThrow() + getBackupTier(aci).successOrThrow() } catch (e: Exception) { Log.i(TAG, "Could not retrieve backup tier.", e) null @@ -867,12 +852,11 @@ object BackupRepository { ) } - val api = AppDependencies.signalServiceAccountManager.archiveApi val backupKey = SignalStore.svr.getOrCreateMasterKey().deriveBackupKey() return initBackupAndFetchAuth(backupKey) .then { credential -> - api.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential).map { + SignalNetwork.archive.getBackupInfo(backupKey, SignalStore.account.requireAci(), credential).map { SignalStore.backup.usedBackupMediaSpace = it.usedSpace ?: 0L BackupDirectories(it.backupDir!!, it.mediaDir!!) } @@ -941,15 +925,13 @@ object BackupRepository { * Should be the basis of all backup operations. */ private fun initBackupAndFetchAuth(backupKey: BackupKey): NetworkResult { - val api = AppDependencies.signalServiceAccountManager.archiveApi - return if (SignalStore.backup.backupsInitialized) { getAuthCredential().runOnStatusCodeError(resetInitializedStateErrorAction) } else { - return api - .triggerBackupIdReservation(backupKey) + return SignalNetwork.archive + .triggerBackupIdReservation(backupKey, SignalStore.account.requireAci()) .then { getAuthCredential() } - .then { credential -> api.setPublicKey(backupKey, SignalStore.account.requireAci(), credential).map { credential } } + .then { credential -> SignalNetwork.archive.setPublicKey(backupKey, SignalStore.account.requireAci(), credential).map { credential } } .runIfSuccessful { SignalStore.backup.backupsInitialized = true } .runOnStatusCodeError(resetInitializedStateErrorAction) } @@ -969,7 +951,7 @@ object BackupRepository { Log.w(TAG, "No credentials found for today, need to fetch new ones! This shouldn't happen under normal circumstances. We should ensure the routine fetch is running properly.") - return AppDependencies.signalServiceAccountManager.archiveApi.getServiceCredentials(currentTime).map { result -> + return SignalNetwork.archive.getServiceCredentials(currentTime).map { result -> SignalStore.backup.addCredentials(result.credentials.toList()) SignalStore.backup.clearCredentialsOlderThan(currentTime) SignalStore.backup.credentialsByDay.getForCurrentTime(currentTime.milliseconds)!! diff --git a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundViewModel.kt index 8b90918f3a..d368b81915 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/components/settings/app/internal/backup/InternalBackupPlaygroundViewModel.kt @@ -171,7 +171,7 @@ class InternalBackupPlaygroundViewModel : ViewModel() { disposables += Single .fromCallable { - BackupRepository.restoreBackupTier() + BackupRepository.restoreBackupTier(SignalStore.account.requireAci()) BackupRepository.getRemoteBackupState() } .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt index dff0e61889..ab923317d1 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/AppDependencies.kt @@ -46,12 +46,14 @@ import org.whispersystems.signalservice.api.SignalServiceDataStore import org.whispersystems.signalservice.api.SignalServiceMessageReceiver import org.whispersystems.signalservice.api.SignalServiceMessageSender import org.whispersystems.signalservice.api.SignalWebSocket +import org.whispersystems.signalservice.api.archive.ArchiveApi import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations import org.whispersystems.signalservice.api.services.CallLinksService import org.whispersystems.signalservice.api.services.DonationsService import org.whispersystems.signalservice.api.services.ProfileService import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration +import org.whispersystems.signalservice.internal.push.PushServiceSocket import java.util.function.Supplier /** @@ -290,6 +292,10 @@ object AppDependencies { val donationsService: DonationsService get() = networkModule.donationsService + @JvmStatic + val archiveApi: ArchiveApi + get() = networkModule.archiveApi + @JvmStatic val okHttpClient: OkHttpClient get() = networkModule.okHttpClient @@ -310,10 +316,11 @@ object AppDependencies { } interface Provider { + fun providePushServiceSocket(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): PushServiceSocket fun provideGroupsV2Operations(signalServiceConfiguration: SignalServiceConfiguration): GroupsV2Operations - fun provideSignalServiceAccountManager(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): SignalServiceAccountManager - fun provideSignalServiceMessageSender(signalWebSocket: SignalWebSocket, protocolStore: SignalServiceDataStore, signalServiceConfiguration: SignalServiceConfiguration): SignalServiceMessageSender - fun provideSignalServiceMessageReceiver(signalServiceConfiguration: SignalServiceConfiguration): SignalServiceMessageReceiver + fun provideSignalServiceAccountManager(pushServiceSocket: PushServiceSocket, groupsV2Operations: GroupsV2Operations): SignalServiceAccountManager + fun provideSignalServiceMessageSender(signalWebSocket: SignalWebSocket, protocolStore: SignalServiceDataStore, pushServiceSocket: PushServiceSocket): SignalServiceMessageSender + fun provideSignalServiceMessageReceiver(pushServiceSocket: PushServiceSocket): SignalServiceMessageReceiver fun provideSignalServiceNetworkAccess(): SignalServiceNetworkAccess fun provideRecipientCache(): LiveRecipientCache fun provideJobManager(): JobManager @@ -341,13 +348,14 @@ object AppDependencies { fun provideGiphyMp4Cache(): GiphyMp4Cache fun provideExoPlayerPool(): SimpleExoPlayerPool fun provideAndroidCallAudioManager(): AudioManagerCompat - fun provideDonationsService(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): DonationsService - fun provideCallLinksService(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): CallLinksService + fun provideDonationsService(pushServiceSocket: PushServiceSocket): DonationsService + fun provideCallLinksService(pushServiceSocket: PushServiceSocket): CallLinksService fun provideProfileService(profileOperations: ClientZkProfileOperations, signalServiceMessageReceiver: SignalServiceMessageReceiver, signalWebSocket: SignalWebSocket): ProfileService fun provideDeadlockDetector(): DeadlockDetector fun provideClientZkReceiptOperations(signalServiceConfiguration: SignalServiceConfiguration): ClientZkReceiptOperations fun provideScheduledMessageManager(): ScheduledMessageManager fun provideLibsignalNetwork(config: SignalServiceConfiguration): Network fun provideBillingApi(): BillingApi + fun provideArchiveApi(pushServiceSocket: PushServiceSocket): ArchiveApi } } diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java index 56a19674e0..30d9aa48d9 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/ApplicationDependencyProvider.java @@ -82,6 +82,7 @@ import org.whispersystems.signalservice.api.SignalServiceDataStore; import org.whispersystems.signalservice.api.SignalServiceMessageReceiver; import org.whispersystems.signalservice.api.SignalServiceMessageSender; import org.whispersystems.signalservice.api.SignalWebSocket; +import org.whispersystems.signalservice.api.archive.ArchiveApi; import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations; import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations; import org.whispersystems.signalservice.api.push.ServiceId.ACI; @@ -94,6 +95,7 @@ import org.whispersystems.signalservice.api.util.SleepTimer; import org.whispersystems.signalservice.api.util.UptimeSleepTimer; import org.whispersystems.signalservice.api.websocket.WebSocketFactory; import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration; +import org.whispersystems.signalservice.internal.push.PushServiceSocket; import org.whispersystems.signalservice.internal.websocket.LibSignalChatConnection; import org.whispersystems.signalservice.internal.websocket.LibSignalNetworkExtensions; import org.whispersystems.signalservice.internal.websocket.OkHttpWebSocketConnection; @@ -120,42 +122,39 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { return ClientZkOperations.create(signalServiceConfiguration); } + @Override + public @NonNull PushServiceSocket providePushServiceSocket(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations) { + return new PushServiceSocket(signalServiceConfiguration, + new DynamicCredentialsProvider(), + BuildConfig.SIGNAL_AGENT, + groupsV2Operations.getProfileOperations(), + RemoteConfig.okHttpAutomaticRetry()); + } + @Override public @NonNull GroupsV2Operations provideGroupsV2Operations(@NonNull SignalServiceConfiguration signalServiceConfiguration) { return new GroupsV2Operations(provideClientZkOperations(signalServiceConfiguration), RemoteConfig.groupLimits().getHardLimit()); } @Override - public @NonNull SignalServiceAccountManager provideSignalServiceAccountManager(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations) { - return new SignalServiceAccountManager(signalServiceConfiguration, - new DynamicCredentialsProvider(), - BuildConfig.SIGNAL_AGENT, - groupsV2Operations, - RemoteConfig.okHttpAutomaticRetry()); + public @NonNull SignalServiceAccountManager provideSignalServiceAccountManager(@NonNull PushServiceSocket pushServiceSocket, @NonNull GroupsV2Operations groupsV2Operations) { + return new SignalServiceAccountManager(pushServiceSocket, groupsV2Operations); } @Override - public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalWebSocket signalWebSocket, @NonNull SignalServiceDataStore protocolStore, @NonNull SignalServiceConfiguration signalServiceConfiguration) { - return new SignalServiceMessageSender(signalServiceConfiguration, - new DynamicCredentialsProvider(), + public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalWebSocket signalWebSocket, @NonNull SignalServiceDataStore protocolStore, @NonNull PushServiceSocket pushServiceSocket) { + return new SignalServiceMessageSender(pushServiceSocket, protocolStore, ReentrantSessionLock.INSTANCE, - BuildConfig.SIGNAL_AGENT, signalWebSocket, Optional.of(new SecurityEventListener(context)), - provideGroupsV2Operations(signalServiceConfiguration).getProfileOperations(), SignalExecutors.newCachedBoundedExecutor("signal-messages", ThreadUtil.PRIORITY_IMPORTANT_BACKGROUND_THREAD, 1, 16, 30), - ByteUnit.KILOBYTES.toBytes(256), - RemoteConfig.okHttpAutomaticRetry()); + ByteUnit.KILOBYTES.toBytes(256)); } @Override - public @NonNull SignalServiceMessageReceiver provideSignalServiceMessageReceiver(@NonNull SignalServiceConfiguration signalServiceConfiguration) { - return new SignalServiceMessageReceiver(signalServiceConfiguration, - new DynamicCredentialsProvider(), - BuildConfig.SIGNAL_AGENT, - provideGroupsV2Operations(signalServiceConfiguration).getProfileOperations(), - RemoteConfig.okHttpAutomaticRetry()); + public @NonNull SignalServiceMessageReceiver provideSignalServiceMessageReceiver(@NonNull PushServiceSocket pushServiceSocket) { + return new SignalServiceMessageReceiver(pushServiceSocket); } @Override @@ -371,21 +370,13 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { } @Override - public @NonNull DonationsService provideDonationsService(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations) { - return new DonationsService(signalServiceConfiguration, - new DynamicCredentialsProvider(), - BuildConfig.SIGNAL_AGENT, - groupsV2Operations, - RemoteConfig.okHttpAutomaticRetry()); + public @NonNull DonationsService provideDonationsService(@NonNull PushServiceSocket pushServiceSocket) { + return new DonationsService(pushServiceSocket); } @Override - public @NonNull CallLinksService provideCallLinksService(@NonNull SignalServiceConfiguration signalServiceConfiguration, @NonNull GroupsV2Operations groupsV2Operations) { - return new CallLinksService(signalServiceConfiguration, - new DynamicCredentialsProvider(), - BuildConfig.SIGNAL_AGENT, - groupsV2Operations, - RemoteConfig.okHttpAutomaticRetry()); + public @NonNull CallLinksService provideCallLinksService(@NonNull PushServiceSocket pushServiceSocket) { + return new CallLinksService(pushServiceSocket); } @Override @@ -464,6 +455,11 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider { return BillingFactory.create(context, RemoteConfig.messageBackups()); } + @Override + public @NonNull ArchiveApi provideArchiveApi(@NonNull PushServiceSocket pushServiceSocket) { + return new ArchiveApi(pushServiceSocket); + } + @VisibleForTesting static class DynamicCredentialsProvider implements CredentialsProvider { diff --git a/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt b/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt index 3ad063e199..a845b80931 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/dependencies/NetworkDependenciesModule.kt @@ -27,6 +27,7 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager import org.whispersystems.signalservice.api.SignalServiceMessageReceiver import org.whispersystems.signalservice.api.SignalServiceMessageSender import org.whispersystems.signalservice.api.SignalWebSocket +import org.whispersystems.signalservice.api.archive.ArchiveApi import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations import org.whispersystems.signalservice.api.push.TrustStore import org.whispersystems.signalservice.api.services.CallLinksService @@ -34,6 +35,7 @@ import org.whispersystems.signalservice.api.services.DonationsService import org.whispersystems.signalservice.api.services.ProfileService import org.whispersystems.signalservice.api.util.Tls12SocketFactory import org.whispersystems.signalservice.api.websocket.WebSocketConnectionState +import org.whispersystems.signalservice.internal.push.PushServiceSocket import org.whispersystems.signalservice.internal.util.BlacklistingTrustManager import org.whispersystems.signalservice.internal.util.Util import java.security.KeyManagementException @@ -63,7 +65,7 @@ class NetworkDependenciesModule( val protocolStore: SignalServiceDataStoreImpl by _protocolStore private val _signalServiceMessageSender = resettableLazy { - provider.provideSignalServiceMessageSender(signalWebSocket, protocolStore, signalServiceNetworkAccess.getConfiguration()) + provider.provideSignalServiceMessageSender(signalWebSocket, protocolStore, pushServiceSocket) } val signalServiceMessageSender: SignalServiceMessageSender by _signalServiceMessageSender @@ -71,8 +73,12 @@ class NetworkDependenciesModule( provider.provideIncomingMessageObserver() } + val pushServiceSocket: PushServiceSocket by lazy { + provider.providePushServiceSocket(signalServiceNetworkAccess.getConfiguration(), groupsV2Operations) + } + val signalServiceAccountManager: SignalServiceAccountManager by lazy { - provider.provideSignalServiceAccountManager(signalServiceNetworkAccess.getConfiguration(), groupsV2Operations) + provider.provideSignalServiceAccountManager(pushServiceSocket, groupsV2Operations) } val libsignalNetwork: Network by lazy { @@ -99,7 +105,7 @@ class NetworkDependenciesModule( } val signalServiceMessageReceiver: SignalServiceMessageReceiver by lazy { - provider.provideSignalServiceMessageReceiver(signalServiceNetworkAccess.getConfiguration()) + provider.provideSignalServiceMessageReceiver(pushServiceSocket) } val payments: Payments by lazy { @@ -107,7 +113,7 @@ class NetworkDependenciesModule( } val callLinksService: CallLinksService by lazy { - provider.provideCallLinksService(signalServiceNetworkAccess.getConfiguration(), groupsV2Operations) + provider.provideCallLinksService(pushServiceSocket) } val profileService: ProfileService by lazy { @@ -115,7 +121,11 @@ class NetworkDependenciesModule( } val donationsService: DonationsService by lazy { - provider.provideDonationsService(signalServiceNetworkAccess.getConfiguration(), groupsV2Operations) + provider.provideDonationsService(pushServiceSocket) + } + + val archiveApi: ArchiveApi by lazy { + provider.provideArchiveApi(pushServiceSocket) } val okHttpClient: OkHttpClient by lazy { diff --git a/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt b/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt new file mode 100644 index 0000000000..6638190af7 --- /dev/null +++ b/app/src/main/java/org/thoughtcrime/securesms/net/SignalNetwork.kt @@ -0,0 +1,17 @@ +/* + * Copyright 2024 Signal Messenger, LLC + * SPDX-License-Identifier: AGPL-3.0-only + */ + +package org.thoughtcrime.securesms.net + +import org.thoughtcrime.securesms.dependencies.AppDependencies +import org.whispersystems.signalservice.api.archive.ArchiveApi + +/** + * A convenient way to access network operations, similar to [org.thoughtcrime.securesms.database.SignalDatabase] and [org.thoughtcrime.securesms.keyvalue.SignalStore]. + */ +object SignalNetwork { + val archive: ArchiveApi + get() = AppDependencies.archiveApi +} diff --git a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreViewModel.kt b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreViewModel.kt index ce5c9b61f9..0bf182baa6 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreViewModel.kt +++ b/app/src/main/java/org/thoughtcrime/securesms/pin/PinRestoreViewModel.kt @@ -8,6 +8,7 @@ import io.reactivex.rxjava3.disposables.CompositeDisposable import io.reactivex.rxjava3.kotlin.plusAssign import io.reactivex.rxjava3.schedulers.Schedulers import org.thoughtcrime.securesms.backup.v2.BackupRepository +import org.thoughtcrime.securesms.keyvalue.SignalStore import org.thoughtcrime.securesms.lock.v2.PinKeyboardType import org.thoughtcrime.securesms.lock.v2.SvrConstants import org.thoughtcrime.securesms.util.DefaultValueLiveData @@ -38,7 +39,7 @@ class PinRestoreViewModel : ViewModel() { disposables += Single .fromCallable { val response = repo.restoreMasterKeyPostRegistration(pin, pinKeyboardType) - BackupRepository.restoreBackupTier() + BackupRepository.restoreBackupTier(SignalStore.account.requireAci()) response } .subscribeOn(Schedulers.io()) diff --git a/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java b/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java index f738e7fa66..a78fc5b7c7 100644 --- a/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java +++ b/app/src/main/java/org/thoughtcrime/securesms/push/AccountManagerFactory.java @@ -38,34 +38,6 @@ public class AccountManagerFactory { } private static final String TAG = Log.tag(AccountManagerFactory.class); - public @NonNull SignalServiceAccountManager createAuthenticated(@NonNull Context context, - @NonNull ACI aci, - @NonNull PNI pni, - @NonNull String e164, - int deviceId, - @NonNull String password) - { - if (AppDependencies.getSignalServiceNetworkAccess().isCensored(e164)) { - SignalExecutors.BOUNDED.execute(() -> { - try { - ProviderInstaller.installIfNeeded(context); - } catch (Throwable t) { - Log.w(TAG, t); - } - }); - } - - return new SignalServiceAccountManager(AppDependencies.getSignalServiceNetworkAccess().getConfiguration(e164), - aci, - pni, - e164, - deviceId, - password, - BuildConfig.SIGNAL_AGENT, - RemoteConfig.okHttpAutomaticRetry(), - RemoteConfig.groupLimits().getHardLimit()); - } - /** * Should only be used during registration when you haven't yet been assigned an ACI. */ @@ -84,15 +56,17 @@ public class AccountManagerFactory { }); } - return new SignalServiceAccountManager(AppDependencies.getSignalServiceNetworkAccess().getConfiguration(e164), - null, - null, - e164, - deviceId, - password, - BuildConfig.SIGNAL_AGENT, - RemoteConfig.okHttpAutomaticRetry(), - RemoteConfig.groupLimits().getHardLimit()); + return SignalServiceAccountManager.createWithStaticCredentials( + AppDependencies.getSignalServiceNetworkAccess().getConfiguration(e164), + null, + null, + e164, + deviceId, + password, + BuildConfig.SIGNAL_AGENT, + RemoteConfig.okHttpAutomaticRetry(), + RemoteConfig.groupLimits().getHardLimit() + ); } } diff --git a/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.kt b/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.kt index 9dc89e94a9..6f5a320610 100644 --- a/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.kt +++ b/app/src/test/java/org/thoughtcrime/securesms/dependencies/MockApplicationDependencyProvider.kt @@ -39,27 +39,33 @@ import org.whispersystems.signalservice.api.SignalServiceDataStore import org.whispersystems.signalservice.api.SignalServiceMessageReceiver import org.whispersystems.signalservice.api.SignalServiceMessageSender import org.whispersystems.signalservice.api.SignalWebSocket +import org.whispersystems.signalservice.api.archive.ArchiveApi import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations import org.whispersystems.signalservice.api.services.CallLinksService import org.whispersystems.signalservice.api.services.DonationsService import org.whispersystems.signalservice.api.services.ProfileService import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration +import org.whispersystems.signalservice.internal.push.PushServiceSocket import java.util.function.Supplier class MockApplicationDependencyProvider : AppDependencies.Provider { + override fun providePushServiceSocket(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): PushServiceSocket { + return mockk() + } + override fun provideGroupsV2Operations(signalServiceConfiguration: SignalServiceConfiguration): GroupsV2Operations { return mockk() } - override fun provideSignalServiceAccountManager(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): SignalServiceAccountManager { + override fun provideSignalServiceAccountManager(pushServiceSocket: PushServiceSocket, groupsV2Operations: GroupsV2Operations): SignalServiceAccountManager { return mockk() } - override fun provideSignalServiceMessageSender(signalWebSocket: SignalWebSocket, protocolStore: SignalServiceDataStore, signalServiceConfiguration: SignalServiceConfiguration): SignalServiceMessageSender { + override fun provideSignalServiceMessageSender(signalWebSocket: SignalWebSocket, protocolStore: SignalServiceDataStore, pushServiceSocket: PushServiceSocket): SignalServiceMessageSender { return mockk() } - override fun provideSignalServiceMessageReceiver(signalServiceConfiguration: SignalServiceConfiguration): SignalServiceMessageReceiver { + override fun provideSignalServiceMessageReceiver(pushServiceSocket: PushServiceSocket): SignalServiceMessageReceiver { return mockk() } @@ -171,11 +177,11 @@ class MockApplicationDependencyProvider : AppDependencies.Provider { return mockk() } - override fun provideDonationsService(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): DonationsService { + override fun provideDonationsService(pushServiceSocket: PushServiceSocket): DonationsService { return mockk() } - override fun provideCallLinksService(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): CallLinksService { + override fun provideCallLinksService(pushServiceSocket: PushServiceSocket): CallLinksService { return mockk() } @@ -202,4 +208,8 @@ class MockApplicationDependencyProvider : AppDependencies.Provider { override fun provideBillingApi(): BillingApi { return mockk() } + + override fun provideArchiveApi(pushServiceSocket: PushServiceSocket): ArchiveApi { + return mockk() + } } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java index 2dee1dcc5f..5d5b1bad54 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceAccountManager.java @@ -24,7 +24,6 @@ import org.whispersystems.signalservice.api.account.ChangePhoneNumberRequest; import org.whispersystems.signalservice.api.account.PniKeyDistributionRequest; import org.whispersystems.signalservice.api.account.PreKeyCollection; import org.whispersystems.signalservice.api.account.PreKeyUpload; -import org.whispersystems.signalservice.api.archive.ArchiveApi; import org.whispersystems.signalservice.api.crypto.ProfileCipher; import org.whispersystems.signalservice.api.crypto.ProfileCipherOutputStream; import org.whispersystems.signalservice.api.crypto.SealedSenderAccess; @@ -59,7 +58,6 @@ import org.whispersystems.signalservice.api.storage.StorageKey; import org.whispersystems.signalservice.api.storage.StorageManifestKey; import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV2; import org.whispersystems.signalservice.api.svr.SecureValueRecoveryV3; -import org.whispersystems.signalservice.api.svr.SvrApi; import org.whispersystems.signalservice.api.util.CredentialsProvider; import org.whispersystems.signalservice.api.util.Preconditions; import org.whispersystems.signalservice.internal.ServiceResponse; @@ -130,7 +128,6 @@ public class SignalServiceAccountManager { private final PushServiceSocket pushServiceSocket; private final CredentialsProvider credentials; - private final String userAgent; private final GroupsV2Operations groupsV2Operations; private final SignalServiceConfiguration configuration; @@ -143,34 +140,30 @@ public class SignalServiceAccountManager { * @param password A Signal Service password. * @param signalAgent A string which identifies the client software. */ - public SignalServiceAccountManager(SignalServiceConfiguration configuration, - ACI aci, - PNI pni, - String e164, - int deviceId, - String password, - String signalAgent, - boolean automaticNetworkRetry, - int maxGroupSize) + public static SignalServiceAccountManager createWithStaticCredentials(SignalServiceConfiguration configuration, + ACI aci, + PNI pni, + String e164, + int deviceId, + String password, + String signalAgent, + boolean automaticNetworkRetry, + int maxGroupSize) { - this(configuration, - new StaticCredentialsProvider(aci, pni, e164, deviceId, password), - signalAgent, - new GroupsV2Operations(ClientZkOperations.create(configuration), maxGroupSize), - automaticNetworkRetry); + StaticCredentialsProvider credentialProvider = new StaticCredentialsProvider(aci, pni, e164, deviceId, password); + GroupsV2Operations gv2Operations = new GroupsV2Operations(ClientZkOperations.create(configuration), maxGroupSize); + + return new SignalServiceAccountManager( + new PushServiceSocket(configuration, credentialProvider, signalAgent, gv2Operations.getProfileOperations(), automaticNetworkRetry), + gv2Operations + ); } - public SignalServiceAccountManager(SignalServiceConfiguration configuration, - CredentialsProvider credentialsProvider, - String signalAgent, - GroupsV2Operations groupsV2Operations, - boolean automaticNetworkRetry) - { + public SignalServiceAccountManager(PushServiceSocket pushServiceSocket, GroupsV2Operations groupsV2Operations) { this.groupsV2Operations = groupsV2Operations; - this.pushServiceSocket = new PushServiceSocket(configuration, credentialsProvider, signalAgent, groupsV2Operations.getProfileOperations(), automaticNetworkRetry); - this.credentials = credentialsProvider; - this.userAgent = signalAgent; - this.configuration = configuration; + this.pushServiceSocket = pushServiceSocket; + this.credentials = pushServiceSocket.getCredentialsProvider(); + this.configuration = pushServiceSocket.getConfiguration(); } public byte[] getSenderCertificate() throws IOException { @@ -869,10 +862,6 @@ public class SignalServiceAccountManager { return new GroupsV2Api(pushServiceSocket, groupsV2Operations); } - public ArchiveApi getArchiveApi() { - return ArchiveApi.create(pushServiceSocket, configuration.getBackupServerPublicParams(), credentials.getAci()); - } - public KeysApi getKeysApi() { return KeysApi.create(pushServiceSocket); } @@ -881,10 +870,6 @@ public class SignalServiceAccountManager { return new RegistrationApi(pushServiceSocket); } - public SvrApi getSvrApi() { - return new SvrApi(pushServiceSocket); - } - public AuthCredentials getPaymentsAuthorization() throws IOException { return pushServiceSocket.getPaymentsAuthorization(); } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java index be61d6a3d0..74842e67d5 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageReceiver.java @@ -68,17 +68,9 @@ public class SignalServiceMessageReceiver { /** * Construct a SignalServiceMessageReceiver. - * - * @param urls The URL of the Signal Service. - * @param credentials The Signal Service user's credentials. */ - public SignalServiceMessageReceiver(SignalServiceConfiguration urls, - CredentialsProvider credentials, - String signalAgent, - ClientZkProfileOperations clientZkProfileOperations, - boolean automaticNetworkRetry) - { - this.socket = new PushServiceSocket(urls, credentials, signalAgent, clientZkProfileOperations, automaticNetworkRetry); + public SignalServiceMessageReceiver(PushServiceSocket socket) { + this.socket = socket; } /** diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java index 69c8b96305..70f59f3295 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/SignalServiceMessageSender.java @@ -187,19 +187,17 @@ public class SignalServiceMessageSender { private final Scheduler scheduler; private final long maxEnvelopeSize; - public SignalServiceMessageSender(SignalServiceConfiguration urls, - CredentialsProvider credentialsProvider, + public SignalServiceMessageSender(PushServiceSocket pushServiceSocket, SignalServiceDataStore store, SignalSessionLock sessionLock, - String signalAgent, SignalWebSocket signalWebSocket, Optional eventListener, - ClientZkProfileOperations clientZkProfileOperations, ExecutorService executor, - long maxEnvelopeSize, - boolean automaticNetworkRetry) + long maxEnvelopeSize) { - this.socket = new PushServiceSocket(urls, credentialsProvider, signalAgent, clientZkProfileOperations, automaticNetworkRetry); + CredentialsProvider credentialsProvider = pushServiceSocket.getCredentialsProvider(); + + this.socket = pushServiceSocket; this.webSocket = signalWebSocket; this.aciStore = store.aci(); this.sessionLock = sessionLock; diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/archive/ArchiveApi.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/archive/ArchiveApi.kt index 4e9ec6b786..4aa3d58f4b 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/archive/ArchiveApi.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/archive/ArchiveApi.kt @@ -25,19 +25,14 @@ import java.time.Instant * Class to interact with various archive-related endpoints. * Why is it called archive instead of backup? Because SVR took the "backup" endpoint namespace first :) */ -class ArchiveApi( - private val pushServiceSocket: PushServiceSocket, - private val backupServerPublicParams: GenericServerPublicParams, - private val aci: ACI -) { +class ArchiveApi(private val pushServiceSocket: PushServiceSocket) { + + private val backupServerPublicParams: GenericServerPublicParams = GenericServerPublicParams(pushServiceSocket.configuration.backupServerPublicParams) + companion object { @JvmStatic - fun create(pushServiceSocket: PushServiceSocket, backupServerPublicParams: ByteArray, aci: ACI): ArchiveApi { - return ArchiveApi( - pushServiceSocket, - GenericServerPublicParams(backupServerPublicParams), - aci - ) + fun create(pushServiceSocket: PushServiceSocket): ArchiveApi { + return ArchiveApi(pushServiceSocket) } } @@ -59,7 +54,7 @@ class ArchiveApi( fun getCdnReadCredentials(cdnNumber: Int, backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.getArchiveCdnReadCredentials(cdnNumber, presentationData.toArchiveCredentialPresentation()) @@ -70,7 +65,7 @@ class ArchiveApi( * Ensures that you reserve a backupId on the service. This must be done before any other * backup-related calls. You only need to do it once, but repeated calls are safe. */ - fun triggerBackupIdReservation(backupKey: BackupKey): NetworkResult { + fun triggerBackupIdReservation(backupKey: BackupKey, aci: ACI): NetworkResult { return NetworkResult.fromFetch { val backupRequestContext = BackupAuthCredentialRequestContext.create(backupKey.value, aci.rawUuid) pushServiceSocket.setArchiveBackupId(backupRequestContext.request) @@ -84,7 +79,7 @@ class ArchiveApi( */ fun setPublicKey(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.setArchivePublicKey(presentationData.publicKey, presentationData.toArchiveCredentialPresentation()) } @@ -95,7 +90,7 @@ class ArchiveApi( */ fun getMessageBackupUploadForm(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.getArchiveMessageBackupUploadForm(presentationData.toArchiveCredentialPresentation()) } @@ -108,7 +103,7 @@ class ArchiveApi( */ fun getBackupInfo(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.getArchiveBackupInfo(presentationData.toArchiveCredentialPresentation()) } @@ -119,7 +114,7 @@ class ArchiveApi( */ fun listMediaObjects(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential, limit: Int, cursor: String? = null): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.getArchiveMediaItemsPage(presentationData.toArchiveCredentialPresentation(), limit, cursor) } @@ -149,7 +144,7 @@ class ArchiveApi( */ fun getMediaUploadForm(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.getArchiveMediaUploadForm(presentationData.toArchiveCredentialPresentation()) } @@ -191,7 +186,7 @@ class ArchiveApi( */ fun getArchiveMediaItemsPage(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential, limit: Int, cursor: String?): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.getArchiveMediaItemsPage(presentationData.toArchiveCredentialPresentation(), limit, cursor) @@ -215,7 +210,7 @@ class ArchiveApi( item: ArchiveMediaRequest ): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) pushServiceSocket.archiveAttachmentMedia(presentationData.toArchiveCredentialPresentation(), item) @@ -232,7 +227,7 @@ class ArchiveApi( items: List ): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) val request = BatchArchiveMediaRequest(items = items) @@ -251,7 +246,7 @@ class ArchiveApi( mediaToDelete: List ): NetworkResult { return NetworkResult.fromFetch { - val zkCredential = getZkCredential(backupKey, serviceCredential) + val zkCredential = getZkCredential(backupKey, aci, serviceCredential) val presentationData = CredentialPresentationData.from(backupKey, aci, zkCredential, backupServerPublicParams) val request = DeleteArchivedMediaRequest(mediaToDelete = mediaToDelete) @@ -259,7 +254,7 @@ class ArchiveApi( } } - fun getZkCredential(backupKey: BackupKey, serviceCredential: ArchiveServiceCredential): BackupAuthCredential { + fun getZkCredential(backupKey: BackupKey, aci: ACI, serviceCredential: ArchiveServiceCredential): BackupAuthCredential { val backupAuthResponse = BackupAuthCredentialResponse(serviceCredential.credential) val backupRequestContext = BackupAuthCredentialRequestContext.create(backupKey.value, aci.rawUuid) diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CallLinksService.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CallLinksService.kt index 18e74e8fd4..897f2ce4fa 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CallLinksService.kt +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/CallLinksService.kt @@ -6,28 +6,11 @@ package org.whispersystems.signalservice.api.services import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialRequest import org.signal.libsignal.zkgroup.calllinks.CreateCallLinkCredentialResponse -import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations -import org.whispersystems.signalservice.api.util.CredentialsProvider import org.whispersystems.signalservice.internal.ServiceResponse -import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration import org.whispersystems.signalservice.internal.push.PushServiceSocket import java.io.IOException -class CallLinksService( - configuration: SignalServiceConfiguration, - credentialsProvider: CredentialsProvider, - signalAgent: String, - groupsV2Operations: GroupsV2Operations, - automaticNetworkRetry: Boolean -) { - - private val pushServiceSocket = PushServiceSocket( - configuration, - credentialsProvider, - signalAgent, - groupsV2Operations.profileOperations, - automaticNetworkRetry - ) +class CallLinksService(private val pushServiceSocket: PushServiceSocket) { fun getCreateCallLinkAuthCredential(request: CreateCallLinkCredentialRequest): ServiceResponse { return try { diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/DonationsService.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/DonationsService.java index 88f6e11801..56c40a6bd8 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/DonationsService.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/services/DonationsService.java @@ -57,19 +57,7 @@ public class DonationsService { } } - public DonationsService( - SignalServiceConfiguration configuration, - CredentialsProvider credentialsProvider, - String signalAgent, - GroupsV2Operations groupsV2Operations, - boolean automaticNetworkRetry - ) - { - this(new PushServiceSocket(configuration, credentialsProvider, signalAgent, groupsV2Operations.getProfileOperations(), automaticNetworkRetry)); - } - - // Visible for testing. - DonationsService(@NonNull PushServiceSocket pushServiceSocket) { + public DonationsService(@NonNull PushServiceSocket pushServiceSocket) { this.pushServiceSocket = pushServiceSocket; } diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/svr/SvrApi.kt b/libsignal-service/src/main/java/org/whispersystems/signalservice/api/svr/SvrApi.kt deleted file mode 100644 index 20d162144f..0000000000 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/api/svr/SvrApi.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2024 Signal Messenger, LLC - * SPDX-License-Identifier: AGPL-3.0-only - */ - -package org.whispersystems.signalservice.api.svr - -import org.whispersystems.signalservice.api.NetworkResult -import org.whispersystems.signalservice.internal.push.PushServiceSocket - -class SvrApi(private val pushServiceSocket: PushServiceSocket) { - - companion object { - @JvmStatic - fun create(pushServiceSocket: PushServiceSocket): SvrApi { - return SvrApi(pushServiceSocket) - } - } - - /** - * Store the latest share-set on the service. The share-set is a piece of data generated in the course of setting a PIN on SVR3 that needs to be - */ - fun setShareSet(shareSet: ByteArray): NetworkResult { - return NetworkResult.fromFetch { - pushServiceSocket.setShareSet(shareSet) - } - } -} diff --git a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java index 20d216e4a3..ff785f19b1 100644 --- a/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java +++ b/libsignal-service/src/main/java/org/whispersystems/signalservice/internal/push/PushServiceSocket.java @@ -354,6 +354,7 @@ public class PushServiceSocket { private final Map cdnClientsMap; private final ConnectionHolder[] storageClients; + private final SignalServiceConfiguration configuration; private final CredentialsProvider credentialsProvider; private final String signalAgent; private final SecureRandom random; @@ -366,6 +367,7 @@ public class PushServiceSocket { ClientZkProfileOperations clientZkProfileOperations, boolean automaticNetworkRetry) { + this.configuration = configuration; this.credentialsProvider = credentialsProvider; this.signalAgent = signalAgent; this.automaticNetworkRetry = automaticNetworkRetry; @@ -376,6 +378,14 @@ public class PushServiceSocket { this.clientZkProfileOperations = clientZkProfileOperations; } + public SignalServiceConfiguration getConfiguration() { + return configuration; + } + + public CredentialsProvider getCredentialsProvider() { + return credentialsProvider; + } + public RegistrationSessionMetadataResponse createVerificationSession(@Nullable String pushToken, @Nullable String mcc, @Nullable String mnc) throws IOException { final String jsonBody = JsonUtil.toJson(new VerificationSessionMetadataRequestBody(credentialsProvider.getE164(), pushToken, mcc, mnc)); try (Response response = makeServiceRequest(VERIFICATION_SESSION_PATH, "POST", jsonRequestBody(jsonBody), NO_HEADERS, new RegistrationSessionResponseHandler(), SealedSenderAccess.NONE, false)) {