mirror of
https://github.com/signalapp/Signal-Server
synced 2026-04-20 07:08:05 +01:00
Username reservation table
This commit is contained in:
@@ -157,13 +157,14 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
FaultTolerantDatabase messageDatabase = new FaultTolerantDatabase("message_database", messageJdbi, config.getMessageStoreConfiguration().getCircuitBreakerConfiguration());
|
||||
FaultTolerantDatabase abuseDatabase = new FaultTolerantDatabase("abuse_database", abuseJdbi, config.getAbuseDatabaseConfiguration().getCircuitBreakerConfiguration());
|
||||
|
||||
Accounts accounts = new Accounts(accountDatabase);
|
||||
PendingAccounts pendingAccounts = new PendingAccounts(accountDatabase);
|
||||
PendingDevices pendingDevices = new PendingDevices(accountDatabase);
|
||||
Usernames usernames = new Usernames(accountDatabase);
|
||||
Keys keys = new Keys(keysDatabase);
|
||||
Messages messages = new Messages(messageDatabase);
|
||||
AbusiveHostRules abusiveHostRules = new AbusiveHostRules(abuseDatabase);
|
||||
Accounts accounts = new Accounts(accountDatabase);
|
||||
PendingAccounts pendingAccounts = new PendingAccounts(accountDatabase);
|
||||
PendingDevices pendingDevices = new PendingDevices (accountDatabase);
|
||||
Usernames usernames = new Usernames(accountDatabase);
|
||||
ReservedUsernames reservedUsernames = new ReservedUsernames(accountDatabase);
|
||||
Keys keys = new Keys(keysDatabase);
|
||||
Messages messages = new Messages(messageDatabase);
|
||||
AbusiveHostRules abusiveHostRules = new AbusiveHostRules(abuseDatabase);
|
||||
|
||||
RedisClientFactory cacheClientFactory = new RedisClientFactory("main_cache", config.getCacheConfiguration().getUrl(), config.getCacheConfiguration().getReplicaUrls(), config.getCacheConfiguration().getCircuitBreakerConfiguration());
|
||||
RedisClientFactory directoryClientFactory = new RedisClientFactory("directory_cache", config.getDirectoryConfiguration().getRedisConfiguration().getUrl(), config.getDirectoryConfiguration().getRedisConfiguration().getReplicaUrls(), config.getDirectoryConfiguration().getRedisConfiguration().getCircuitBreakerConfiguration());
|
||||
@@ -180,7 +181,7 @@ public class WhisperServerService extends Application<WhisperServerConfiguration
|
||||
PendingAccountsManager pendingAccountsManager = new PendingAccountsManager(pendingAccounts, cacheClient);
|
||||
PendingDevicesManager pendingDevicesManager = new PendingDevicesManager (pendingDevices, cacheClient );
|
||||
AccountsManager accountsManager = new AccountsManager(accounts, directory, cacheClient);
|
||||
UsernamesManager usernamesManager = new UsernamesManager(usernames, cacheClient);
|
||||
UsernamesManager usernamesManager = new UsernamesManager(usernames, reservedUsernames, cacheClient);
|
||||
MessagesCache messagesCache = new MessagesCache(messagesClient, messages, accountsManager, config.getMessageCacheConfiguration().getPersistDelayMinutes());
|
||||
MessagesManager messagesManager = new MessagesManager(messages, messagesCache);
|
||||
DeadLetterHandler deadLetterHandler = new DeadLetterHandler(messagesManager);
|
||||
|
||||
@@ -0,0 +1,53 @@
|
||||
package org.whispersystems.textsecuregcm.storage;
|
||||
|
||||
import com.codahale.metrics.MetricRegistry;
|
||||
import com.codahale.metrics.SharedMetricRegistries;
|
||||
import com.codahale.metrics.Timer;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import org.whispersystems.textsecuregcm.util.Constants;
|
||||
|
||||
import java.util.Optional;
|
||||
import java.util.UUID;
|
||||
|
||||
import static com.codahale.metrics.MetricRegistry.name;
|
||||
|
||||
public class ReservedUsernames {
|
||||
|
||||
public static final String ID = "id";
|
||||
public static final String UID = "uuid";
|
||||
public static final String USERNAME = "username";
|
||||
|
||||
private final MetricRegistry metricRegistry = SharedMetricRegistries.getOrCreate(Constants.METRICS_NAME);
|
||||
private final Timer queryTimer = metricRegistry.timer(name(ReservedUsernames.class, "query"));
|
||||
|
||||
private final FaultTolerantDatabase database;
|
||||
|
||||
public ReservedUsernames(FaultTolerantDatabase database) {
|
||||
this.database = database;
|
||||
}
|
||||
|
||||
public boolean isReserved(String username, UUID uuid) {
|
||||
return database.with(jdbi -> jdbi.withHandle(handle -> {
|
||||
try (Timer.Context ignored = queryTimer.time()) {
|
||||
Optional<Integer> reservations = handle.createQuery("SELECT COUNT(*) FROM reserved_usernames WHERE " + UID + " != :uuid AND :username ~* " + USERNAME)
|
||||
.bind("username", username)
|
||||
.bind("uuid", uuid)
|
||||
.mapTo(Integer.class)
|
||||
.findFirst();
|
||||
|
||||
return reservations.isPresent() && reservations.get() > 0;
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
public void setReserved(String username, UUID reservedFor) {
|
||||
database.use(jdbi -> jdbi.useHandle(handle -> {
|
||||
handle.createUpdate("INSERT INTO reserved_usernames (" + USERNAME + ", " + UID + ") VALUES(:username, :uuid)")
|
||||
.bind("username", username)
|
||||
.bind("uuid", reservedFor)
|
||||
.execute();
|
||||
}));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -30,15 +30,21 @@ public class UsernamesManager {
|
||||
private final Logger logger = LoggerFactory.getLogger(AccountsManager.class);
|
||||
|
||||
private final Usernames usernames;
|
||||
private final ReservedUsernames reservedUsernames;
|
||||
private final ReplicatedJedisPool cacheClient;
|
||||
|
||||
public UsernamesManager(Usernames usernames, ReplicatedJedisPool cacheClient) {
|
||||
this.usernames = usernames;
|
||||
this.cacheClient = cacheClient;
|
||||
public UsernamesManager(Usernames usernames, ReservedUsernames reservedUsernames, ReplicatedJedisPool cacheClient) {
|
||||
this.usernames = usernames;
|
||||
this.reservedUsernames = reservedUsernames;
|
||||
this.cacheClient = cacheClient;
|
||||
}
|
||||
|
||||
public boolean put(UUID uuid, String username) {
|
||||
try (Timer.Context ignored = createTimer.time()) {
|
||||
if (reservedUsernames.isReserved(username, uuid)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (databasePut(uuid, username)) {
|
||||
redisSet(uuid, username);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user