From 498ace048835ed0d228cbeaa0ef7f980e51d925e Mon Sep 17 00:00:00 2001 From: Katherine Date: Thu, 25 Jan 2024 10:52:17 -0800 Subject: [PATCH] Remove iOS special case handling logic for SEPA/iDEAL --- .../controllers/SubscriptionController.java | 34 +++---------------- .../SubscriptionControllerTest.java | 23 ++----------- 2 files changed, 8 insertions(+), 49 deletions(-) diff --git a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java index 25827b692..33e35cf9c 100644 --- a/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java +++ b/service/src/main/java/org/whispersystems/textsecuregcm/controllers/SubscriptionController.java @@ -35,7 +35,6 @@ import java.util.concurrent.CompletableFuture; import java.util.concurrent.CompletionException; import java.util.stream.Collectors; import javax.annotation.Nonnull; -import javax.annotation.Nullable; import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import javax.validation.Valid; @@ -99,10 +98,6 @@ import org.whispersystems.textsecuregcm.subscriptions.SubscriptionCurrencyUtil; import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessor; import org.whispersystems.textsecuregcm.subscriptions.SubscriptionProcessorManager; import org.whispersystems.textsecuregcm.util.ExactlySize; -import org.whispersystems.textsecuregcm.util.ua.ClientPlatform; -import org.whispersystems.textsecuregcm.util.ua.UnrecognizedUserAgentException; -import org.whispersystems.textsecuregcm.util.ua.UserAgent; -import org.whispersystems.textsecuregcm.util.ua.UserAgentUtil; @Path("/v1/subscription") @io.swagger.v3.oas.annotations.tags.Tag(name = "Subscriptions") @@ -157,7 +152,7 @@ public class SubscriptionController { this.bankMandateTranslator = Objects.requireNonNull(bankMandateTranslator); } - private Map buildCurrencyConfiguration(@Nullable final UserAgent userAgent) { + private Map buildCurrencyConfiguration() { final List subscriptionProcessorManagers = List.of(stripeManager, braintreeManager); return oneTimeDonationConfiguration.currencies() .entrySet().stream() @@ -178,7 +173,6 @@ public class SubscriptionController { levelIdAndConfig -> levelIdAndConfig.getValue().getPrices().get(currency).amount())); final List supportedPaymentMethods = Arrays.stream(PaymentMethod.values()) - .filter(paymentMethod -> !excludePaymentMethod(userAgent, paymentMethod)) .filter(paymentMethod -> subscriptionProcessorManagers.stream() .anyMatch(manager -> manager.supportsPaymentMethod(paymentMethod) && manager.getSupportedCurrenciesForPaymentMethod(paymentMethod).contains(currency))) @@ -194,18 +188,8 @@ public class SubscriptionController { })); } - // This logic to exclude some iOS client versions from receiving SEPA_DEBIT or IDEAL - // as a supported payment method can be removed after 01-23-24. - private boolean excludePaymentMethod(@Nullable final UserAgent userAgent, final PaymentMethod paymentMethod) { - return (paymentMethod == PaymentMethod.SEPA_DEBIT || paymentMethod == PaymentMethod.IDEAL) - && userAgent != null - && userAgent.getPlatform() == ClientPlatform.IOS - && userAgent.getVersion().isLowerThanOrEqualTo(LAST_PROBLEMATIC_IOS_VERSION); - } - @VisibleForTesting - GetSubscriptionConfigurationResponse buildGetSubscriptionConfigurationResponse(final List acceptableLanguages, - final UserAgent userAgent) { + GetSubscriptionConfigurationResponse buildGetSubscriptionConfigurationResponse(final List acceptableLanguages) { final Map levels = new HashMap<>(); subscriptionConfiguration.getLevels().forEach((levelId, levelConfig) -> { @@ -233,7 +217,7 @@ public class SubscriptionController { giftBadge, oneTimeDonationConfiguration.gift().expiration()))); - return new GetSubscriptionConfigurationResponse(buildCurrencyConfiguration(userAgent), levels, oneTimeDonationConfiguration.sepaMaximumEuros()); + return new GetSubscriptionConfigurationResponse(buildCurrencyConfiguration(), levels, oneTimeDonationConfiguration.sepaMaximumEuros()); } @DELETE @@ -574,18 +558,10 @@ public class SubscriptionController { @GET @Path("/configuration") @Produces(MediaType.APPLICATION_JSON) - public CompletableFuture getConfiguration(@Context ContainerRequestContext containerRequestContext, - @HeaderParam(HttpHeaders.USER_AGENT) final String userAgentString) { + public CompletableFuture getConfiguration(@Context ContainerRequestContext containerRequestContext) { return CompletableFuture.supplyAsync(() -> { List acceptableLanguages = getAcceptableLanguagesForRequest(containerRequestContext); - - UserAgent userAgent; - try { - userAgent = UserAgentUtil.parseUserAgentString(userAgentString); - } catch (UnrecognizedUserAgentException e) { - userAgent = null; - } - return Response.ok(buildGetSubscriptionConfigurationResponse(acceptableLanguages, userAgent)).build(); + return Response.ok(buildGetSubscriptionConfigurationResponse(acceptableLanguages)).build(); }); } diff --git a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/SubscriptionControllerTest.java b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/SubscriptionControllerTest.java index ae29d3220..77208f5bb 100644 --- a/service/src/test/java/org/whispersystems/textsecuregcm/controllers/SubscriptionControllerTest.java +++ b/service/src/test/java/org/whispersystems/textsecuregcm/controllers/SubscriptionControllerTest.java @@ -43,7 +43,6 @@ import java.util.function.Predicate; import java.util.stream.Stream; import javax.ws.rs.client.Entity; import javax.ws.rs.core.Response; -import org.apache.http.HttpHeaders; import org.assertj.core.api.InstanceOfAssertFactories; import org.glassfish.jersey.server.ServerProperties; import org.glassfish.jersey.test.grizzly.GrizzlyWebTestContainerFactory; @@ -775,9 +774,8 @@ class SubscriptionControllerTest { assertThat(response.getStatus()).isEqualTo(400); } - @ParameterizedTest - @MethodSource - void getSubscriptionConfiguration(final String userAgent, final boolean expectNonCardPaymentMethods) { + @Test + void getSubscriptionConfiguration() { when(BADGE_TRANSLATOR.translate(any(), eq("B1"))).thenReturn(new Badge("B1", "cat1", "name1", "desc1", List.of("l", "m", "h", "x", "xx", "xxx"), "SVG", List.of(new BadgeSvg("sl", "sd"), new BadgeSvg("ml", "md"), new BadgeSvg("ll", "ld")))); @@ -799,7 +797,6 @@ class SubscriptionControllerTest { GetSubscriptionConfigurationResponse response = RESOURCE_EXTENSION.target("/v1/subscription/configuration") .request() - .header(HttpHeaders.USER_AGENT, userAgent) .get(GetSubscriptionConfigurationResponse.class); assertThat(response.sepaMaximumEuros()).isEqualTo("10000"); @@ -856,7 +853,7 @@ class SubscriptionControllerTest { List.of(BigDecimal.valueOf(5)))); assertThat(currency.subscription()).isEqualTo( Map.of("5", BigDecimal.valueOf(5), "15", BigDecimal.valueOf(15),"35", BigDecimal.valueOf(35))); - final List expectedPaymentMethods = expectNonCardPaymentMethods ? List.of("CARD", "SEPA_DEBIT", "IDEAL") : List.of("CARD"); + final List expectedPaymentMethods = List.of("CARD", "SEPA_DEBIT", "IDEAL"); assertThat(currency.supportedPaymentMethods()).isEqualTo(expectedPaymentMethods); }); }); @@ -907,7 +904,6 @@ class SubscriptionControllerTest { // subscription levels are Badge, while one-time levels are PurchasableBadge, which adds `duration` Map genericResponse = RESOURCE_EXTENSION.target("/v1/subscription/configuration") .request() - .header(HttpHeaders.USER_AGENT, userAgent) .get(Map.class); assertThat(genericResponse.get("levels")).satisfies(levels -> { @@ -930,19 +926,6 @@ class SubscriptionControllerTest { }); } - private static Stream getSubscriptionConfiguration() { - return Stream.of( - Arguments.of("Signal-iOS/6.44.0.8", false), - Arguments.of("Signal-iOS/6.45.0.0", true), - Arguments.of("Signal-iOS/6.45.0.2", true), - Arguments.of("Signal-iOS/6.46.0.0", true), - Arguments.of("Signal-Android/1.2.3", true), - Arguments.of(null, true), - Arguments.of("", true), - Arguments.of("definitely not a parseable user agent", true) - ); - } - /** * Encapsulates {@code static} configuration, to keep the class header simpler and avoid illegal forward references */