mirror of
https://github.com/signalapp/Signal-Android.git
synced 2026-02-26 12:44:38 +00:00
Convert rate limit apis to WebSocket.
This commit is contained in:
committed by
Greyson Parrelli
parent
86b2fe9742
commit
61a8636217
@@ -51,6 +51,7 @@ import org.whispersystems.signalservice.api.groupsv2.GroupsV2Operations
|
||||
import org.whispersystems.signalservice.api.keys.KeysApi
|
||||
import org.whispersystems.signalservice.api.link.LinkDeviceApi
|
||||
import org.whispersystems.signalservice.api.payments.PaymentsApi
|
||||
import org.whispersystems.signalservice.api.ratelimit.RateLimitChallengeApi
|
||||
import org.whispersystems.signalservice.api.registration.RegistrationApi
|
||||
import org.whispersystems.signalservice.api.services.DonationsService
|
||||
import org.whispersystems.signalservice.api.services.ProfileService
|
||||
@@ -326,6 +327,9 @@ object AppDependencies {
|
||||
val cdsApi: CdsApi
|
||||
get() = networkModule.cdsApi
|
||||
|
||||
val rateLimitChallengeApi: RateLimitChallengeApi
|
||||
get() = networkModule.rateLimitChallengeApi
|
||||
|
||||
@JvmStatic
|
||||
val okHttpClient: OkHttpClient
|
||||
get() = networkModule.okHttpClient
|
||||
@@ -401,5 +405,6 @@ object AppDependencies {
|
||||
fun provideCallingApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket, pushServiceSocket: PushServiceSocket): CallingApi
|
||||
fun providePaymentsApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): PaymentsApi
|
||||
fun provideCdsApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): CdsApi
|
||||
fun provideRateLimitChallengeApi(authWebSocket: SignalWebSocket.AuthenticatedWebSocket): RateLimitChallengeApi
|
||||
}
|
||||
}
|
||||
|
||||
@@ -92,6 +92,7 @@ import org.whispersystems.signalservice.api.link.LinkDeviceApi;
|
||||
import org.whispersystems.signalservice.api.payments.PaymentsApi;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.ACI;
|
||||
import org.whispersystems.signalservice.api.push.ServiceId.PNI;
|
||||
import org.whispersystems.signalservice.api.ratelimit.RateLimitChallengeApi;
|
||||
import org.whispersystems.signalservice.api.registration.RegistrationApi;
|
||||
import org.whispersystems.signalservice.api.services.DonationsService;
|
||||
import org.whispersystems.signalservice.api.services.ProfileService;
|
||||
@@ -516,6 +517,11 @@ public class ApplicationDependencyProvider implements AppDependencies.Provider {
|
||||
return new CdsApi(authWebSocket);
|
||||
}
|
||||
|
||||
@Override
|
||||
public @NonNull RateLimitChallengeApi provideRateLimitChallengeApi(@NonNull SignalWebSocket.AuthenticatedWebSocket authWebSocket) {
|
||||
return new RateLimitChallengeApi(authWebSocket);
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static class DynamicCredentialsProvider implements CredentialsProvider {
|
||||
|
||||
|
||||
@@ -36,6 +36,7 @@ import org.whispersystems.signalservice.api.keys.KeysApi
|
||||
import org.whispersystems.signalservice.api.link.LinkDeviceApi
|
||||
import org.whispersystems.signalservice.api.payments.PaymentsApi
|
||||
import org.whispersystems.signalservice.api.push.TrustStore
|
||||
import org.whispersystems.signalservice.api.ratelimit.RateLimitChallengeApi
|
||||
import org.whispersystems.signalservice.api.registration.RegistrationApi
|
||||
import org.whispersystems.signalservice.api.services.DonationsService
|
||||
import org.whispersystems.signalservice.api.services.ProfileService
|
||||
@@ -177,6 +178,10 @@ class NetworkDependenciesModule(
|
||||
provider.provideCdsApi(authWebSocket)
|
||||
}
|
||||
|
||||
val rateLimitChallengeApi: RateLimitChallengeApi by lazy {
|
||||
provider.provideRateLimitChallengeApi(authWebSocket)
|
||||
}
|
||||
|
||||
val okHttpClient: OkHttpClient by lazy {
|
||||
OkHttpClient.Builder()
|
||||
.addInterceptor(StandardUserAgentInterceptor())
|
||||
|
||||
@@ -4,13 +4,14 @@ import androidx.annotation.NonNull;
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.greenrobot.eventbus.EventBus;
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||
import org.thoughtcrime.securesms.jobmanager.JsonJobData;
|
||||
import org.thoughtcrime.securesms.jobmanager.Job;
|
||||
import org.thoughtcrime.securesms.jobmanager.impl.NetworkConstraint;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.net.SignalNetwork;
|
||||
import org.thoughtcrime.securesms.ratelimit.RateLimitUtil;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.thoughtcrime.securesms.util.ExceptionHelper;
|
||||
import org.whispersystems.signalservice.api.NetworkResultUtil;
|
||||
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@@ -51,7 +52,7 @@ public final class SubmitRateLimitPushChallengeJob extends BaseJob {
|
||||
|
||||
@Override
|
||||
protected void onRun() throws Exception {
|
||||
AppDependencies.getSignalServiceAccountManager().submitRateLimitPushChallenge(challenge);
|
||||
NetworkResultUtil.toBasicLegacy(SignalNetwork.rateLimitChallenge().submitPushChallenge(challenge));
|
||||
SignalStore.rateLimit().onProofAccepted();
|
||||
EventBus.getDefault().post(new SuccessEvent());
|
||||
RateLimitUtil.retryAllRateLimitedMessages(context);
|
||||
@@ -59,7 +60,7 @@ public final class SubmitRateLimitPushChallengeJob extends BaseJob {
|
||||
|
||||
@Override
|
||||
protected boolean onShouldRetry(@NonNull Exception e) {
|
||||
return e instanceof PushNetworkException;
|
||||
return ExceptionHelper.isRetryableIOException(e);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -14,6 +14,7 @@ import org.whispersystems.signalservice.api.cds.CdsApi
|
||||
import org.whispersystems.signalservice.api.keys.KeysApi
|
||||
import org.whispersystems.signalservice.api.link.LinkDeviceApi
|
||||
import org.whispersystems.signalservice.api.payments.PaymentsApi
|
||||
import org.whispersystems.signalservice.api.ratelimit.RateLimitChallengeApi
|
||||
import org.whispersystems.signalservice.api.storage.StorageServiceApi
|
||||
import org.whispersystems.signalservice.api.username.UsernameApi
|
||||
|
||||
@@ -51,6 +52,11 @@ object SignalNetwork {
|
||||
val payments: PaymentsApi
|
||||
get() = AppDependencies.paymentsApi
|
||||
|
||||
@JvmStatic
|
||||
@get:JvmName("rateLimitChallenge")
|
||||
val rateLimitChallenge: RateLimitChallengeApi
|
||||
get() = AppDependencies.rateLimitChallengeApi
|
||||
|
||||
val storageService: StorageServiceApi
|
||||
get() = AppDependencies.storageServiceApi
|
||||
|
||||
|
||||
@@ -16,11 +16,11 @@ import org.thoughtcrime.securesms.database.model.ParentStoryId
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies
|
||||
import org.thoughtcrime.securesms.jobs.SubmitRateLimitPushChallengeJob.SuccessEvent
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore
|
||||
import org.thoughtcrime.securesms.net.SignalNetwork
|
||||
import org.thoughtcrime.securesms.notifications.v2.ConversationId
|
||||
import org.thoughtcrime.securesms.recipients.Recipient
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException
|
||||
import org.whispersystems.signalservice.api.NetworkResult
|
||||
import org.whispersystems.signalservice.api.push.exceptions.ProofRequiredException
|
||||
import java.io.IOException
|
||||
import java.util.concurrent.CountDownLatch
|
||||
import java.util.concurrent.TimeUnit
|
||||
import kotlin.time.Duration
|
||||
@@ -42,25 +42,26 @@ object ProofRequiredExceptionHandler {
|
||||
fun handle(context: Context, proofRequired: ProofRequiredException, recipient: Recipient?, threadId: Long, messageId: Long): Result {
|
||||
Log.w(TAG, "[Proof Required] Options: ${proofRequired.options}")
|
||||
|
||||
try {
|
||||
if (ProofRequiredException.Option.PUSH_CHALLENGE in proofRequired.options) {
|
||||
AppDependencies.signalServiceAccountManager.requestRateLimitPushChallenge()
|
||||
Log.i(TAG, "[Proof Required] Successfully requested a challenge. Waiting up to $PUSH_CHALLENGE_TIMEOUT ms.")
|
||||
if (ProofRequiredException.Option.PUSH_CHALLENGE in proofRequired.options) {
|
||||
when (val result = SignalNetwork.rateLimitChallenge.requestPushChallenge()) {
|
||||
is NetworkResult.Success -> {
|
||||
Log.i(TAG, "[Proof Required] Successfully requested a challenge. Waiting up to $PUSH_CHALLENGE_TIMEOUT ms.")
|
||||
val success = PushChallengeRequest(PUSH_CHALLENGE_TIMEOUT).blockUntilSuccess()
|
||||
|
||||
val success = PushChallengeRequest(PUSH_CHALLENGE_TIMEOUT).blockUntilSuccess()
|
||||
|
||||
if (success) {
|
||||
Log.i(TAG, "Successfully responded to a push challenge. Retrying message send.")
|
||||
return Result.RETRY_NOW
|
||||
} else {
|
||||
Log.w(TAG, "Failed to respond to the push challeng in time. Falling back.")
|
||||
if (success) {
|
||||
Log.i(TAG, "Successfully responded to a push challenge. Retrying message send.")
|
||||
return Result.RETRY_NOW
|
||||
} else {
|
||||
Log.w(TAG, "Failed to respond to the push challeng in time. Falling back.")
|
||||
}
|
||||
}
|
||||
is NetworkResult.StatusCodeError -> Log.w(TAG, "[Proof Required] Could not request a push challenge (${result.code}). Falling back.", result.exception)
|
||||
is NetworkResult.NetworkError -> {
|
||||
Log.w(TAG, "[Proof Required] Network error when requesting push challenge. Retrying later.")
|
||||
return Result.RETRY_LATER
|
||||
}
|
||||
is NetworkResult.ApplicationError -> throw result.throwable
|
||||
}
|
||||
} catch (e: NonSuccessfulResponseCodeException) {
|
||||
Log.w(TAG, "[Proof Required] Could not request a push challenge (${e.code}). Falling back.", e)
|
||||
} catch (e: IOException) {
|
||||
Log.w(TAG, "[Proof Required] Network error when requesting push challenge. Retrying later.")
|
||||
return Result.RETRY_LATER
|
||||
}
|
||||
|
||||
if (messageId > 0) {
|
||||
|
||||
@@ -19,12 +19,13 @@ import org.signal.core.util.logging.Log;
|
||||
import org.thoughtcrime.securesms.BuildConfig;
|
||||
import org.thoughtcrime.securesms.PassphraseRequiredActivity;
|
||||
import org.thoughtcrime.securesms.R;
|
||||
import org.thoughtcrime.securesms.dependencies.AppDependencies;
|
||||
import org.thoughtcrime.securesms.keyvalue.SignalStore;
|
||||
import org.thoughtcrime.securesms.net.SignalNetwork;
|
||||
import org.thoughtcrime.securesms.util.DynamicTheme;
|
||||
import org.thoughtcrime.securesms.util.ExceptionHelper;
|
||||
import org.thoughtcrime.securesms.util.Util;
|
||||
import org.thoughtcrime.securesms.util.views.SimpleProgressDialog;
|
||||
import org.whispersystems.signalservice.api.push.exceptions.PushNetworkException;
|
||||
import org.whispersystems.signalservice.api.NetworkResultUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
@@ -98,12 +99,16 @@ public class RecaptchaProofActivity extends PassphraseRequiredActivity {
|
||||
try {
|
||||
for (int i = 0; i < 3; i++) {
|
||||
try {
|
||||
AppDependencies.getSignalServiceAccountManager().submitRateLimitRecaptchaChallenge(challenge, token);
|
||||
NetworkResultUtil.toBasicLegacy(SignalNetwork.rateLimitChallenge().submitCaptchaChallenge(challenge, token));
|
||||
RateLimitUtil.retryAllRateLimitedMessages(this);
|
||||
Log.i(TAG, "Successfully completed reCAPTCHA.");
|
||||
return new TokenResult(true, true);
|
||||
} catch (PushNetworkException e) {
|
||||
Log.w(TAG, "Network error during submission. Retrying.", e);
|
||||
} catch (IOException e) {
|
||||
if (ExceptionHelper.isRetryableIOException(e)) {
|
||||
Log.w(TAG, "Network error during submission. Retrying.", e);
|
||||
} else {
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch (IOException e) {
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright 2025 Signal Messenger, LLC
|
||||
* SPDX-License-Identifier: AGPL-3.0-only
|
||||
*/
|
||||
|
||||
@file:JvmName("ExceptionHelper")
|
||||
|
||||
package org.thoughtcrime.securesms.util
|
||||
|
||||
import org.whispersystems.signalservice.api.push.exceptions.NonSuccessfulResponseCodeException
|
||||
import java.io.IOException
|
||||
|
||||
/**
|
||||
* Returns true if this exception is a retryable I/O Exception. Helpful for jobs.
|
||||
*/
|
||||
fun Throwable.isRetryableIOException(): Boolean {
|
||||
return this is IOException && this !is NonSuccessfulResponseCodeException
|
||||
}
|
||||
Reference in New Issue
Block a user