From 3131bd3dd9dd5e5cc4ff1659338efc07d17e1906 Mon Sep 17 00:00:00 2001
From: Jon Chambers <jon@signal.org>
Date: Mon, 24 May 2021 15:29:13 -0400
Subject: [PATCH] Allow iOS callers to specify whether they're providing a VOIP
 token for preauth.

---
 .../controllers/AccountController.java        |  5 ++-
 .../controllers/AccountControllerTest.java    | 45 +++++++++++++++++++
 2 files changed, 48 insertions(+), 2 deletions(-)

diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java
index f6bf7cff2..ff50422ba 100644
--- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java
+++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/AccountController.java
@@ -170,7 +170,8 @@ public class AccountController {
   @Path("/{type}/preauth/{token}/{number}")
   public Response getPreAuth(@PathParam("type")   String pushType,
                              @PathParam("token")  String pushToken,
-                             @PathParam("number") String number)
+                             @PathParam("number") String number,
+                             @QueryParam("voip")  Optional<Boolean> useVoip)
   {
     if (!"apn".equals(pushType) && !"fcm".equals(pushType)) {
       return Response.status(400).build();
@@ -190,7 +191,7 @@ public class AccountController {
     if ("fcm".equals(pushType)) {
       gcmSender.sendMessage(new GcmMessage(pushToken, number, 0, GcmMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
     } else if ("apn".equals(pushType)) {
-      apnSender.sendMessage(new ApnMessage(pushToken, number, 0, true, ApnMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
+      apnSender.sendMessage(new ApnMessage(pushToken, number, 0, useVoip.orElse(true), ApnMessage.Type.CHALLENGE, Optional.of(storedVerificationCode.getPushCode())));
     } else {
       throw new AssertionError();
     }
diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java
index dbfca8872..dec54c034 100644
--- a/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java
+++ b/service/src/test/java/org/whispersystems/textsecuregcm/tests/controllers/AccountControllerTest.java
@@ -322,6 +322,51 @@ class AccountControllerTest {
     assertThat(captor.getValue().getChallengeData().isPresent()).isTrue();
     assertThat(captor.getValue().getChallengeData().get().length()).isEqualTo(32);
     assertThat(captor.getValue().getMessage()).contains("\"challenge\" : \"" + captor.getValue().getChallengeData().get() + "\"");
+    assertThat(captor.getValue().isVoip()).isTrue();
+
+    verifyNoMoreInteractions(gcmSender);
+  }
+
+  @Test
+  void testGetApnPreauthExplicitVoip() throws Exception {
+    Response response = resources.getJerseyTest()
+        .target("/v1/accounts/apn/preauth/mytoken/+14152222222")
+        .queryParam("voip", "true")
+        .request()
+        .get();
+
+    assertThat(response.getStatus()).isEqualTo(200);
+
+    ArgumentCaptor<ApnMessage> captor = ArgumentCaptor.forClass(ApnMessage.class);
+
+    verify(apnSender, times(1)).sendMessage(captor.capture());
+    assertThat(captor.getValue().getApnId()).isEqualTo("mytoken");
+    assertThat(captor.getValue().getChallengeData().isPresent()).isTrue();
+    assertThat(captor.getValue().getChallengeData().get().length()).isEqualTo(32);
+    assertThat(captor.getValue().getMessage()).contains("\"challenge\" : \"" + captor.getValue().getChallengeData().get() + "\"");
+    assertThat(captor.getValue().isVoip()).isTrue();
+
+    verifyNoMoreInteractions(gcmSender);
+  }
+
+  @Test
+  void testGetApnPreauthExplicitNoVoip() throws Exception {
+    Response response = resources.getJerseyTest()
+        .target("/v1/accounts/apn/preauth/mytoken/+14152222222")
+        .queryParam("voip", "false")
+        .request()
+        .get();
+
+    assertThat(response.getStatus()).isEqualTo(200);
+
+    ArgumentCaptor<ApnMessage> captor = ArgumentCaptor.forClass(ApnMessage.class);
+
+    verify(apnSender, times(1)).sendMessage(captor.capture());
+    assertThat(captor.getValue().getApnId()).isEqualTo("mytoken");
+    assertThat(captor.getValue().getChallengeData().isPresent()).isTrue();
+    assertThat(captor.getValue().getChallengeData().get().length()).isEqualTo(32);
+    assertThat(captor.getValue().getMessage()).contains("\"challenge\" : \"" + captor.getValue().getChallengeData().get() + "\"");
+    assertThat(captor.getValue().isVoip()).isFalse();
 
     verifyNoMoreInteractions(gcmSender);
   }
-- 
GitLab