Use ACIs instead of E164s for TURN URI overrides

This commit is contained in:
Jon Chambers 2023-08-01 15:38:44 -04:00 committed by Jon Chambers
parent b01945ff50
commit 42141e51a1
5 changed files with 22 additions and 17 deletions

View File

@ -23,6 +23,7 @@ import java.time.Instant;
import java.util.Base64; import java.util.Base64;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.UUID;
public class TurnTokenGenerator { public class TurnTokenGenerator {
@ -39,9 +40,9 @@ public class TurnTokenGenerator {
this.turnSecret = turnSecret; this.turnSecret = turnSecret;
} }
public TurnToken generate(final String e164) { public TurnToken generate(final UUID aci) {
try { try {
final List<String> urls = urls(e164); final List<String> urls = urls(aci);
final Mac mac = Mac.getInstance(ALGORITHM); final Mac mac = Mac.getInstance(ALGORITHM);
final long validUntilSeconds = Instant.now().plus(Duration.ofDays(1)).getEpochSecond(); final long validUntilSeconds = Instant.now().plus(Duration.ofDays(1)).getEpochSecond();
final long user = Util.ensureNonNegativeInt(new SecureRandom().nextInt()); final long user = Util.ensureNonNegativeInt(new SecureRandom().nextInt());
@ -56,12 +57,12 @@ public class TurnTokenGenerator {
} }
} }
private List<String> urls(final String e164) { private List<String> urls(final UUID aci) {
final DynamicTurnConfiguration turnConfig = dynamicConfigurationManager.getConfiguration().getTurnConfiguration(); final DynamicTurnConfiguration turnConfig = dynamicConfigurationManager.getConfiguration().getTurnConfiguration();
// Check if number is enrolled to test out specific turn servers // Check if number is enrolled to test out specific turn servers
final Optional<TurnUriConfiguration> enrolled = turnConfig.getUriConfigs().stream() final Optional<TurnUriConfiguration> enrolled = turnConfig.getUriConfigs().stream()
.filter(config -> config.getEnrolledNumbers().contains(e164)) .filter(config -> config.getEnrolledAcis().contains(aci))
.findFirst(); .findFirst();
if (enrolled.isPresent()) { if (enrolled.isPresent()) {

View File

@ -6,6 +6,7 @@ import javax.validation.constraints.NotNull;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.UUID;
public class TurnUriConfiguration { public class TurnUriConfiguration {
@JsonProperty @JsonProperty
@ -22,7 +23,8 @@ public class TurnUriConfiguration {
/** /**
* Enrolled numbers will always get this uri list * Enrolled numbers will always get this uri list
*/ */
private Set<String> enrolledNumbers = Collections.emptySet(); @JsonProperty
private Set<UUID> enrolledAcis = Collections.emptySet();
public List<String> getUris() { public List<String> getUris() {
return uris; return uris;
@ -32,7 +34,7 @@ public class TurnUriConfiguration {
return weight; return weight;
} }
public Set<String> getEnrolledNumbers() { public Set<UUID> getEnrolledAcis() {
return Collections.unmodifiableSet(enrolledNumbers); return Collections.unmodifiableSet(enrolledAcis);
} }
} }

View File

@ -97,7 +97,7 @@ public class AccountController {
@Produces(MediaType.APPLICATION_JSON) @Produces(MediaType.APPLICATION_JSON)
public TurnToken getTurnToken(@Auth AuthenticatedAccount auth) throws RateLimitExceededException { public TurnToken getTurnToken(@Auth AuthenticatedAccount auth) throws RateLimitExceededException {
rateLimiters.getTurnLimiter().validate(auth.getAccount().getUuid()); rateLimiters.getTurnLimiter().validate(auth.getAccount().getUuid());
return turnTokenGenerator.generate(auth.getAccount().getNumber()); return turnTokenGenerator.generate(auth.getAccount().getUuid());
} }
@Timed @Timed

View File

@ -7,6 +7,7 @@ import org.whispersystems.textsecuregcm.storage.DynamicConfigurationManager;
import java.nio.charset.StandardCharsets; import java.nio.charset.StandardCharsets;
import java.util.Map; import java.util.Map;
import java.util.UUID;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
@ -46,7 +47,7 @@ public class TurnTokenGeneratorTest {
final long COUNT = 1000; final long COUNT = 1000;
final Map<String, Long> urlCounts = Stream final Map<String, Long> urlCounts = Stream
.generate(() -> turnTokenGenerator.generate("")) .generate(() -> turnTokenGenerator.generate(UUID.randomUUID()))
.limit(COUNT) .limit(COUNT)
.flatMap(token -> token.getUrls().stream()) .flatMap(token -> token.getUrls().stream())
.collect(Collectors.groupingBy(i -> i, Collectors.counting())); .collect(Collectors.groupingBy(i -> i, Collectors.counting()));
@ -87,7 +88,7 @@ public class TurnTokenGeneratorTest {
final long COUNT = 1000; final long COUNT = 1000;
final Map<String, Long> urlCounts = Stream final Map<String, Long> urlCounts = Stream
.generate(() -> turnTokenGenerator.generate("")) .generate(() -> turnTokenGenerator.generate(UUID.randomUUID()))
.limit(COUNT) .limit(COUNT)
.flatMap(token -> token.getUrls().stream()) .flatMap(token -> token.getUrls().stream())
.collect(Collectors.groupingBy(i -> i, Collectors.counting())); .collect(Collectors.groupingBy(i -> i, Collectors.counting()));
@ -108,8 +109,8 @@ public class TurnTokenGeneratorTest {
- uris: - uris:
- enrolled.org - enrolled.org
weight: 0 weight: 0
enrolledNumbers: enrolledAcis:
- +15555555555 - 732506d7-d04f-43a4-b1d7-8a3a91ebe8a6
- uris: - uris:
- unenrolled.org - unenrolled.org
weight: 1 weight: 1
@ -127,9 +128,9 @@ public class TurnTokenGeneratorTest {
final TurnTokenGenerator turnTokenGenerator = final TurnTokenGenerator turnTokenGenerator =
new TurnTokenGenerator(mockDynamicConfigManager, "bloop".getBytes(StandardCharsets.UTF_8)); new TurnTokenGenerator(mockDynamicConfigManager, "bloop".getBytes(StandardCharsets.UTF_8));
TurnToken token = turnTokenGenerator.generate("+15555555555"); TurnToken token = turnTokenGenerator.generate(UUID.fromString("732506d7-d04f-43a4-b1d7-8a3a91ebe8a6"));
assertThat(token.getUrls().get(0)).isEqualTo("enrolled.org"); assertThat(token.getUrls().get(0)).isEqualTo("enrolled.org");
token = turnTokenGenerator.generate("+15555555556"); token = turnTokenGenerator.generate(UUID.randomUUID());
assertThat(token.getUrls().get(0)).isEqualTo("unenrolled.org"); assertThat(token.getUrls().get(0)).isEqualTo("unenrolled.org");
} }

View File

@ -336,8 +336,8 @@ class DynamicConfigurationTest {
- uris: - uris:
- turn:test2.org - turn:test2.org
weight: 2 weight: 2
enrolledNumbers: enrolledAcis:
- +15555555555 - 732506d7-d04f-43a4-b1d7-8a3a91ebe8a6
"""); """);
DynamicTurnConfiguration turnConfiguration = DynamicConfigurationManager DynamicTurnConfiguration turnConfiguration = DynamicConfigurationManager
.parseConfiguration(config, DynamicConfiguration.class) .parseConfiguration(config, DynamicConfiguration.class)
@ -347,7 +347,8 @@ class DynamicConfigurationTest {
assertThat(turnConfiguration.getUriConfigs().get(1).getUris()).hasSize(1); assertThat(turnConfiguration.getUriConfigs().get(1).getUris()).hasSize(1);
assertThat(turnConfiguration.getUriConfigs().get(0).getWeight()).isEqualTo(1); assertThat(turnConfiguration.getUriConfigs().get(0).getWeight()).isEqualTo(1);
assertThat(turnConfiguration.getUriConfigs().get(1).getWeight()).isEqualTo(2); assertThat(turnConfiguration.getUriConfigs().get(1).getWeight()).isEqualTo(2);
assertThat(turnConfiguration.getUriConfigs().get(1).getEnrolledNumbers()).containsExactly("+15555555555"); assertThat(turnConfiguration.getUriConfigs().get(1).getEnrolledAcis())
.containsExactly(UUID.fromString("732506d7-d04f-43a4-b1d7-8a3a91ebe8a6"));
} }
} }