Handle "transport not allowed" responses from the registration service
This commit is contained in:
parent
3e53884979
commit
300ac16cf1
|
@ -74,6 +74,7 @@ import org.whispersystems.textsecuregcm.registration.MessageTransport;
|
||||||
import org.whispersystems.textsecuregcm.registration.RegistrationServiceClient;
|
import org.whispersystems.textsecuregcm.registration.RegistrationServiceClient;
|
||||||
import org.whispersystems.textsecuregcm.registration.RegistrationServiceException;
|
import org.whispersystems.textsecuregcm.registration.RegistrationServiceException;
|
||||||
import org.whispersystems.textsecuregcm.registration.RegistrationServiceSenderException;
|
import org.whispersystems.textsecuregcm.registration.RegistrationServiceSenderException;
|
||||||
|
import org.whispersystems.textsecuregcm.registration.TransportNotAllowedException;
|
||||||
import org.whispersystems.textsecuregcm.registration.VerificationSession;
|
import org.whispersystems.textsecuregcm.registration.VerificationSession;
|
||||||
import org.whispersystems.textsecuregcm.spam.Extract;
|
import org.whispersystems.textsecuregcm.spam.Extract;
|
||||||
import org.whispersystems.textsecuregcm.spam.FilterSpam;
|
import org.whispersystems.textsecuregcm.spam.FilterSpam;
|
||||||
|
@ -488,8 +489,13 @@ public class VerificationController {
|
||||||
|
|
||||||
throw registrationServiceException.getRegistrationSession()
|
throw registrationServiceException.getRegistrationSession()
|
||||||
.map(s -> buildResponse(s, verificationSession))
|
.map(s -> buildResponse(s, verificationSession))
|
||||||
.map(verificationSessionResponse -> new ClientErrorException(
|
.map(verificationSessionResponse -> {
|
||||||
Response.status(Response.Status.CONFLICT).entity(verificationSessionResponse).build()))
|
final Response response = registrationServiceException instanceof TransportNotAllowedException
|
||||||
|
? Response.status(418).entity(verificationSessionResponse).build()
|
||||||
|
: Response.status(Response.Status.CONFLICT).entity(verificationSessionResponse).build();
|
||||||
|
|
||||||
|
return new ClientErrorException(response);
|
||||||
|
})
|
||||||
.orElseGet(NotFoundException::new);
|
.orElseGet(NotFoundException::new);
|
||||||
|
|
||||||
} else if (unwrappedException instanceof RegistrationServiceSenderException) {
|
} else if (unwrappedException instanceof RegistrationServiceSenderException) {
|
||||||
|
|
|
@ -157,6 +157,8 @@ public class RegistrationServiceClient implements Managed {
|
||||||
RegistrationServiceSenderException.illegalArgument(response.getError().getMayRetry()));
|
RegistrationServiceSenderException.illegalArgument(response.getError().getMayRetry()));
|
||||||
case SEND_VERIFICATION_CODE_ERROR_TYPE_UNSPECIFIED -> throw new CompletionException(
|
case SEND_VERIFICATION_CODE_ERROR_TYPE_UNSPECIFIED -> throw new CompletionException(
|
||||||
RegistrationServiceSenderException.unknown(response.getError().getMayRetry()));
|
RegistrationServiceSenderException.unknown(response.getError().getMayRetry()));
|
||||||
|
case SEND_VERIFICATION_CODE_ERROR_TYPE_TRANSPORT_NOT_ALLOWED -> throw new CompletionException(
|
||||||
|
new TransportNotAllowedException(buildSessionResponseFromMetadata(response.getSessionMetadata())));
|
||||||
|
|
||||||
default -> throw new CompletionException(
|
default -> throw new CompletionException(
|
||||||
new RuntimeException("Failed to send verification code: " + response.getError().getErrorType()));
|
new RuntimeException("Failed to send verification code: " + response.getError().getErrorType()));
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
package org.whispersystems.textsecuregcm.registration;
|
||||||
|
|
||||||
|
import org.whispersystems.textsecuregcm.entities.RegistrationServiceSession;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Indicates that a request to send a verification code failed because the destination number does not support the
|
||||||
|
* requested transport (e.g. the caller asked to send an SMS to a landline number).
|
||||||
|
*/
|
||||||
|
public class TransportNotAllowedException extends RegistrationServiceException {
|
||||||
|
|
||||||
|
public TransportNotAllowedException(RegistrationServiceSession registrationServiceSession) {
|
||||||
|
super(registrationServiceSession);
|
||||||
|
}
|
||||||
|
}
|
|
@ -318,6 +318,13 @@ enum SendVerificationCodeErrorType {
|
||||||
* been verified.
|
* been verified.
|
||||||
*/
|
*/
|
||||||
SEND_VERIFICATION_CODE_ERROR_TYPE_SESSION_ALREADY_VERIFIED = 5;
|
SEND_VERIFICATION_CODE_ERROR_TYPE_SESSION_ALREADY_VERIFIED = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A verification code could not be sent via the requested transport because
|
||||||
|
* the destination phone number (or the sender) does not support the requested
|
||||||
|
* transport.
|
||||||
|
*/
|
||||||
|
SEND_VERIFICATION_CODE_ERROR_TYPE_TRANSPORT_NOT_ALLOWED = 6;
|
||||||
}
|
}
|
||||||
|
|
||||||
message CheckVerificationCodeRequest {
|
message CheckVerificationCodeRequest {
|
||||||
|
|
|
@ -68,6 +68,7 @@ import org.whispersystems.textsecuregcm.push.PushNotificationManager;
|
||||||
import org.whispersystems.textsecuregcm.registration.RegistrationServiceClient;
|
import org.whispersystems.textsecuregcm.registration.RegistrationServiceClient;
|
||||||
import org.whispersystems.textsecuregcm.registration.RegistrationServiceException;
|
import org.whispersystems.textsecuregcm.registration.RegistrationServiceException;
|
||||||
import org.whispersystems.textsecuregcm.registration.RegistrationServiceSenderException;
|
import org.whispersystems.textsecuregcm.registration.RegistrationServiceSenderException;
|
||||||
|
import org.whispersystems.textsecuregcm.registration.TransportNotAllowedException;
|
||||||
import org.whispersystems.textsecuregcm.registration.VerificationSession;
|
import org.whispersystems.textsecuregcm.registration.VerificationSession;
|
||||||
import org.whispersystems.textsecuregcm.spam.ScoreThresholdProvider;
|
import org.whispersystems.textsecuregcm.spam.ScoreThresholdProvider;
|
||||||
import org.whispersystems.textsecuregcm.storage.Account;
|
import org.whispersystems.textsecuregcm.storage.Account;
|
||||||
|
@ -983,6 +984,38 @@ class VerificationControllerTest {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
void requestVerificationCodeTransportNotAllowed() {
|
||||||
|
final String encodedSessionId = encodeSessionId(SESSION_ID);
|
||||||
|
final RegistrationServiceSession registrationServiceSession = new RegistrationServiceSession(SESSION_ID, NUMBER,
|
||||||
|
false, null, null,
|
||||||
|
null, SESSION_EXPIRATION_SECONDS);
|
||||||
|
when(registrationServiceClient.getSession(any(), any()))
|
||||||
|
.thenReturn(CompletableFuture.completedFuture(Optional.of(registrationServiceSession)));
|
||||||
|
when(verificationSessionManager.findForId(any()))
|
||||||
|
.thenReturn(CompletableFuture.completedFuture(
|
||||||
|
Optional.of(new VerificationSession(null, Collections.emptyList(), Collections.emptyList(), true,
|
||||||
|
clock.millis(), clock.millis(), registrationServiceSession.expiration()))));
|
||||||
|
when(registrationServiceClient.sendVerificationCode(any(), any(), any(), any(), any()))
|
||||||
|
.thenReturn(CompletableFuture.failedFuture(
|
||||||
|
new CompletionException(new TransportNotAllowedException(registrationServiceSession))));
|
||||||
|
|
||||||
|
final Invocation.Builder request = resources.getJerseyTest()
|
||||||
|
.target("/v1/verification/session/" + encodedSessionId + "/code")
|
||||||
|
.request()
|
||||||
|
.header(HttpHeaders.X_FORWARDED_FOR, "127.0.0.1");
|
||||||
|
|
||||||
|
try (final Response response = request.post(Entity.json(requestVerificationCodeJson("sms", "android")))) {
|
||||||
|
assertEquals(418, response.getStatus());
|
||||||
|
|
||||||
|
final VerificationSessionResponse verificationSessionResponse =
|
||||||
|
response.readEntity(VerificationSessionResponse.class);
|
||||||
|
|
||||||
|
assertTrue(verificationSessionResponse.allowedToRequestCode());
|
||||||
|
assertTrue(verificationSessionResponse.requestedInformation().isEmpty());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
void requestVerificationCodeSuccess() {
|
void requestVerificationCodeSuccess() {
|
||||||
final String encodedSessionId = encodeSessionId(SESSION_ID);
|
final String encodedSessionId = encodeSessionId(SESSION_ID);
|
||||||
|
|
Loading…
Reference in New Issue