package org.whispersystems.textsecuregcm.workers; import com.fasterxml.jackson.databind.DeserializationFeature; import com.google.common.base.Optional; import net.sourceforge.argparse4j.inf.Namespace; import net.sourceforge.argparse4j.inf.Subparser; import org.skife.jdbi.v2.DBI; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.whispersystems.textsecuregcm.WhisperServerConfiguration; import org.whispersystems.textsecuregcm.auth.AuthenticationCredentials; import org.whispersystems.textsecuregcm.providers.RedisClientFactory; import org.whispersystems.textsecuregcm.storage.Account; import org.whispersystems.textsecuregcm.storage.Accounts; import org.whispersystems.textsecuregcm.storage.AccountsManager; import org.whispersystems.textsecuregcm.storage.Device; import org.whispersystems.textsecuregcm.storage.DirectoryManager; import org.whispersystems.textsecuregcm.util.Base64; import java.security.SecureRandom; import io.dropwizard.Application; import io.dropwizard.cli.EnvironmentCommand; import io.dropwizard.db.DataSourceFactory; import io.dropwizard.jdbi.ImmutableListContainerFactory; import io.dropwizard.jdbi.ImmutableSetContainerFactory; import io.dropwizard.jdbi.OptionalContainerFactory; import io.dropwizard.jdbi.args.OptionalArgumentFactory; import io.dropwizard.setup.Environment; import redis.clients.jedis.JedisPool; public class DeleteUserCommand extends EnvironmentCommand<WhisperServerConfiguration> { private final Logger logger = LoggerFactory.getLogger(DirectoryCommand.class); public DeleteUserCommand() { super(new Application<WhisperServerConfiguration>() { @Override public void run(WhisperServerConfiguration configuration, Environment environment) throws Exception { } }, "rmuser", "remove user"); } @Override public void configure(Subparser subparser) { super.configure(subparser); subparser.addArgument("-u", "--user") .dest("user") .type(String.class) .required(true) .help("The user to remove"); } @Override protected void run(Environment environment, Namespace namespace, WhisperServerConfiguration configuration) throws Exception { try { String[] users = namespace.getString("user").split(","); environment.getObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); DataSourceFactory dbConfig = configuration.getDataSourceFactory(); DBI dbi = new DBI(dbConfig.getUrl(), dbConfig.getUser(), dbConfig.getPassword()); dbi.registerArgumentFactory(new OptionalArgumentFactory(dbConfig.getDriverClass())); dbi.registerContainerFactory(new ImmutableListContainerFactory()); dbi.registerContainerFactory(new ImmutableSetContainerFactory()); dbi.registerContainerFactory(new OptionalContainerFactory()); Accounts accounts = dbi.onDemand(Accounts.class); JedisPool cacheClient = new RedisClientFactory(configuration.getCacheConfiguration().getUrl()).getRedisClientPool(); JedisPool redisClient = new RedisClientFactory(configuration.getDirectoryConfiguration().getUrl()).getRedisClientPool(); DirectoryManager directory = new DirectoryManager(redisClient); AccountsManager accountsManager = new AccountsManager(accounts, directory, cacheClient); for (String user: users) { Optional<Account> account = accountsManager.get(user); if (account.isPresent()) { Optional<Device> device = account.get().getDevice(1); if (device.isPresent()) { byte[] random = new byte[16]; new SecureRandom().nextBytes(random); device.get().setGcmId(null); device.get().setFetchesMessages(false); device.get().setAuthenticationCredentials(new AuthenticationCredentials(Base64.encodeBytes(random))); accountsManager.update(account.get()); logger.warn("Removed " + account.get().getNumber()); } else { logger.warn("No primary device found..."); } } else { logger.warn("Account not found..."); } } } catch (Exception ex) { logger.warn("Removal Exception", ex); throw new RuntimeException(ex); } } }