Fix some stuff for Velt
This commit is contained in:
parent
276564f21f
commit
408124f5cd
@ -1,20 +1,5 @@
|
|||||||
package net.frozenorb.apiv3.domain;
|
package net.frozenorb.apiv3.domain;
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
import com.google.common.hash.Hashing;
|
|
||||||
|
|
||||||
import com.mongodb.async.SingleResultCallback;
|
|
||||||
import com.mongodb.async.client.MongoCollection;
|
|
||||||
import com.mongodb.async.client.MongoDatabase;
|
|
||||||
|
|
||||||
import net.frozenorb.apiv3.service.geoip.GeoIpInfo;
|
|
||||||
import net.frozenorb.apiv3.service.geoip.GeoIpService;
|
|
||||||
import net.frozenorb.apiv3.util.GeoJsonPoint;
|
|
||||||
import net.frozenorb.apiv3.util.SpringUtils;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
|
|
||||||
import org.bson.Document;
|
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
@ -23,6 +8,14 @@ import java.util.List;
|
|||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.concurrent.ConcurrentHashMap;
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.bson.Document;
|
||||||
|
|
||||||
|
import com.google.common.base.Charsets;
|
||||||
|
import com.google.common.hash.Hashing;
|
||||||
|
import com.mongodb.async.SingleResultCallback;
|
||||||
|
import com.mongodb.async.client.MongoCollection;
|
||||||
|
import com.mongodb.async.client.MongoDatabase;
|
||||||
|
|
||||||
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.CompositeFuture;
|
||||||
@ -30,6 +23,10 @@ import io.vertx.core.Future;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
|
import net.frozenorb.apiv3.service.geoip.GeoIpInfo;
|
||||||
|
import net.frozenorb.apiv3.util.GeoJsonPoint;
|
||||||
|
import net.frozenorb.apiv3.util.SpringUtils;
|
||||||
|
import net.frozenorb.apiv3.util.SyncUtils;
|
||||||
|
|
||||||
@Entity
|
@Entity
|
||||||
@AllArgsConstructor
|
@AllArgsConstructor
|
||||||
@ -66,6 +63,7 @@ public final class IpIntel {
|
|||||||
} else if (existingIpIntel != null) {
|
} else if (existingIpIntel != null) {
|
||||||
callback.onResult(existingIpIntel, null);
|
callback.onResult(existingIpIntel, null);
|
||||||
} else {
|
} else {
|
||||||
|
/*
|
||||||
SpringUtils.getBean(GeoIpService.class).lookupInfo(id, (geoIpResult, error2) -> {
|
SpringUtils.getBean(GeoIpService.class).lookupInfo(id, (geoIpResult, error2) -> {
|
||||||
if (error2 != null) {
|
if (error2 != null) {
|
||||||
callback.onResult(null, error2);
|
callback.onResult(null, error2);
|
||||||
@ -83,7 +81,8 @@ public final class IpIntel {
|
|||||||
// MaxMind failed to return result
|
// MaxMind failed to return result
|
||||||
callback.onResult(null, null);
|
callback.onResult(null, null);
|
||||||
}
|
}
|
||||||
});
|
});*/
|
||||||
|
callback.onResult(null, null);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -111,6 +110,7 @@ public final class IpIntel {
|
|||||||
Future createNewIntelFuture = Future.future();
|
Future createNewIntelFuture = Future.future();
|
||||||
createNewIntelFutures.add(createNewIntelFuture);
|
createNewIntelFutures.add(createNewIntelFuture);
|
||||||
|
|
||||||
|
/*
|
||||||
SpringUtils.getBean(GeoIpService.class).lookupInfo(ip, (geoIpResult, error2) -> {
|
SpringUtils.getBean(GeoIpService.class).lookupInfo(ip, (geoIpResult, error2) -> {
|
||||||
if (error2 != null) {
|
if (error2 != null) {
|
||||||
createNewIntelFuture.fail(error2);
|
createNewIntelFuture.fail(error2);
|
||||||
@ -133,7 +133,8 @@ public final class IpIntel {
|
|||||||
createNewIntelFuture.complete();
|
createNewIntelFuture.complete();
|
||||||
}
|
}
|
||||||
}));
|
}));
|
||||||
});
|
});*/
|
||||||
|
createNewIntelFuture.complete();
|
||||||
});
|
});
|
||||||
|
|
||||||
CompositeFuture.all(createNewIntelFutures).setHandler((creationStatus) -> {
|
CompositeFuture.all(createNewIntelFutures).setHandler((creationStatus) -> {
|
||||||
|
@ -1,81 +0,0 @@
|
|||||||
package net.frozenorb.apiv3.service.geoip;
|
|
||||||
|
|
||||||
import com.google.common.base.Charsets;
|
|
||||||
|
|
||||||
import com.mongodb.async.SingleResultCallback;
|
|
||||||
|
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
|
||||||
import org.springframework.beans.factory.annotation.Value;
|
|
||||||
import org.springframework.stereotype.Component;
|
|
||||||
|
|
||||||
import java.util.Base64;
|
|
||||||
|
|
||||||
import io.vertx.circuitbreaker.CircuitBreaker;
|
|
||||||
import io.vertx.circuitbreaker.CircuitBreakerOptions;
|
|
||||||
import io.vertx.core.Vertx;
|
|
||||||
import io.vertx.core.http.HttpClient;
|
|
||||||
import io.vertx.core.json.JsonObject;
|
|
||||||
|
|
||||||
@Component
|
|
||||||
public final class MaxMindGeoIpService implements GeoIpService {
|
|
||||||
|
|
||||||
@Autowired private HttpClient httpsClient;
|
|
||||||
@Value("${maxMind.userId}") private String userId;
|
|
||||||
@Value("${maxMind.licenseKey}") private String licenseKey;
|
|
||||||
private final CircuitBreaker breaker;
|
|
||||||
|
|
||||||
// MaxMind likes to randomly not respond, so we take advantage of the circuit breaker pattern to only
|
|
||||||
// check MaxMind periodically (while it's in a non-responsive state) to keep our average response times
|
|
||||||
// nice and low.
|
|
||||||
@Autowired
|
|
||||||
public MaxMindGeoIpService(Vertx vertx) {
|
|
||||||
this.breaker = CircuitBreaker.create(getClass().getName(), vertx,
|
|
||||||
new CircuitBreakerOptions()
|
|
||||||
.setMaxFailures(5)
|
|
||||||
.setTimeout(5000) // 5 seconds
|
|
||||||
.setFallbackOnFailure(true)
|
|
||||||
.setResetTimeout(120_000) // 2 minutes
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void lookupInfo(String ip, SingleResultCallback<GeoIpInfo> callback) {
|
|
||||||
breaker.execute((future) -> {
|
|
||||||
String authHeader = "Basic " + Base64.getEncoder().encodeToString((userId + ":" + licenseKey).getBytes(Charsets.UTF_8));
|
|
||||||
|
|
||||||
httpsClient.get(443, "geoip.maxmind.com", "/geoip/v2.1/insights/" + ip, (response) -> {
|
|
||||||
response.bodyHandler((body) -> {
|
|
||||||
JsonObject bodyJson = new JsonObject(body.toString());
|
|
||||||
|
|
||||||
try {
|
|
||||||
GeoIpInfo geoIpInfo = new GeoIpInfo(bodyJson);
|
|
||||||
|
|
||||||
// we have to check !isComplete() because the circuit breaker's timeout might mark us as failed already
|
|
||||||
if (!future.isComplete()) {
|
|
||||||
future.complete(geoIpInfo);
|
|
||||||
}
|
|
||||||
} catch (Exception ignored) {
|
|
||||||
// we have to check !isComplete() because the circuit breaker's timeout might mark us as failed already
|
|
||||||
if (!future.isComplete()) {
|
|
||||||
future.complete(null);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
response.exceptionHandler((error) -> {
|
|
||||||
// we have to check !isComplete() because the circuit breaker's timeout will might us as failed already
|
|
||||||
if (!future.isComplete()) {
|
|
||||||
future.fail(error);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}).putHeader("Authorization", authHeader).end();
|
|
||||||
}).setHandler((result) -> {
|
|
||||||
if (result.failed()) {
|
|
||||||
callback.onResult(null, result.cause());
|
|
||||||
} else {
|
|
||||||
callback.onResult((GeoIpInfo) result.result(), null);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,6 +1,7 @@
|
|||||||
package net.frozenorb.apiv3.util;
|
package net.frozenorb.apiv3.util;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
import lombok.experimental.UtilityClass;
|
import lombok.experimental.UtilityClass;
|
||||||
|
|
||||||
@ -8,17 +9,58 @@ import lombok.experimental.UtilityClass;
|
|||||||
public class UuidUtils {
|
public class UuidUtils {
|
||||||
|
|
||||||
public static boolean isAcceptableUuid(UUID uuid) {
|
public static boolean isAcceptableUuid(UUID uuid) {
|
||||||
return uuid.version() == 4;
|
return uuid != null && uuid.version() == 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static UUID parseUuid(String input) {
|
public static UUID parseUuid(String input) {
|
||||||
if (input.length() == 36) {
|
if (input.length() == 36) {
|
||||||
return UUID.fromString(input);
|
return UUID.fromString(input);
|
||||||
} else if (input.length() == 32) {
|
} else if (input.length() == 32) {
|
||||||
return UUID.fromString(input.replaceFirst("([0-9a-fA-F]{8})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]{4})([0-9a-fA-F]+)", "$1-$2-$3-$4-$5"));
|
Logger.getGlobal().info("Got 32 length UUID");
|
||||||
|
return from32(input);
|
||||||
} else {
|
} else {
|
||||||
throw new IllegalArgumentException("Invalid UUID string: " + input);
|
throw new IllegalArgumentException("Invalid UUID string: " + input);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static UUID from32(String id) {
|
||||||
|
long lo, hi;
|
||||||
|
lo = hi = 0;
|
||||||
|
|
||||||
|
for (int i = 0, j = 0; i < 32; ++j) {
|
||||||
|
int curr;
|
||||||
|
char c = id.charAt(i);
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
curr = (c - '0');
|
||||||
|
} else if (c >= 'a' && c <= 'f') {
|
||||||
|
curr = (c - 'a' + 10);
|
||||||
|
} else if (c >= 'A' && c <= 'F') {
|
||||||
|
curr = (c - 'A' + 10);
|
||||||
|
} else {
|
||||||
|
throw new NumberFormatException("Non-hex character at #" + i + ": '" + c + "' (value 0x" + Integer.toHexString(c) + ")");
|
||||||
|
}
|
||||||
|
curr = (curr << 4);
|
||||||
|
|
||||||
|
c = id.charAt(++i);
|
||||||
|
|
||||||
|
if (c >= '0' && c <= '9') {
|
||||||
|
curr |= (c - '0');
|
||||||
|
} else if (c >= 'a' && c <= 'f') {
|
||||||
|
curr |= (c - 'a' + 10);
|
||||||
|
} else if (c >= 'A' && c <= 'F') {
|
||||||
|
curr |= (c - 'A' + 10);
|
||||||
|
} else {
|
||||||
|
throw new NumberFormatException("Non-hex character at #" + i + ": '" + c + "' (value 0x" + Integer.toHexString(c) + ")");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (j < 8) {
|
||||||
|
hi = (hi << 8) | curr;
|
||||||
|
} else {
|
||||||
|
lo = (lo << 8) | curr;
|
||||||
|
}
|
||||||
|
++i;
|
||||||
|
}
|
||||||
|
return new UUID(hi, lo);
|
||||||
|
}
|
||||||
}
|
}
|
@ -91,6 +91,11 @@ public final class POSTGrants implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (rank.isGrantRequiresTotp()) {
|
if (rank.isGrantRequiresTotp()) {
|
||||||
|
if (!requestBody.containsKey("totpCode")) {
|
||||||
|
ErrorUtils.respondInvalidInput(ctx, "Rank must be granted through API or website.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
int code = requestBody.getInteger("totpCode", -1);
|
int code = requestBody.getInteger("totpCode", -1);
|
||||||
TotpAuthorizationResult totpAuthorizationResult = SyncUtils.runBlocking(v -> addedBy.checkTotpAuthorization(code, null, v));
|
TotpAuthorizationResult totpAuthorizationResult = SyncUtils.runBlocking(v -> addedBy.checkTotpAuthorization(code, null, v));
|
||||||
|
|
||||||
|
@ -58,7 +58,13 @@ public final class POSTPunishments implements Handler<RoutingContext> {
|
|||||||
for (Punishment alternatePunishment : punishments) {
|
for (Punishment alternatePunishment : punishments) {
|
||||||
if (alternatePunishment.isActive()) {
|
if (alternatePunishment.isActive()) {
|
||||||
User user = SyncUtils.runBlocking(v -> User.findById(alternatePunishment.getAddedBy(), v));
|
User user = SyncUtils.runBlocking(v -> User.findById(alternatePunishment.getAddedBy(), v));
|
||||||
ErrorUtils.respondOther(ctx, 409, "User already covered by alternate punishment.", "alreadyCoveredByAlternatePunishment", ImmutableMap.of("alternatePunishmentBy", user.getLastUsername()));
|
String lastPunishmentAddedBy = "";
|
||||||
|
|
||||||
|
if (user != null) {
|
||||||
|
lastPunishmentAddedBy = user.getLastUsername();
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorUtils.respondOther(ctx, 409, "User already covered by alternate punishment.", "alreadyCoveredByAlternatePunishment", ImmutableMap.of("alternatePunishmentBy", lastPunishmentAddedBy));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user