From 6368b9383a8687677c44f0dfff13ee0e10cddd2c Mon Sep 17 00:00:00 2001 From: Moxie Marlinspike Date: Tue, 3 Nov 2015 08:12:18 -0800 Subject: [PATCH] Stripe SMS/Vox across multiple numbers // FREEBIE --- .../configuration/TwilioConfiguration.java | 11 +++++---- .../textsecuregcm/sms/TwilioSmsSender.java | 23 +++++++++++++------ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/src/main/java/org/whispersystems/textsecuregcm/configuration/TwilioConfiguration.java b/src/main/java/org/whispersystems/textsecuregcm/configuration/TwilioConfiguration.java index bba847b84..c65e4fd3d 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/configuration/TwilioConfiguration.java +++ b/src/main/java/org/whispersystems/textsecuregcm/configuration/TwilioConfiguration.java @@ -19,6 +19,9 @@ package org.whispersystems.textsecuregcm.configuration; import com.fasterxml.jackson.annotation.JsonProperty; import org.hibernate.validator.constraints.NotEmpty; +import javax.validation.constraints.NotNull; +import java.util.List; + public class TwilioConfiguration { @NotEmpty @@ -29,9 +32,9 @@ public class TwilioConfiguration { @JsonProperty private String accountToken; - @NotEmpty + @NotNull @JsonProperty - private String number; + private List numbers; @NotEmpty @JsonProperty @@ -48,8 +51,8 @@ public class TwilioConfiguration { return accountToken; } - public String getNumber() { - return number; + public List getNumbers() { + return numbers; } public String getLocalDomain() { diff --git a/src/main/java/org/whispersystems/textsecuregcm/sms/TwilioSmsSender.java b/src/main/java/org/whispersystems/textsecuregcm/sms/TwilioSmsSender.java index 1f60ae003..efe636bcf 100644 --- a/src/main/java/org/whispersystems/textsecuregcm/sms/TwilioSmsSender.java +++ b/src/main/java/org/whispersystems/textsecuregcm/sms/TwilioSmsSender.java @@ -29,10 +29,12 @@ import org.whispersystems.textsecuregcm.configuration.TwilioConfiguration; import org.whispersystems.textsecuregcm.util.Constants; import java.io.IOException; +import java.util.ArrayList; import java.util.HashMap; import java.util.LinkedList; import java.util.List; import java.util.Map; +import java.util.Random; import static com.codahale.metrics.MetricRegistry.name; @@ -47,16 +49,18 @@ public class TwilioSmsSender { private final Meter smsMeter = metricRegistry.meter(name(getClass(), "sms", "delivered")); private final Meter voxMeter = metricRegistry.meter(name(getClass(), "vox", "delivered")); - private final String accountId; - private final String accountToken; - private final String number; - private final String localDomain; + private final String accountId; + private final String accountToken; + private final ArrayList numbers; + private final String localDomain; + private final Random random; public TwilioSmsSender(TwilioConfiguration config) { this.accountId = config.getAccountId(); this.accountToken = config.getAccountToken(); - this.number = config.getNumber(); + this.numbers = new ArrayList<>(config.getNumbers()); this.localDomain = config.getLocalDomain(); + this.random = new Random(System.currentTimeMillis()); } public void deliverSmsVerification(String destination, String verificationCode) @@ -66,7 +70,7 @@ public class TwilioSmsSender { MessageFactory messageFactory = client.getAccount().getMessageFactory(); List messageParams = new LinkedList<>(); messageParams.add(new BasicNameValuePair("To", destination)); - messageParams.add(new BasicNameValuePair("From", number)); + messageParams.add(new BasicNameValuePair("From", getRandom(random, numbers))); messageParams.add(new BasicNameValuePair("Body", SmsSender.SMS_VERIFICATION_TEXT + verificationCode)); try { @@ -85,7 +89,7 @@ public class TwilioSmsSender { CallFactory callFactory = client.getAccount().getCallFactory(); Map callParams = new HashMap<>(); callParams.put("To", destination); - callParams.put("From", number); + callParams.put("From", getRandom(random, numbers)); callParams.put("Url", "https://" + localDomain + "/v1/accounts/voice/twiml/" + verificationCode); try { @@ -96,4 +100,9 @@ public class TwilioSmsSender { voxMeter.mark(); } + + private String getRandom(Random random, ArrayList elements) { + return elements.get(random.nextInt(elements.size())); + } + }