Clean up prohibited username references
This commit is contained in:
parent
8847cb92ac
commit
61af1ba029
|
@ -79,8 +79,6 @@ dynamoDbTables:
|
|||
tableName: Example_RemoteConfig
|
||||
reportMessage:
|
||||
tableName: Example_ReportMessage
|
||||
reservedUsernames:
|
||||
tableName: Example_ReservedUsernames
|
||||
subscriptions:
|
||||
tableName: Example_Subscriptions
|
||||
verificationSessions:
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue