Add SignalRestClient.

This commit is contained in:
Greyson Parrelli
2026-05-15 14:01:10 -04:00
committed by jeffrey-signal
parent ec47b83f76
commit 2aa27df95b
31 changed files with 1232 additions and 80 deletions
@@ -71,6 +71,7 @@ import org.signal.network.NetworkResult
import org.signal.network.StatusCodeErrorAction
import org.signal.network.api.SvrBApi
import org.signal.network.exceptions.NonSuccessfulResponseCodeException
import org.signal.network.rest.toNetworkResult
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.attachments.AttachmentId
import org.thoughtcrime.securesms.attachments.Cdn
@@ -1628,19 +1629,6 @@ object BackupRepository {
}
}
fun getResumableMessagesBackupUploadSpec(backupFileSize: Long): NetworkResult<ResumableMessagesBackupUploadSpec> {
return initBackupAndFetchAuth()
.then { credential ->
SignalNetwork.archive.getMessageBackupUploadForm(SignalStore.account.requireAci(), credential.messageBackupAccess, backupFileSize)
.also { Log.i(TAG, "UploadFormResult: ${it::class.simpleName}") }
}
.then { form ->
SignalNetwork.archive.getBackupResumableUploadUrl(form)
.also { Log.i(TAG, "ResumableUploadUrlResult: ${it::class.simpleName}") }
.map { ResumableMessagesBackupUploadSpec(attachmentUploadForm = form, resumableUri = it) }
}
}
fun getMessageBackupUploadForm(backupFileSize: Long): NetworkResult<AttachmentUploadForm> {
return initBackupAndFetchAuth()
.then { credential ->
@@ -66,6 +66,7 @@ import org.signal.core.util.toInt
import org.signal.core.util.update
import org.signal.core.util.withinTransaction
import org.signal.glide.decryptableuri.DecryptableUri
import org.signal.network.api.AttachmentUploadResult
import org.thoughtcrime.securesms.attachments.ArchivedAttachment
import org.thoughtcrime.securesms.attachments.Attachment
import org.thoughtcrime.securesms.attachments.AttachmentId
@@ -107,7 +108,6 @@ import org.thoughtcrime.securesms.util.ImageCompressionUtil
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.RemoteConfig
import org.thoughtcrime.securesms.video.EncryptedMediaDataSource
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
import org.whispersystems.signalservice.internal.crypto.PaddingInputStream
import java.io.ByteArrayInputStream
@@ -17,6 +17,7 @@ import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations
import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations
import org.signal.mediasend.MediaSendDependencies
import org.signal.network.api.ArchiveApi
import org.signal.network.api.AttachmentApi
import org.signal.network.api.CallingApi
import org.signal.network.api.CdsApi
import org.signal.network.api.CertificateApi
@@ -27,6 +28,7 @@ import org.signal.network.api.RateLimitChallengeApi
import org.signal.network.api.RemoteConfigApi
import org.signal.network.api.SvrBApi
import org.signal.network.api.UsernameApi
import org.signal.network.rest.SignalRestClient
import org.thoughtcrime.securesms.BuildConfig
import org.thoughtcrime.securesms.components.TypingStatusRepository
import org.thoughtcrime.securesms.components.TypingStatusSender
@@ -63,7 +65,6 @@ import org.whispersystems.signalservice.api.SignalServiceDataStore
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver
import org.whispersystems.signalservice.api.SignalServiceMessageSender
import org.whispersystems.signalservice.api.account.AccountApi
import org.whispersystems.signalservice.api.attachment.AttachmentApi
import org.whispersystems.signalservice.api.donations.DonationsApi
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations
import org.whispersystems.signalservice.api.keys.KeysApi
@@ -348,6 +349,10 @@ object AppDependencies {
val pushServiceSocket: PushServiceSocket
get() = networkModule.pushServiceSocket
@JvmStatic
val signalRestClient: SignalRestClient
get() = networkModule.signalRestClient
@JvmStatic
val registrationApi: RegistrationApi
get() = networkModule.registrationApi
@@ -433,9 +438,10 @@ object AppDependencies {
interface Provider {
fun providePushServiceSocket(signalServiceConfiguration: SignalServiceConfiguration, groupsV2Operations: GroupsV2Operations): PushServiceSocket
fun provideSignalRestClient(signalServiceConfiguration: SignalServiceConfiguration): SignalRestClient
fun provideGroupsV2Operations(signalServiceConfiguration: SignalServiceConfiguration): GroupsV2Operations
fun provideSignalServiceAccountManager(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, accountApi: AccountApi, pushServiceSocket: PushServiceSocket, groupsV2Operations: GroupsV2Operations): SignalServiceAccountManager
fun provideSignalServiceMessageSender(protocolStore: SignalServiceDataStore, pushServiceSocket: PushServiceSocket, attachmentApi: AttachmentApi, messageApi: MessageApi, keysApi: KeysApi): SignalServiceMessageSender
fun provideSignalServiceMessageSender(protocolStore: SignalServiceDataStore, pushServiceSocket: PushServiceSocket, messageApi: MessageApi, keysApi: KeysApi): SignalServiceMessageSender
fun provideSignalServiceMessageReceiver(pushServiceSocket: PushServiceSocket): SignalServiceMessageReceiver
fun provideSignalServiceNetworkAccess(): SignalServiceNetworkAccess
fun provideRecipientCache(): LiveRecipientCache
@@ -471,7 +477,7 @@ object AppDependencies {
fun providePinnedMessageManager(): PinnedMessageManager
fun provideLibsignalNetwork(config: SignalServiceConfiguration): Network
fun provideBillingApi(): BillingApi
fun provideArchiveApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket, pushServiceSocket: PushServiceSocket): ArchiveApi
fun provideArchiveApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket, pushServiceSocket: PushServiceSocket, signalServiceConfiguration: SignalServiceConfiguration): ArchiveApi
fun provideKeysApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, unauthWebSocket: SignalWebSocket.UnauthenticatedWebSocket): KeysApi
fun provideAttachmentApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, pushServiceSocket: PushServiceSocket): AttachmentApi
fun provideLinkDeviceApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): LinkDeviceApi
@@ -18,9 +18,12 @@ import org.signal.core.util.concurrent.DeadlockDetector;
import org.signal.core.util.concurrent.SignalExecutors;
import org.signal.libsignal.net.Network;
import org.signal.libsignal.protocol.SignalProtocolAddress;
import org.signal.libsignal.zkgroup.GenericServerPublicParams;
import org.signal.libsignal.zkgroup.InvalidInputException;
import org.signal.libsignal.zkgroup.profiles.ClientZkProfileOperations;
import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations;
import org.signal.network.api.ArchiveApi;
import org.signal.network.rest.SignalRestClient;
import org.signal.network.api.CallingApi;
import org.signal.network.api.CdsApi;
import org.signal.network.api.CertificateApi;
@@ -104,7 +107,7 @@ import org.whispersystems.signalservice.api.SignalServiceDataStore;
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver;
import org.whispersystems.signalservice.api.SignalServiceMessageSender;
import org.whispersystems.signalservice.api.account.AccountApi;
import org.whispersystems.signalservice.api.attachment.AttachmentApi;
import org.signal.network.api.AttachmentApi;
import org.whispersystems.signalservice.api.donations.DonationsApi;
import org.whispersystems.signalservice.api.groupsv2.ClientZkOperations;
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations;
@@ -154,6 +157,14 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
RemoteConfig.okHttpAutomaticRetry());
}
@Override
public @NonNull SignalRestClient provideSignalRestClient(@NonNull SignalServiceConfiguration signalServiceConfiguration) {
return new SignalRestClient(signalServiceConfiguration,
BuildConfig.SIGNAL_AGENT,
new DynamicCredentialsProvider(),
RemoteConfig.okHttpAutomaticRetry());
}
@Override
public @NonNull GroupsV2Operations provideGroupsV2Operations(@NonNull SignalServiceConfiguration signalServiceConfiguration) {
return new GroupsV2Operations(provideClientZkOperations(signalServiceConfiguration), RemoteConfig.groupLimits().getHardLimit());
@@ -167,13 +178,11 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
@Override
public @NonNull SignalServiceMessageSender provideSignalServiceMessageSender(@NonNull SignalServiceDataStore protocolStore,
@NonNull PushServiceSocket pushServiceSocket,
@NonNull AttachmentApi attachmentApi,
@NonNull MessageApi messageApi,
@NonNull KeysApi keysApi) {
return new SignalServiceMessageSender(pushServiceSocket,
protocolStore,
ReentrantSessionLock.INSTANCE,
attachmentApi,
messageApi,
keysApi,
Optional.of(new SecurityEventListener(context)),
@@ -502,8 +511,12 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
}
@Override
public @NonNull ArchiveApi provideArchiveApi(@NonNull SignalWebSocket.AuthenticatedWebSocket authWebSocket, @NonNull SignalWebSocket.UnauthenticatedWebSocket unauthWebSocket, @NonNull PushServiceSocket pushServiceSocket) {
return new ArchiveApi(authWebSocket, unauthWebSocket, pushServiceSocket);
public @NonNull ArchiveApi provideArchiveApi(@NonNull SignalWebSocket.AuthenticatedWebSocket authWebSocket, @NonNull SignalWebSocket.UnauthenticatedWebSocket unauthWebSocket, @NonNull PushServiceSocket pushServiceSocket, @NonNull SignalServiceConfiguration signalServiceConfiguration) {
try {
return new ArchiveApi(authWebSocket, unauthWebSocket, pushServiceSocket, new GenericServerPublicParams(signalServiceConfiguration.getBackupServerPublicParams()));
} catch (InvalidInputException e) {
throw new RuntimeException(e);
}
}
@Override
@@ -17,6 +17,7 @@ import org.signal.core.util.resettableLazy
import org.signal.libsignal.net.Network
import org.signal.libsignal.zkgroup.receipts.ClientZkReceiptOperations
import org.signal.network.api.ArchiveApi
import org.signal.network.api.AttachmentApi
import org.signal.network.api.CallingApi
import org.signal.network.api.CdsApi
import org.signal.network.api.CertificateApi
@@ -27,6 +28,7 @@ import org.signal.network.api.RateLimitChallengeApi
import org.signal.network.api.RemoteConfigApi
import org.signal.network.api.SvrBApi
import org.signal.network.api.UsernameApi
import org.signal.network.rest.SignalRestClient
import org.thoughtcrime.securesms.crypto.storage.SignalServiceDataStoreImpl
import org.thoughtcrime.securesms.groups.GroupsV2Authorization
import org.thoughtcrime.securesms.groups.GroupsV2AuthorizationMemoryValueCache
@@ -40,7 +42,6 @@ import org.whispersystems.signalservice.api.SignalServiceAccountManager
import org.whispersystems.signalservice.api.SignalServiceMessageReceiver
import org.whispersystems.signalservice.api.SignalServiceMessageSender
import org.whispersystems.signalservice.api.account.AccountApi
import org.whispersystems.signalservice.api.attachment.AttachmentApi
import org.whispersystems.signalservice.api.donations.DonationsApi
import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations
import org.whispersystems.signalservice.api.keys.KeysApi
@@ -90,7 +91,7 @@ class NetworkDependenciesModule(
val protocolStore: SignalServiceDataStoreImpl by _protocolStore
private val _signalServiceMessageSender = resettableLazy {
provider.provideSignalServiceMessageSender(protocolStore, pushServiceSocket, attachmentApi, messageApi, keysApi)
provider.provideSignalServiceMessageSender(protocolStore, pushServiceSocket, messageApi, keysApi)
}
val signalServiceMessageSender: SignalServiceMessageSender by _signalServiceMessageSender
@@ -102,6 +103,10 @@ class NetworkDependenciesModule(
provider.providePushServiceSocket(signalServiceNetworkAccess.getConfiguration(), groupsV2Operations)
}
val signalRestClient: SignalRestClient by lazy {
provider.provideSignalRestClient(signalServiceNetworkAccess.getConfiguration())
}
val signalServiceAccountManager: SignalServiceAccountManager by lazy {
provider.provideSignalServiceAccountManager(authWebSocket, accountApi, pushServiceSocket, groupsV2Operations)
}
@@ -150,7 +155,7 @@ class NetworkDependenciesModule(
}
val archiveApi: ArchiveApi by lazy {
provider.provideArchiveApi(authWebSocket, unauthWebSocket, pushServiceSocket)
provider.provideArchiveApi(authWebSocket, unauthWebSocket, pushServiceSocket, signalServiceNetworkAccess.getConfiguration())
}
val keysApi: KeysApi by lazy {
@@ -9,6 +9,7 @@ import org.signal.core.util.Util
import org.signal.core.util.logging.Log
import org.signal.glide.decryptableuri.DecryptableUri
import org.signal.network.NetworkResult
import org.signal.network.api.AttachmentUploadResult
import org.thoughtcrime.securesms.attachments.AttachmentId
import org.thoughtcrime.securesms.attachments.AttachmentUploadUtil
import org.thoughtcrime.securesms.attachments.DatabaseAttachment
@@ -30,7 +31,6 @@ import org.thoughtcrime.securesms.net.SignalNetwork
import org.thoughtcrime.securesms.util.ImageCompressionUtil
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
import org.whispersystems.signalservice.api.messages.SignalServiceAttachmentStream
@@ -16,6 +16,7 @@ import org.signal.core.util.readLength
import org.signal.libsignal.net.RequestResult
import org.signal.libsignal.net.RetryLaterException
import org.signal.libsignal.net.UploadTooLargeException
import org.signal.network.api.AttachmentUploadResult
import org.signal.protos.resumableuploads.ResumableUpload
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.attachments.Attachment
@@ -41,7 +42,6 @@ import org.thoughtcrime.securesms.transport.UndeliverableMessageException
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.MessageUtil
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
@@ -19,6 +19,7 @@ import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.database.RecipientTable;
import org.thoughtcrime.securesms.database.SignalDatabase;
import org.thoughtcrime.securesms.database.model.IdentityRecord;
import org.signal.network.service.CdnService;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
import org.thoughtcrime.securesms.jobmanager.Job;
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
@@ -286,11 +287,12 @@ public class MultiDeviceContactUpdateJob extends BaseJob {
{
if (length > 0) {
try {
CdnService cdnService = new CdnService(AppDependencies.getSignalRestClient(), AppDependencies.getAttachmentApi());
SignalServiceAttachmentStream.Builder attachmentStream = SignalServiceAttachment.newStreamBuilder()
.withStream(stream)
.withContentType("application/octet-stream")
.withLength(length)
.withResumableUploadSpec(messageSender.getResumableUploadSpec(AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(length))));
.withResumableUploadSpec(cdnService.getResumableUploadSpecBlocking(AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(length))));
messageSender.sendSyncMessage(SignalServiceSyncMessage.forContacts(new ContactsMessage(attachmentStream.build(), complete))
);
@@ -6,6 +6,7 @@ import androidx.annotation.Nullable;
import org.signal.core.util.logging.Log;
import org.signal.libsignal.zkgroup.profiles.ProfileKey;
import org.signal.network.service.CdnService;
import org.thoughtcrime.securesms.BuildConfig;
import org.thoughtcrime.securesms.crypto.ProfileKeyUtil;
import org.thoughtcrime.securesms.dependencies.AppDependencies;
@@ -93,7 +94,8 @@ public class MultiDeviceProfileKeyUpdateJob extends BaseJob {
SignalServiceMessageSender messageSender = AppDependencies.getSignalServiceMessageSender();
long dataLength = baos.toByteArray().length;
long ciphertextLength = AttachmentCipherStreamUtil.getCiphertextLength(PaddingInputStream.getPaddedSize(dataLength));
ResumableUploadSpec uploadSpec = messageSender.getResumableUploadSpec(ciphertextLength);
CdnService cdnService = new CdnService(AppDependencies.getSignalRestClient(), AppDependencies.getAttachmentApi());
ResumableUploadSpec uploadSpec = cdnService.getResumableUploadSpecBlocking(ciphertextLength);
SignalServiceAttachmentStream attachmentStream = SignalServiceAttachment.newStreamBuilder()
.withStream(new ByteArrayInputStream(baos.toByteArray()))
.withContentType("application/octet-stream")
@@ -16,6 +16,7 @@ import org.signal.core.util.Util
import org.signal.core.util.logging.Log
import org.signal.libsignal.zkgroup.InvalidInputException
import org.signal.libsignal.zkgroup.receipts.ReceiptCredentialPresentation
import org.signal.network.service.CdnService
import org.thoughtcrime.securesms.BuildConfig
import org.thoughtcrime.securesms.TextSecureExpiredException
import org.thoughtcrime.securesms.attachments.Attachment
@@ -233,7 +234,7 @@ abstract class PushSendJob protected constructor(parameters: Parameters) : BaseJ
val inputStream = PartAuthority.getAttachmentStream(context, attachment.uri!!)
val ciphertextLength = getCiphertextLength(PaddingInputStream.getPaddedSize(attachment.size))
val uploadSpec = AppDependencies.signalServiceMessageSender.getResumableUploadSpec(ciphertextLength)
val uploadSpec = CdnService(AppDependencies.signalRestClient, AppDependencies.attachmentApi).getResumableUploadSpecBlocking(ciphertextLength)
return SignalServiceAttachment.newStreamBuilder()
.withStream(inputStream)
@@ -14,6 +14,7 @@ import org.signal.core.util.isNotNullOrBlank
import org.signal.core.util.logging.Log
import org.signal.core.util.readLength
import org.signal.network.NetworkResult
import org.signal.network.api.AttachmentUploadResult
import org.signal.protos.resumableuploads.ResumableUpload
import org.thoughtcrime.securesms.R
import org.thoughtcrime.securesms.attachments.AttachmentId
@@ -35,7 +36,6 @@ import org.thoughtcrime.securesms.service.AttachmentProgressService
import org.thoughtcrime.securesms.util.MediaUtil
import org.thoughtcrime.securesms.util.RemoteConfig
import org.whispersystems.signalservice.api.archive.ArchiveMediaUploadFormStatusCodes
import org.whispersystems.signalservice.api.attachment.AttachmentUploadResult
import org.whispersystems.signalservice.api.crypto.AttachmentCipherStreamUtil
import org.whispersystems.signalservice.api.messages.AttachmentTransferProgress
import org.whispersystems.signalservice.api.messages.SignalServiceAttachment
@@ -6,6 +6,7 @@
package org.thoughtcrime.securesms.net
import org.signal.network.api.ArchiveApi
import org.signal.network.api.AttachmentApi
import org.signal.network.api.CallingApi
import org.signal.network.api.CdsApi
import org.signal.network.api.CertificateApi
@@ -19,7 +20,6 @@ import org.signal.network.api.UsernameApi
import org.thoughtcrime.securesms.dependencies.AppDependencies
import org.thoughtcrime.securesms.dependencies.KeyTransparencyApi
import org.whispersystems.signalservice.api.account.AccountApi
import org.whispersystems.signalservice.api.attachment.AttachmentApi
import org.whispersystems.signalservice.api.keys.KeysApi
import org.whispersystems.signalservice.api.message.MessageApi
import org.whispersystems.signalservice.api.profiles.ProfileApi