Fix some stuff for Velt
This commit is contained in:
parent
276564f21f
commit
408124f5cd
|
@ -1,20 +1,5 @@
|
|||
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.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -23,6 +8,14 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
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.objectId.Id;
|
||||
import io.vertx.core.CompositeFuture;
|
||||
|
@ -30,6 +23,10 @@ import io.vertx.core.Future;
|
|||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
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
|
||||
@AllArgsConstructor
|
||||
|
@ -66,6 +63,7 @@ public final class IpIntel {
|
|||
} else if (existingIpIntel != null) {
|
||||
callback.onResult(existingIpIntel, null);
|
||||
} else {
|
||||
/*
|
||||
SpringUtils.getBean(GeoIpService.class).lookupInfo(id, (geoIpResult, error2) -> {
|
||||
if (error2 != null) {
|
||||
callback.onResult(null, error2);
|
||||
|
@ -83,7 +81,8 @@ public final class IpIntel {
|
|||
// MaxMind failed to return result
|
||||
callback.onResult(null, null);
|
||||
}
|
||||
});
|
||||
});*/
|
||||
callback.onResult(null, null);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -111,6 +110,7 @@ public final class IpIntel {
|
|||
Future createNewIntelFuture = Future.future();
|
||||
createNewIntelFutures.add(createNewIntelFuture);
|
||||
|
||||
/*
|
||||
SpringUtils.getBean(GeoIpService.class).lookupInfo(ip, (geoIpResult, error2) -> {
|
||||
if (error2 != null) {
|
||||
createNewIntelFuture.fail(error2);
|
||||
|
@ -133,7 +133,8 @@ public final class IpIntel {
|
|||
createNewIntelFuture.complete();
|
||||
}
|
||||
}));
|
||||
});
|
||||
});*/
|
||||
createNewIntelFuture.complete();
|
||||
});
|
||||
|
||||
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;
|
||||
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
|
||||
|
@ -8,17 +9,58 @@ import lombok.experimental.UtilityClass;
|
|||
public class UuidUtils {
|
||||
|
||||
public static boolean isAcceptableUuid(UUID uuid) {
|
||||
return uuid.version() == 4;
|
||||
return uuid != null && uuid.version() == 4;
|
||||
}
|
||||
|
||||
public static UUID parseUuid(String input) {
|
||||
if (input.length() == 36) {
|
||||
return UUID.fromString(input);
|
||||
} 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 {
|
||||
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 (!requestBody.containsKey("totpCode")) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "Rank must be granted through API or website.");
|
||||
return;
|
||||
}
|
||||
|
||||
int code = requestBody.getInteger("totpCode", -1);
|
||||
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) {
|
||||
if (alternatePunishment.isActive()) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue