Store geospatial information with IpIntel documents, which can be accessed via GET /dumps/ipIntel(Formatted)
This commit is contained in:
parent
5c03e4aebf
commit
a3d1812b83
@ -220,7 +220,8 @@ public final class APIv3 extends AbstractVerticle {
|
||||
), (a, b) -> {
|
||||
});
|
||||
database.getCollection("ipIntel").createIndexes(ImmutableList.of(
|
||||
new IndexModel(new Document("hashedIp", 1))
|
||||
new IndexModel(new Document("hashedIp", 1)),
|
||||
new IndexModel(new Document("location", "2dsphere"))
|
||||
), (a, b) -> {
|
||||
});
|
||||
database.getCollection("punishments").createIndexes(ImmutableList.of(
|
||||
|
@ -11,7 +11,9 @@ import io.vertx.core.Future;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.maxmind.MaxMindLocation;
|
||||
import net.frozenorb.apiv3.maxmind.MaxMindResult;
|
||||
import net.frozenorb.apiv3.util.GeoJsonPoint;
|
||||
import net.frozenorb.apiv3.util.MaxMindUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import org.bson.Document;
|
||||
@ -30,6 +32,11 @@ public final class IpIntel {
|
||||
@Getter private String hashedIp;
|
||||
@Getter private Instant lastUpdatedAt;
|
||||
@Getter private MaxMindResult result;
|
||||
@Getter private GeoJsonPoint location;
|
||||
|
||||
public static void findAllNoSort(SingleResultCallback<List<IpIntel>> callback) {
|
||||
ipIntelCollection.find().into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public static void findAll(SingleResultCallback<List<IpIntel>> callback) {
|
||||
ipIntelCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
|
||||
@ -133,6 +140,11 @@ public final class IpIntel {
|
||||
this.hashedIp = Hashing.sha256().hashString(id + APIv3.getConfig().getProperty("ipHashing.salt"), Charsets.UTF_8).toString();
|
||||
this.lastUpdatedAt = Instant.now();
|
||||
this.result = result;
|
||||
|
||||
if (result.getLocation() != null) {
|
||||
MaxMindLocation location = result.getLocation();
|
||||
this.location = new GeoJsonPoint(location.getLongitude(), location.getLatitude());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -8,18 +8,24 @@ import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.model.Grant;
|
||||
import net.frozenorb.apiv3.model.IpBan;
|
||||
import net.frozenorb.apiv3.model.IpIntel;
|
||||
import net.frozenorb.apiv3.model.Punishment;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import net.frozenorb.apiv3.util.GeoJsonPoint;
|
||||
|
||||
import java.text.DecimalFormat;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public final class GETDumpsType implements Handler<RoutingContext> {
|
||||
|
||||
private static final DecimalFormat coordinateFormat = new DecimalFormat("#.#####");
|
||||
|
||||
private static List<UUID> banCache = ImmutableList.of();
|
||||
private static List<UUID> blacklistCache = ImmutableList.of();
|
||||
private static List<String> ipBanCache = ImmutableList.of();
|
||||
private static Map<String, List<UUID>> grantCache = ImmutableMap.of();
|
||||
private static Map<String, GeoJsonPoint> ipIntelCache = ImmutableMap.of();
|
||||
|
||||
static {
|
||||
APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(5), (id) -> updateCache());
|
||||
@ -98,6 +104,26 @@ public final class GETDumpsType implements Handler<RoutingContext> {
|
||||
|
||||
GETDumpsType.ipBanCache = ipBanCache;
|
||||
});
|
||||
|
||||
IpIntel.findAllNoSort((ipIntel, error) -> {
|
||||
if (error != null) {
|
||||
error.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
Map<String, GeoJsonPoint> ipIntelCache = new HashMap<>();
|
||||
|
||||
for (IpIntel intel : ipIntel) {
|
||||
GeoJsonPoint point = intel.getLocation();
|
||||
|
||||
if (point != null) {
|
||||
String key = coordinateFormat.format(point.getLongitude()) + ":" + coordinateFormat.format(point.getLatitude());
|
||||
ipIntelCache.put(key, point);
|
||||
}
|
||||
}
|
||||
|
||||
GETDumpsType.ipIntelCache = ipIntelCache;
|
||||
});
|
||||
}
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
@ -124,8 +150,26 @@ public final class GETDumpsType implements Handler<RoutingContext> {
|
||||
case "grant":
|
||||
APIv3.respondJson(ctx, 200, grantCache);
|
||||
return;
|
||||
case "ipintel":
|
||||
APIv3.respondJson(ctx, 200, ipIntelCache.values());
|
||||
return;
|
||||
case "ipintelformatted":
|
||||
List<Map<String, Object>> features = new ArrayList<>(ipIntelCache.size());
|
||||
|
||||
ipIntelCache.values().forEach(point -> {
|
||||
features.add(ImmutableMap.of(
|
||||
"type", "Feature",
|
||||
"geometry", point
|
||||
));
|
||||
});
|
||||
|
||||
APIv3.respondJson(ctx, 200, ImmutableMap.of(
|
||||
"type", "FeatureCollection",
|
||||
"features", features
|
||||
));
|
||||
return;
|
||||
default:
|
||||
ErrorUtils.respondInvalidInput(ctx, dumpType + " is not a valid type. Not in [ban, blacklist, accessDeniable, ipBan, grant]");
|
||||
ErrorUtils.respondInvalidInput(ctx, dumpType + " is not a valid type. Not in [ban, blacklist, accessDeniable, ipBan, grant, ipIntel, ipIntelFormatted]");
|
||||
}
|
||||
}
|
||||
|
||||
|
22
src/main/java/net/frozenorb/apiv3/util/GeoJsonPoint.java
Normal file
22
src/main/java/net/frozenorb/apiv3/util/GeoJsonPoint.java
Normal file
@ -0,0 +1,22 @@
|
||||
package net.frozenorb.apiv3.util;
|
||||
|
||||
public final class GeoJsonPoint {
|
||||
|
||||
private String type = "Point";
|
||||
private double[] coordinates;
|
||||
|
||||
private GeoJsonPoint() {} // For Jackson
|
||||
|
||||
public GeoJsonPoint(double longitude, double latitude) {
|
||||
this.coordinates = new double[] { longitude, latitude};
|
||||
}
|
||||
|
||||
public double getLongitude() {
|
||||
return coordinates[0];
|
||||
}
|
||||
|
||||
public double getLatitude() {
|
||||
return coordinates[1];
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user