Convert some basic read-only routes to async

This commit is contained in:
Colin McDonald 2016-06-17 01:10:09 -04:00
parent a92dee1e6f
commit de933bc571
24 changed files with 304 additions and 191 deletions

View File

@ -21,10 +21,7 @@ import com.mongodb.connection.ClusterSettings;
import fr.javatic.mongo.jacksonCodec.JacksonCodecProvider;
import fr.javatic.mongo.jacksonCodec.ObjectMapperFactory;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpHeaders;
import io.vertx.core.http.HttpMethod;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.*;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
@ -63,11 +60,13 @@ import net.frozenorb.apiv3.route.serverGroups.POSTServerGroup;
import net.frozenorb.apiv3.route.servers.*;
import net.frozenorb.apiv3.route.users.*;
import net.frozenorb.apiv3.serialization.gson.FollowAnnotationExclusionStrategy;
import net.frozenorb.apiv3.serialization.gson.InstantTimeAdapter;
import net.frozenorb.apiv3.serialization.jackson.UUIDJsonDeserializer;
import net.frozenorb.apiv3.serialization.jackson.UUIDJsonSerializer;
import net.frozenorb.apiv3.serialization.mongodb.UUIDCodecProvider;
import net.frozenorb.apiv3.unsorted.BugsnagSLF4JLogger;
import net.frozenorb.apiv3.serialization.gson.InstantTypeAdapter;
import net.frozenorb.apiv3.serialization.jackson.InstantJsonDeserializer;
import net.frozenorb.apiv3.serialization.jackson.InstantJsonSerializer;
import net.frozenorb.apiv3.serialization.jackson.UuidJsonDeserializer;
import net.frozenorb.apiv3.serialization.jackson.UuidJsonSerializer;
import net.frozenorb.apiv3.serialization.mongodb.UuidCodecProvider;
import net.frozenorb.apiv3.unsorted.BugsnagSlf4jLogger;
import org.bson.Document;
import org.bson.codecs.BsonValueCodecProvider;
import org.bson.codecs.DocumentCodecProvider;
@ -89,11 +88,12 @@ import java.util.UUID;
public final class APIv3 extends AbstractVerticle {
@Getter private static HttpClient httpClient;
@Getter private static HttpClient httpsClient;
@Getter private static MongoDatabase database;
@Getter private static Properties config = new Properties();
@Getter private static RedisClient redisClient;
private static final Gson gson = new GsonBuilder()
.registerTypeAdapter(Instant.class, new InstantTimeAdapter())
.registerTypeAdapter(Instant.class, new InstantTypeAdapter())
.setExclusionStrategies(new FollowAnnotationExclusionStrategy())
.create();
@ -164,11 +164,15 @@ public final class APIv3 extends AbstractVerticle {
new IndexModel(new Document("user", 1)),
new IndexModel(new Document("user", 1).append("userIp", 1))
), (a, b) -> {});
database.getCollection("ipBans").createIndexes(ImmutableList.of(
new IndexModel(new Document("userIp", 1))
), (a, b) -> {});
database.getCollection("punishments").createIndexes(ImmutableList.of(
new IndexModel(new Document("user", 1)),
new IndexModel(new Document("type", 1)),
new IndexModel(new Document("addedAt", 1)),
new IndexModel(new Document("addedBy", 1))
new IndexModel(new Document("addedBy", 1)),
new IndexModel(new Document("linkedIpBanId", 1))
), (a, b) -> {});
database.getCollection("users").createIndexes(ImmutableList.of(
new IndexModel(new Document("lastUsername", 1)),
@ -183,8 +187,10 @@ public final class APIv3 extends AbstractVerticle {
ObjectMapper objectMapper = ObjectMapperFactory.createObjectMapper();
SimpleModule simpleModule = new SimpleModule();
simpleModule.addSerializer(UUID.class, new UUIDJsonSerializer());
simpleModule.addDeserializer(UUID.class, new UUIDJsonDeserializer());
simpleModule.addSerializer(Instant.class, new InstantJsonSerializer());
simpleModule.addDeserializer(Instant.class, new InstantJsonDeserializer());
simpleModule.addSerializer(UUID.class, new UuidJsonSerializer());
simpleModule.addDeserializer(UUID.class, new UuidJsonDeserializer());
objectMapper.registerModule(simpleModule);
objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE);
@ -194,7 +200,7 @@ public final class APIv3 extends AbstractVerticle {
List<CodecProvider> providers = new ArrayList<>();
// Our fixed uuid codec
providers.add(new UUIDCodecProvider());
providers.add(new UuidCodecProvider());
// Normal providers
providers.add(new ValueCodecProvider());
@ -220,7 +226,7 @@ public final class APIv3 extends AbstractVerticle {
Client bugsnag = new Client(config.getProperty("bugsnag.apiKey"));
bugsnag.setReleaseStage(config.getProperty("general.releaseStage"));
bugsnag.setProjectPackages("net.frozenorb.apiv3");
bugsnag.setLogger(new BugsnagSLF4JLogger());
bugsnag.setLogger(new BugsnagSlf4jLogger());
}
// TODO: blockingHandler -> handler
@ -235,79 +241,80 @@ public final class APIv3 extends AbstractVerticle {
// TODO: The commented out routes
mainRouter.get("/announcements/:id").blockingHandler(new GETAnnouncements());
mainRouter.put("/announcements/:id").blockingHandler(new PUTAnnouncements());
mainRouter.get("/announcements/:id").handler(new GETAnnouncements());
mainRouter.put("/announcements/:id").handler(new PUTAnnouncements());
mainRouter.get("/auditLog").blockingHandler(new GETAuditLog());
mainRouter.post("/user/:id/auditLogEntry").blockingHandler(new POSTUserAuditLogEntry());
mainRouter.get("/auditLog").handler(new GETAuditLog());
mainRouter.post("/user/:id/auditLogEntry").handler(new POSTUserAuditLogEntry());
mainRouter.get("/chatFilterList").handler(new GETChatFilterList());
mainRouter.get("/grant/:id").blockingHandler(new GETGrant());
mainRouter.get("/grants").blockingHandler(new GETGrants());
mainRouter.get("/user/:id/grants").blockingHandler(new GETUserGrants());
mainRouter.post("/user/:id/grant").blockingHandler(new POSTUserGrant());
mainRouter.delete("/grant/:id").blockingHandler(new DELETEGrant());
mainRouter.get("/grant/:id").handler(new GETGrant());
mainRouter.get("/grants").handler(new GETGrants());
mainRouter.get("/user/:id/grants").handler(new GETUserGrants());
mainRouter.post("/user/:id/grant").blockingHandler(new POSTUserGrant(), false);
mainRouter.delete("/grant/:id").blockingHandler(new DELETEGrant(), false);
mainRouter.get("/ipBan/:id").blockingHandler(new GETIpBan());
mainRouter.get("/ipBans").blockingHandler(new GETIpBans());
mainRouter.get("/ip/:id/ipBans").blockingHandler(new GETIpIpBans());
mainRouter.post("/ip/:id/ipBan").blockingHandler(new POSTIpIpBan());
mainRouter.delete("/ipBan/:id").blockingHandler(new DELETEIpBan());
mainRouter.get("/ipBan/:id").handler(new GETIpBan());
mainRouter.get("/ipBans").handler(new GETIpBans());
mainRouter.get("/ip/:id/ipBans").handler(new GETIpIpBans());
mainRouter.post("/ip/:id/ipBan").blockingHandler(new POSTIpIpBan(), false);
mainRouter.delete("/ipBan/:id").blockingHandler(new DELETEIpBan(), false);
mainRouter.get("/user/:id/ipLog").blockingHandler(new GETUserIpLog());
mainRouter.get("/user/:id/ipLog").handler(new GETUserIpLog());
mainRouter.get("/notificationTemplate/:id").blockingHandler(new GETNotificationTemplate());
mainRouter.get("/notificationTemplates").blockingHandler(new GETNotificationTemplates());
mainRouter.post("/notificationTemplate").blockingHandler(new POSTNotificationTemplate());
//mainRouter.put("/notificationTemplate/:id").blockingHandler(new PUTNotificationTemplate());
mainRouter.delete("/notificationTemplate/:id").blockingHandler(new DELETENotificationTemplate());
mainRouter.get("/notificationTemplate/:id").handler(new GETNotificationTemplate());
mainRouter.get("/notificationTemplates").handler(new GETNotificationTemplates());
mainRouter.post("/notificationTemplate").blockingHandler(new POSTNotificationTemplate(), false);
//mainRouter.put("/notificationTemplate/:id").blockingHandler(new PUTNotificationTemplate(), false);
mainRouter.delete("/notificationTemplate/:id").blockingHandler(new DELETENotificationTemplate(), false);
mainRouter.get("/punishment/:id").blockingHandler(new GETPunishment());
mainRouter.get("/punishments").blockingHandler(new GETPunishments());
mainRouter.get("/user/:id/punishments").blockingHandler(new GETUserPunishments());
mainRouter.post("/user/:id/punish").blockingHandler(new POSTUserPunish());
mainRouter.delete("/punishment/:id").blockingHandler(new DELETEPunishment());
mainRouter.delete("/user/:id/punishment").blockingHandler(new DELETEUserPunishment());
mainRouter.get("/punishment/:id").handler(new GETPunishment());
mainRouter.get("/punishments").handler(new GETPunishments());
mainRouter.get("/user/:id/punishments").handler(new GETUserPunishments());
mainRouter.post("/user/:id/punish").blockingHandler(new POSTUserPunish(), false);
mainRouter.delete("/punishment/:id").blockingHandler(new DELETEPunishment(), false);
mainRouter.delete("/user/:id/punishment").blockingHandler(new DELETEUserPunishment(), false);
mainRouter.get("/rank/:id").handler(new GETRank());
mainRouter.get("/ranks").handler(new GETRanks());
mainRouter.post("/rank").blockingHandler(new POSTRank());
//mainRouter.put("/rank/:id").blockingHandler(new PUTRank());
mainRouter.delete("/rank/:id").blockingHandler(new DELETERank());
mainRouter.post("/rank").blockingHandler(new POSTRank(), false);
//mainRouter.put("/rank/:id").blockingHandler(new PUTRank(), false);
mainRouter.delete("/rank/:id").blockingHandler(new DELETERank(), false);
mainRouter.get("/serverGroup/:id").handler(new GETServerGroup());
mainRouter.get("/serverGroups").handler(new GETServerGroups());
mainRouter.post("/serverGroup").blockingHandler(new POSTServerGroup());
//mainRouter.put("/serverGroup/:id").blockingHandler(new PUTServerGroup());
mainRouter.delete("/serverGroup/:id").blockingHandler(new DELETEServerGroup());
mainRouter.post("/serverGroup").blockingHandler(new POSTServerGroup(), false);
//mainRouter.put("/serverGroup/:id").blockingHandler(new PUTServerGroup(), false);
mainRouter.delete("/serverGroup/:id").blockingHandler(new DELETEServerGroup(), false);
mainRouter.get("/server/:id").handler(new GETServer());
mainRouter.get("/servers").handler(new GETServers());
mainRouter.post("/server/heartbeat").handler(new POSTServerHeartbeat());
mainRouter.post("/server").blockingHandler(new POSTServer());
//mainRouter.put("/server/:id").blockingHandler(new PUTServer());
mainRouter.delete("/server/:id").blockingHandler(new DELETEServer());
mainRouter.post("/server").blockingHandler(new POSTServer(), false);
//mainRouter.put("/server/:id").blockingHandler(new PUTServer(), false);
mainRouter.delete("/server/:id").blockingHandler(new DELETEServer(), false);
mainRouter.get("/staff").blockingHandler(new GETStaff());
mainRouter.get("/user/:id").blockingHandler(new GETUser());
mainRouter.get("/user/:id/details").blockingHandler(new GETUserDetails());
mainRouter.get("/user/:id/meta/:serverGroup").blockingHandler(new GETUserMeta());
mainRouter.get("/user/:id/requiresTOTP").blockingHandler(new GETUserRequiresTOTP());
mainRouter.get("/user/:id/verifyPassword").blockingHandler(new GETUserVerifyPassword());
mainRouter.post("/user/confirmRegister/:emailToken").blockingHandler(new POSTUserConfirmRegister());
mainRouter.get("/staff").blockingHandler(new GETStaff(), false);
mainRouter.get("/user/:id").handler(new GETUser());
mainRouter.get("/user/:id/details").blockingHandler(new GETUserDetails(), false);
mainRouter.get("/user/:id/meta/:serverGroup").blockingHandler(new GETUserMeta(), false);
mainRouter.get("/user/:id/permissions").blockingHandler(new GETUserPermissions(), false);
mainRouter.get("/user/:id/requiresTOTP").blockingHandler(new GETUserRequiresTOTP(), false);
mainRouter.get("/user/:id/verifyPassword").blockingHandler(new GETUserVerifyPassword(), false);
mainRouter.post("/user/confirmRegister/:emailToken").blockingHandler(new POSTUserConfirmRegister(), false);
mainRouter.post("/user/:id/leave").handler(new POSTUserLeave());
mainRouter.post("/user/:id/login").handler(new POSTUserLogin());
mainRouter.post("/user/:id/notify").blockingHandler(new POSTUserNotify());
mainRouter.post("/user/:id/register").blockingHandler(new POSTUserRegister());
mainRouter.post("/user/:id/setupTOTP").blockingHandler(new POSTUserSetupTOTP());
mainRouter.post("/user/:id/verifyTOTP").blockingHandler(new POSTUserVerifyTOTP());
mainRouter.put("/user/:id/meta/:serverGroup").blockingHandler(new PUTUserMeta());
mainRouter.delete("/user/:id/meta/:serverGroup").blockingHandler(new DELETEUserMeta());
mainRouter.post("/user/:id/login").blockingHandler(new POSTUserLogin());
mainRouter.post("/user/:id/notify").blockingHandler(new POSTUserNotify(), false);
mainRouter.post("/user/:id/register").blockingHandler(new POSTUserRegister(), false);
mainRouter.post("/user/:id/setupTOTP").blockingHandler(new POSTUserSetupTOTP(), false);
mainRouter.post("/user/:id/verifyTOTP").blockingHandler(new POSTUserVerifyTOTP(), false);
mainRouter.put("/user/:id/meta/:serverGroup").blockingHandler(new PUTUserMeta(), false);
mainRouter.delete("/user/:id/meta/:serverGroup").blockingHandler(new DELETEUserMeta(), false);
mainRouter.get("/dump/:type").handler(new GETDump());
mainRouter.get("/whoami").handler(new GETWhoAmI());
mainRouter.post("/metrics").blockingHandler(new POSTMetrics());
mainRouter.post("/metrics").handler(new POSTMetrics());
int port = Integer.parseInt(config.getProperty("http.port"));
webServer.requestHandler(mainRouter::accept).listen(port);
@ -315,6 +322,11 @@ public final class APIv3 extends AbstractVerticle {
private void setupHttpClient() {
httpClient = vertx.createHttpClient();
httpsClient = vertx.createHttpClient(
new HttpClientOptions()
.setSsl(true)
.setTrustAll(true)
);
}
public static void respondJson(RoutingContext ctx, Object response) {

View File

@ -13,10 +13,9 @@ public final class GETAnnouncements implements Handler<RoutingContext> {
if (serverGroup == null) {
ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("id"));
return;
} else {
APIv3.respondJson(ctx, serverGroup.getAnnouncements());
}
APIv3.respondJson(ctx, serverGroup.getAnnouncements());
}
}

View File

@ -16,18 +16,22 @@ public final class PUTAnnouncements implements Handler<RoutingContext> {
if (serverGroup == null) {
ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("id"));
return;
} else {
Set<String> announcements = new HashSet<>();
for (Object announcement : ctx.getBodyAsJsonArray()) {
announcements.add((String) announcement);
}
serverGroup.setAnnouncements(announcements);
serverGroup.save((ignored, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, serverGroup.getAnnouncements());
}
});
}
Set<String> announcements = new HashSet<>();
for (Object announcement : ctx.getBodyAsJsonArray()) {
announcements.add((String) announcement);
}
serverGroup.setAnnouncements(announcements);
serverGroup.save();
APIv3.respondJson(ctx, serverGroup.getAnnouncements());
}
}

View File

@ -13,7 +13,13 @@ public final class GETAuditLog implements Handler<RoutingContext> {
int skip = ctx.request().getParam("skip") == null ? 0 : Integer.parseInt(ctx.request().getParam("skip"));
int pageSize = ctx.request().getParam("pageSize") == null ? 100 : Integer.parseInt(ctx.request().getParam("pageSize"));
APIv3.respondJson(ctx, AuditLogEntry.findAllPaginatedSync(skip, pageSize));
AuditLogEntry.findAllPaginated(skip, pageSize, (auditLog, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, auditLog);
}
});
} catch (NumberFormatException ex) {
ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs.");
}

View File

@ -15,33 +15,37 @@ import org.bson.Document;
public final class POSTUserAuditLogEntry implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
User user = User.findByIdSync(ctx.request().getParam("id"));
User.findById(ctx.request().getParam("id"), (user, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else if (user == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
} else {
String userIp = ctx.request().getParam("userIp");
if (user == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
return;
}
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
String userIp = ctx.request().getParam("userIp");
AuditLogActionType type;
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
try {
type = AuditLogActionType.valueOf(ctx.request().getParam("type"));
} catch (IllegalArgumentException ex) {
ErrorUtils.respondNotFound(ctx, "Audit log action type", ctx.request().getParam("type"));
return;
}
AuditLogActionType type;
try {
type = AuditLogActionType.valueOf(ctx.request().getParam("type"));
} catch (IllegalArgumentException ex) {
ErrorUtils.respondNotFound(ctx, "Audit log action type", ctx.request().getParam("type"));
return;
}
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
AuditLog.log(user, userIp, ctx.get("actor"), type, Document.parse(ctx.getBodyAsString()), blockingCallback);
AuditLogEntry entry = blockingCallback.get();
APIv3.respondJson(ctx, entry);
AuditLog.log(user, userIp, ctx.get("actor"), type, Document.parse(ctx.getBodyAsString()), (auditLogEntry, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {
APIv3.respondJson(ctx, auditLogEntry);
}
});
}
});
}
}

View File

@ -4,11 +4,18 @@ import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.Grant;
import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETGrant implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
APIv3.respondJson(ctx, Grant.findByIdSync(ctx.request().getParam("id")));
Grant.findById(ctx.request().getParam("id"), (grant, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, grant);
}
});
}
}

View File

@ -13,7 +13,13 @@ public final class GETGrants implements Handler<RoutingContext> {
int skip = ctx.request().getParam("skip") == null ? 0 : Integer.parseInt(ctx.request().getParam("skip"));
int pageSize = ctx.request().getParam("pageSize") == null ? 100 : Integer.parseInt(ctx.request().getParam("pageSize"));
APIv3.respondJson(ctx, Grant.findAllPaginatedSync(skip, pageSize));
Grant.findAllPaginated(skip, pageSize, (grants, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, grants);
}
});
} catch (NumberFormatException ex) {
ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs.");
}

View File

@ -10,14 +10,21 @@ import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETUserGrants implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
User target = User.findByIdSync(ctx.request().getParam("id"));
if (target == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
return;
}
APIv3.respondJson(ctx, Grant.findByUserSync(target));
User.findById(ctx.request().getParam("id"), (user, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else if (user == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
} else {
Grant.findByUser(user, (grants, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {
APIv3.respondJson(ctx, grants);
}
});
}
});
}
}

View File

@ -3,12 +3,20 @@ package net.frozenorb.apiv3.route.ipBans;
import io.vertx.core.Handler;
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.util.ErrorUtils;
public final class GETIpBan implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
APIv3.respondJson(ctx, IpBan.findByIdSync(ctx.request().getParam("id")));
IpBan.findById(ctx.request().getParam("id"), (ipBan, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, ipBan);
}
});
}
}

View File

@ -3,6 +3,7 @@ package net.frozenorb.apiv3.route.ipBans;
import io.vertx.core.Handler;
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.util.ErrorUtils;
@ -13,7 +14,13 @@ public final class GETIpBans implements Handler<RoutingContext> {
int skip = ctx.request().getParam("skip") == null ? 0 : Integer.parseInt(ctx.request().getParam("skip"));
int pageSize = ctx.request().getParam("pageSize") == null ? 100 : Integer.parseInt(ctx.request().getParam("pageSize"));
APIv3.respondJson(ctx, IpBan.findAllPaginatedSync(skip, pageSize));
IpBan.findAllPaginated(skip, pageSize, (grants, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, grants);
}
});
} catch (NumberFormatException ex) {
ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs.");
}

View File

@ -4,6 +4,8 @@ import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.model.Punishment;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
@ -17,7 +19,13 @@ public final class GETIpIpBans implements Handler<RoutingContext> {
return;
}
APIv3.respondJson(ctx, IpBan.findByIpSync(userIp));
IpBan.findByIp(userIp, (ipBans, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, ipBans);
}
});
}
}

View File

@ -3,21 +3,30 @@ package net.frozenorb.apiv3.route.ipLog;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.model.IpLogEntry;
import net.frozenorb.apiv3.model.Punishment;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETUserIpLog implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
User target = User.findByIdSync(ctx.request().getParam("id"));
if (target == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
return;
}
APIv3.respondJson(ctx, IpLogEntry.findByUserSync(target));
User.findById(ctx.request().getParam("id"), (user, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else if (user == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
} else {
IpLogEntry.findByUser(user, (ipLog, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {
APIv3.respondJson(ctx, ipLog);
}
});
}
});
}
}

View File

@ -3,12 +3,20 @@ package net.frozenorb.apiv3.route.notificationTemplates;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.model.NotificationTemplate;
import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETNotificationTemplate implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
APIv3.respondJson(ctx, NotificationTemplate.findByIdSync(ctx.request().getParam("id")));
NotificationTemplate.findById(ctx.request().getParam("id"), (notificationTemplate, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, notificationTemplate);
}
});
}
}

View File

@ -3,12 +3,20 @@ package net.frozenorb.apiv3.route.notificationTemplates;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.model.NotificationTemplate;
import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETNotificationTemplates implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
APIv3.respondJson(ctx, NotificationTemplate.findAllSync());
NotificationTemplate.findAll((notificationTemplates, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, notificationTemplates);
}
});
}
}

View File

@ -3,12 +3,20 @@ package net.frozenorb.apiv3.route.punishments;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.model.Punishment;
import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETPunishment implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
APIv3.respondJson(ctx, Punishment.findByIdSync(ctx.request().getParam("id")));
Punishment.findById(ctx.request().getParam("id"), (punishment, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, punishment);
}
});
}
}

View File

@ -3,6 +3,7 @@ package net.frozenorb.apiv3.route.punishments;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.Grant;
import net.frozenorb.apiv3.model.Punishment;
import net.frozenorb.apiv3.util.ErrorUtils;
@ -13,7 +14,13 @@ public final class GETPunishments implements Handler<RoutingContext> {
int skip = ctx.request().getParam("skip") == null ? 0 : Integer.parseInt(ctx.request().getParam("skip"));
int pageSize = ctx.request().getParam("pageSize") == null ? 100 : Integer.parseInt(ctx.request().getParam("pageSize"));
APIv3.respondJson(ctx, Punishment.findAllPaginatedSync(skip, pageSize));
Punishment.findAllPaginated(skip, pageSize, (grants, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, grants);
}
});
} catch (NumberFormatException ex) {
ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs.");
}

View File

@ -3,6 +3,7 @@ package net.frozenorb.apiv3.route.punishments;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.Grant;
import net.frozenorb.apiv3.model.Punishment;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
@ -10,14 +11,21 @@ import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETUserPunishments implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
User target = User.findByIdSync(ctx.request().getParam("id"));
if (target == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
return;
}
APIv3.respondJson(ctx, Punishment.findByUserSync(target));
User.findById(ctx.request().getParam("id"), (user, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else if (user == null) {
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
} else {
Punishment.findByUser(user, (punishments, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {
APIv3.respondJson(ctx, punishments);
}
});
}
});
}
}

View File

@ -73,7 +73,7 @@ public final class POSTUserPunish implements Handler<RoutingContext> {
Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, ctx.get("actor"), meta);
String accessDenialReason = punishment.getAccessDenialReason();
String userIp = ctx.request().getParam("userIp");
String userIp = ctx.request().getParam("playerIp"); // TODO: YELL AT GRIFFIN FOR THIS, IT SHOULD BE USERIP
if (userIp != null) {
IpBan ipBan = new IpBan(userIp, punishment);

View File

@ -13,7 +13,7 @@ import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.model.*;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.PermissionUtils;
import net.frozenorb.apiv3.util.UUIDUtils;
import net.frozenorb.apiv3.util.UuidUtils;
import org.bson.Document;
import java.time.Instant;
@ -190,7 +190,7 @@ public final class POSTServerHeartbeat implements Handler<RoutingContext> {
UUID uuid = UUID.fromString(playerJson.getString("uuid"));
String username = playerJson.getString("username");
if (UUIDUtils.isAcceptableUUID(uuid)) {
if (UuidUtils.isAcceptableUuid(uuid)) {
result.put(uuid, username);
}
}

View File

@ -3,12 +3,20 @@ package net.frozenorb.apiv3.route.users;
import io.vertx.core.Handler;
import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
public final class GETUser implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
APIv3.respondJson(ctx, User.findByIdSync(ctx.request().getParam("id")));
User.findById(ctx.request().getParam("id"), (user, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
APIv3.respondJson(ctx, user);
}
});
}
}

View File

@ -8,7 +8,7 @@ import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.BlockingCallback;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.TOTPUtils;
import net.frozenorb.apiv3.util.TotpUtils;
public final class GETUserRequiresTOTP implements Handler<RoutingContext> {
@ -36,7 +36,7 @@ public final class GETUserRequiresTOTP implements Handler<RoutingContext> {
}
BlockingCallback<Boolean> preAuthorizedCallback = new BlockingCallback<>();
TOTPUtils.isPreAuthorized(user, userIp, preAuthorizedCallback);
TotpUtils.isPreAuthorized(user, userIp, preAuthorizedCallback);
if (preAuthorizedCallback.get()) {
APIv3.respondJson(ctx, ImmutableMap.of(

View File

@ -11,7 +11,7 @@ import net.frozenorb.apiv3.model.Server;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.UUIDUtils;
import net.frozenorb.apiv3.util.UuidUtils;
import java.util.UUID;
@ -20,11 +20,14 @@ public final class POSTUserLogin implements Handler<RoutingContext> {
public void handle(RoutingContext ctx) {
UUID uuid = UUID.fromString(ctx.request().getParam("id"));
if (!UUIDUtils.isAcceptableUUID(uuid)) {
if (!UuidUtils.isAcceptableUuid(uuid)) {
ErrorUtils.respondInvalidInput(ctx, "UUID \"" + uuid + "\" is not valid - must be version 4 UUID.");
return;
}
User user = User.findByIdSync(uuid);
String username = ctx.request().getParam("username");
String userIp = ctx.request().getParam("userIp");
Actor actor = ctx.get("actor");
Server server;
@ -39,52 +42,38 @@ public final class POSTUserLogin implements Handler<RoutingContext> {
}
}
String username = ctx.request().getParam("username");
String userIp = ctx.request().getParam("userIp");
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid.");
return;
}
User.findById(uuid, (user, error) -> {
if (user == null) {
// Will be saved in the User constructor
user = new User(uuid, username);
}
Server actorServer = Server.findById(actor.getName());
IpLogEntry ipLogEntry = IpLogEntry.findByUserAndIpSync(user, userIp);
// We use a little bit more verbose code here to save on the
// overhead of a .insert() immediately followed by a .save()
if (ipLogEntry == null) {
ipLogEntry = new IpLogEntry(user, userIp);
ipLogEntry.used();
ipLogEntry.insert();
} else {
ipLogEntry.used();
ipLogEntry.save();
}
user.updateUsername(username);
user.getLoginInfo(actorServer, userIp, (loginInfo, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
return;
} else if (user == null) {
user = new User(uuid, username);
user.insert(); // TODO
} else {
APIv3.respondJson(ctx, loginInfo);
}
User finalUser = user;
IpLogEntry.findByUserAndIp(user, userIp, (ipLogEntry, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
return;
} else if (ipLogEntry == null) {
ipLogEntry = new IpLogEntry(finalUser, userIp);
ipLogEntry.used();
ipLogEntry.insert(); //TODO
} else {
ipLogEntry.used();
ipLogEntry.save(); // TODO
}
finalUser.updateUsername(username, (ignored, error3) -> {
if (error3 != null) {
ErrorUtils.respondInternalError(ctx, error3);
} else {
finalUser.getLoginInfo(server, userIp, (loginInfo, error4) -> {
if (error4 != null) {
ErrorUtils.respondInternalError(ctx, error4);
} else {
APIv3.respondJson(ctx, loginInfo);
}
});
}
});
});
});
}

View File

@ -7,7 +7,7 @@ import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.TOTPUtils;
import net.frozenorb.apiv3.util.TotpUtils;
public final class POSTUserSetupTOTP implements Handler<RoutingContext> {
@ -24,13 +24,13 @@ public final class POSTUserSetupTOTP implements Handler<RoutingContext> {
return;
}
GoogleAuthenticatorKey generated = TOTPUtils.generateTOTPSecret();
GoogleAuthenticatorKey generated = TotpUtils.generateTotpSecret();
user.setTotpSecret(generated.getKey());
user.save();
APIv3.respondJson(ctx, ImmutableMap.of(
"qrCode", TOTPUtils.getQRCodeURL(user, generated)
"qrCode", TotpUtils.getQrCodeUrl(user, generated)
));
}

View File

@ -8,7 +8,7 @@ import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.BlockingCallback;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.TOTPUtils;
import net.frozenorb.apiv3.util.TotpUtils;
import java.util.concurrent.TimeUnit;
@ -36,7 +36,7 @@ public final class POSTUserVerifyTOTP implements Handler<RoutingContext> {
int providedCode = Integer.parseInt(ctx.request().getParam("code"));
BlockingCallback<Boolean> recentlyUsedCallback = new BlockingCallback<>();
TOTPUtils.wasRecentlyUsed(user, providedCode, recentlyUsedCallback);
TotpUtils.wasRecentlyUsed(user, providedCode, recentlyUsedCallback);
if (recentlyUsedCallback.get()) {
APIv3.respondJson(ctx, ImmutableMap.of(
@ -46,15 +46,15 @@ public final class POSTUserVerifyTOTP implements Handler<RoutingContext> {
return;
}
boolean authorized = TOTPUtils.authorizeUser(user, providedCode);
boolean authorized = TotpUtils.authorizeUser(user, providedCode);
if (authorized) {
BlockingCallback<Void> markPreAuthorizedCallback = new BlockingCallback<>();
TOTPUtils.markPreAuthorized(user, userIp, 3, TimeUnit.DAYS, markPreAuthorizedCallback);
TotpUtils.markPreAuthorized(user, userIp, 3, TimeUnit.DAYS, markPreAuthorizedCallback);
markPreAuthorizedCallback.get();
BlockingCallback<Void> markRecentlyUsedCallback = new BlockingCallback<>();
TOTPUtils.markRecentlyUsed(user, providedCode, markRecentlyUsedCallback);
TotpUtils.markRecentlyUsed(user, providedCode, markRecentlyUsedCallback);
markRecentlyUsedCallback.get();
APIv3.respondJson(ctx, ImmutableMap.of(