Fix logins not saving users, ip intel in heartbeats
This commit is contained in:
parent
adb16d8c8d
commit
77c3e49048
@ -4,6 +4,8 @@ import com.mongodb.async.SingleResultCallback;
|
|||||||
import com.mongodb.async.client.MongoCollection;
|
import com.mongodb.async.client.MongoCollection;
|
||||||
import fr.javatic.mongo.jacksonCodec.Entity;
|
import fr.javatic.mongo.jacksonCodec.Entity;
|
||||||
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
||||||
|
import io.vertx.core.CompositeFuture;
|
||||||
|
import io.vertx.core.Future;
|
||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
@ -12,8 +14,8 @@ import net.frozenorb.apiv3.util.MaxMindUtils;
|
|||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.LinkedList;
|
import java.util.*;
|
||||||
import java.util.List;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@AllArgsConstructor
|
@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() {} // For Jackson
|
||||||
|
|
||||||
private IpIntel(String ip, MaxMindResult result) {
|
private IpIntel(String ip, MaxMindResult result) {
|
||||||
|
@ -37,11 +37,13 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
Server actorServer = Server.findById(actor.getName());
|
Server actorServer = Server.findById(actor.getName());
|
||||||
ServerGroup actorServerGroup = ServerGroup.findById(actorServer.getServerGroup());
|
ServerGroup actorServerGroup = ServerGroup.findById(actorServer.getServerGroup());
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
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(
|
CompositeFuture.all(
|
||||||
createInfoResponse(actorServer, requestBody.getDouble("lastTps"), playerNames),
|
createInfoResponse(actorServer, requestBody.getDouble("lastTps"), playerNames),
|
||||||
createPlayerResponse(actorServer, playerNames),
|
createPlayerResponse(actorServer, playerNames, playerIps),
|
||||||
createPermissionsResponse(actorServerGroup),
|
createPermissionsResponse(actorServerGroup),
|
||||||
createEventsResponse(requestBody.getJsonArray("events"))
|
createEventsResponse(requestBody.getJsonArray("events"))
|
||||||
).setHandler((result) -> {
|
).setHandler((result) -> {
|
||||||
@ -74,19 +76,22 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
return callback;
|
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<String, Object>> callback = Future.future();
|
||||||
|
|
||||||
Future<Map<UUID, User>> userLookupCallback = 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<Grant>>> grantLookupCallback = Future.future();
|
||||||
Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future();
|
Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future();
|
||||||
|
|
||||||
User.findOrCreateByIdGrouped(playerNames, new MongoToVertxCallback<>(userLookupCallback));
|
User.findOrCreateByIdGrouped(playerNames, new MongoToVertxCallback<>(userLookupCallback));
|
||||||
|
IpIntel.findOrCreateByIdGrouped(playerIps.values(), new MongoToVertxCallback<>(ipIntelCallback));
|
||||||
Grant.findByUserGrouped(playerNames.keySet(), new MongoToVertxCallback<>(grantLookupCallback));
|
Grant.findByUserGrouped(playerNames.keySet(), new MongoToVertxCallback<>(grantLookupCallback));
|
||||||
Punishment.findByUserGrouped(playerNames.keySet(), new MongoToVertxCallback<>(punishmentLookupCallback));
|
Punishment.findByUserGrouped(playerNames.keySet(), new MongoToVertxCallback<>(punishmentLookupCallback));
|
||||||
|
|
||||||
CompositeFuture.all(
|
CompositeFuture.all(
|
||||||
userLookupCallback,
|
userLookupCallback,
|
||||||
|
ipIntelCallback,
|
||||||
grantLookupCallback,
|
grantLookupCallback,
|
||||||
punishmentLookupCallback
|
punishmentLookupCallback
|
||||||
).setHandler((batchLookupInfo) -> {
|
).setHandler((batchLookupInfo) -> {
|
||||||
@ -96,13 +101,14 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Map<UUID, User> users = batchLookupInfo.result().result(0);
|
Map<UUID, User> users = batchLookupInfo.result().result(0);
|
||||||
Map<UUID, List<Grant>> grants = batchLookupInfo.result().result(1);
|
Map<String, IpIntel> ipIntel = batchLookupInfo.result().result(1);
|
||||||
Map<UUID, List<Punishment>> punishments = batchLookupInfo.result().result(2);
|
Map<UUID, List<Grant>> grants = batchLookupInfo.result().result(2);
|
||||||
|
Map<UUID, List<Punishment>> punishments = batchLookupInfo.result().result(3);
|
||||||
Map<UUID, Future> loginInfoFutures = new HashMap<>();
|
Map<UUID, Future> loginInfoFutures = new HashMap<>();
|
||||||
|
|
||||||
users.forEach((uuid, user) -> {
|
users.forEach((uuid, user) -> {
|
||||||
Future<Map<String, Object>> loginInfoFuture = Future.future();
|
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);
|
loginInfoFutures.put(uuid, loginInfoFuture);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -170,7 +176,22 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
return result;
|
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)) {
|
if (user.seenOnServer(server)) {
|
||||||
user.save((ignored, error) -> {
|
user.save((ignored, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
@ -178,11 +199,10 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: IP BAN INFO (AND FOR LINE BELOW)
|
user.getLoginInfo(server, ipIntel, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
|
||||||
user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
user.getLoginInfo(server, null, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
|
user.getLoginInfo(server, ipIntel, punishments, ImmutableList.of(), grants, new MongoToVertxCallback<>(callback));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,7 +31,7 @@ public final class POSTUsersIdLogin implements Handler<RoutingContext> {
|
|||||||
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
User.findById(uuid, userCallback);
|
User.findById(uuid, userCallback);
|
||||||
User user = userCallback.get();
|
User user = userCallback.get();
|
||||||
String username = requestBody.getString("username");
|
String currentUsername = requestBody.getString("username");
|
||||||
String userIp = requestBody.getString("userIp");
|
String userIp = requestBody.getString("userIp");
|
||||||
Actor actor = ctx.get("actor");
|
Actor actor = ctx.get("actor");
|
||||||
|
|
||||||
@ -48,12 +48,12 @@ public final class POSTUsersIdLogin implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = new User(uuid, username);
|
user = new User(uuid, currentUsername);
|
||||||
BlockingCallback<Void> nameCollisionCallback = new BlockingCallback<>();
|
BlockingCallback<Void> nameCollisionCallback = new BlockingCallback<>();
|
||||||
user.checkNameCollisions(nameCollisionCallback);
|
user.checkNameCollisions(nameCollisionCallback);
|
||||||
nameCollisionCallback.get();
|
nameCollisionCallback.get();
|
||||||
BlockingCallback<Void> insertCallback = new BlockingCallback<>();
|
BlockingCallback<Void> insertCallback = new BlockingCallback<>();
|
||||||
user.checkNameCollisions(insertCallback);
|
user.insert(insertCallback);
|
||||||
insertCallback.get();
|
insertCallback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,14 +76,15 @@ public final class POSTUsersIdLogin implements Handler<RoutingContext> {
|
|||||||
callback.get();
|
callback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!username.equals(user.getLastUsername())) {
|
String lastUsername = user.getLastUsername();
|
||||||
|
user.updateUsername(currentUsername);
|
||||||
|
|
||||||
|
if (!currentUsername.equals(lastUsername)) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
user.checkNameCollisions(callback);
|
user.checkNameCollisions(callback);
|
||||||
callback.get();
|
callback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
user.updateUsername(username);
|
|
||||||
|
|
||||||
user.getLoginInfo(actorServer, userIp, (loginInfo, error) -> {
|
user.getLoginInfo(actorServer, userIp, (loginInfo, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
ErrorUtils.respondInternalError(ctx, error);
|
ErrorUtils.respondInternalError(ctx, error);
|
||||||
|
Loading…
Reference in New Issue
Block a user