Fix logins not saving users, ip intel in heartbeats

This commit is contained in:
Colin McDonald 2016-07-02 17:39:30 -04:00
parent adb16d8c8d
commit 77c3e49048
3 changed files with 93 additions and 18 deletions

View File

@ -4,6 +4,8 @@ import com.mongodb.async.SingleResultCallback;
import com.mongodb.async.client.MongoCollection;
import fr.javatic.mongo.jacksonCodec.Entity;
import fr.javatic.mongo.jacksonCodec.objectId.Id;
import io.vertx.core.CompositeFuture;
import io.vertx.core.Future;
import lombok.AllArgsConstructor;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
@ -12,8 +14,8 @@ import net.frozenorb.apiv3.util.MaxMindUtils;
import org.bson.Document;
import java.time.Instant;
import java.util.LinkedList;
import java.util.List;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
@Entity
@AllArgsConstructor
@ -59,6 +61,58 @@ public final class IpIntel {
});
}
public static void findOrCreateByIdGrouped(Collection<String> search, SingleResultCallback<Map<String, IpIntel>> callback) {
ipIntelCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (existingIntel, error) -> {
if (error != null) {
callback.onResult(null, error);
return;
}
Map<String, IpIntel> result = new ConcurrentHashMap<>();
for (IpIntel ipIntel : existingIntel) {
result.put(ipIntel.getId(), ipIntel);
}
List<Future> createNewIntelFutures = new ArrayList<>();
search.forEach((ip) -> {
if (result.containsKey(ip)) {
return;
}
Future createNewIntelFuture = Future.future();
createNewIntelFutures.add(createNewIntelFuture);
MaxMindUtils.getInsights(ip, (maxMindResult, error2) -> {
if (error2 != null) {
createNewIntelFuture.fail(error2);
return;
}
IpIntel newIpIntel = new IpIntel(ip, maxMindResult);
ipIntelCollection.insertOne(newIpIntel, (ignored, error3) -> {
if (error3 != null) {
createNewIntelFuture.fail(error3);
} else {
result.put(ip, newIpIntel);
createNewIntelFuture.complete();
}
});
});
});
CompositeFuture.all(createNewIntelFutures).setHandler((creationStatus) -> {
if (creationStatus.failed()) {
callback.onResult(null, creationStatus.cause());
} else {
callback.onResult(result, null);
}
});
});
}
private IpIntel() {} // For Jackson
private IpIntel(String ip, MaxMindResult result) {

View File

@ -37,11 +37,13 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
Server actorServer = Server.findById(actor.getName());
ServerGroup actorServerGroup = ServerGroup.findById(actorServer.getServerGroup());
JsonObject requestBody = ctx.getBodyAsJson();
Map<UUID, String> playerNames = extractPlayerNames(requestBody.getJsonObject("players"));
JsonObject players = requestBody.getJsonObject("players");
Map<UUID, String> playerNames = extractPlayerNames(players);
Map<UUID, String> playerIps = extractPlayerIps(players);
CompositeFuture.all(
createInfoResponse(actorServer, requestBody.getDouble("lastTps"), playerNames),
createPlayerResponse(actorServer, playerNames),
createPlayerResponse(actorServer, playerNames, playerIps),
createPermissionsResponse(actorServerGroup),
createEventsResponse(requestBody.getJsonArray("events"))
).setHandler((result) -> {
@ -74,19 +76,22 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
return callback;
}
private Future<Map<String, Object>> createPlayerResponse(Server server, Map<UUID, String> playerNames) {
private Future<Map<String, Object>> createPlayerResponse(Server server, Map<UUID, String> playerNames, Map<UUID, String> playerIps) {
Future<Map<String, Object>> callback = Future.future();
Future<Map<UUID, User>> userLookupCallback = Future.future();
Future<Map<String, IpIntel>> ipIntelCallback = Future.future();
Future<Map<UUID, List<Grant>>> grantLookupCallback = Future.future();
Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future();
User.findOrCreateByIdGrouped(playerNames, new MongoToVertxCallback<>(userLookupCallback));
IpIntel.findOrCreateByIdGrouped(playerIps.values(), new MongoToVertxCallback<>(ipIntelCallback));
Grant.findByUserGrouped(playerNames.keySet(), new MongoToVertxCallback<>(grantLookupCallback));
Punishment.findByUserGrouped(playerNames.keySet(), new MongoToVertxCallback<>(punishmentLookupCallback));
CompositeFuture.all(
userLookupCallback,
ipIntelCallback,
grantLookupCallback,
punishmentLookupCallback
).setHandler((batchLookupInfo) -> {
@ -96,13 +101,14 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
}
Map<UUID, User> users = batchLookupInfo.result().result(0);
Map<UUID, List<Grant>> grants = batchLookupInfo.result().result(1);
Map<UUID, List<Punishment>> punishments = batchLookupInfo.result().result(2);
Map<String, IpIntel> ipIntel = batchLookupInfo.result().result(1);
Map<UUID, List<Grant>> grants = batchLookupInfo.result().result(2);
Map<UUID, List<Punishment>> punishments = batchLookupInfo.result().result(3);
Map<UUID, Future> loginInfoFutures = new HashMap<>();
users.forEach((uuid, user) -> {
Future<Map<String, Object>> loginInfoFuture = Future.future();
createLoginInfo(user, server, grants.get(uuid), punishments.get(uuid), loginInfoFuture);
createLoginInfo(user, server, ipIntel.get(playerIps.get(uuid)), grants.get(uuid), punishments.get(uuid), loginInfoFuture);
loginInfoFutures.put(uuid, loginInfoFuture);
});
@ -170,7 +176,22 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
return result;
}
private void createLoginInfo(User user, Server server, List<Grant> grants, List<Punishment> punishments, Future<Map<String, Object>> callback) {
private Map<UUID, String> extractPlayerIps(JsonObject players) {
Map<UUID, String> result = new HashMap<>();
players.forEach((entry) -> {
UUID uuid = UUID.fromString(entry.getKey());
JsonObject data = (JsonObject) entry.getValue();
if (UuidUtils.isAcceptableUuid(uuid)) {
result.put(uuid, data.getString("userIp"));
}
});
return result;
}
private void createLoginInfo(User user, Server server, IpIntel ipIntel, List<Grant> grants, List<Punishment> punishments, Future<Map<String, Object>> callback) {
if (user.seenOnServer(server)) {
user.save((ignored, error) -> {
if (error != null) {
@ -178,11 +199,10 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
return;
}
// TODO: IP BAN INFO (AND FOR LINE BELOW)
user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
user.getLoginInfo(server, ipIntel, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
});
} else {
user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
user.getLoginInfo(server, ipIntel, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
}
}

View File

@ -31,7 +31,7 @@ public final class POSTUsersIdLogin implements Handler<RoutingContext> {
BlockingCallback<User> userCallback = new BlockingCallback<>();
User.findById(uuid, userCallback);
User user = userCallback.get();
String username = requestBody.getString("username");
String currentUsername = requestBody.getString("username");
String userIp = requestBody.getString("userIp");
Actor actor = ctx.get("actor");
@ -48,12 +48,12 @@ public final class POSTUsersIdLogin implements Handler<RoutingContext> {
}
if (user == null) {
user = new User(uuid, username);
user = new User(uuid, currentUsername);
BlockingCallback<Void> nameCollisionCallback = new BlockingCallback<>();
user.checkNameCollisions(nameCollisionCallback);
nameCollisionCallback.get();
BlockingCallback<Void> insertCallback = new BlockingCallback<>();
user.checkNameCollisions(insertCallback);
user.insert(insertCallback);
insertCallback.get();
}
@ -76,14 +76,15 @@ public final class POSTUsersIdLogin implements Handler<RoutingContext> {
callback.get();
}
if (!username.equals(user.getLastUsername())) {
String lastUsername = user.getLastUsername();
user.updateUsername(currentUsername);
if (!currentUsername.equals(lastUsername)) {
BlockingCallback<Void> callback = new BlockingCallback<>();
user.checkNameCollisions(callback);
callback.get();
}
user.updateUsername(username);
user.getLoginInfo(actorServer, userIp, (loginInfo, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);