0
0
mirror of https://github.com/signalapp/Signal-Server.git synced 2024-09-20 03:52:16 +02:00

Clean up prohibited username references

This commit is contained in:
Katherine Yen 2023-04-10 15:21:02 -07:00 committed by GitHub
parent 8847cb92ac
commit 61af1ba029
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 0 additions and 177 deletions

View File

@ -79,8 +79,6 @@ dynamoDbTables:
tableName: Example_RemoteConfig
reportMessage:
tableName: Example_ReportMessage
reservedUsernames:
tableName: Example_ReservedUsernames
subscriptions:
tableName: Example_Subscriptions
verificationSessions:

View File

@ -229,7 +229,6 @@ import org.whispersystems.textsecuregcm.workers.AssignUsernameCommand;
import org.whispersystems.textsecuregcm.workers.CertificateCommand;
import org.whispersystems.textsecuregcm.workers.CheckDynamicConfigurationCommand;
import org.whispersystems.textsecuregcm.workers.DeleteUserCommand;
import org.whispersystems.textsecuregcm.workers.ReserveUsernameCommand;
import org.whispersystems.textsecuregcm.workers.ServerVersionCommand;
import org.whispersystems.textsecuregcm.workers.SetCrawlerAccelerationTask;
import org.whispersystems.textsecuregcm.workers.SetRequestLoggingEnabledTask;
@ -259,7 +258,6 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
bootstrap.addCommand(new ServerVersionCommand());
bootstrap.addCommand(new CheckDynamicConfigurationCommand());
bootstrap.addCommand(new SetUserDiscoverabilityCommand());
bootstrap.addCommand(new ReserveUsernameCommand());
bootstrap.addCommand(new AssignUsernameCommand());
bootstrap.addCommand(new UnlinkDeviceCommand());
}

View File

@ -61,7 +61,6 @@ public class DynamoDbTables {
private final TableWithExpiration registrationRecovery;
private final Table remoteConfig;
private final Table reportMessage;
private final Table reservedUsernames;
private final Table subscriptions;
private final Table verificationSessions;
@ -81,7 +80,6 @@ public class DynamoDbTables {
@JsonProperty("registrationRecovery") final TableWithExpiration registrationRecovery,
@JsonProperty("remoteConfig") final Table remoteConfig,
@JsonProperty("reportMessage") final Table reportMessage,
@JsonProperty("reservedUsernames") final Table reservedUsernames,
@JsonProperty("subscriptions") final Table subscriptions,
@JsonProperty("verificationSessions") final Table verificationSessions) {
@ -100,7 +98,6 @@ public class DynamoDbTables {
this.registrationRecovery = registrationRecovery;
this.remoteConfig = remoteConfig;
this.reportMessage = reportMessage;
this.reservedUsernames = reservedUsernames;
this.subscriptions = subscriptions;
this.verificationSessions = verificationSessions;
}
@ -195,12 +192,6 @@ public class DynamoDbTables {
return reportMessage;
}
@NotNull
@Valid
public Table getReservedUsernames() {
return reservedUsernames;
}
@NotNull
@Valid
public Table getSubscriptions() {

View File

@ -1,97 +0,0 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.storage;
import static org.whispersystems.textsecuregcm.metrics.MetricsUtil.name;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import io.micrometer.core.instrument.Metrics;
import io.micrometer.core.instrument.Timer;
import java.util.Map;
import java.util.UUID;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.whispersystems.textsecuregcm.util.AttributeValues;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import software.amazon.awssdk.services.dynamodb.model.AttributeValue;
import software.amazon.awssdk.services.dynamodb.model.PutItemRequest;
import software.amazon.awssdk.services.dynamodb.model.ScanRequest;
import software.amazon.awssdk.services.dynamodb.model.ScanResponse;
import software.amazon.awssdk.services.dynamodb.paginators.ScanIterable;
public class ProhibitedUsernames {
private final DynamoDbClient dynamoDbClient;
private final String tableName;
private final LoadingCache<String, Pattern> patternCache = CacheBuilder.newBuilder()
.maximumSize(1_000)
.build(new CacheLoader<>() {
@Override
public Pattern load(final String s) {
return Pattern.compile(s, Pattern.CASE_INSENSITIVE);
}
});
@VisibleForTesting
static final String KEY_PATTERN = "P";
private static final String ATTR_RESERVED_FOR_UUID = "U";
private static final Timer IS_PROHIBITED_TIMER = Metrics.timer(name(ProhibitedUsernames.class, "isProhibited"));
private static final Logger log = LoggerFactory.getLogger(ProhibitedUsernames.class);
public ProhibitedUsernames(final DynamoDbClient dynamoDbClient, final String tableName) {
this.dynamoDbClient = dynamoDbClient;
this.tableName = tableName;
}
public boolean isProhibited(final String nickname, final UUID accountIdentifier) {
return IS_PROHIBITED_TIMER.record(() -> {
final ScanIterable scanIterable = dynamoDbClient.scanPaginator(ScanRequest.builder()
.tableName(tableName)
.build());
for (final ScanResponse scanResponse : scanIterable) {
if (scanResponse.hasItems()) {
for (final Map<String, AttributeValue> item : scanResponse.items()) {
try {
final Pattern pattern = patternCache.get(item.get(KEY_PATTERN).s());
final UUID reservedFor = AttributeValues.getUUID(item, ATTR_RESERVED_FOR_UUID, null);
if (pattern.matcher(nickname).matches() && !accountIdentifier.equals(reservedFor)) {
return true;
}
} catch (final Exception e) {
log.error("Failed to load pattern from item: {}", item, e);
}
}
}
}
return false;
});
}
/**
* Prohibits username except for all accounts except `reservedFor`
*
* @param pattern pattern to prohibit
* @param reservedFor an account that is allowed to use names in the pattern
*/
public void prohibitUsername(final String pattern, final UUID reservedFor) {
dynamoDbClient.putItem(PutItemRequest.builder()
.tableName(tableName)
.item(Map.of(
KEY_PATTERN, AttributeValues.fromString(pattern),
ATTR_RESERVED_FOR_UUID, AttributeValues.fromUUID(reservedFor)))
.build());
}
}

View File

@ -50,7 +50,6 @@ import org.whispersystems.textsecuregcm.storage.MessagesManager;
import org.whispersystems.textsecuregcm.storage.PhoneNumberIdentifiers;
import org.whispersystems.textsecuregcm.storage.Profiles;
import org.whispersystems.textsecuregcm.storage.ProfilesManager;
import org.whispersystems.textsecuregcm.storage.ProhibitedUsernames;
import org.whispersystems.textsecuregcm.storage.RegistrationRecoveryPasswords;
import org.whispersystems.textsecuregcm.storage.RegistrationRecoveryPasswordsManager;
import org.whispersystems.textsecuregcm.storage.ReportMessageDynamoDb;
@ -176,8 +175,6 @@ public class AssignUsernameCommand extends EnvironmentCommand<WhisperServerConfi
configuration.getDynamoDbTables().getPhoneNumberIdentifiers().getTableName());
Profiles profiles = new Profiles(dynamoDbClient, dynamoDbAsyncClient,
configuration.getDynamoDbTables().getProfiles().getTableName());
ProhibitedUsernames prohibitedUsernames = new ProhibitedUsernames(dynamoDbClient,
configuration.getDynamoDbTables().getReservedUsernames().getTableName());
Keys keys = new Keys(dynamoDbClient,
configuration.getDynamoDbTables().getKeys().getTableName());
MessagesDynamoDb messagesDynamoDb = new MessagesDynamoDb(dynamoDbClient, dynamoDbAsyncClient,

View File

@ -1,64 +0,0 @@
/*
* Copyright 2013-2021 Signal Messenger, LLC
* SPDX-License-Identifier: AGPL-3.0-only
*/
package org.whispersystems.textsecuregcm.workers;
import io.dropwizard.cli.ConfiguredCommand;
import io.dropwizard.setup.Bootstrap;
import net.sourceforge.argparse4j.inf.Namespace;
import net.sourceforge.argparse4j.inf.Subparser;
import org.whispersystems.textsecuregcm.WhisperServerConfiguration;
import org.whispersystems.textsecuregcm.storage.ProhibitedUsernames;
import org.whispersystems.textsecuregcm.util.DynamoDbFromConfig;
import software.amazon.awssdk.services.dynamodb.DynamoDbClient;
import java.util.UUID;
import java.util.regex.Pattern;
public class ReserveUsernameCommand extends ConfiguredCommand<WhisperServerConfiguration> {
public ReserveUsernameCommand() {
super("reserve-username", "Reserve a username pattern for a specific account identifier");
}
@Override
public void configure(final Subparser subparser) {
super.configure(subparser);
subparser.addArgument("-p", "--pattern")
.dest("pattern")
.type(String.class)
.required(true);
subparser.addArgument("-u", "--uuid")
.dest("uuid")
.type(String.class)
.required(true);
}
@Override
protected void run(final Bootstrap<WhisperServerConfiguration> bootstrap, final Namespace namespace,
final WhisperServerConfiguration config) throws Exception {
final DynamoDbClient dynamoDbClient = DynamoDbFromConfig.client(config.getDynamoDbClientConfiguration(),
software.amazon.awssdk.auth.credentials.InstanceProfileCredentialsProvider.create());
final ProhibitedUsernames prohibitedUsernames = new ProhibitedUsernames(dynamoDbClient,
config.getDynamoDbTables().getReservedUsernames().getTableName());
final String pattern = namespace.getString("pattern").trim();
try {
Pattern.compile(pattern);
} catch (final Exception e) {
throw new IllegalArgumentException("Bad pattern: " + pattern, e);
}
final UUID aci = UUID.fromString(namespace.getString("uuid").trim());
prohibitedUsernames.prohibitUsername(pattern, aci);
System.out.format("Reserved %s for account %s\n", pattern, aci);
}
}