From 7d626afa204101eaf2d5647990a9b436490a6022 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Wed, 1 Jun 2016 14:23:37 -0400 Subject: [PATCH 1/8] Vertx prototyping --- pom.xml | 11 +++++-- src/main/java/net/frozenorb/apiv3/APIv3.java | 13 ++++++-- .../apiv3/filters/ActorAttributeFilter.java | 2 +- .../apiv3/filters/AuthorizationFilter.java | 2 +- .../apiv3/filters/LoggingFilter.java | 2 +- .../java/net/frozenorb/apiv3/models/Rank.java | 5 ++- .../net/frozenorb/apiv3/routes/GETDump.java | 14 ++++---- .../net/frozenorb/apiv3/routes/GETWhoAmI.java | 9 ++---- .../net/frozenorb/apiv3/routes/NotFound.java | 9 ++---- .../frozenorb/apiv3/routes/POSTMetrics.java | 7 ++-- .../announcements/GETAnnouncements.java | 19 +++++------ .../apiv3/routes/auditLog/GETAuditLog.java | 17 +++++----- .../chatFilterList/GETChatFilterList.java | 13 ++++---- .../apiv3/routes/grants/DELETEGrant.java | 32 +++++++++++-------- .../apiv3/routes/grants/GETGrant.java | 12 +++---- .../apiv3/routes/grants/GETGrants.java | 17 +++++----- .../apiv3/routes/grants/GETUserGrants.java | 17 +++++----- .../apiv3/routes/grants/POSTUserGrant.java | 29 ++++++++--------- .../apiv3/routes/ipLog/GETUserIPLog.java | 17 +++++----- .../DELETENotificationTemplate.java | 17 +++++----- .../GETNotificationTemplate.java | 12 +++---- .../GETNotificationTemplates.java | 12 +++---- .../POSTNotificationTemplate.java | 17 +++++----- .../routes/punishments/DELETEPunishment.java | 23 ++++++------- .../routes/punishments/GETPunishment.java | 9 ++---- .../routes/punishments/GETPunishments.java | 13 +++----- .../punishments/GETUserPunishments.java | 11 +++---- .../routes/punishments/POSTUserPunish.java | 27 +++++++--------- .../apiv3/routes/ranks/DELETERank.java | 11 +++---- .../frozenorb/apiv3/routes/ranks/GETRank.java | 9 ++---- .../apiv3/routes/ranks/GETRanks.java | 7 ++-- .../apiv3/routes/ranks/POSTRank.java | 19 +++++------ .../serverGroups/DELETEServerGroup.java | 11 +++---- .../routes/serverGroups/GETServerGroup.java | 9 ++---- .../routes/serverGroups/GETServerGroups.java | 7 ++-- .../routes/serverGroups/POSTServerGroup.java | 13 +++----- .../apiv3/routes/servers/DELETEServer.java | 11 +++---- .../apiv3/routes/servers/GETServer.java | 9 ++---- .../apiv3/routes/servers/GETServers.java | 7 ++-- .../apiv3/routes/servers/POSTServer.java | 21 ++++++------ .../routes/servers/POSTServerHeartbeat.java | 11 +++---- .../apiv3/routes/users/DELETEUserMeta.java | 15 ++++----- .../routes/users/DELETEUserPunishment.java | 23 ++++++------- .../apiv3/routes/users/GETStaff.java | 7 ++-- .../frozenorb/apiv3/routes/users/GETUser.java | 9 ++---- .../apiv3/routes/users/GETUserDetails.java | 11 +++---- .../apiv3/routes/users/GETUserMeta.java | 15 ++++----- .../routes/users/GETUserRequiresTOTP.java | 15 ++++----- .../routes/users/GETUserVerifyPassword.java | 15 ++++----- .../routes/users/POSTUserConfirmRegister.java | 13 +++----- .../apiv3/routes/users/POSTUserLeave.java | 7 ++-- .../apiv3/routes/users/POSTUserLogin.java | 22 ++++++------- .../apiv3/routes/users/POSTUserNotify.java | 15 ++++----- .../apiv3/routes/users/POSTUserRegister.java | 15 ++++----- .../apiv3/routes/users/POSTUserSetupTOTP.java | 13 +++----- .../routes/users/POSTUserVerifyTOTP.java | 19 +++++------ .../apiv3/routes/users/PUTUserMeta.java | 15 ++++----- .../net/frozenorb/apiv3/utils/ErrorUtils.java | 26 +++++++-------- 58 files changed, 348 insertions(+), 440 deletions(-) diff --git a/pom.xml b/pom.xml index 931f5cc..e8340c0 100644 --- a/pom.xml +++ b/pom.xml @@ -59,9 +59,14 @@ - com.sparkjava - spark-core - 2.5 + io.vertx + vertx-core + LATEST + + + io.vertx + vertx-web + LATEST com.google.guava diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 5841fd3..41e0d09 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -10,11 +10,16 @@ import com.mongodb.*; import com.mongodb.client.MongoDatabase; import com.timgroup.statsd.NonBlockingStatsDClient; import com.timgroup.statsd.StatsDClient; +import io.vertx.ext.web.Router; +import io.vertx.ext.web.RoutingContext; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.actors.ActorType; import net.frozenorb.apiv3.filters.*; -import net.frozenorb.apiv3.models.*; +import net.frozenorb.apiv3.models.Grant; +import net.frozenorb.apiv3.models.IPLogEntry; +import net.frozenorb.apiv3.models.Punishment; +import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.routes.GETDump; import net.frozenorb.apiv3.routes.GETWhoAmI; import net.frozenorb.apiv3.routes.NotFound; @@ -45,7 +50,6 @@ import net.frozenorb.apiv3.serialization.ObjectIdTypeAdapter; import net.frozenorb.apiv3.unsorted.BugsnagSLF4JLogger; import net.frozenorb.apiv3.unsorted.LoggingExceptionHandler; import net.frozenorb.apiv3.utils.IPUtils; -import net.frozenorb.apiv3.utils.PermissionUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; import org.bson.types.ObjectId; @@ -157,6 +161,7 @@ public final class APIv3 { } private void setupHttp() { + Router.router() ipAddress(config.getProperty("http.address")); port(Integer.parseInt(config.getProperty("http.port"))); String workerThreads = config.getProperty("http.workerThreads"); @@ -245,6 +250,10 @@ public final class APIv3 { delete("/*", new NotFound(), gson::toJson); } + public static void respond(RoutingContext ctx, Object response) { + ctx.response().end(gson.toJson(response)); + } + private void convertData(String oldIp, boolean forReal) { // A lot of unneeded .toString()'s and cloning objects is our ghetto null validation. MongoDatabase importFrom = new MongoClient(oldIp).getDatabase("minehq"); diff --git a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java index b0b6a95..293e754 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java @@ -63,7 +63,7 @@ public final class ActorAttributeFilter implements Filter { Server server = Server.byId(split[1]); if (server == null) { - Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.notFound("Server", split[1]))); + Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.respondNotFound("Server", split[1]))); } String givenKey = split[2]; diff --git a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java index f9070cd..407a5bf 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java @@ -11,7 +11,7 @@ import spark.Spark; public final class AuthorizationFilter implements Filter { public void handle(Request req, Response res) { - Actor actor = req.attribute("actor"); + Actor actor = ctx.get("actor"); if (!actor.isAuthorized()) { APIv3.getStatsD().incrementCounter("apiv3.http.unauthorized"); diff --git a/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java b/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java index 0eb5dc6..55b2667 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java @@ -14,7 +14,7 @@ public final class LoggingFilter implements Filter { @Getter @Setter private static boolean debug = false; public void handle(Request req, Response res) { - Actor actor = req.attribute("actor"); + Actor actor = ctx.get("actor"); log.info("(" + actor.getName() + " - " + actor.getType() + ") " + req.requestMethod().toUpperCase() + " " + req.pathInfo() + (debug ? "\n" + res.body() : "")); } diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/models/Rank.java index 49b0e4f..18373bc 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Rank.java +++ b/src/main/java/net/frozenorb/apiv3/models/Rank.java @@ -7,7 +7,10 @@ import org.mongodb.morphia.annotations.Entity; import org.mongodb.morphia.annotations.Id; import org.mongodb.morphia.annotations.Indexed; -import java.util.*; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.concurrent.TimeUnit; @Entity(value = "ranks", noClassnameStored = true) diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java index 6bacbfb..72d16b6 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java @@ -1,19 +1,16 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableSet; -import com.timgroup.statsd.Event; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.*; import java.util.concurrent.TimeUnit; -public final class GETDump implements Route { +public final class GETDump implements Handler { private List banCache = new ArrayList<>(); private List blacklistCache = new ArrayList<>(); @@ -86,8 +83,8 @@ public final class GETDump implements Route { dumpUpdater.start(); } - public Object handle(Request req, Response res) { - String type = req.params("type"); + public void handle(RoutingContext ctx) { + String type = ctx.request().getParam("type"); switch (type.toLowerCase()) { case "ban": @@ -104,7 +101,8 @@ public final class GETDump implements Route { case "grant": return grantCache; default: - return ErrorUtils.invalidInput(type + " is not a valid type. Not in [ban, blacklist, accessDeniable, grant]"); + ErrorUtils.respondInvalidInput(ctx, "type", type + " is not a valid type. Not in [ban, blacklist, accessDeniable, grant]"); + return } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java b/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java index 3126bed..6301ccd 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java @@ -2,14 +2,11 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableMap; import net.frozenorb.apiv3.actors.Actor; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETWhoAmI implements Route { +public final class GETWhoAmI implements Handler { - public Object handle(Request req, Response res) { - Actor actor = req.attribute("actor"); + public void handle(RoutingContext ctx) { + Actor actor = ctx.get("actor"); return ImmutableMap.of( "name", actor.getName(), diff --git a/src/main/java/net/frozenorb/apiv3/routes/NotFound.java b/src/main/java/net/frozenorb/apiv3/routes/NotFound.java index be8d636..da5b900 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/NotFound.java +++ b/src/main/java/net/frozenorb/apiv3/routes/NotFound.java @@ -3,17 +3,14 @@ package net.frozenorb.apiv3.routes; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; import spark.Spark; @Slf4j -public final class NotFound implements Route { +public final class NotFound implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { log.info(req.requestMethod().toUpperCase() + " " + req.url()); - Spark.halt(404, APIv3.getGson().toJson(ErrorUtils.notFound("Route", req.url()))); + Spark.halt(404, APIv3.getGson().toJson(ErrorUtils.respondNotFound("Route", req.url()))); return null; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java b/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java index 9ff93d4..a6708f8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java +++ b/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java @@ -1,13 +1,10 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableMap; -import spark.Request; -import spark.Response; -import spark.Route; -public final class POSTMetrics implements Route { +public final class POSTMetrics implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { //LibratoBatch batch = new LibratoBatch(); return ImmutableMap.of(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java index 2be906a..3bb43e8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java +++ b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java @@ -1,28 +1,29 @@ package net.frozenorb.apiv3.routes.announcements; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; import net.frozenorb.apiv3.actors.ServerActor; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETAnnouncements implements Route { +public final class GETAnnouncements implements Handler { - public Object handle(Request req, Response res) { - Actor actor = req.attribute("actor"); + public void handle(RoutingContext ctx) { + Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { - return ErrorUtils.serverOnly(); + ErrorUtils.respondServerOnly(ctx); + return; } - Server sender = ((ServerActor) req.attribute("actor")).getServer(); + Server sender = ((ServerActor) actor).getServer(); ServerGroup senderGroup = ServerGroup.byId(sender.getServerGroup()); - return senderGroup.getAnnouncements(); + APIv3.respond(ctx, senderGroup.getAnnouncements()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java b/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java index a196e8c..32df4bc 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java @@ -1,22 +1,21 @@ package net.frozenorb.apiv3.routes.auditLog; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.AuditLogEntry; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETAuditLog implements Route { +public final class GETAuditLog implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { try { - int limit = req.queryParams("limit") == null ? 100 : Integer.parseInt(req.queryParams("limit")); - int offset = req.queryParams("offset") == null ? 0 : Integer.parseInt(req.queryParams("offset")); + int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); + int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); - return APIv3.getDatastore().createQuery(AuditLogEntry.class).order("performedAt").limit(limit).offset(offset).asList(); + APIv3.respond(ctx, APIv3.getDatastore().createQuery(AuditLogEntry.class).order("performedAt").limit(limit).offset(offset).asList()); } catch (NumberFormatException ex) { - return ErrorUtils.invalidInput("limit and offset must be numerical inputs."); + ErrorUtils.respondInvalidInput(ctx, "limit/offset must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java b/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java index 0a644ce..8c4e414 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java +++ b/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java @@ -1,14 +1,15 @@ package net.frozenorb.apiv3.routes.chatFilterList; +import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; -import spark.Request; -import spark.Response; -import spark.Route; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; -public final class GETChatFilterList implements Route { +public final class GETChatFilterList implements Handler { - public Object handle(Request req, Response res) { - return ImmutableSet.of(); + public void handle(RoutingContext ctx) { + APIv3.respond(ctx, ImmutableMap.of()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java index 6e4a46a..ed3116a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java @@ -1,41 +1,45 @@ package net.frozenorb.apiv3.routes.grants; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETEGrant implements Route { +public final class DELETEGrant implements Handler { - public Object handle(Request req, Response res) { - Grant grant = Grant.byId(req.params("id")); + public void handle(RoutingContext ctx) { + Grant grant = Grant.byId(ctx.request().getParam("id")); if (grant == null) { - return ErrorUtils.notFound("Grant", req.params("id")); + ErrorUtils.respondNotFound(ctx, "Grant", ctx.request().getParam("id")); + return; } else if (!grant.isActive()) { - return ErrorUtils.invalidInput("Cannot remove an inactive grant."); + ErrorUtils.respondInvalidInput(ctx, "Cannot remove an inactive grant."); + return; } - User removedBy = User.byId(req.queryParams("removedBy")); + User removedBy = User.byId(ctx.request().getParam("removedBy")); if (removedBy == null) { - return ErrorUtils.notFound("User", req.queryParams("removedBy")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); + return; } - String reason = req.queryParams("reason"); + String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.requiredInput("reason"); + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; } grant.delete(removedBy, reason); - AuditLog.log(removedBy, "", req.attribute("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of()); - return grant; + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of()); + APIv3.respond(ctx, grant); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java index 226ac9f..7be04ae 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java @@ -1,14 +1,14 @@ package net.frozenorb.apiv3.routes.grants; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETGrant implements Route { +public final class GETGrant implements Handler { - public Object handle(Request req, Response res) { - return Grant.byId(req.params("id")); + public void handle(RoutingContext ctx) { + APIv3.respond(ctx, Grant.byId(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java index 37c33ca..e3403c8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java @@ -1,22 +1,21 @@ package net.frozenorb.apiv3.routes.grants; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETGrants implements Route { +public final class GETGrants implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { try { - int limit = req.queryParams("limit") == null ? 100 : Integer.parseInt(req.queryParams("limit")); - int offset = req.queryParams("offset") == null ? 0 : Integer.parseInt(req.queryParams("offset")); + int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); + int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); - return APIv3.getDatastore().createQuery(Grant.class).order("addedAt").limit(limit).offset(offset).asList(); + APIv3.respond(ctx, APIv3.getDatastore().createQuery(Grant.class).order("addedAt").limit(limit).offset(offset).asList()); } catch (NumberFormatException ex) { - return ErrorUtils.invalidInput("limit and offset must be numerical inputs."); + ErrorUtils.respondInvalidInput(ctx, "limit and offset must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java index 726e15b..028d17b 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java @@ -1,21 +1,22 @@ package net.frozenorb.apiv3.routes.grants; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserGrants implements Route { +public final class GETUserGrants implements Handler { - public Object handle(Request req, Response res) { - User target = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User target = User.byId(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.notFound("User", req.params("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } - return target.getGrants(); + APIv3.respond(ctx, target.getGrants()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java index 14bc083..6c12062 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java @@ -6,64 +6,61 @@ import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.Date; import java.util.HashSet; import java.util.Set; -public final class POSTUserGrant implements Route { +public final class POSTUserGrant implements Handler { - public Object handle(Request req, Response res) { - User target = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User target = User.byId(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } - String reason = req.queryParams("reason"); + String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.requiredInput("reason"); + return ErrorUtils.respondRequiredInput("reason"); } Set scopes = new HashSet<>(); - String scopesUnparsed = req.queryParams("scopes"); + String scopesUnparsed = ctx.request().getParam("scopes"); if (!scopesUnparsed.isEmpty()) { for (String serverGroupId : scopesUnparsed.split(",")) { ServerGroup serverGroup = ServerGroup.byId(serverGroupId); if (serverGroup == null) { - return ErrorUtils.notFound("Server group", serverGroupId); + return ErrorUtils.respondNotFound("Server group", serverGroupId); } scopes.add(serverGroup); } } - Rank rank = Rank.byId(req.queryParams("rank")); + Rank rank = Rank.byId(ctx.request().getParam("rank")); if (rank == null) { - return ErrorUtils.notFound("Rank", req.queryParams("rank")); + return ErrorUtils.respondNotFound("Rank", ctx.request().getParam("rank")); } Date expiresAt; try { - expiresAt = new Date(Long.parseLong(req.queryParams("expiresAt"))); + expiresAt = new Date(Long.parseLong(ctx.request().getParam("expiresAt"))); } catch (NumberFormatException ex) { expiresAt = null; } if (expiresAt != null && expiresAt.before(new Date())) { - return ErrorUtils.invalidInput("Expiration date cannot be in the past."); + return ErrorUtils.respondInvalidInput("Expiration date cannot be in the past."); } // We purposely don't do a null check, grants don't have to have a source. - User addedBy = User.byId(req.queryParams("addedBy")); + User addedBy = User.byId(ctx.request().getParam("addedBy")); Grant grant = new Grant(target, reason, scopes, rank, expiresAt, addedBy); APIv3.getDatastore().save(grant); diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java index 13149ab..863a7d4 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java @@ -1,21 +1,22 @@ package net.frozenorb.apiv3.routes.ipLog; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserIPLog implements Route { +public final class GETUserIPLog implements Handler { - public Object handle(Request req, Response res) { - User target = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User target = User.byId(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.notFound("User", req.params("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } - return target.getIPLog(); + APIv3.respond(ctx, target.getIPLog()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java index 22ee7e9..95fe657 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java @@ -1,22 +1,23 @@ package net.frozenorb.apiv3.routes.notificationTemplate; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETENotificationTemplate implements Route { +public final class DELETENotificationTemplate implements Handler { - public Object handle(Request req, Response res) { - NotificationTemplate notificationTemplate = NotificationTemplate.byId(req.params("id")); + public void handle(RoutingContext ctx) { + NotificationTemplate notificationTemplate = NotificationTemplate.byId(ctx.request().getParam("id")); if (notificationTemplate == null) { - return ErrorUtils.notFound("Notification template", req.params("id")); + ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("id")); + return; } notificationTemplate.delete(); - return notificationTemplate; + APIv3.respond(ctx, notificationTemplate); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java index efe8129..9e55dbf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java @@ -1,14 +1,14 @@ package net.frozenorb.apiv3.routes.notificationTemplate; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETNotificationTemplate implements Route { +public final class GETNotificationTemplate implements Handler { - public Object handle(Request req, Response res) { - return NotificationTemplate.byId(req.params("id")); + public void handle(RoutingContext ctx) { + APIv3.respond(ctx, NotificationTemplate.byId(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java index 398510b..3c6f162 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java @@ -1,14 +1,14 @@ package net.frozenorb.apiv3.routes.notificationTemplate; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETNotificationTemplates implements Route { +public final class GETNotificationTemplates implements Handler { - public Object handle(Request req, Response res) { - return NotificationTemplate.values(); + public void handle(RoutingContext ctx) { + APIv3.respond(ctx, NotificationTemplate.values()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java index 43e8398..9aa8c4c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java @@ -1,21 +1,20 @@ package net.frozenorb.apiv3.routes.notificationTemplate; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; -import spark.Request; -import spark.Response; -import spark.Route; -public final class POSTNotificationTemplate implements Route { +public final class POSTNotificationTemplate implements Handler { - public Object handle(Request req, Response res) { - String id = req.queryParams("id"); - String subject = req.queryParams("subject"); - String body = req.queryParams("body"); + public void handle(RoutingContext ctx) { + String id = ctx.request().getParam("id"); + String subject = ctx.request().getParam("subject"); + String body = ctx.request().getParam("body"); NotificationTemplate notificationTemplate = new NotificationTemplate(id, subject, body); APIv3.getDatastore().save(notificationTemplate); - return notificationTemplate; + APIv3.respond(ctx, notificationTemplate); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java index b2fb077..bd578e1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java @@ -6,35 +6,32 @@ import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETEPunishment implements Route { +public final class DELETEPunishment implements Handler { - public Object handle(Request req, Response res) { - Punishment punishment = Punishment.byId(req.params("id")); + public void handle(RoutingContext ctx) { + Punishment punishment = Punishment.byId(ctx.request().getParam("id")); if (punishment == null) { - return ErrorUtils.notFound("Punishment", req.params("id")); + return ErrorUtils.respondNotFound("Punishment", ctx.request().getParam("id")); } else if (!punishment.isActive()) { - return ErrorUtils.invalidInput("Cannot remove an inactive punishment."); + return ErrorUtils.respondInvalidInput("Cannot remove an inactive punishment."); } - User removedBy = User.byId(req.queryParams("removedBy")); + User removedBy = User.byId(ctx.request().getParam("removedBy")); if (removedBy == null) { - return ErrorUtils.notFound("User", req.queryParams("removedBy")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("removedBy")); } - String reason = req.queryParams("reason"); + String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.requiredInput("reason"); + return ErrorUtils.respondRequiredInput("reason"); } punishment.delete(removedBy, reason); - AuditLog.log(removedBy, "", req.attribute("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); return punishment; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java index bfcd539..1315bd4 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java @@ -1,14 +1,11 @@ package net.frozenorb.apiv3.routes.punishments; import net.frozenorb.apiv3.models.Punishment; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETPunishment implements Route { +public final class GETPunishment implements Handler { - public Object handle(Request req, Response res) { - return Punishment.byId(req.params("id")); + public void handle(RoutingContext ctx) { + return Punishment.byId(ctx.request().getParam("id")); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java index 52b1946..821dfb1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java @@ -3,20 +3,17 @@ package net.frozenorb.apiv3.routes.punishments; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETPunishments implements Route { +public final class GETPunishments implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { try { - int limit = req.queryParams("limit") == null ? 100 : Integer.parseInt(req.queryParams("limit")); - int offset = req.queryParams("offset") == null ? 0 : Integer.parseInt(req.queryParams("offset")); + int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); + int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); return APIv3.getDatastore().createQuery(Punishment.class).order("addedAt").limit(limit).offset(offset).asList(); } catch (NumberFormatException ex) { - return ErrorUtils.invalidInput("limit and offset must be numerical inputs."); + return ErrorUtils.respondInvalidInput("limit and offset must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java index 99aece5..79d5774 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java @@ -2,17 +2,14 @@ package net.frozenorb.apiv3.routes.punishments; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserPunishments implements Route { +public final class GETUserPunishments implements Handler { - public Object handle(Request req, Response res) { - User target = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User target = User.byId(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } return target.getPunishments(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java index 9bb1f40..483c29c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java @@ -8,29 +8,26 @@ import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.Permissions; import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.Date; import java.util.Map; -public final class POSTUserPunish implements Route { +public final class POSTUserPunish implements Handler { - public Object handle(Request req, Response res) { - User target = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User target = User.byId(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } - String reason = req.queryParams("reason"); + String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.requiredInput("reason"); + return ErrorUtils.respondRequiredInput("reason"); } - Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(req.queryParams("type")); + Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(ctx.request().getParam("type")); if (type != Punishment.PunishmentType.WARN) { for (Punishment punishment : target.getPunishments(ImmutableSet.of(type))) { @@ -43,29 +40,29 @@ public final class POSTUserPunish implements Route { Date expiresAt; try { - expiresAt = new Date(Long.parseLong(req.queryParams("expiresAt"))); + expiresAt = new Date(Long.parseLong(ctx.request().getParam("expiresAt"))); } catch (NumberFormatException ex) { expiresAt = null; } if (expiresAt != null && expiresAt.before(new Date())) { - return ErrorUtils.invalidInput("Expiration date cannot be in the past."); + return ErrorUtils.respondInvalidInput("Expiration date cannot be in the past."); } Map meta = Document.parse(req.body()); if (meta == null) { - return ErrorUtils.requiredInput("request body meta"); + return ErrorUtils.respondRequiredInput("request body meta"); } // We purposely don't do a null check, grants don't have to have a source. - User addedBy = User.byId(req.queryParams("addedBy")); + User addedBy = User.byId(ctx.request().getParam("addedBy")); if (target.hasPermissionAnywhere(Permissions.PROTECTED_PUNISHMENT)) { return ErrorUtils.error(target.getLastSeenOn() + " is protected from punishments."); } - Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, req.attribute("actor"), meta); + Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, ctx.get("actor"), meta); String accessDenialReason = punishment.getAccessDenialReason(); APIv3.getDatastore().save(punishment); diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java index 2972a3a..b9e1092 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java @@ -2,17 +2,14 @@ package net.frozenorb.apiv3.routes.ranks; import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETERank implements Route { +public final class DELETERank implements Handler { - public Object handle(Request req, Response res) { - Rank rank = Rank.byId(req.params("id")); + public void handle(RoutingContext ctx) { + Rank rank = Rank.byId(ctx.request().getParam("id")); if (rank == null) { - return ErrorUtils.notFound("Rank", req.params("id")); + return ErrorUtils.respondNotFound("Rank", ctx.request().getParam("id")); } rank.delete(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java index de038cb..91a692f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java @@ -1,14 +1,11 @@ package net.frozenorb.apiv3.routes.ranks; import net.frozenorb.apiv3.models.Rank; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETRank implements Route { +public final class GETRank implements Handler { - public Object handle(Request req, Response res) { - return Rank.byId(req.params("id")); + public void handle(RoutingContext ctx) { + return Rank.byId(ctx.request().getParam("id")); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java index 6d366da..d8dd68e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java @@ -1,13 +1,10 @@ package net.frozenorb.apiv3.routes.ranks; import net.frozenorb.apiv3.models.Rank; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETRanks implements Route { +public final class GETRanks implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { return Rank.values(); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java index 5ad1351..e7ed2e8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java @@ -2,19 +2,16 @@ package net.frozenorb.apiv3.routes.ranks; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Rank; -import spark.Request; -import spark.Response; -import spark.Route; -public final class POSTRank implements Route { +public final class POSTRank implements Handler { - public Object handle(Request req, Response res) { - String id = req.queryParams("id"); - int weight = Integer.parseInt(req.queryParams("weight")); - String displayName = req.queryParams("displayName"); - String gameColor = req.queryParams("gameColor"); - String websiteColor = req.queryParams("websiteColor"); - boolean staffRank = Boolean.parseBoolean(req.queryParams("staffRank")); + public void handle(RoutingContext ctx) { + String id = ctx.request().getParam("id"); + int weight = Integer.parseInt(ctx.request().getParam("weight")); + String displayName = ctx.request().getParam("displayName"); + String gameColor = ctx.request().getParam("gameColor"); + String websiteColor = ctx.request().getParam("websiteColor"); + boolean staffRank = Boolean.parseBoolean(ctx.request().getParam("staffRank")); Rank rank = new Rank(id, weight, displayName, gameColor, websiteColor, staffRank); APIv3.getDatastore().save(rank); diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java index 37bb85e..1fa5451 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java @@ -2,17 +2,14 @@ package net.frozenorb.apiv3.routes.serverGroups; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETEServerGroup implements Route { +public final class DELETEServerGroup implements Handler { - public Object handle(Request req, Response res) { - ServerGroup serverGroup = ServerGroup.byId(req.params("id")); + public void handle(RoutingContext ctx) { + ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("id")); if (serverGroup == null) { - return ErrorUtils.notFound("Server group", req.params("id")); + return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("id")); } serverGroup.delete(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java index f6ef344..39ba0ea 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java @@ -1,14 +1,11 @@ package net.frozenorb.apiv3.routes.serverGroups; import net.frozenorb.apiv3.models.ServerGroup; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETServerGroup implements Route { +public final class GETServerGroup implements Handler { - public Object handle(Request req, Response res) { - return ServerGroup.byId(req.params("id")); + public void handle(RoutingContext ctx) { + return ServerGroup.byId(ctx.request().getParam("id")); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java index c330538..1788dda 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java @@ -1,13 +1,10 @@ package net.frozenorb.apiv3.routes.serverGroups; import net.frozenorb.apiv3.models.ServerGroup; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETServerGroups implements Route { +public final class GETServerGroups implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { return ServerGroup.values(); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java index 100a44a..3055f8e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java @@ -2,16 +2,13 @@ package net.frozenorb.apiv3.routes.serverGroups; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; -import spark.Request; -import spark.Response; -import spark.Route; -public final class POSTServerGroup implements Route { +public final class POSTServerGroup implements Handler { - public Object handle(Request req, Response res) { - String id = req.queryParams("id"); - String image = req.queryParams("image"); - boolean isPublic = Boolean.valueOf(req.queryParams("public")); + public void handle(RoutingContext ctx) { + String id = ctx.request().getParam("id"); + String image = ctx.request().getParam("image"); + boolean isPublic = Boolean.valueOf(ctx.request().getParam("public")); ServerGroup serverGroup = new ServerGroup(id, image, isPublic); APIv3.getDatastore().save(serverGroup); diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java index 8333b89..83cf362 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java @@ -2,17 +2,14 @@ package net.frozenorb.apiv3.routes.servers; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETEServer implements Route { +public final class DELETEServer implements Handler { - public Object handle(Request req, Response res) { - Server server = Server.byId(req.params("id")); + public void handle(RoutingContext ctx) { + Server server = Server.byId(ctx.request().getParam("id")); if (server == null) { - return ErrorUtils.notFound("Server", req.params("id")); + return ErrorUtils.respondNotFound("Server", ctx.request().getParam("id")); } server.delete(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java index 6058c1b..973528c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java @@ -1,14 +1,11 @@ package net.frozenorb.apiv3.routes.servers; import net.frozenorb.apiv3.models.Server; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETServer implements Route { +public final class GETServer implements Handler { - public Object handle(Request req, Response res) { - return Server.byId(req.params("id")); + public void handle(RoutingContext ctx) { + return Server.byId(ctx.request().getParam("id")); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java index c1a853f..52cb5ad 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java @@ -1,13 +1,10 @@ package net.frozenorb.apiv3.routes.servers; import net.frozenorb.apiv3.models.Server; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETServers implements Route { +public final class GETServers implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { return Server.values(); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java index 8a41865..a534f03 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java @@ -5,25 +5,22 @@ import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class POSTServer implements Route { +public final class POSTServer implements Handler { - public Object handle(Request req, Response res) { - String id = req.queryParams("id"); - String displayName = req.queryParams("displayName"); - String apiKey = req.queryParams("apiKey"); - ServerGroup group = ServerGroup.byId(req.queryParams("group")); - String ip = req.queryParams("ip"); + public void handle(RoutingContext ctx) { + String id = ctx.request().getParam("id"); + String displayName = ctx.request().getParam("displayName"); + String apiKey = ctx.request().getParam("apiKey"); + ServerGroup group = ServerGroup.byId(ctx.request().getParam("group")); + String ip = ctx.request().getParam("ip"); if (group == null) { - return ErrorUtils.notFound("Server group", req.queryParams("group")); + return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("group")); } if (!IPUtils.isValidIP(ip)) { - return ErrorUtils.invalidInput("IP address \"" + ip + "\" is not valid."); + return ErrorUtils.respondInvalidInput("IP address \"" + ip + "\" is not valid."); } Server server = new Server(id, displayName, apiKey, group, ip); diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java index 278f592..bbd3721 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java @@ -10,21 +10,18 @@ import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.PermissionUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.*; @Slf4j -public final class POSTServerHeartbeat implements Route { +public final class POSTServerHeartbeat implements Handler { @SuppressWarnings("unchecked") - public Object handle(Request req, Response res) { - Actor actor = req.attribute("actor"); + public void handle(RoutingContext ctx) { + Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { - return ErrorUtils.serverOnly(); + return ErrorUtils.respondServerOnly(); } Server actorServer = Server.byId(actor.getName()); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java index cfca7ce..e7c9cd6 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java @@ -4,23 +4,20 @@ import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.UserMetaEntry; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETEUserMeta implements Route { +public final class DELETEUserMeta implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } - ServerGroup serverGroup = ServerGroup.byId(req.params("serverGroup")); + ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("serverGroup")); if (serverGroup == null) { - return ErrorUtils.notFound("Server group", req.params("serverGroup")); + return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("serverGroup")); } UserMetaEntry userMetaEntry = user.getMeta(serverGroup); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java index 2dd304e..ecfc385 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java @@ -7,36 +7,33 @@ import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class DELETEUserPunishment implements Route { +public final class DELETEUserPunishment implements Handler { - public Object handle(Request req, Response res) { - User target = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User target = User.byId(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } - Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(req.queryParams("type").toUpperCase()); - User removedBy = User.byId(req.queryParams("removedBy")); + Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(ctx.request().getParam("type").toUpperCase()); + User removedBy = User.byId(ctx.request().getParam("removedBy")); if (removedBy == null) { - return ErrorUtils.notFound("User", req.queryParams("removedBy")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("removedBy")); } - String reason = req.queryParams("reason"); + String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.requiredInput("reason"); + return ErrorUtils.respondRequiredInput("reason"); } for (Punishment punishment : target.getPunishments(ImmutableSet.of(type))) { if (punishment.isActive()) { punishment.delete(removedBy, reason); - AuditLog.log(removedBy, "", req.attribute("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); return punishment; } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java index 271eb1a..55291f2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java @@ -4,15 +4,12 @@ import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.models.User; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.*; -public final class GETStaff implements Route { +public final class GETStaff implements Handler { - public Object handle(Request req, Response res) { + public void handle(RoutingContext ctx) { Map staffRanks = new HashMap<>(); Rank.values().forEach(rank -> { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java index 42fefbb..f18c8ce 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java @@ -1,14 +1,11 @@ package net.frozenorb.apiv3.routes.users; import net.frozenorb.apiv3.models.User; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUser implements Route { +public final class GETUser implements Handler { - public Object handle(Request req, Response res) { - return User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + return User.byId(ctx.request().getParam("id")); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java index 76079c9..c4cf2ff 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java @@ -3,17 +3,14 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserDetails implements Route { +public final class GETUserDetails implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } // Too many fields to use .of() diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java index 90dbde4..4d1e38e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java @@ -4,23 +4,20 @@ import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.UserMetaEntry; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserMeta implements Route { +public final class GETUserMeta implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } - ServerGroup serverGroup = ServerGroup.byId(req.params("serverGroup")); + ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("serverGroup")); if (serverGroup == null) { - return ErrorUtils.notFound("Server group", req.params("serverGroup")); + return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("serverGroup")); } UserMetaEntry userMetaEntry = user.getMeta(serverGroup); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java index 201d0c7..f8b080f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java @@ -5,17 +5,14 @@ import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.TOTPUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserRequiresTOTP implements Route { +public final class GETUserRequiresTOTP implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } if (user.getTotpSecret() == null) { @@ -25,10 +22,10 @@ public final class GETUserRequiresTOTP implements Route { ); } - String userIp = req.queryParams("userIp"); + String userIp = ctx.request().getParam("userIp"); if (!IPUtils.isValidIP(userIp)) { - return ErrorUtils.invalidInput("IP address \"" + userIp + "\" is not valid."); + return ErrorUtils.respondInvalidInput("IP address \"" + userIp + "\" is not valid."); } if (TOTPUtils.isPreAuthorized(user, userIp)) { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java index 35fdf69..cd6794d 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java @@ -3,24 +3,21 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class GETUserVerifyPassword implements Route { +public final class GETUserVerifyPassword implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } if (user.getPassword() == null) { - return ErrorUtils.invalidInput("User provided does not have password set."); + return ErrorUtils.respondInvalidInput("User provided does not have password set."); } - boolean authorized = user.checkPassword(req.queryParams("password")); + boolean authorized = user.checkPassword(ctx.request().getParam("password")); return ImmutableMap.of( "authorized", authorized diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java index b70b41f..af17685 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java @@ -5,14 +5,11 @@ import com.google.common.collect.ImmutableMap; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.List; import java.util.concurrent.TimeUnit; -public final class POSTUserConfirmRegister implements Route { +public final class POSTUserConfirmRegister implements Handler { private final List commonPasswords = ImmutableList.copyOf(("123456 password 12345678 qwerty 123456789 12345 1234 111111 1234567 dragon " + "123123 baseball abc123 football monkey letmein 696969 shadow master 666666 qwertyuiop 123321 mustang 1234567890 " + @@ -22,11 +19,11 @@ public final class POSTUserConfirmRegister implements Route { " 131313 freedom 777777 pass fuck maggie 159753 aaaaaa ginger princess joshua cheese amanda summer love ashley 6969 " + "nicole chelsea biteme matthew access yankees 987654321 dallas austin thunder taylor matrix").split(" ")); - public Object handle(Request req, Response res) { - User user = User.byEmailToken(req.params("emailToken")); + public void handle(RoutingContext ctx) { + User user = User.byEmailToken(ctx.request().getParam("emailToken")); if (user == null) { - return ErrorUtils.notFound("Email token", req.params("emailToken")); + return ErrorUtils.respondNotFound("Email token", ctx.request().getParam("emailToken")); } // We can't check email != null as that's set while we're pending @@ -39,7 +36,7 @@ public final class POSTUserConfirmRegister implements Route { return ErrorUtils.error("Email token is expired"); } - String password = req.queryParams("password"); + String password = ctx.request().getParam("password"); if (password.length() < 8) { return ErrorUtils.error("Your password is too short."); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java index b3c47b1..8e2a6e5 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java @@ -5,16 +5,15 @@ import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; -import spark.Route; -public class POSTUserLeave implements Route { +public class POSTUserLeave implements Handler { @Override public Object handle(Request req, Response res) throws Exception { - User user = User.byId(req.params("id")); + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } user.leftServer(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java index ad6e4d5..9fbc900 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java @@ -1,6 +1,5 @@ package net.frozenorb.apiv3.routes.users; -import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; import net.frozenorb.apiv3.models.Server; @@ -8,32 +7,29 @@ import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.UUIDUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.UUID; -public final class POSTUserLogin implements Route { +public final class POSTUserLogin implements Handler { - public Object handle(Request req, Response res) { - UUID uuid = UUID.fromString(req.params("id")); + public void handle(RoutingContext ctx) { + UUID uuid = UUID.fromString(ctx.request().getParam("id")); if (!UUIDUtils.isAcceptableUUID(uuid)) { - return ErrorUtils.invalidInput("UUID \"" + uuid + "\" is not valid - must be version 4 UUID."); + return ErrorUtils.respondInvalidInput("UUID \"" + uuid + "\" is not valid - must be version 4 UUID."); } User user = User.byId(uuid); - String username = req.queryParams("username"); - String userIp = req.queryParams("userIp"); - Actor actor = req.attribute("actor"); + String username = ctx.request().getParam("username"); + String userIp = ctx.request().getParam("userIp"); + Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { - return ErrorUtils.serverOnly(); + return ErrorUtils.respondServerOnly(); } if (!IPUtils.isValidIP(userIp)) { - return ErrorUtils.invalidInput("IP address \"" + userIp + "\" is not valid."); + return ErrorUtils.respondInvalidInput("IP address \"" + userIp + "\" is not valid."); } if (user == null) { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java index 4774817..d79d783 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java @@ -5,30 +5,27 @@ import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.HashMap; import java.util.Map; -public final class POSTUserNotify implements Route { +public final class POSTUserNotify implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } if (user.getEmail() == null) { return ErrorUtils.error("User provided does not have email set."); } - NotificationTemplate template = NotificationTemplate.byId(req.queryParams("template")); + NotificationTemplate template = NotificationTemplate.byId(ctx.request().getParam("template")); if (template == null) { - return ErrorUtils.notFound("Notification template", req.queryParams("template")); + return ErrorUtils.respondNotFound("Notification template", ctx.request().getParam("template")); } Map subjectReplacements = new HashMap<>(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java index 185fa74..7b80338 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java @@ -6,9 +6,6 @@ import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.math.BigInteger; import java.util.Date; @@ -17,25 +14,25 @@ import java.util.Random; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; -public final class POSTUserRegister implements Route { +public final class POSTUserRegister implements Handler { private static final Pattern VALID_EMAIL_PATTERN = Pattern.compile( "^[A-Z0-9._%+-]+@[A-Z0-9.-]+\\.[A-Z]{2,6}$", Pattern.CASE_INSENSITIVE ); - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } if (user.getEmail() != null) { - return ErrorUtils.invalidInput("User provided already has email set."); + return ErrorUtils.respondInvalidInput("User provided already has email set."); } - String email = req.queryParams("email"); + String email = ctx.request().getParam("email"); if (!VALID_EMAIL_PATTERN.matcher(email).matches()) { return ErrorUtils.error(email + " is not a valid email."); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java index 0305087..5a4e9c6 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java @@ -6,21 +6,18 @@ import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.TOTPUtils; -import spark.Request; -import spark.Response; -import spark.Route; -public final class POSTUserSetupTOTP implements Route { +public final class POSTUserSetupTOTP implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } if (user.getTotpSecret() != null) { - return ErrorUtils.invalidInput("User provided already has TOTP code set."); + return ErrorUtils.respondInvalidInput("User provided already has TOTP code set."); } GoogleAuthenticatorKey generated = TOTPUtils.generateTOTPKey(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java index 2e0c19b..2deb032 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java @@ -5,32 +5,29 @@ import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.TOTPUtils; -import spark.Request; -import spark.Response; -import spark.Route; import java.util.concurrent.TimeUnit; -public final class POSTUserVerifyTOTP implements Route { +public final class POSTUserVerifyTOTP implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } if (user.getTotpSecret() == null) { - return ErrorUtils.invalidInput("User provided does not have TOTP code set."); + return ErrorUtils.respondInvalidInput("User provided does not have TOTP code set."); } - String userIp = req.queryParams("userIp"); + String userIp = ctx.request().getParam("userIp"); if (!IPUtils.isValidIP(userIp)) { - return ErrorUtils.invalidInput("IP address \"" + userIp + "\" is not valid."); + return ErrorUtils.respondInvalidInput("IP address \"" + userIp + "\" is not valid."); } - int providedCode = Integer.parseInt(req.queryParams("code")); + int providedCode = Integer.parseInt(ctx.request().getParam("code")); if (TOTPUtils.wasRecentlyUsed(user, providedCode)) { return ImmutableMap.of( diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java index 3eded9f..0ff4eca 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java @@ -4,23 +4,20 @@ import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; -import spark.Request; -import spark.Response; -import spark.Route; -public final class PUTUserMeta implements Route { +public final class PUTUserMeta implements Handler { - public Object handle(Request req, Response res) { - User user = User.byId(req.params("id")); + public void handle(RoutingContext ctx) { + User user = User.byId(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.notFound("User", req.params("id")); + return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); } - ServerGroup serverGroup = ServerGroup.byId(req.params("serverGroup")); + ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("serverGroup")); if (serverGroup == null) { - return ErrorUtils.notFound("Server group", req.params("serverGroup")); + return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("serverGroup")); } Document data = Document.parse(req.body()); diff --git a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java index e0b4c83..9e25530 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java @@ -1,34 +1,34 @@ package net.frozenorb.apiv3.utils; import com.google.common.collect.ImmutableMap; +import io.vertx.ext.web.RoutingContext; import lombok.experimental.UtilityClass; - -import java.util.Map; +import net.frozenorb.apiv3.APIv3; @UtilityClass public class ErrorUtils { - public static Map serverOnly() { - return error("This action can only be performed when requested by a server."); + public static void respondServerOnly(RoutingContext ctx) { + error(ctx, "This action can only be performed when requested by a server."); } - public static Map notFound(String itemType, String id) { - return error("Not found: " + itemType + " with id " + id + " cannot be found."); + public static void respondNotFound(RoutingContext ctx, String itemType, String id) { + error(ctx, "Not found: " + itemType + " with id " + id + " cannot be found."); } - public static Map invalidInput(String message) { - return error("Invalid input: " + message); + public static void respondInvalidInput(RoutingContext ctx, String message) { + error(ctx, "Invalid input: " + message + "."); } - public static Map requiredInput(String field) { - return error("Field \"" + field + "\" is required."); + public static void respondRequiredInput(RoutingContext ctx, String field) { + error(ctx, "Field \"" + field + "\" is required."); } - public static Map error(String message) { - return ImmutableMap.of( + public static void error(RoutingContext ctx, String message) { + APIv3.respond(ctx, ImmutableMap.of( "success", false, "message", message - ); + )); } } \ No newline at end of file From 60a622fc43c579df17fce19f7e928caa7589c0c4 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 9 Jun 2016 22:39:23 -0400 Subject: [PATCH 2/8] Push a bunch of experimental code (this doesn't currently work/compile) --- apiv3.properties | 2 - pom.xml | 88 +++--- src/main/java/net/frozenorb/apiv3/APIv3.java | 261 +++++++++--------- src/main/java/net/frozenorb/apiv3/Main.java | 4 +- .../net/frozenorb/apiv3/actors/UserActor.java | 2 +- .../frozenorb/apiv3/auditLog/AuditLog.java | 3 +- .../apiv3/filters/ActorAttributeFilter.java | 57 ++-- .../apiv3/filters/AuthorizationFilter.java | 16 +- .../apiv3/filters/ContentTypeFilter.java | 13 - .../apiv3/filters/LoggingFilter.java | 21 -- .../apiv3/filters/MetricsAfterFilter.java | 16 -- .../apiv3/filters/MetricsBeforeFilter.java | 13 - .../apiv3/filters/MetricsHandler.java | 14 + .../frozenorb/apiv3/models/AuditLogEntry.java | 42 ++- .../net/frozenorb/apiv3/models/Grant.java | 75 ++--- .../frozenorb/apiv3/models/IPLogEntry.java | 52 +++- .../apiv3/models/NotificationTemplate.java | 58 ++-- .../frozenorb/apiv3/models/Punishment.java | 85 +++--- .../java/net/frozenorb/apiv3/models/Rank.java | 56 ++-- .../net/frozenorb/apiv3/models/Server.java | 60 ++-- .../frozenorb/apiv3/models/ServerGroup.java | 55 ++-- .../java/net/frozenorb/apiv3/models/User.java | 177 +++++------- .../frozenorb/apiv3/models/UserMetaEntry.java | 52 +++- .../net/frozenorb/apiv3/routes/GETDump.java | 22 +- .../net/frozenorb/apiv3/routes/GETWhoAmI.java | 7 +- .../net/frozenorb/apiv3/routes/NotFound.java | 17 -- .../frozenorb/apiv3/routes/POSTMetrics.java | 7 +- .../announcements/GETAnnouncements.java | 4 +- .../apiv3/routes/auditLog/GETAuditLog.java | 2 +- .../chatFilterList/GETChatFilterList.java | 3 +- .../apiv3/routes/grants/DELETEGrant.java | 6 +- .../apiv3/routes/grants/GETGrant.java | 2 +- .../apiv3/routes/grants/GETGrants.java | 2 +- .../apiv3/routes/grants/GETUserGrants.java | 5 +- .../apiv3/routes/grants/POSTUserGrant.java | 29 +- .../apiv3/routes/ipLog/GETUserIPLog.java | 5 +- .../DELETENotificationTemplate.java | 4 +- .../GETNotificationTemplate.java | 2 +- .../GETNotificationTemplates.java | 2 +- .../POSTNotificationTemplate.java | 4 +- .../routes/punishments/DELETEPunishment.java | 21 +- .../routes/punishments/GETPunishment.java | 5 +- .../routes/punishments/GETPunishments.java | 6 +- .../punishments/GETUserPunishments.java | 11 +- .../routes/punishments/POSTUserPunish.java | 34 ++- .../apiv3/routes/ranks/DELETERank.java | 10 +- .../frozenorb/apiv3/routes/ranks/GETRank.java | 5 +- .../apiv3/routes/ranks/GETRanks.java | 5 +- .../apiv3/routes/ranks/POSTRank.java | 6 +- .../serverGroups/DELETEServerGroup.java | 10 +- .../routes/serverGroups/GETServerGroup.java | 5 +- .../routes/serverGroups/GETServerGroups.java | 5 +- .../routes/serverGroups/POSTServerGroup.java | 6 +- .../apiv3/routes/servers/DELETEServer.java | 10 +- .../apiv3/routes/servers/GETServer.java | 5 +- .../apiv3/routes/servers/GETServers.java | 5 +- .../apiv3/routes/servers/POSTServer.java | 14 +- .../routes/servers/POSTServerHeartbeat.java | 23 +- .../apiv3/routes/users/DELETEUserMeta.java | 24 +- .../routes/users/DELETEUserPunishment.java | 21 +- .../apiv3/routes/users/GETStaff.java | 14 +- .../frozenorb/apiv3/routes/users/GETUser.java | 5 +- .../apiv3/routes/users/GETUserDetails.java | 22 +- .../apiv3/routes/users/GETUserMeta.java | 17 +- .../routes/users/GETUserRequiresTOTP.java | 30 +- .../routes/users/GETUserVerifyPassword.java | 15 +- .../routes/users/POSTUserConfirmRegister.java | 25 +- .../apiv3/routes/users/POSTUserLeave.java | 17 +- .../apiv3/routes/users/POSTUserLogin.java | 18 +- .../apiv3/routes/users/POSTUserNotify.java | 27 +- .../apiv3/routes/users/POSTUserRegister.java | 26 +- .../apiv3/routes/users/POSTUserSetupTOTP.java | 16 +- .../routes/users/POSTUserVerifyTOTP.java | 27 +- .../apiv3/routes/users/PUTUserMeta.java | 17 +- .../apiv3/unsorted/BlockingCallback.java | 29 ++ .../unsorted/LoggingExceptionHandler.java | 27 -- .../net/frozenorb/apiv3/utils/ErrorUtils.java | 13 +- .../frozenorb/apiv3/utils/MojangUtils.java | 47 ++-- .../apiv3/utils/PermissionUtils.java | 2 +- .../net/frozenorb/apiv3/utils/SyncUtils.java | 27 ++ 80 files changed, 1156 insertions(+), 841 deletions(-) delete mode 100644 src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java delete mode 100644 src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java delete mode 100644 src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java delete mode 100644 src/main/java/net/frozenorb/apiv3/filters/MetricsBeforeFilter.java create mode 100644 src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/NotFound.java create mode 100644 src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java delete mode 100644 src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java create mode 100644 src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java diff --git a/apiv3.properties b/apiv3.properties index 18a9727..e307d26 100644 --- a/apiv3.properties +++ b/apiv3.properties @@ -8,9 +8,7 @@ mongo.username= mongo.password= redis.address=localhost redis.port=6379 -http.address=0.0.0.0 http.port=80 -http.workerThreads= twillio.accountSID=AC9e2f88c5690134d29a56f698de3cd740 twillio.authToken=982592505a171d3be6b0722f5ecacc0e mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ diff --git a/pom.xml b/pom.xml index e8340c0..2ce866f 100644 --- a/pom.xml +++ b/pom.xml @@ -58,6 +58,7 @@ + io.vertx vertx-core @@ -68,36 +69,39 @@ vertx-web LATEST + + com.google.guava guava 19.0 - - redis.clients - jedis - 2.8.1 - com.google.code.gson gson 2.6.2 - - com.indeed - java-dogstatsd-client - 2.0.12 - - - com.bugsnag - bugsnag - 2.0.0 - + + org.mongodb - mongo-java-driver - 3.2.2 + mongodb-driver-async + 3.0.4 + + eu.dozd + mongo-mapper + 1.0.1 + + + + + redis.clients + jedis + 2.8.1 + + + com.cribbstechnologies.clients mandrillClient @@ -108,46 +112,34 @@ twilio-java-sdk 6.3.0 - - org.mindrot - jbcrypt - 0.3m - - - org.mongodb.morphia - morphia - 1.1.0 - - - org.mongodb.morphia - morphia-logging-slf4j - 1.1.0 - - - org.slf4j - slf4j-simple - 1.6.4 - - - org.apache.httpcomponents - httpcore - 4.4 - + + com.warrenstrange googleauth 0.5.0 + + - com.squareup.okhttp3 - okhttp - 3.2.0 + com.indeed + java-dogstatsd-client + 2.0.12 - com.squareup.okio - okio - 1.8.0 + com.bugsnag + bugsnag + 2.0.0 + + + + org.slf4j + slf4j-simple + 1.6.4 + + + org.projectlombok lombok diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 41e0d09..a82c07c 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -6,23 +6,36 @@ import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.mongodb.*; -import com.mongodb.client.MongoDatabase; +import com.mongodb.Block; +import com.mongodb.MongoCredential; +import com.mongodb.ServerAddress; +import com.mongodb.async.client.MongoClient; +import com.mongodb.async.client.MongoClientSettings; +import com.mongodb.async.client.MongoClients; +import com.mongodb.async.client.MongoDatabase; +import com.mongodb.connection.ClusterSettings; import com.timgroup.statsd.NonBlockingStatsDClient; import com.timgroup.statsd.StatsDClient; +import eu.dozd.mongo.MongoMapper; +import io.vertx.core.AbstractVerticle; +import io.vertx.core.http.HttpClient; +import io.vertx.core.http.HttpServer; import io.vertx.ext.web.Router; import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.BodyHandler; +import io.vertx.ext.web.handler.LoggerHandler; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.filters.*; +import net.frozenorb.apiv3.filters.ActorAttributeFilter; +import net.frozenorb.apiv3.filters.AuthorizationFilter; +import net.frozenorb.apiv3.filters.MetricsHandler; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.IPLogEntry; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.routes.GETDump; import net.frozenorb.apiv3.routes.GETWhoAmI; -import net.frozenorb.apiv3.routes.NotFound; import net.frozenorb.apiv3.routes.POSTMetrics; import net.frozenorb.apiv3.routes.announcements.GETAnnouncements; import net.frozenorb.apiv3.routes.auditLog.GETAuditLog; @@ -48,16 +61,11 @@ import net.frozenorb.apiv3.serialization.DateTypeAdapter; import net.frozenorb.apiv3.serialization.FollowAnnotationExclusionStrategy; import net.frozenorb.apiv3.serialization.ObjectIdTypeAdapter; import net.frozenorb.apiv3.unsorted.BugsnagSLF4JLogger; -import net.frozenorb.apiv3.unsorted.LoggingExceptionHandler; import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; +import org.bson.codecs.configuration.CodecRegistries; import org.bson.types.ObjectId; -import org.mongodb.morphia.Datastore; -import org.mongodb.morphia.Morphia; -import org.mongodb.morphia.converters.UUIDConverter; -import org.mongodb.morphia.logging.MorphiaLoggerFactory; -import org.mongodb.morphia.logging.slf4j.SLF4JLoggerImplFactory; import redis.clients.jedis.JedisPool; import java.io.FileInputStream; @@ -66,13 +74,11 @@ import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; -import static spark.Spark.*; -import static spark.route.RouteOverview.enableRouteOverview; - @Slf4j -public final class APIv3 { +public final class APIv3 extends AbstractVerticle { - @Getter private static Datastore datastore; + @Getter private static HttpClient httpClient; + @Getter private static MongoDatabase database; @Getter private static Properties config = new Properties(); @Getter private static JedisPool redisPool; @Getter private static StatsDClient statsD; @@ -82,7 +88,8 @@ public final class APIv3 { .setExclusionStrategies(new FollowAnnotationExclusionStrategy()) .create(); - APIv3() { + @Override + public void start() { setupConfig(); System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", config.getProperty("logging.level")); @@ -90,10 +97,9 @@ public final class APIv3 { setupRedis(); setupMetrics(); setupBugsnag(); - setupHttp(); + setupHttpServer(); //convertData("158.69.126.126", true); - LoggingFilter.setDebug(Boolean.valueOf(config.getProperty("logging.debug"))); } private void setupConfig() { @@ -108,28 +114,33 @@ public final class APIv3 { ImmutableList credentials = ImmutableList.of(); if (!config.getProperty("mongo.username").isEmpty()) { - credentials = ImmutableList.of(MongoCredential.createCredential( - config.getProperty("mongo.username"), - config.getProperty("mongo.database"), - config.getProperty("mongo.password").toCharArray() - )); + credentials = ImmutableList.of( + MongoCredential.createCredential( + config.getProperty("mongo.username"), + config.getProperty("mongo.database"), + config.getProperty("mongo.password").toCharArray() + ) + ); } - MongoClient mongoClient = new MongoClient(new ServerAddress( - config.getProperty("mongo.address"), - Integer.parseInt(config.getProperty("mongo.port"))), - credentials - ); + ClusterSettings clusterSettings = ClusterSettings + .builder() + .hosts(ImmutableList.of( + new ServerAddress( + config.getProperty("mongo.address"), + Integer.parseInt(config.getProperty("mongo.port")) + ) + )) + .build(); + MongoClientSettings settings = MongoClientSettings + .builder() + .codecRegistry(CodecRegistries.fromProviders(MongoMapper.getProviders())) + .credentialList(credentials) + .clusterSettings(clusterSettings).build(); - MorphiaLoggerFactory.reset(); - MorphiaLoggerFactory.registerLogger(SLF4JLoggerImplFactory.class); - - Morphia morphia = new Morphia(); - morphia.mapPackage("net.frozenorb.apiv3.models"); - morphia.getMapper().getConverters().addConverter(new UUIDConverter()); - - datastore = morphia.createDatastore(mongoClient, config.getProperty("mongo.database")); - datastore.ensureIndexes(); + MongoClient client = MongoClients.create(settings); + database = client.getDatabase(config.getProperty("mongo.database")); + // TODO: Indexes } private void setupRedis() { @@ -160,103 +171,105 @@ public final class APIv3 { bugsnag.setLogger(new BugsnagSLF4JLogger()); } - private void setupHttp() { - Router.router() - ipAddress(config.getProperty("http.address")); - port(Integer.parseInt(config.getProperty("http.port"))); - String workerThreads = config.getProperty("http.workerThreads"); + private void setupHttpServer() { + HttpServer webServer = vertx.createHttpServer(); + Router mainRouter = Router.router(vertx); - if (!workerThreads.isEmpty()) { - threadPool(Integer.parseInt(workerThreads)); - } - - before(new MetricsBeforeFilter()); - before(new ContentTypeFilter()); - before(new ActorAttributeFilter()); - before(new AuthorizationFilter()); - after(new MetricsAfterFilter()); - after(new LoggingFilter()); - exception(Exception.class, new LoggingExceptionHandler()); + mainRouter.route().handler(new MetricsHandler()); + mainRouter.route().handler(new ActorAttributeFilter()); + mainRouter.route().handler(new AuthorizationFilter()); + mainRouter.route().handler(LoggerHandler.create()); + mainRouter.route().handler(BodyHandler.create()); // TODO: The commented out routes - post("/metrics", new POSTMetrics(), gson::toJson); - get("/announcements", new GETAnnouncements(), gson::toJson); - get("/auditLog", new GETAuditLog(), gson::toJson); - get("/chatFilterList", new GETChatFilterList(), gson::toJson); - get("/dump/:type", new GETDump(), gson::toJson); - get("/whoami", new GETWhoAmI(), gson::toJson); - enableRouteOverview("/routes"); + mainRouter.post("/metrics").blockingHandler(new POSTMetrics()); + mainRouter.get("/announcements").blockingHandler(new GETAnnouncements()); + mainRouter.get("/auditLog").blockingHandler(new GETAuditLog()); + mainRouter.get("/chatFilterList").blockingHandler(new GETChatFilterList()); + mainRouter.get("/dump/:type").blockingHandler(new GETDump()); + mainRouter.get("/whoami").blockingHandler(new GETWhoAmI()); - get("/grant/:id", new GETGrant(), gson::toJson); - get("/grants", new GETGrants(), gson::toJson); - delete("/grant/:id", new DELETEGrant(), gson::toJson); + mainRouter.get("/grant/:id").blockingHandler(new GETGrant()); + mainRouter.get("/grants").blockingHandler(new GETGrants()); + mainRouter.delete("/grant/:id").blockingHandler(new DELETEGrant()); - get("/notificationTemplate/:id", new GETNotificationTemplate(), gson::toJson); - get("/notificationTemplates", new GETNotificationTemplates(), gson::toJson); - post("/notificationTemplate", new POSTNotificationTemplate(), gson::toJson); - //put("/notificationTemplate/:id", new PUTNotificationTemplate(), gson::toJson); - delete("/notificationTemplate/:id", new DELETENotificationTemplate(), gson::toJson); + 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()); - get("/punishment/:id", new GETPunishment(), gson::toJson); - get("/punishments", new GETPunishments(), gson::toJson); - delete("/punishment/:id", new DELETEPunishment(), gson::toJson); + mainRouter.get("/punishment/:id").blockingHandler(new GETPunishment()); + mainRouter.get("/punishments").blockingHandler(new GETPunishments()); + mainRouter.delete("/punishment/:id").blockingHandler(new DELETEPunishment()); - get("/rank/:id", new GETRank(), gson::toJson); - get("/ranks", new GETRanks(), gson::toJson); - post("/rank", new POSTRank(), gson::toJson); - //put("/rank/:id", new PUTRank(), gson::toJson); - delete("/rank/:id", new DELETERank(), gson::toJson); + mainRouter.get("/rank/:id").blockingHandler(new GETRank()); + mainRouter.get("/ranks").blockingHandler(new GETRanks()); + mainRouter.post("/rank").blockingHandler(new POSTRank()); + //put("/rank/:id").blockingHandler(new PUTRank()); + mainRouter.delete("/rank/:id").blockingHandler(new DELETERank()); - get("/serverGroup/:id", new GETServerGroup(), gson::toJson); - get("/serverGroups", new GETServerGroups(), gson::toJson); - post("/serverGroup", new POSTServerGroup(), gson::toJson); - //put("/serverGroup/:id", new PUTServerGroup(), gson::toJson); - delete("/serverGroup/:id", new DELETEServerGroup(), gson::toJson); + mainRouter.get("/serverGroup/:id").blockingHandler(new GETServerGroup()); + mainRouter.get("/serverGroups").blockingHandler(new GETServerGroups()); + mainRouter.post("/serverGroup").blockingHandler(new POSTServerGroup()); + //put("/serverGroup/:id").blockingHandler(new PUTServerGroup()); + mainRouter.delete("/serverGroup/:id").blockingHandler(new DELETEServerGroup()); - get("/server/:id", new GETServer(), gson::toJson); - get("/servers", new GETServers(), gson::toJson); - post("/server/heartbeat", new POSTServerHeartbeat(), gson::toJson); - post("/server", new POSTServer(), gson::toJson); - //put("/server/:id", new PUTServer(), gson::toJson); - delete("/server/:id", new DELETEServer(), gson::toJson); + mainRouter.get("/server/:id").blockingHandler(new GETServer()); + mainRouter.get("/servers").blockingHandler(new GETServers()); + mainRouter.post("/server/heartbeat").blockingHandler(new POSTServerHeartbeat()); + mainRouter.post("/server").blockingHandler(new POSTServer()); + //put("/server/:id").blockingHandler(new PUTServer()); + mainRouter.delete("/server/:id").blockingHandler(new DELETEServer()); - get("/staff", new GETStaff(), gson::toJson); - get("/user/:id/details", new GETUserDetails(), gson::toJson); - get("/user/:id/meta/:serverGroup", new GETUserMeta(), gson::toJson); - get("/user/:id/grants", new GETUserGrants(), gson::toJson); - get("/user/:id/punishments", new GETUserPunishments(), gson::toJson); - get("/user/:id/ipLog", new GETUserIPLog(), gson::toJson); - get("/user/:id/requiresTOTP", new GETUserRequiresTOTP(), gson::toJson); - get("/user/:id/verifyPassword", new GETUserVerifyPassword(), gson::toJson); - get("/user/:id", new GETUser(), gson::toJson); - post("/user/:id/verifyTOTP", new POSTUserVerifyTOTP(), gson::toJson); - post("/user/:id/grant", new POSTUserGrant(), gson::toJson); - post("/user/:id/punish", new POSTUserPunish(), gson::toJson); - post("/user/:id/login", new POSTUserLogin(), gson::toJson); - post("/user/:id/leave", new POSTUserLeave(), gson::toJson); - post("/user/:id/notify", new POSTUserNotify(), gson::toJson); - post("/user/:id/register", new POSTUserRegister(), gson::toJson); - post("/user/:id/setupTOTP", new POSTUserSetupTOTP(), gson::toJson); - post("/user/confirmRegister/:emailToken", new POSTUserConfirmRegister(), gson::toJson); - put("/user/:id/meta/:serverGroup", new PUTUserMeta(), gson::toJson); - delete("/user/:id/meta/:serverGroup", new DELETEUserMeta(), gson::toJson); - delete("/user/:id/punishment", new DELETEUserPunishment(), gson::toJson); + mainRouter.get("/staff").blockingHandler(new GETStaff()); + mainRouter.get("/user/:id/details").blockingHandler(new GETUserDetails()); + mainRouter.get("/user/:id/meta/:serverGroup").blockingHandler(new GETUserMeta()); + mainRouter.get("/user/:id/grants").blockingHandler(new GETUserGrants()); + mainRouter.get("/user/:id/punishments").blockingHandler(new GETUserPunishments()); + mainRouter.get("/user/:id/ipLog").blockingHandler(new GETUserIPLog()); + mainRouter.get("/user/:id/requiresTOTP").blockingHandler(new GETUserRequiresTOTP()); + mainRouter.get("/user/:id/verifyPassword").blockingHandler(new GETUserVerifyPassword()); + mainRouter.get("/user/:id").blockingHandler(new GETUser()); + mainRouter.post("/user/:id/verifyTOTP").blockingHandler(new POSTUserVerifyTOTP()); + mainRouter.post("/user/:id/grant").blockingHandler(new POSTUserGrant()); + mainRouter.post("/user/:id/punish").blockingHandler(new POSTUserPunish()); + mainRouter.post("/user/:id/login").blockingHandler(new POSTUserLogin()); + mainRouter.post("/user/:id/leave").blockingHandler(new POSTUserLeave()); + 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/confirmRegister/:emailToken").blockingHandler(new POSTUserConfirmRegister()); + mainRouter.put("/user/:id/meta/:serverGroup").blockingHandler(new PUTUserMeta()); + mainRouter.delete("/user/:id/meta/:serverGroup").blockingHandler(new DELETEUserMeta()); + mainRouter.delete("/user/:id/punishment").blockingHandler(new DELETEUserPunishment()); - // There's no way to do a JSON 404 page w/o doing this :( - get("/*", new NotFound(), gson::toJson); - post("/*", new NotFound(), gson::toJson); - put("/*", new NotFound(), gson::toJson); - delete("/*", new NotFound(), gson::toJson); + mainRouter.getRoutes().forEach((route) -> { + System.out.println(route.getClass() + "||" + route.getPath()); + }); + + int port = Integer.parseInt(config.getProperty("http.port")); + webServer.requestHandler(mainRouter::accept).listen(port); } - public static void respond(RoutingContext ctx, Object response) { + private void setupHttpClient() { + httpClient = vertx.createHttpClient(); + } + + public static void respondJson(RoutingContext ctx, Object response) { + respondJson(ctx, 200, response); + } + + public static void respondJson(RoutingContext ctx, int code, Object response) { + ctx.response().putHeader("Content-Type", "application/json"); + ctx.response().setStatusCode(code); ctx.response().end(gson.toJson(response)); } private void convertData(String oldIp, boolean forReal) { // A lot of unneeded .toString()'s and cloning objects is our ghetto null validation. - MongoDatabase importFrom = new MongoClient(oldIp).getDatabase("minehq"); + MongoDatabase importFrom = MongoClients.create(oldIp).getDatabase("minehq"); Map mongoIdToUUID = new HashMap<>(); AtomicInteger skippedUsers = new AtomicInteger(); AtomicInteger skippedPunishments = new AtomicInteger(); @@ -299,12 +312,12 @@ public final class APIv3 { ); if (forReal) { - APIv3.getDatastore().save(created); + created.insert(); } log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")"); } - }); + }, (a, b) -> {}); importFrom.getCollection("punishment").find().forEach(new Block() { @@ -322,6 +335,8 @@ public final class APIv3 { return; } + com.mongodb. + Punishment created = new Punishment( new ObjectId().toString(), target, @@ -339,12 +354,12 @@ public final class APIv3 { ); if (forReal) { - APIv3.getDatastore().save(created); + created.insert(); } log.info("Created punishment " + created.getId() + " (" + created.getType() + ")"); } - }); + }, (a, b) -> {}); importFrom.getCollection("grant").find().forEach(new Block() { @@ -382,12 +397,12 @@ public final class APIv3 { ); if (forReal) { - APIv3.getDatastore().save(created); + created.insert(); } log.info("Created grant " + created.getId() + " (" + created.getRank() + ")"); } - }); + }, (a, b) -> {}); importFrom.getCollection("iplog").find().forEach(new Block() { @@ -423,12 +438,12 @@ public final class APIv3 { ); if (forReal) { - APIv3.getDatastore().save(created); + created.insert(); } log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")"); } - }); + }, (a, b) -> {}); log.info("Skipped " + skippedUsers.get() + " users, " + skippedPunishments.get() + " punishments, " + skippedGrants.get() + " grants, and " + skippedIpLogs.get() + " ip logs"); } diff --git a/src/main/java/net/frozenorb/apiv3/Main.java b/src/main/java/net/frozenorb/apiv3/Main.java index 9239ac2..1c60617 100644 --- a/src/main/java/net/frozenorb/apiv3/Main.java +++ b/src/main/java/net/frozenorb/apiv3/Main.java @@ -1,9 +1,11 @@ package net.frozenorb.apiv3; +import io.vertx.core.Vertx; + final class Main { public static void main(String[] args) { - new APIv3(); + Vertx.vertx().deployVerticle(new APIv3()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java index f0bd997..0da25d3 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java @@ -23,7 +23,7 @@ public final class UserActor implements Actor { if (cachedAuthorized != null) { return cachedAuthorized; } else { - String highestRankId = user.getHighestRank().getId(); + String highestRankId = user.getHighestRankAnywhere().getId(); cachedAuthorized = permittedUserRanks.contains(highestRankId.toLowerCase()); return cachedAuthorized; } diff --git a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java index a8eef3c..24a33c1 100644 --- a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java @@ -17,8 +17,9 @@ public class AuditLog { } public static void log(User performedBy, String performedByIp, Actor actor, AuditLogActionType actionType, Map actionData) { + AuditLogEntry entry = new AuditLogEntry(performedBy, performedByIp, actor, actionType, actionData); + entry.insert(); APIv3.getStatsD().incrementCounter("apiv3.auditLog.insertions"); - APIv3.getDatastore().save(new AuditLogEntry(performedBy, performedByIp, actor, actionType, actionData)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java index 293e754..3c47fbf 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java @@ -1,52 +1,53 @@ package net.frozenorb.apiv3.filters; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.*; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Filter; -import spark.Request; -import spark.Response; -import spark.Spark; import java.util.Base64; -public final class ActorAttributeFilter implements Filter { +public final class ActorAttributeFilter implements Handler { - public void handle(Request req, Response res) { - String authHeader = req.headers("Authorization"); - String mhqAuthHeader = req.headers("MHQ-Authorization"); + // TODO: MAKE THIS ASYNC + public void handle(RoutingContext ctx) { + String authHeader = ctx.request().getHeader("Authorization"); + String mhqAuthHeader = ctx.request().getHeader("MHQ-Authorization"); if (authHeader != null) { - req.attribute("actor", processBasicAuthorization(authHeader, res)); + processBasicAuthorization(authHeader, ctx); } else if (mhqAuthHeader != null) { - req.attribute("actor", processMHQAuthorization(mhqAuthHeader)); + processMHQAuthorization(mhqAuthHeader, ctx); } else { - req.attribute("actor", new UnknownActor()); + ctx.put("actor", new UnknownActor()); + ctx.next(); } } @SuppressWarnings("deprecation") // We purposely get the User by their last username. - private Actor processBasicAuthorization(String authHeader, Response res) { + private void processBasicAuthorization(String authHeader, RoutingContext ctx) { String encodedHeader = authHeader.substring("Basic ".length()); String[] credentials = new String(Base64.getDecoder().decode(encodedHeader.getBytes())).split(":"); if (credentials.length == 2) { - User user = User.byLastUsername(credentials[0]); + User user = User.findByLastUsername(credentials[0]); String password = credentials[1]; if (user != null && user.getPassword() != null && user.checkPassword(password)) { - return new UserActor(user); + ctx.put("actor", new UserActor(user)); + ctx.next(); + return; } } - res.header("WWW-Authenticate", "Basic realm=\"MineHQ\""); - Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.error("Failed to authorize as " + credentials[0] + "."))); - return null; + ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); + ErrorUtils.respondGeneric(ctx, "Failed to authorize as " + credentials[0] + "."); } - private Actor processMHQAuthorization(String authHeader) { + private void processMHQAuthorization(String authHeader, RoutingContext ctx) { String[] split = authHeader.split(" "); if (split.length >= 2) { @@ -57,33 +58,39 @@ public final class ActorAttributeFilter implements Filter { String properKey = APIv3.getConfig().getProperty("auth.websiteApiKey"); if (givenKey.equals(properKey)) { - return new WebsiteActor(); + ctx.put("actor", new WebsiteActor()); + ctx.next(); + return; } } else if (type.equals("Server") && split.length == 3) { - Server server = Server.byId(split[1]); + Server server = Server.findById(split[1]); if (server == null) { - Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.respondNotFound("Server", split[1]))); + ErrorUtils.respondNotFound(ctx, "Server", split[1]); + return; } String givenKey = split[2]; String properKey = server.getApiKey(); if (givenKey.equals(properKey)) { - return new ServerActor(server); + ctx.put("actor", new ServerActor(server)); + ctx.next(); + return; } } else if (type.equals("BungeeCord") && split.length == 2) { String givenKey = split[1]; String properKey = APIv3.getConfig().getProperty("auth.bungeeCordApiKey"); if (givenKey.equals(properKey)) { - return new BungeeCordActor(); + ctx.put("actor", new BungeeCordActor()); + ctx.next(); + return; } } } - Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.error("Failed to authorize."))); - return null; + ErrorUtils.respondGeneric(ctx, "Failed to authorize."); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java index 407a5bf..b078397 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java @@ -1,22 +1,22 @@ package net.frozenorb.apiv3.filters; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Filter; -import spark.Request; -import spark.Response; -import spark.Spark; -public final class AuthorizationFilter implements Filter { +public final class AuthorizationFilter implements Handler { - public void handle(Request req, Response res) { + public void handle(RoutingContext ctx) { Actor actor = ctx.get("actor"); if (!actor.isAuthorized()) { APIv3.getStatsD().incrementCounter("apiv3.http.unauthorized"); - res.header("WWW-Authenticate", "Basic realm=\"MineHQ\""); - Spark.halt(401, APIv3.getGson().toJson(ErrorUtils.error("Unauthorized access: Please authorize as an approved actor. You're currently authorized as " + actor.getName()))); + ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); + ErrorUtils.respondGeneric(ctx, "Unauthorized access: Please authorize as an approved actor. You're currently authorized as " + actor.getName()); + } else { + ctx.next(); } } diff --git a/src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java deleted file mode 100644 index 1f02c07..0000000 --- a/src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.frozenorb.apiv3.filters; - -import spark.Filter; -import spark.Request; -import spark.Response; - -public final class ContentTypeFilter implements Filter { - - public void handle(Request req, Response res) { - res.type("application/json"); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java b/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java deleted file mode 100644 index 55b2667..0000000 --- a/src/main/java/net/frozenorb/apiv3/filters/LoggingFilter.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.frozenorb.apiv3.filters; - -import lombok.Getter; -import lombok.Setter; -import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.actors.Actor; -import spark.Filter; -import spark.Request; -import spark.Response; - -@Slf4j -public final class LoggingFilter implements Filter { - - @Getter @Setter private static boolean debug = false; - - public void handle(Request req, Response res) { - Actor actor = ctx.get("actor"); - log.info("(" + actor.getName() + " - " + actor.getType() + ") " + req.requestMethod().toUpperCase() + " " + req.pathInfo() + (debug ? "\n" + res.body() : "")); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java b/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java deleted file mode 100644 index 8bf5d4a..0000000 --- a/src/main/java/net/frozenorb/apiv3/filters/MetricsAfterFilter.java +++ /dev/null @@ -1,16 +0,0 @@ -package net.frozenorb.apiv3.filters; - -import net.frozenorb.apiv3.APIv3; -import spark.Filter; -import spark.Request; -import spark.Response; - -public final class MetricsAfterFilter implements Filter { - - public void handle(Request req, Response res) { - long started = req.attribute("requestStarted"); - APIv3.getStatsD().recordExecutionTime("apiv3.http.executionTime", System.currentTimeMillis() - started); - APIv3.getStatsD().incrementCounter("apiv3.http.requests"); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/MetricsBeforeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/MetricsBeforeFilter.java deleted file mode 100644 index 059c8b8..0000000 --- a/src/main/java/net/frozenorb/apiv3/filters/MetricsBeforeFilter.java +++ /dev/null @@ -1,13 +0,0 @@ -package net.frozenorb.apiv3.filters; - -import spark.Filter; -import spark.Request; -import spark.Response; - -public final class MetricsBeforeFilter implements Filter { - - public void handle(Request req, Response res) { - req.attribute("requestStarted", System.currentTimeMillis()); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java b/src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java new file mode 100644 index 0000000..5d0fa69 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java @@ -0,0 +1,14 @@ +package net.frozenorb.apiv3.filters; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; + +public final class MetricsHandler implements Handler { + + public void handle(RoutingContext ctx) { + APIv3.getStatsD().incrementCounter("apiv3.http.requests"); + ctx.next(); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java index 93989cc..fe6a990 100644 --- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java @@ -1,31 +1,55 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.ImmutableMap; +import com.mongodb.async.client.MongoCollection; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.Getter; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Indexed; import java.util.Date; +import java.util.List; import java.util.Map; import java.util.UUID; -@Entity(value = "auditLog", noClassnameStored = true) +@Entity public final class AuditLogEntry { + private static final MongoCollection auditLogCollection = APIv3.getDatabase().getCollection("auditLog", AuditLogEntry.class); + @Getter @Id private String id; - @Getter @Indexed private UUID user; + @Getter private UUID user; @Getter private String userIp; - @Getter @Indexed private Date performedAt; + @Getter private Date performedAt; @Getter private String actorName; @Getter private ActorType actorType; @Getter private AuditLogActionType type; @Getter private Map metadata; + public static List findAll() { + return SyncUtils.blockMulti(auditLogCollection.find()); + } + + public static AuditLogEntry findById(String id) { + return SyncUtils.blockOne(auditLogCollection.find(new Document("_id", id))); + } + + public static List findByUser(User user) { + return findByUser(user.getId()); + } + + public static List findByUser(UUID user) { + return SyncUtils.blockMulti(auditLogCollection.find(new Document("user", user))); + } + public AuditLogEntry() {} // For Morphia public AuditLogEntry(User user, String userIp, Actor actor, AuditLogActionType type, Map metadata) { @@ -39,4 +63,10 @@ public final class AuditLogEntry { this.metadata = ImmutableMap.copyOf(metadata); } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + auditLogCollection.insertOne(this, callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/Grant.java b/src/main/java/net/frozenorb/apiv3/models/Grant.java index 772a8e9..7960b16 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Grant.java +++ b/src/main/java/net/frozenorb/apiv3/models/Grant.java @@ -1,56 +1,59 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.Collections2; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.utils.UUIDUtils; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Indexed; import java.util.*; -@Entity(value = "grants", noClassnameStored = true) +@Entity @AllArgsConstructor public final class Grant { + private static final MongoCollection grantsCollection = APIv3.getDatabase().getCollection("grants", Grant.class); + @Getter @Id private String id; - @Getter @Indexed private UUID user; + @Getter private UUID user; @Getter private String reason; @Getter private Set scopes = new HashSet<>(); // So on things w/o scopes we still load properly (Morphia drops empty sets) - @Getter @Indexed private String rank; + @Getter private String rank; @Getter private Date expiresAt; @Getter private UUID addedBy; - @Getter @Indexed private Date addedAt; + @Getter private Date addedAt; @Getter private UUID removedBy; @Getter private Date removedAt; @Getter private String removalReason; - public static Grant byId(String id) { - return APIv3.getDatastore().createQuery(Grant.class).field("id").equal(id).get(); + public static List findAll() { + return SyncUtils.blockMulti(grantsCollection.find()); } - public static Map> byUserGrouped(Iterable ids) { - Map> result = new HashMap<>(); - Set uuidsToSearch = new HashSet<>(); + public static List findByRank(Iterable ranks) { + return SyncUtils.blockMulti(grantsCollection.find(new Document("rank", new Document("$in", ranks)))); + } - for (UUID id : ids) { - result.put(id, new ArrayList<>()); + public static Grant findById(String id) { + return SyncUtils.blockOne(grantsCollection.find(new Document("_id", id))); + } - if (UUIDUtils.isAcceptableUUID(id)) { - uuidsToSearch.add(id); - } - } + public static List findByUser(User user) { + return findByUser(user.getId()); + } - APIv3.getDatastore().createQuery(Grant.class).field("user").in(uuidsToSearch).forEach((grant) -> { - result.get(grant.getUser()).add(grant); - }); - - return result; + public static List findByUser(UUID user) { + return SyncUtils.blockMulti(grantsCollection.find(new Document("user", user))); } public Grant() {} // For Morphia @@ -66,14 +69,6 @@ public final class Grant { this.addedAt = new Date(); } - public void delete(User removedBy, String reason) { - this.removedBy = removedBy.getId(); - this.removedAt = new Date(); - this.removalReason = reason; - - APIv3.getDatastore().save(this); - } - public boolean isActive() { return !(isExpired() || isRemoved()); } @@ -98,4 +93,20 @@ public final class Grant { return scopes.isEmpty(); } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + grantsCollection.insertOne(this, callback); + callback.get(); + } + + public void delete(User removedBy, String reason) { + this.removedBy = removedBy.getId(); + this.removedAt = new Date(); + this.removalReason = reason; + + BlockingCallback callback = new BlockingCallback<>(); + grantsCollection.deleteOne(new Document("_id", id), callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java index 0e77799..3a52456 100644 --- a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java @@ -1,31 +1,57 @@ package net.frozenorb.apiv3.models; +import com.mongodb.async.client.MongoCollection; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.*; import java.util.Date; +import java.util.List; import java.util.UUID; -@Entity(value = "ipLog", noClassnameStored = true) +@Entity @AllArgsConstructor -@Indexes( - @Index(fields = { - @Field("user"), - @Field("userIp") - }) -) public final class IPLogEntry { + private static final MongoCollection ipLogCollection = APIv3.getDatabase().getCollection("ipLog", IPLogEntry.class); + @Getter @Id private String id; - @Getter @Indexed private UUID user; - @Getter @Indexed private String userIp; + @Getter private UUID user; + @Getter private String userIp; @Getter private Date firstSeenAt; @Getter private Date lastSeenAt; @Getter private int uses; + public static List findAll() { + return SyncUtils.blockMulti(ipLogCollection.find()); + } + + public static IPLogEntry findById(String id) { + return SyncUtils.blockOne(ipLogCollection.find(new Document("_id", id))); + } + + public static List findByUser(User user) { + return findByUser(user.getId()); + } + + public static List findByUser(UUID user) { + return SyncUtils.blockMulti(ipLogCollection.find(new Document("user", user))); + } + + public static IPLogEntry findByUserAndIp(User user, String userIp) { + return findByUserAndIp(user.getId(), userIp); + } + + public static IPLogEntry findByUserAndIp(UUID user, String userIp) { + return SyncUtils.blockOne(ipLogCollection.find(new Document("user", user).append("userIp", userIp))); + } + public IPLogEntry() {} // For Morphia public IPLogEntry(User user, String userIp) { @@ -40,8 +66,12 @@ public final class IPLogEntry { public void used() { this.lastSeenAt = new Date(); this.uses++; + } - APIv3.getDatastore().save(this); + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + ipLogCollection.insertOne(this, callback); + callback.get(); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java index 1cffe9f..cf56f6c 100644 --- a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java @@ -1,26 +1,35 @@ package net.frozenorb.apiv3.models; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.Getter; +import lombok.Setter; import net.frozenorb.apiv3.APIv3; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import java.util.List; import java.util.Map; -@Entity(value = "notificationTemplates", noClassnameStored = true) +@Entity public final class NotificationTemplate { - @Getter @Id private String id; - @Getter private String subject; - @Getter private String body; + private static final MongoCollection notificationTemplatesCollection = APIv3.getDatabase().getCollection("notificationTemplates", NotificationTemplate.class); - public static NotificationTemplate byId(String id) { - return APIv3.getDatastore().createQuery(NotificationTemplate.class).field("id").equal(id).get(); + @Getter @Id private String id; + @Getter @Setter private String subject; + @Getter @Setter private String body; + + public static List findAll() { + return SyncUtils.blockMulti(notificationTemplatesCollection.find()); } - public static List values() { - return APIv3.getDatastore().createQuery(NotificationTemplate.class).asList(); + public static NotificationTemplate findById(String id) { + return SyncUtils.blockOne(notificationTemplatesCollection.find(new Document("_id", id))); } public NotificationTemplate() {} // For Morphia @@ -31,17 +40,6 @@ public final class NotificationTemplate { this.body = body; } - public void update(String subject, String body) { - this.subject = subject; - this.body = body; - - APIv3.getDatastore().save(this); - } - - public void delete() { - APIv3.getDatastore().delete(this); - } - public String fillSubject(Map replacements) { return fill(subject, replacements); } @@ -61,4 +59,22 @@ public final class NotificationTemplate { return working; } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + notificationTemplatesCollection.insertOne(this, callback); + callback.get(); + } + + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + notificationTemplatesCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + + public void delete() { + BlockingCallback callback = new BlockingCallback<>(); + notificationTemplatesCollection.deleteOne(new Document("_id", id), callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/Punishment.java b/src/main/java/net/frozenorb/apiv3/models/Punishment.java index 909d419..643ce5b 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Punishment.java +++ b/src/main/java/net/frozenorb/apiv3/models/Punishment.java @@ -1,37 +1,37 @@ package net.frozenorb.apiv3.models; -import com.google.common.collect.ImmutableSet; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; import net.frozenorb.apiv3.utils.TimeUtils; -import net.frozenorb.apiv3.utils.UUIDUtils; +import org.bson.Document; import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.*; import java.util.*; -@Entity(value = "punishments", noClassnameStored = true) +@Entity @AllArgsConstructor -@Indexes( - @Index(fields = { - @Field("user"), - @Field("type") - }) -) public final class Punishment { + private static final MongoCollection punishmentsCollection = APIv3.getDatabase().getCollection("punishments", Punishment.class); + @Getter @Id private String id; - @Getter @Indexed private UUID user; + @Getter private UUID user; @Getter private String reason; - @Getter @Indexed private PunishmentType type; // Type is indexed for the rank dump + @Getter private PunishmentType type; @Getter private Date expiresAt; @Getter private Map metadata; @Getter private UUID addedBy; - @Getter @Indexed private Date addedAt; + @Getter private Date addedAt; @Getter private String actorName; @Getter private ActorType actorType; @@ -39,31 +39,32 @@ public final class Punishment { @Getter private Date removedAt; @Getter private String removalReason; - public static Punishment byId(String id) { - return APIv3.getDatastore().createQuery(Punishment.class).field("id").equal(id).get(); + public static List findAll() { + return SyncUtils.blockMulti(punishmentsCollection.find()); } - public static Map> byUserGrouped(Iterable ids) { - return byUserGrouped(ids, ImmutableSet.copyOf(PunishmentType.values())); + public static List findByType(Iterable types) { + return SyncUtils.blockMulti(punishmentsCollection.find(new Document("type", new Document("$in", types)))); } - public static Map> byUserGrouped(Iterable ids, Iterable types) { - Map> result = new HashMap<>(); - Set uuidsToSearch = new HashSet<>(); + public static Punishment findById(String id) { + return SyncUtils.blockOne(punishmentsCollection.find(new Document("_id", id))); + } - for (UUID id : ids) { - result.put(id, new ArrayList<>()); + public static List findByUser(User user) { + return findByUser(user.getId()); + } - if (UUIDUtils.isAcceptableUUID(id)) { - uuidsToSearch.add(id); - } - } + public static List findByUser(UUID user) { + return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user))); + } - APIv3.getDatastore().createQuery(Punishment.class).field("user").in(uuidsToSearch).field("type").in(types).forEach((punishment) -> { - result.get(punishment.getUser()).add(punishment); - }); + public static List findByUserAndType(User user, Iterable types) { + return findByUserAndType(user.getId(), types); + } - return result; + public static List findByUserAndType(UUID user, Iterable types) { + return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", types)))); } public Punishment() {} // For Morphia @@ -81,14 +82,6 @@ public final class Punishment { this.metadata = metadata; } - public void delete(User removedBy, String reason) { - this.removedBy = removedBy.getId(); - this.removedAt = new Date(); - this.removalReason = reason; - - APIv3.getDatastore().save(this); - } - public boolean isActive() { return !(isExpired() || isRemoved()); } @@ -124,6 +117,22 @@ public final class Punishment { } } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + punishmentsCollection.insertOne(this, callback); + callback.get(); + } + + public void delete(User removedBy, String reason) { + this.removedBy = removedBy.getId(); + this.removedAt = new Date(); + this.removalReason = reason; + + BlockingCallback callback = new BlockingCallback<>(); + punishmentsCollection.deleteOne(new Document("_id", id), callback); + callback.get(); + } + public enum PunishmentType { BLACKLIST, BAN, MUTE, WARN diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/models/Rank.java index 18373bc..f035a7e 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Rank.java +++ b/src/main/java/net/frozenorb/apiv3/models/Rank.java @@ -1,11 +1,17 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.ImmutableList; +import com.google.common.primitives.Ints; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Indexed; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import java.util.ArrayList; import java.util.HashMap; @@ -13,9 +19,11 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -@Entity(value = "ranks", noClassnameStored = true) +@Entity public final class Rank { + private static final MongoCollection ranksCollection = APIv3.getDatabase().getCollection("ranks", Rank.class); + private static Map rankCache = null; private static List rankAltCache = null; private static long rankCacheUpdated = 0; @@ -25,18 +33,18 @@ public final class Rank { @Getter private String displayName; @Getter private String gameColor; @Getter private String websiteColor; - @Getter @Indexed private boolean staffRank; + @Getter private boolean staffRank; - public static Rank byId(String id) { - updateCacheIfNeeded(); - return rankCache.get(id); - } - - public static List values() { + public static List findAll() { updateCacheIfNeeded(); return ImmutableList.copyOf(rankAltCache); } + public static Rank findById(String id) { + updateCacheIfNeeded(); + return rankCache.get(id); + } + public Rank() {} // For Morphia public Rank(String id, int weight, String displayName, String gameColor, String websiteColor, boolean staffRank) { @@ -48,16 +56,14 @@ public final class Rank { this.staffRank = staffRank; } - public void delete() { - APIv3.getDatastore().delete(this); - } - private static void updateCacheIfNeeded() { if (rankCache == null || (System.currentTimeMillis() - rankCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) { Map working = new HashMap<>(); List workingAlt = new ArrayList<>(); + List allRanks = SyncUtils.blockMulti(ranksCollection.find()); + allRanks.sort((a, b) -> Ints.compare(a.getWeight(), b.getWeight())); - for (Rank rank : APIv3.getDatastore().createQuery(Rank.class).order("weight").asList()) { + for (Rank rank : allRanks) { working.put(rank.getId(), rank); workingAlt.add(rank); } @@ -68,4 +74,22 @@ public final class Rank { } } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + ranksCollection.insertOne(this, callback); + callback.get(); + } + + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + ranksCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + + public void delete() { + BlockingCallback callback = new BlockingCallback<>(); + ranksCollection.deleteOne(new Document("_id", id), callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/Server.java b/src/main/java/net/frozenorb/apiv3/models/Server.java index 6fb5b3a..b5b9727 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Server.java +++ b/src/main/java/net/frozenorb/apiv3/models/Server.java @@ -1,19 +1,27 @@ package net.frozenorb.apiv3.models; +import com.google.common.collect.ImmutableSet; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.ExcludeFromReplies; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Indexed; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import java.util.*; import java.util.concurrent.TimeUnit; -@Entity(value = "servers", noClassnameStored = true) +@Entity public final class Server { + private static final MongoCollection serversCollection = APIv3.getDatabase().getCollection("servers", Server.class); + private static Map serverCache = null; private static List serverCacheAlt = null; private static long serverCacheUpdated = 0; @@ -21,22 +29,22 @@ public final class Server { @Getter @Id private String id; @Getter private String displayName; @Getter @ExcludeFromReplies String apiKey; - @Getter @Indexed private String serverGroup; + @Getter private String serverGroup; @Getter private String serverIp; @Getter @Setter private Date lastUpdatedAt; @Getter @Setter private double lastTps; @Getter @Setter @ExcludeFromReplies private Set players; - public static Server byId(String id) { - updateCacheIfNeeded(); - return serverCache.get(id); - } - - public static List values() { + public static List findAll() { updateCacheIfNeeded(); return serverCacheAlt; } + public static Server findById(String id) { + updateCacheIfNeeded(); + return serverCache.get(id); + } + public Server() {} // For Morphia public Server(String id, String displayName, String apiKey, ServerGroup serverGroup, String serverIp) { @@ -50,16 +58,12 @@ public final class Server { this.players = new HashSet<>(); } - public void delete() { - APIv3.getDatastore().delete(this); - } - private static void updateCacheIfNeeded() { if (serverCache == null || (System.currentTimeMillis() - serverCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) { Map working = new HashMap<>(); List workingAlt = new ArrayList<>(); - for (Server server : APIv3.getDatastore().createQuery(Server.class).asList()) { + for (Server server : SyncUtils.blockMulti(serversCollection.find())) { working.put(server.getId(), server); workingAlt.add(server); } @@ -70,4 +74,28 @@ public final class Server { } } + public void receivedHeartbeat(double tps, Iterable players) { + this.lastUpdatedAt = new Date(); + this.lastTps = tps; + this.players = ImmutableSet.copyOf(players); + } + + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + serversCollection.insertOne(this, callback); + callback.get(); + } + + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + serversCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + + public void delete() { + BlockingCallback callback = new BlockingCallback<>(); + serversCollection.deleteOne(new Document("_id", id), callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java index 0e9ab6d..8c5ade2 100644 --- a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java @@ -1,44 +1,51 @@ package net.frozenorb.apiv3.models; import com.google.gson.annotations.SerializedName; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.ExcludeFromReplies; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.PermissionUtils; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Property; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import java.util.*; import java.util.concurrent.TimeUnit; -@Entity(value = "serverGroups", noClassnameStored = true) +@Entity public final class ServerGroup { + private static final MongoCollection serverGroupsCollection = APIv3.getDatabase().getCollection("serverGroups", ServerGroup.class); + private static Map serverGroupCache = null; private static List serverGroupAltCache = null; private static long serverGroupCacheUpdated = 0; @Getter @Id private String id; @Getter private String image; - // We rename this to public, we just can't name it that because it's a Java identifier. - @Getter @Property("public") @SerializedName("public") private boolean isPublic; + // We rename this to public (only to gson), we just can't name it that because it's a Java identifier. + @Getter @SerializedName("public") private boolean isPublic; // We define these HashSets up here because, in the event they're // empty, Morphia will load them as null, not empty sets. @Getter @Setter @ExcludeFromReplies private Set announcements = new HashSet<>(); @Getter @Setter @ExcludeFromReplies private Map> permissions = new HashMap<>(); - public static ServerGroup byId(String id) { - updateCacheIfNeeded(); - return serverGroupCache.get(id); - } - - public static List values() { + public static List findAll() { updateCacheIfNeeded(); return serverGroupAltCache; } + public static ServerGroup findById(String id) { + updateCacheIfNeeded(); + return serverGroupCache.get(id); + } + public ServerGroup() {} // For Morphia public ServerGroup(String id, String image, boolean isPublic) { @@ -51,16 +58,12 @@ public final class ServerGroup { return PermissionUtils.mergeUpTo(permissions, userRank); } - public void delete() { - APIv3.getDatastore().delete(this); - } - private static void updateCacheIfNeeded() { if (serverGroupCache == null || (System.currentTimeMillis() - serverGroupCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) { Map working = new HashMap<>(); List workingAlt = new ArrayList<>(); - for (ServerGroup serverGroup : APIv3.getDatastore().createQuery(ServerGroup.class).asList()) { + for (ServerGroup serverGroup : SyncUtils.blockMulti(serverGroupsCollection.find())) { working.put(serverGroup.getId(), serverGroup); workingAlt.add(serverGroup); } @@ -71,4 +74,22 @@ public final class ServerGroup { } } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + serverGroupsCollection.insertOne(this, callback); + callback.get(); + } + + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + serverGroupsCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + + public void delete() { + BlockingCallback callback = new BlockingCallback<>(); + serverGroupsCollection.deleteOne(new Document("_id", id), callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/models/User.java index 18afd78..6e27e32 100644 --- a/src/main/java/net/frozenorb/apiv3/models/User.java +++ b/src/main/java/net/frozenorb/apiv3/models/User.java @@ -4,30 +4,35 @@ import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.hash.Hashing; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.ExcludeFromReplies; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.MojangUtils; import net.frozenorb.apiv3.utils.PermissionUtils; +import net.frozenorb.apiv3.utils.SyncUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Indexed; import java.util.*; -@Entity(value = "users", noClassnameStored = true) +@Entity @AllArgsConstructor -public final class User { +public final class User { + + private static final MongoCollection usersCollection = APIv3.getDatabase().getCollection("users", User.class); @Getter @Id private UUID id; - @Getter @Indexed private String lastUsername; + @Getter private String lastUsername; @Getter @ExcludeFromReplies private Map aliases = new HashMap<>(); - @Getter @Setter @ExcludeFromReplies private String totpSecret; - @Getter @Indexed @ExcludeFromReplies @Setter private String emailToken; + @Getter @ExcludeFromReplies @Setter private String totpSecret; + @Getter @ExcludeFromReplies @Setter private String emailToken; @Getter @ExcludeFromReplies @Setter private Date emailTokenSetAt; @Getter @ExcludeFromReplies private String password; @Getter @Setter private String email; @@ -37,48 +42,36 @@ public final class User { @Getter private Date firstSeenAt; @Getter private boolean online; - public static User byId(String id) { - try { - return byId(UUID.fromString(id)); - } catch (Exception ex) { - return null; - } + public static List findAll() { + return SyncUtils.blockMulti(usersCollection.find()); } - public static User byId(UUID id) { + public static User findById(String id) { + UUID uuid; + + try { + uuid = UUID.fromString(id); + } catch (IllegalArgumentException ex) { + return null; + } + + return findById(uuid); + } + + public static User findById(UUID id) { if (UUIDUtils.isAcceptableUUID(id)) { - return APIv3.getDatastore().createQuery(User.class).field("id").equal(id).get(); + return SyncUtils.blockOne(usersCollection.find(new Document("_id", id))); } else { return null; } } - public static Map byIdGrouped(Iterable ids) { - Map result = new HashMap<>(); - Set uuidsToSearch = new HashSet<>(); - - for (UUID id : ids) { - result.put(id, null); - - if (UUIDUtils.isAcceptableUUID(id)) { - uuidsToSearch.add(id); - } - } - - APIv3.getDatastore().createQuery(User.class).field("id").in(uuidsToSearch).forEach((user) -> { - result.put(user.getId(), user); - }); - - return result; + public static User findByEmailToken(String emailToken) { + return SyncUtils.blockOne(usersCollection.find(new Document("emailToken", emailToken))); } - public static User byEmailToken(String name) { - return APIv3.getDatastore().createQuery(User.class).field("emailToken").equal(name).get(); - } - - @Deprecated - public static User byLastUsername(String lastUsername) { - return APIv3.getDatastore().createQuery(User.class).field("lastUsername").equal(lastUsername).get(); + public static User findByLastUsername(String lastUsername) { + return SyncUtils.blockOne(usersCollection.find(new Document("lastUsername", lastUsername))); } public User() {} // For Morphia @@ -98,18 +91,8 @@ public final class User { updateUsername(lastUsername); } - public boolean hasPermissionScoped(String permission, ServerGroup scope) { - Rank highestRank = getHighestRank(scope); - Map scopedPermissions = PermissionUtils.mergePermissions( - PermissionUtils.getDefaultPermissions(highestRank), - scope.calculatePermissions(highestRank) - ); - - return scopedPermissions.containsKey(permission) && scopedPermissions.get(permission); - } - public boolean hasPermissionAnywhere(String permission) { - Map globalPermissions = PermissionUtils.getDefaultPermissions(getHighestRank()); + Map globalPermissions = PermissionUtils.getDefaultPermissions(getHighestRankAnywhere()); for (Map.Entry serverGroupEntry : getHighestRanks().entrySet()) { ServerGroup serverGroup = serverGroupEntry.getKey(); @@ -124,48 +107,7 @@ public final class User { return globalPermissions.containsKey(permission) && globalPermissions.get(permission); } - public List getGrants() { - return APIv3.getDatastore().createQuery(Grant.class).field("user").equal(id).asList(); - } - - public List getIPLog() { - return APIv3.getDatastore().createQuery(IPLogEntry.class).field("user").equal(id).asList(); - } - - public IPLogEntry getIPLogEntry(String ip) { - IPLogEntry existing = APIv3.getDatastore().createQuery(IPLogEntry.class).field("user").equal(id).field("userIp").equal(ip).get(); - - if (existing == null) { - existing = new IPLogEntry(this, ip); - APIv3.getDatastore().save(existing); - } - - return existing; - } - - public List getPunishments() { - return APIv3.getDatastore().createQuery(Punishment.class).field("user").equal(id).asList(); - } - - public List getPunishments(Iterable types) { - return APIv3.getDatastore().createQuery(Punishment.class).field("user").equal(id).field("type").in(types).asList(); - } - - public UserMetaEntry getMeta(ServerGroup group) { - return APIv3.getDatastore().createQuery(UserMetaEntry.class).field("user").equal(id).field("serverGroup").equal(group.getId()).get(); - } - - public void saveMeta(ServerGroup group, Document data) { - UserMetaEntry entry = getMeta(group); - - if (entry == null) { - APIv3.getDatastore().save(new UserMetaEntry(this, group, data)); - } else { - entry.setData(data); - APIv3.getDatastore().save(entry); - } - } - + // TODO: Clean public boolean seenOnServer(Server server) { if (online && server.getId().equals(this.lastSeenOn)) { return false; @@ -192,14 +134,13 @@ public final class User { User withNewUsername; - while ((withNewUsername = User.byLastUsername(username)) != null) { + while ((withNewUsername = User.findByLastUsername(username)) != null) { String newUsername = MojangUtils.getName(withNewUsername.getId()); withNewUsername.updateUsername(newUsername); } } this.aliases.put(username, new Date()); - APIv3.getDatastore().save(this); } public void setPassword(String input) { @@ -218,16 +159,17 @@ public final class User { return hashed.equals(password); } - public Rank getHighestRank() { - return getHighestRank(null); + public Rank getHighestRankAnywhere() { + return getHighestRankScoped(null); } - public Rank getHighestRank(ServerGroup serverGroup) { - return getHighestRank(serverGroup, getGrants()); + public Rank getHighestRankScoped(ServerGroup serverGroup) { + return getHighestRankScoped(serverGroup, Grant.findByUser(this)); } + // TODO: Clean // This is only used to help batch requests to mongo - public Rank getHighestRank(ServerGroup serverGroup, Iterable grants) { + public Rank getHighestRankScoped(ServerGroup serverGroup, Iterable grants) { Rank highest = null; for (Grant grant : grants) { @@ -235,7 +177,7 @@ public final class User { continue; } - Rank rank = Rank.byId(grant.getRank()); + Rank rank = Rank.findById(grant.getRank()); if (highest == null || rank.getWeight() > highest.getWeight()) { highest = rank; @@ -245,16 +187,17 @@ public final class User { if (highest != null) { return highest; } else { - return Rank.byId("default"); + return Rank.findById("default"); } } + // TODO: Clean public Map getHighestRanks() { Map highestRanks = new HashMap<>(); - Rank defaultRank = Rank.byId("default"); - List userGrants = getGrants(); + Rank defaultRank = Rank.findById("default"); + List userGrants = Grant.findByUser(this); - for (ServerGroup serverGroup : ServerGroup.values()) { + for (ServerGroup serverGroup : ServerGroup.findAll()) { Rank highest = defaultRank; for (Grant grant : userGrants) { @@ -262,7 +205,7 @@ public final class User { continue; } - Rank rank = Rank.byId(grant.getRank()); + Rank rank = Rank.findById(grant.getRank()); if (highest == null || rank.getWeight() > highest.getWeight()) { highest = rank; @@ -276,19 +219,19 @@ public final class User { } public Map getLoginInfo(Server server) { - return getLoginInfo( + return createLoginInfo( server, - getPunishments(ImmutableSet.of( + Punishment.findByUserAndType(this, ImmutableSet.of( Punishment.PunishmentType.BLACKLIST, Punishment.PunishmentType.BAN, Punishment.PunishmentType.MUTE )), - getGrants() + Grant.findByUser(this) ); } // This is only used to help batch requests to mongo - public Map getLoginInfo(Server server, Iterable punishments, Iterable grants) { + public Map createLoginInfo(Server server, Iterable punishments, Iterable grants) { Punishment activeMute = null; String accessDenialReason = null; @@ -304,7 +247,7 @@ public final class User { } } - Rank highestRank = getHighestRank(ServerGroup.byId(server.getServerGroup()), grants); + Rank highestRank = getHighestRankScoped(ServerGroup.findById(server.getServerGroup()), grants); // Generics are weird, yes we have to do this. ImmutableMap.Builder result = ImmutableMap.builder() @@ -323,4 +266,16 @@ public final class User { return result.build(); } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + usersCollection.insertOne(this, callback); + callback.get(); + } + + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + usersCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java index 319fc51..bee4fed 100644 --- a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java @@ -1,25 +1,49 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.ImmutableMap; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import eu.dozd.mongo.annotation.Entity; +import eu.dozd.mongo.annotation.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import org.bson.Document; import org.bson.types.ObjectId; -import org.mongodb.morphia.annotations.Entity; -import org.mongodb.morphia.annotations.Id; -import org.mongodb.morphia.annotations.Indexed; +import java.util.List; import java.util.Map; import java.util.UUID; -@Entity(value = "userMeta", noClassnameStored = true) +@Entity public final class UserMetaEntry { + private static final MongoCollection userMetaCollection = APIv3.getDatabase().getCollection("userMeta", UserMetaEntry.class); + @Getter @Id private String id; - @Getter @Indexed private UUID user; - @Getter @Indexed private String serverGroup; + @Getter private UUID user; + @Getter private String serverGroup; @Getter @Setter private Map data; + public static List findAll() { + return SyncUtils.blockMulti(userMetaCollection.find()); + } + + public static UserMetaEntry findById(String id) { + return SyncUtils.blockOne(userMetaCollection.find(new Document("_id", id))); + } + + public static UserMetaEntry findByUserAndGroup(User user, ServerGroup serverGroup) { + return findByUserAndGroup(user.getId(), serverGroup); + } + + public static UserMetaEntry findByUserAndGroup(UUID user, ServerGroup serverGroup) { + return SyncUtils.blockOne(userMetaCollection.find(new Document("user", user).append("serverGroup", serverGroup.getId()))); + } + public UserMetaEntry() {} // For Morphia public UserMetaEntry(User user, ServerGroup serverGroup, Map data) { @@ -29,8 +53,22 @@ public final class UserMetaEntry { this.data = ImmutableMap.copyOf(data); } + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + userMetaCollection.insertOne(this, callback); + callback.get(); + } + + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + userMetaCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + public void delete() { - APIv3.getDatastore().delete(this); + BlockingCallback callback = new BlockingCallback<>(); + userMetaCollection.deleteOne(new Document("_id", id), callback); + callback.get(); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java index 72d16b6..449e054 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java @@ -1,6 +1,7 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableSet; +import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; @@ -28,7 +29,8 @@ public final class GETDump implements Handler { List banCache = new ArrayList<>(); List blacklistCache = new ArrayList<>(); - APIv3.getDatastore().createQuery(Punishment.class).field("type").in(ImmutableSet.of( + Punishment.findByType + (ImmutableSet.of( Punishment.PunishmentType.BAN, Punishment.PunishmentType.BLACKLIST )).forEach((punishment) -> { @@ -50,7 +52,7 @@ public final class GETDump implements Handler { if (tick == 0 || tick % 2 == 0) { Map> grantCache = new HashMap<>(); - APIv3.getDatastore().createQuery(Grant.class).forEach((grant) -> { + Grant.findAll().forEach((grant) -> { if (grant.isActive()) { List users = grantCache.get(grant.getRank()); @@ -88,21 +90,25 @@ public final class GETDump implements Handler { switch (type.toLowerCase()) { case "ban": - return banCache; + APIv3.respondJson(ctx, banCache); + return; case "blacklist": - return blacklistCache; + APIv3.respondJson(ctx, blacklistCache); + return; case "accessdeniable": // Lowercase d because we convert to lowercase above List result = new ArrayList<>(); result.addAll(banCache); result.addAll(blacklistCache); - return result; + APIv3.respondJson(ctx, result); + return; case "grant": - return grantCache; + APIv3.respondJson(ctx, grantCache); + return; default: - ErrorUtils.respondInvalidInput(ctx, "type", type + " is not a valid type. Not in [ban, blacklist, accessDeniable, grant]"); - return + ErrorUtils.respondInvalidInput(ctx, type + " is not a valid type. Not in [ban, blacklist, accessDeniable, grant]"); + return; } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java b/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java index 6301ccd..0649b92 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java @@ -1,6 +1,9 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; public final class GETWhoAmI implements Handler { @@ -8,11 +11,11 @@ public final class GETWhoAmI implements Handler { public void handle(RoutingContext ctx) { Actor actor = ctx.get("actor"); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "name", actor.getName(), "type", actor.getType(), "authorized", actor.isAuthorized() - ); + )); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/NotFound.java b/src/main/java/net/frozenorb/apiv3/routes/NotFound.java deleted file mode 100644 index da5b900..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/NotFound.java +++ /dev/null @@ -1,17 +0,0 @@ -package net.frozenorb.apiv3.routes; - -import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Spark; - -@Slf4j -public final class NotFound implements Handler { - - public void handle(RoutingContext ctx) { - log.info(req.requestMethod().toUpperCase() + " " + req.url()); - Spark.halt(404, APIv3.getGson().toJson(ErrorUtils.respondNotFound("Route", req.url()))); - return null; - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java b/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java index a6708f8..1756ee9 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java +++ b/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java @@ -1,13 +1,14 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; public final class POSTMetrics implements Handler { public void handle(RoutingContext ctx) { - //LibratoBatch batch = new LibratoBatch(); - - return ImmutableMap.of(); + APIv3.respondJson(ctx, ImmutableMap.of()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java index 3bb43e8..dd6b553 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java +++ b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java @@ -21,9 +21,9 @@ public final class GETAnnouncements implements Handler { } Server sender = ((ServerActor) actor).getServer(); - ServerGroup senderGroup = ServerGroup.byId(sender.getServerGroup()); + ServerGroup senderGroup = ServerGroup.findById(sender.getServerGroup()); - APIv3.respond(ctx, senderGroup.getAnnouncements()); + APIv3.respondJson(ctx, senderGroup.getAnnouncements()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java b/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java index 32df4bc..1f3ce08 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java @@ -13,7 +13,7 @@ public final class GETAuditLog implements Handler { int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); - APIv3.respond(ctx, APIv3.getDatastore().createQuery(AuditLogEntry.class).order("performedAt").limit(limit).offset(offset).asList()); + APIv3.respondJson(ctx, APIv3.getDatastore().createQuery(AuditLogEntry.class).order("performedAt").limit(limit).offset(offset).asList()); } catch (NumberFormatException ex) { ErrorUtils.respondInvalidInput(ctx, "limit/offset must be numerical inputs."); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java b/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java index 8c4e414..879edbf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java +++ b/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java @@ -1,7 +1,6 @@ package net.frozenorb.apiv3.routes.chatFilterList; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; @@ -9,7 +8,7 @@ import net.frozenorb.apiv3.APIv3; public final class GETChatFilterList implements Handler { public void handle(RoutingContext ctx) { - APIv3.respond(ctx, ImmutableMap.of()); + APIv3.respondJson(ctx, ImmutableMap.of()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java index ed3116a..4dc0c67 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java @@ -13,7 +13,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEGrant implements Handler { public void handle(RoutingContext ctx) { - Grant grant = Grant.byId(ctx.request().getParam("id")); + Grant grant = Grant.findById(ctx.request().getParam("id")); if (grant == null) { ErrorUtils.respondNotFound(ctx, "Grant", ctx.request().getParam("id")); @@ -23,7 +23,7 @@ public final class DELETEGrant implements Handler { return; } - User removedBy = User.byId(ctx.request().getParam("removedBy")); + User removedBy = User.findById(ctx.request().getParam("removedBy")); if (removedBy == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); @@ -39,7 +39,7 @@ public final class DELETEGrant implements Handler { grant.delete(removedBy, reason); AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of()); - APIv3.respond(ctx, grant); + APIv3.respondJson(ctx, grant); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java index 7be04ae..d544499 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.Grant; public final class GETGrant implements Handler { public void handle(RoutingContext ctx) { - APIv3.respond(ctx, Grant.byId(ctx.request().getParam("id"))); + APIv3.respondJson(ctx, Grant.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java index e3403c8..f7120f0 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java @@ -13,7 +13,7 @@ public final class GETGrants implements Handler { int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); - APIv3.respond(ctx, APIv3.getDatastore().createQuery(Grant.class).order("addedAt").limit(limit).offset(offset).asList()); + APIv3.respondJson(ctx, APIv3.getDatastore().createQuery(Grant.class).order("addedAt").limit(limit).offset(offset).asList()); } catch (NumberFormatException ex) { ErrorUtils.respondInvalidInput(ctx, "limit and offset must be numerical inputs."); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java index 028d17b..36e392a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java @@ -3,20 +3,21 @@ package net.frozenorb.apiv3.routes.grants; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserGrants implements Handler { public void handle(RoutingContext ctx) { - User target = User.byId(ctx.request().getParam("id")); + User target = User.findById(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); return; } - APIv3.respond(ctx, target.getGrants()); + APIv3.respondJson(ctx, Grant.findByUser(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java index 6c12062..709bc5f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java @@ -1,5 +1,7 @@ package net.frozenorb.apiv3.routes.grants; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Rank; @@ -14,16 +16,18 @@ import java.util.Set; public final class POSTUserGrant implements Handler { public void handle(RoutingContext ctx) { - User target = User.byId(ctx.request().getParam("id")); + User target = User.findById(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.respondRequiredInput("reason"); + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; } Set scopes = new HashSet<>(); @@ -31,20 +35,22 @@ public final class POSTUserGrant implements Handler { if (!scopesUnparsed.isEmpty()) { for (String serverGroupId : scopesUnparsed.split(",")) { - ServerGroup serverGroup = ServerGroup.byId(serverGroupId); + ServerGroup serverGroup = ServerGroup.findById(serverGroupId); if (serverGroup == null) { - return ErrorUtils.respondNotFound("Server group", serverGroupId); + ErrorUtils.respondNotFound(ctx, "Server group", serverGroupId); + return; } scopes.add(serverGroup); } } - Rank rank = Rank.byId(ctx.request().getParam("rank")); + Rank rank = Rank.findById(ctx.request().getParam("rank")); if (rank == null) { - return ErrorUtils.respondNotFound("Rank", ctx.request().getParam("rank")); + ErrorUtils.respondNotFound(ctx, "Rank", ctx.request().getParam("rank")); + return; } Date expiresAt; @@ -56,15 +62,16 @@ public final class POSTUserGrant implements Handler { } if (expiresAt != null && expiresAt.before(new Date())) { - return ErrorUtils.respondInvalidInput("Expiration date cannot be in the past."); + ErrorUtils.respondInvalidInput(ctx, "Expiration date cannot be in the past."); + return; } // We purposely don't do a null check, grants don't have to have a source. - User addedBy = User.byId(ctx.request().getParam("addedBy")); + User addedBy = User.findById(ctx.request().getParam("addedBy")); Grant grant = new Grant(target, reason, scopes, rank, expiresAt, addedBy); - APIv3.getDatastore().save(grant); - return grant; + grant.insert(); + APIv3.respondJson(ctx, grant); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java index 863a7d4..1addce1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java @@ -3,20 +3,21 @@ package net.frozenorb.apiv3.routes.ipLog; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.IPLogEntry; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserIPLog implements Handler { public void handle(RoutingContext ctx) { - User target = User.byId(ctx.request().getParam("id")); + User target = User.findById(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); return; } - APIv3.respond(ctx, target.getIPLog()); + APIv3.respondJson(ctx, IPLogEntry.findByUser(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java index 95fe657..8afc202 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java @@ -9,7 +9,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETENotificationTemplate implements Handler { public void handle(RoutingContext ctx) { - NotificationTemplate notificationTemplate = NotificationTemplate.byId(ctx.request().getParam("id")); + NotificationTemplate notificationTemplate = NotificationTemplate.findById(ctx.request().getParam("id")); if (notificationTemplate == null) { ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("id")); @@ -17,7 +17,7 @@ public final class DELETENotificationTemplate implements Handler } notificationTemplate.delete(); - APIv3.respond(ctx, notificationTemplate); + APIv3.respondJson(ctx, notificationTemplate); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java index 9e55dbf..58bf102 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.NotificationTemplate; public final class GETNotificationTemplate implements Handler { public void handle(RoutingContext ctx) { - APIv3.respond(ctx, NotificationTemplate.byId(ctx.request().getParam("id"))); + APIv3.respondJson(ctx, NotificationTemplate.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java index 3c6f162..2dcd2fc 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.NotificationTemplate; public final class GETNotificationTemplates implements Handler { public void handle(RoutingContext ctx) { - APIv3.respond(ctx, NotificationTemplate.values()); + APIv3.respondJson(ctx, NotificationTemplate.findAll()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java index 9aa8c4c..d913b96 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java @@ -13,8 +13,8 @@ public final class POSTNotificationTemplate implements Handler { String body = ctx.request().getParam("body"); NotificationTemplate notificationTemplate = new NotificationTemplate(id, subject, body); - APIv3.getDatastore().save(notificationTemplate); - APIv3.respond(ctx, notificationTemplate); + notificationTemplate.insert(); + APIv3.respondJson(ctx, notificationTemplate); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java index bd578e1..c517ea4 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java @@ -1,6 +1,9 @@ package net.frozenorb.apiv3.routes.punishments; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.models.Punishment; @@ -10,29 +13,33 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEPunishment implements Handler { public void handle(RoutingContext ctx) { - Punishment punishment = Punishment.byId(ctx.request().getParam("id")); + Punishment punishment = Punishment.findById(ctx.request().getParam("id")); if (punishment == null) { - return ErrorUtils.respondNotFound("Punishment", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "Punishment", ctx.request().getParam("id")); + return; } else if (!punishment.isActive()) { - return ErrorUtils.respondInvalidInput("Cannot remove an inactive punishment."); + ErrorUtils.respondInvalidInput(ctx, "Cannot remove an inactive punishment."); + return; } - User removedBy = User.byId(ctx.request().getParam("removedBy")); + User removedBy = User.findById(ctx.request().getParam("removedBy")); if (removedBy == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("removedBy")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); + return; } String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.respondRequiredInput("reason"); + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; } punishment.delete(removedBy, reason); AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); - return punishment; + APIv3.respondJson(ctx, punishment); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java index 1315bd4..f502ffa 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.punishments; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Punishment; public final class GETPunishment implements Handler { public void handle(RoutingContext ctx) { - return Punishment.byId(ctx.request().getParam("id")); + APIv3.respondJson(ctx, Punishment.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java index 821dfb1..1e0a41a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java @@ -1,5 +1,7 @@ package net.frozenorb.apiv3.routes.punishments; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -11,9 +13,9 @@ public final class GETPunishments implements Handler { int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); - return APIv3.getDatastore().createQuery(Punishment.class).order("addedAt").limit(limit).offset(offset).asList(); + APIv3.respondJson(ctx, APIv3.getDatastore().createQuery(Punishment.class).order("addedAt").limit(limit).offset(offset).asList()); } catch (NumberFormatException ex) { - return ErrorUtils.respondInvalidInput("limit and offset must be numerical inputs."); + ErrorUtils.respondInvalidInput(ctx, "limit and offset must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java index 79d5774..f55ace0 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java @@ -1,18 +1,23 @@ package net.frozenorb.apiv3.routes.punishments; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserPunishments implements Handler { public void handle(RoutingContext ctx) { - User target = User.byId(ctx.request().getParam("id")); + User target = User.findById(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } - return target.getPunishments(); + APIv3.respondJson(ctx, Punishment.findByUser(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java index 483c29c..8cb4dd9 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java @@ -2,6 +2,8 @@ package net.frozenorb.apiv3.routes.punishments; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; @@ -15,24 +17,27 @@ import java.util.Map; public final class POSTUserPunish implements Handler { public void handle(RoutingContext ctx) { - User target = User.byId(ctx.request().getParam("id")); + User target = User.findById(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.respondRequiredInput("reason"); + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; } Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(ctx.request().getParam("type")); if (type != Punishment.PunishmentType.WARN) { - for (Punishment punishment : target.getPunishments(ImmutableSet.of(type))) { + for (Punishment punishment : Punishment.findByUserAndType(target, ImmutableSet.of(type))) { if (punishment.isActive()) { - return ErrorUtils.error("A punishment by " + User.byId(punishment.getAddedBy()).getLastUsername() + " already covers this user."); + ErrorUtils.respondGeneric(ctx, "A punishment by " + User.findById(punishment.getAddedBy()).getLastUsername() + " already covers this user."); + return; } } } @@ -46,30 +51,33 @@ public final class POSTUserPunish implements Handler { } if (expiresAt != null && expiresAt.before(new Date())) { - return ErrorUtils.respondInvalidInput("Expiration date cannot be in the past."); + ErrorUtils.respondInvalidInput(ctx, "Expiration date cannot be in the past."); + return; } - Map meta = Document.parse(req.body()); + Map meta = Document.parse(ctx.getBodyAsString()); if (meta == null) { - return ErrorUtils.respondRequiredInput("request body meta"); + ErrorUtils.respondRequiredInput(ctx, "request body meta"); + return; } // We purposely don't do a null check, grants don't have to have a source. - User addedBy = User.byId(ctx.request().getParam("addedBy")); + User addedBy = User.findById(ctx.request().getParam("addedBy")); if (target.hasPermissionAnywhere(Permissions.PROTECTED_PUNISHMENT)) { - return ErrorUtils.error(target.getLastSeenOn() + " is protected from punishments."); + ErrorUtils.respondGeneric(ctx, target.getLastSeenOn() + " is protected from punishments."); + return; } Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, ctx.get("actor"), meta); String accessDenialReason = punishment.getAccessDenialReason(); - APIv3.getDatastore().save(punishment); + punishment.insert(); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "punishment", punishment, "accessDenialReason", accessDenialReason == null ? "" : accessDenialReason - ); + )); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java index b9e1092..ed97e39 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java @@ -1,19 +1,23 @@ package net.frozenorb.apiv3.routes.ranks; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETERank implements Handler { public void handle(RoutingContext ctx) { - Rank rank = Rank.byId(ctx.request().getParam("id")); + Rank rank = Rank.findById(ctx.request().getParam("id")); if (rank == null) { - return ErrorUtils.respondNotFound("Rank", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "Rank", ctx.request().getParam("id")); + return; } rank.delete(); - return rank; + APIv3.respondJson(ctx, rank); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java index 91a692f..f80c8ba 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.ranks; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Rank; public final class GETRank implements Handler { public void handle(RoutingContext ctx) { - return Rank.byId(ctx.request().getParam("id")); + APIv3.respondJson(ctx, Rank.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java index d8dd68e..637b65e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.ranks; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Rank; public final class GETRanks implements Handler { public void handle(RoutingContext ctx) { - return Rank.values(); + APIv3.respondJson(ctx, Rank.findAll()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java index e7ed2e8..0ad21c9 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java @@ -1,5 +1,7 @@ package net.frozenorb.apiv3.routes.ranks; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Rank; @@ -14,8 +16,8 @@ public final class POSTRank implements Handler { boolean staffRank = Boolean.parseBoolean(ctx.request().getParam("staffRank")); Rank rank = new Rank(id, weight, displayName, gameColor, websiteColor, staffRank); - APIv3.getDatastore().save(rank); - return rank; + rank.insert(); + APIv3.respondJson(ctx, rank); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java index 1fa5451..f8d3315 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java @@ -1,19 +1,23 @@ package net.frozenorb.apiv3.routes.serverGroups; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEServerGroup implements Handler { public void handle(RoutingContext ctx) { - ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("id")); + ServerGroup serverGroup = ServerGroup.findById(ctx.request().getParam("id")); if (serverGroup == null) { - return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("id")); + return; } serverGroup.delete(); - return serverGroup; + APIv3.respondJson(ctx, serverGroup); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java index 39ba0ea..0f288ce 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.serverGroups; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; public final class GETServerGroup implements Handler { public void handle(RoutingContext ctx) { - return ServerGroup.byId(ctx.request().getParam("id")); + APIv3.respondJson(ctx, ServerGroup.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java index 1788dda..a5e9e72 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.serverGroups; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; public final class GETServerGroups implements Handler { public void handle(RoutingContext ctx) { - return ServerGroup.values(); + APIv3.respondJson(ctx, ServerGroup.findAll()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java index 3055f8e..72de2c4 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java @@ -1,5 +1,7 @@ package net.frozenorb.apiv3.routes.serverGroups; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; @@ -11,8 +13,8 @@ public final class POSTServerGroup implements Handler { boolean isPublic = Boolean.valueOf(ctx.request().getParam("public")); ServerGroup serverGroup = new ServerGroup(id, image, isPublic); - APIv3.getDatastore().save(serverGroup); - return serverGroup; + serverGroup.insert(); + APIv3.respondJson(ctx, serverGroup); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java index 83cf362..24ff866 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java @@ -1,19 +1,23 @@ package net.frozenorb.apiv3.routes.servers; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEServer implements Handler { public void handle(RoutingContext ctx) { - Server server = Server.byId(ctx.request().getParam("id")); + Server server = Server.findById(ctx.request().getParam("id")); if (server == null) { - return ErrorUtils.respondNotFound("Server", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "Server", ctx.request().getParam("id")); + return; } server.delete(); - return server; + APIv3.respondJson(ctx, server); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java index 973528c..0a1b3e8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.servers; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Server; public final class GETServer implements Handler { public void handle(RoutingContext ctx) { - return Server.byId(ctx.request().getParam("id")); + APIv3.respondJson(ctx, Server.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java index 52cb5ad..8dc2452 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.servers; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Server; public final class GETServers implements Handler { public void handle(RoutingContext ctx) { - return Server.values(); + APIv3.respondJson(ctx, Server.findAll()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java index a534f03..69e2f5f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java @@ -1,5 +1,7 @@ package net.frozenorb.apiv3.routes.servers; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.ServerGroup; @@ -12,20 +14,22 @@ public final class POSTServer implements Handler { String id = ctx.request().getParam("id"); String displayName = ctx.request().getParam("displayName"); String apiKey = ctx.request().getParam("apiKey"); - ServerGroup group = ServerGroup.byId(ctx.request().getParam("group")); + ServerGroup group = ServerGroup.findById(ctx.request().getParam("group")); String ip = ctx.request().getParam("ip"); if (group == null) { - return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("group")); + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("group")); + return; } if (!IPUtils.isValidIP(ip)) { - return ErrorUtils.respondInvalidInput("IP address \"" + ip + "\" is not valid."); + ErrorUtils.respondInvalidInput(ctx, "IP address \"" + ip + "\" is not valid."); + return; } Server server = new Server(id, displayName, apiKey, group, ip); - APIv3.getDatastore().save(server); - return server; + server.insert(); + APIv3.respondJson(ctx, server); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java index bbd3721..2a34f3e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java @@ -1,6 +1,8 @@ package net.frozenorb.apiv3.routes.servers; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; @@ -21,16 +23,17 @@ public final class POSTServerHeartbeat implements Handler { Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { - return ErrorUtils.respondServerOnly(); + ErrorUtils.respondServerOnly(ctx); + return; } Server actorServer = Server.byId(actor.getName()); ServerGroup actorServerGroup = ServerGroup.byId(actorServer.getServerGroup()); - Document reqJson = Document.parse(req.body()); + Document reqJson = Document.parse(ctx.getBodyAsString()); Map onlinePlayersNames = new HashMap<>(); - Map onlinePlayersUsers = new HashMap<>(); - Map> onlinePlayersGrants = new HashMap<>(); - Map> onlinePlayersPunishments = new HashMap<>(); + Map onlinePlayersUsers; + Map> onlinePlayersGrants; + Map> onlinePlayersPunishments; Map playersResponse = new HashMap<>(); // This code is messy, but we have to do db ops in parallel to avoid @@ -71,7 +74,7 @@ public final class POSTServerHeartbeat implements Handler { UUID uuid = entry.getKey(); User user = entry.getValue(); - playersResponse.put(uuid.toString(), user.getLoginInfo(actorServer, onlinePlayersPunishments.get(uuid), onlinePlayersGrants.get(uuid))); + playersResponse.put(uuid.toString(), user.prepareLoginInfo(actorServer, onlinePlayersPunishments.get(uuid), onlinePlayersGrants.get(uuid))); } for (Object event : (List) reqJson.get("events")) { @@ -92,7 +95,7 @@ public final class POSTServerHeartbeat implements Handler { Map> permissionsResponse = new HashMap<>(); - for (Rank rank : Rank.values()) { + for (Rank rank : Rank.findAll()) { Map scopedPermissions = PermissionUtils.mergePermissions( PermissionUtils.getDefaultPermissions(rank), actorServerGroup.calculatePermissions(rank) @@ -104,12 +107,12 @@ public final class POSTServerHeartbeat implements Handler { actorServer.setPlayers(onlinePlayersNames.keySet()); actorServer.setLastTps(reqJson.getDouble("lastTps")); actorServer.setLastUpdatedAt(new Date()); - APIv3.getDatastore().save(actorServer); + actorServer.save(); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "players", playersResponse, "permissions", permissionsResponse - ); + )); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java index e7c9cd6..03716b5 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java @@ -1,29 +1,39 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.UserMetaEntry; import net.frozenorb.apiv3.utils.ErrorUtils; +import org.bson.Document; public final class DELETEUserMeta implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } - ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("serverGroup")); + ServerGroup serverGroup = ServerGroup.findById(ctx.request().getParam("serverGroup")); if (serverGroup == null) { - return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("serverGroup")); + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("serverGroup")); + return; } - UserMetaEntry userMetaEntry = user.getMeta(serverGroup); + UserMetaEntry userMetaEntry = UserMetaEntry.findByUserAndGroup(user, serverGroup); - userMetaEntry.delete(); - return userMetaEntry.getData(); + if (userMetaEntry != null) { + userMetaEntry.delete(); + APIv3.respondJson(ctx, userMetaEntry.getData()); + } else { + APIv3.respondJson(ctx, new Document()); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java index ecfc385..f35b6cb 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java @@ -2,6 +2,9 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.models.Punishment; @@ -11,34 +14,38 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEUserPunishment implements Handler { public void handle(RoutingContext ctx) { - User target = User.byId(ctx.request().getParam("id")); + User target = User.findById(ctx.request().getParam("id")); if (target == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(ctx.request().getParam("type").toUpperCase()); - User removedBy = User.byId(ctx.request().getParam("removedBy")); + User removedBy = User.findById(ctx.request().getParam("removedBy")); if (removedBy == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("removedBy")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); + return; } String reason = ctx.request().getParam("reason"); if (reason == null || reason.trim().isEmpty()) { - return ErrorUtils.respondRequiredInput("reason"); + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; } for (Punishment punishment : target.getPunishments(ImmutableSet.of(type))) { if (punishment.isActive()) { punishment.delete(removedBy, reason); AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); - return punishment; + APIv3.respondJson(ctx, punishment); + return; } } - return ErrorUtils.error("User provided has no active punishments"); + ErrorUtils.respondGeneric(ctx, "User provided has no active punishments"); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java index 55291f2..3a5a398 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java @@ -1,5 +1,7 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Rank; @@ -12,22 +14,22 @@ public final class GETStaff implements Handler { public void handle(RoutingContext ctx) { Map staffRanks = new HashMap<>(); - Rank.values().forEach(rank -> { + Rank.findAll().forEach(rank -> { if (rank.isStaffRank()) { staffRanks.put(rank.getId(), rank); } }); Map> result = new TreeMap<>((first, second) -> { - Rank firstRank = Rank.byId(first); - Rank secondRank = Rank.byId(second); + Rank firstRank = staffRanks.get(first); + Rank secondRank = staffRanks.get(second); return Integer.compare(firstRank.getWeight(), secondRank.getWeight()); }); - APIv3.getDatastore().createQuery(Grant.class).field("rank").in(staffRanks.keySet()).forEach(grant -> { + Grant.findByRank(staffRanks.values()).forEach(grant -> { if (grant.isActive()) { - User user = User.byId(grant.getUser()); + User user = User.findById(grant.getUser()); Rank rank = staffRanks.get(grant.getRank()); if (!result.containsKey(rank.getId())) { @@ -38,7 +40,7 @@ public final class GETStaff implements Handler { } }); - return result; + APIv3.respondJson(ctx, result); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java index f18c8ce..a0065e0 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java @@ -1,11 +1,14 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; public final class GETUser implements Handler { public void handle(RoutingContext ctx) { - return User.byId(ctx.request().getParam("id")); + APIv3.respondJson(ctx, User.findById(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java index c4cf2ff..4283ba3 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java @@ -1,27 +1,35 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.Grant; +import net.frozenorb.apiv3.models.IPLogEntry; +import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserDetails implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } // Too many fields to use .of() - return ImmutableMap.builder() + APIv3.respondJson(ctx, ImmutableMap.builder() .put("user", user) - .put("grants", user.getGrants()) - .put("ipLog", user.getIPLog()) - .put("punishments", user.getPunishments()) + .put("grants", Grant.findByUser(user)) + .put("ipLog", IPLogEntry.findByUser(user)) + .put("punishments", Punishment.findByUser(user)) .put("aliases", user.getAliases()) .put("totpSetup", user.getTotpSecret() != null) - .build(); + .build() + ); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java index 4d1e38e..948dc60 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java @@ -1,5 +1,8 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.models.UserMetaEntry; @@ -8,20 +11,22 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserMeta implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } - ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("serverGroup")); + ServerGroup serverGroup = ServerGroup.findById(ctx.request().getParam("serverGroup")); if (serverGroup == null) { - return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("serverGroup")); + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("serverGroup")); + return; } - UserMetaEntry userMetaEntry = user.getMeta(serverGroup); - return userMetaEntry.getData(); + UserMetaEntry userMetaEntry = UserMetaEntry.findByUserAndGroup(user, serverGroup); + APIv3.respondJson(ctx, userMetaEntry.getData()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java index f8b080f..fefe302 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java @@ -1,6 +1,9 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; @@ -9,36 +12,39 @@ import net.frozenorb.apiv3.utils.TOTPUtils; public final class GETUserRequiresTOTP implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } if (user.getTotpSecret() == null) { - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "required", false, "message", "User does not have TOTP setup." - ); + )); + return; } String userIp = ctx.request().getParam("userIp"); if (!IPUtils.isValidIP(userIp)) { - return ErrorUtils.respondInvalidInput("IP address \"" + userIp + "\" is not valid."); + ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid."); + return; } if (TOTPUtils.isPreAuthorized(user, userIp)) { - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "required", false, "message", "User's IP has already been validated" - ); + )); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "required", true, + "message", "User has no TOTP exemptions." + )); } - - return ImmutableMap.of( - "required", true, - "message", "User has no TOTP exemptions." - ); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java index cd6794d..fa362ab 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java @@ -1,27 +1,32 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserVerifyPassword implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } if (user.getPassword() == null) { - return ErrorUtils.respondInvalidInput("User provided does not have password set."); + ErrorUtils.respondInvalidInput(ctx, "User provided does not have password set."); + return; } boolean authorized = user.checkPassword(ctx.request().getParam("password")); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "authorized", authorized - ); + )); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java index af17685..39242a2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java @@ -2,6 +2,8 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -20,37 +22,42 @@ public final class POSTUserConfirmRegister implements Handler { "nicole chelsea biteme matthew access yankees 987654321 dallas austin thunder taylor matrix").split(" ")); public void handle(RoutingContext ctx) { - User user = User.byEmailToken(ctx.request().getParam("emailToken")); + User user = User.findByEmailToken(ctx.request().getParam("emailToken")); if (user == null) { - return ErrorUtils.respondNotFound("Email token", ctx.request().getParam("emailToken")); + ErrorUtils.respondNotFound(ctx, "Email token", ctx.request().getParam("emailToken")); + return; } // We can't check email != null as that's set while we're pending // confirmation, we have to check the token. if (user.getEmailToken() == null) { - return ErrorUtils.error("User provided already has email set."); + ErrorUtils.respondGeneric(ctx, "User provided already has email set."); + return; } if ((System.currentTimeMillis() - user.getEmailTokenSetAt().getTime()) > TimeUnit.DAYS.toMillis(2)) { - return ErrorUtils.error("Email token is expired"); + ErrorUtils.respondGeneric(ctx, "Email token is expired"); + return; } String password = ctx.request().getParam("password"); if (password.length() < 8) { - return ErrorUtils.error("Your password is too short."); + ErrorUtils.respondGeneric(ctx, "Your password is too short."); + return; } else if (commonPasswords.contains(password)) { - return ErrorUtils.error("Your password is too common. Please use a more secure password."); + ErrorUtils.respondGeneric(ctx, "Your password is too common. Please use a more secure password."); + return; } user.setEmailToken(null); user.setPassword(password); - APIv3.getDatastore().save(user); + user.save(); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "success", true - ); + )); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java index 8e2a6e5..802c71c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java @@ -1,24 +1,25 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import spark.Request; -import spark.Response; public class POSTUserLeave implements Handler { @Override - public Object handle(Request req, Response res) throws Exception { - User user = User.byId(ctx.request().getParam("id")); + public void handle(RoutingContext ctx) { + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } user.leftServer(); - APIv3.getDatastore().save(user); - return user; + user.save(); + APIv3.respondJson(ctx, user); } -} +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java index 9fbc900..05264fc 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java @@ -1,5 +1,8 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; import net.frozenorb.apiv3.models.Server; @@ -16,20 +19,23 @@ public final class POSTUserLogin implements Handler { UUID uuid = UUID.fromString(ctx.request().getParam("id")); if (!UUIDUtils.isAcceptableUUID(uuid)) { - return ErrorUtils.respondInvalidInput("UUID \"" + uuid + "\" is not valid - must be version 4 UUID."); + ErrorUtils.respondInvalidInput(ctx, "UUID \"" + uuid + "\" is not valid - must be version 4 UUID."); + return; } - User user = User.byId(uuid); + User user = User.findById(uuid); String username = ctx.request().getParam("username"); String userIp = ctx.request().getParam("userIp"); Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { - return ErrorUtils.respondServerOnly(); + ErrorUtils.respondServerOnly(ctx); + return; } if (!IPUtils.isValidIP(userIp)) { - return ErrorUtils.respondInvalidInput("IP address \"" + userIp + "\" is not valid."); + ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid."); + return; } if (user == null) { @@ -37,11 +43,11 @@ public final class POSTUserLogin implements Handler { user = new User(uuid, username); } - Server actorServer = Server.byId(actor.getName()); + Server actorServer = Server.findById(actor.getName()); user.getIPLogEntry(userIp).used(); user.updateUsername(username); - return user.getLoginInfo(actorServer); + APIv3.respondJson(ctx, user.getLoginInfo(actorServer)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java index d79d783..f9454b7 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java @@ -1,6 +1,9 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.Notification; @@ -12,43 +15,47 @@ import java.util.Map; public final class POSTUserNotify implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } if (user.getEmail() == null) { - return ErrorUtils.error("User provided does not have email set."); + ErrorUtils.respondGeneric(ctx, "User provided does not have email set."); + return; } - NotificationTemplate template = NotificationTemplate.byId(ctx.request().getParam("template")); + NotificationTemplate template = NotificationTemplate.findById(ctx.request().getParam("template")); if (template == null) { - return ErrorUtils.respondNotFound("Notification template", ctx.request().getParam("template")); + ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("template")); + return; } Map subjectReplacements = new HashMap<>(); Map bodyReplacements = new HashMap<>(); - req.queryMap("subject").toMap().forEach((key, values) -> { + //TODO: Probably make this use the body as json + /*req.queryMap("subject").toMap().forEach((key, values) -> { subjectReplacements.put(key, values[0]); }); req.queryMap("body").toMap().forEach((key, values) -> { bodyReplacements.put(key, values[0]); - }); + });*/ try { Notification notification = new Notification(template, subjectReplacements, bodyReplacements); notification.sendAsEmail(user.getEmail()); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "success", true - ); + )); } catch (Exception ex) { ex.printStackTrace(); - return ErrorUtils.error("Failed to send notification"); + ErrorUtils.respondGeneric(ctx, "Failed to send notification"); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java index 7b80338..3e3aad3 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java @@ -1,6 +1,8 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; @@ -22,30 +24,34 @@ public final class POSTUserRegister implements Handler { ); public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } if (user.getEmail() != null) { - return ErrorUtils.respondInvalidInput("User provided already has email set."); + ErrorUtils.respondInvalidInput(ctx, "User provided already has email set."); + return; } String email = ctx.request().getParam("email"); if (!VALID_EMAIL_PATTERN.matcher(email).matches()) { - return ErrorUtils.error(email + " is not a valid email."); + ErrorUtils.respondGeneric(ctx, email + " is not a valid email."); + return; } if (user.getEmailToken() != null && (System.currentTimeMillis() - user.getEmailTokenSetAt().getTime()) < TimeUnit.DAYS.toMillis(2)) { - return ErrorUtils.error("We just recently sent you a confirmation email. Please wait before trying to register again."); + ErrorUtils.respondGeneric(ctx, "We just recently sent you a confirmation email. Please wait before trying to register again."); + return; } user.setEmail(email); user.setEmailToken(new BigInteger(130, new Random()).toString(32)); user.setEmailTokenSetAt(new Date()); - APIv3.getDatastore().save(user); + user.save(); Map replacements = ImmutableMap.of( "username", user.getLastUsername(), @@ -53,16 +59,16 @@ public final class POSTUserRegister implements Handler { "emailToken", user.getEmailToken() ); - Notification notification = new Notification(NotificationTemplate.byId("email-confirmation"), replacements, replacements); + Notification notification = new Notification(NotificationTemplate.findById("email-confirmation"), replacements, replacements); try { notification.sendAsEmail(user.getEmail()); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "success", true - ); + )); } catch (Exception ex) { ex.printStackTrace(); - return ErrorUtils.error("Failed to send confirmation email. Please contact a MineHQ staff member."); + ErrorUtils.respondGeneric(ctx, "Failed to send confirmation email. Please contact a MineHQ staff member."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java index 5a4e9c6..9b9f2bc 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java @@ -2,6 +2,8 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import com.warrenstrange.googleauth.GoogleAuthenticatorKey; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -10,24 +12,26 @@ import net.frozenorb.apiv3.utils.TOTPUtils; public final class POSTUserSetupTOTP implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } if (user.getTotpSecret() != null) { - return ErrorUtils.respondInvalidInput("User provided already has TOTP code set."); + ErrorUtils.respondInvalidInput(ctx, "User provided already has TOTP code set."); + return; } GoogleAuthenticatorKey generated = TOTPUtils.generateTOTPKey(); user.setTotpSecret(generated.getKey()); - APIv3.getDatastore().save(user); + user.save(); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "qrCode", TOTPUtils.getQRCodeURL(user, generated) - ); + )); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java index 2deb032..bc27b48 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java @@ -1,6 +1,9 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; @@ -11,29 +14,33 @@ import java.util.concurrent.TimeUnit; public final class POSTUserVerifyTOTP implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } if (user.getTotpSecret() == null) { - return ErrorUtils.respondInvalidInput("User provided does not have TOTP code set."); + ErrorUtils.respondInvalidInput(ctx, "User provided does not have TOTP code set."); + return; } String userIp = ctx.request().getParam("userIp"); if (!IPUtils.isValidIP(userIp)) { - return ErrorUtils.respondInvalidInput("IP address \"" + userIp + "\" is not valid."); + ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid."); + return; } int providedCode = Integer.parseInt(ctx.request().getParam("code")); if (TOTPUtils.wasRecentlyUsed(user, providedCode)) { - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "authorized", false, "message", "TOTP code was recently used." - ); + )); + return; } boolean authorized = TOTPUtils.authorizeUser(user, providedCode); @@ -42,15 +49,15 @@ public final class POSTUserVerifyTOTP implements Handler { TOTPUtils.markPreAuthorized(user, userIp, 3, TimeUnit.DAYS); TOTPUtils.markRecentlyUsed(user, providedCode); - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "authorized", true, "message", "Valid TOTP code provided." - ); + )); } else { - return ImmutableMap.of( + APIv3.respondJson(ctx, ImmutableMap.of( "authorized", false, "message", "TOTP code was not valid." - ); + )); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java index 0ff4eca..3fa80a8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java @@ -1,5 +1,8 @@ package net.frozenorb.apiv3.routes.users; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -8,22 +11,24 @@ import org.bson.Document; public final class PUTUserMeta implements Handler { public void handle(RoutingContext ctx) { - User user = User.byId(ctx.request().getParam("id")); + User user = User.findById(ctx.request().getParam("id")); if (user == null) { - return ErrorUtils.respondNotFound("User", ctx.request().getParam("id")); + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; } - ServerGroup serverGroup = ServerGroup.byId(ctx.request().getParam("serverGroup")); + ServerGroup serverGroup = ServerGroup.findById(ctx.request().getParam("serverGroup")); if (serverGroup == null) { - return ErrorUtils.respondNotFound("Server group", ctx.request().getParam("serverGroup")); + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("serverGroup")); + return; } - Document data = Document.parse(req.body()); + Document data = Document.parse(ctx.getBodyAsString()); user.saveMeta(serverGroup, data); - return data; + APIv3.respondJson(ctx, data); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java b/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java new file mode 100644 index 0000000..939de9c --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java @@ -0,0 +1,29 @@ +package net.frozenorb.apiv3.unsorted; + +import com.google.common.util.concurrent.SettableFuture; +import com.mongodb.async.SingleResultCallback; + +import java.util.concurrent.ExecutionException; + +public final class BlockingCallback implements SingleResultCallback { + + private final SettableFuture future = SettableFuture.create(); + + public void onResult(T val, Throwable error) { + if (error != null) { + future.setException(error); + } else { + future.set(val); + } + } + + public T get() { + try { + return future.get(); + } catch (InterruptedException | ExecutionException ex) { + // No matter what we get we'll just rethrow. + throw new RuntimeException(ex); + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java b/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java deleted file mode 100644 index 193fab4..0000000 --- a/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java +++ /dev/null @@ -1,27 +0,0 @@ -package net.frozenorb.apiv3.unsorted; - -import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.utils.ErrorUtils; -import org.bson.types.ObjectId; -import spark.ExceptionHandler; -import spark.Request; -import spark.Response; - -@Slf4j -public final class LoggingExceptionHandler implements ExceptionHandler { - - public void handle(Exception ex, Request req, Response res) { - long started = req.attribute("requestStarted"); - APIv3.getStatsD().recordExecutionTime("apiv3.http.executionTime", System.currentTimeMillis() - started); - APIv3.getStatsD().incrementCounter("apiv3.http.requests"); - - APIv3.getStatsD().incrementCounter("apiv3.http.errors"); - - String code = new ObjectId().toHexString(); - - log.error(code + ":", ex); - res.body(APIv3.getGson().toJson(ErrorUtils.error("An unknown error has occurred. Please contact an API developer with the code \"" + code + "\"."))); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java index 9e25530..decc5b5 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java @@ -9,23 +9,24 @@ import net.frozenorb.apiv3.APIv3; public class ErrorUtils { public static void respondServerOnly(RoutingContext ctx) { - error(ctx, "This action can only be performed when requested by a server."); + respondGeneric(ctx, "This action can only be performed when requested by a server."); } public static void respondNotFound(RoutingContext ctx, String itemType, String id) { - error(ctx, "Not found: " + itemType + " with id " + id + " cannot be found."); + respondGeneric(ctx, "Not found: " + itemType + " with id " + id + " cannot be found."); } public static void respondInvalidInput(RoutingContext ctx, String message) { - error(ctx, "Invalid input: " + message + "."); + respondGeneric(ctx, "Invalid input: " + message + "."); } public static void respondRequiredInput(RoutingContext ctx, String field) { - error(ctx, "Field \"" + field + "\" is required."); + respondGeneric(ctx, "Field \"" + field + "\" is required."); } - public static void error(RoutingContext ctx, String message) { - APIv3.respond(ctx, ImmutableMap.of( + public static void respondGeneric(RoutingContext ctx, String message) { + // TODO: Proper status codes + APIv3.respondJson(ctx, 400, ImmutableMap.of( "success", false, "message", message )); diff --git a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java index fc5626b..fd25359 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java @@ -1,10 +1,9 @@ package net.frozenorb.apiv3.utils; +import com.mongodb.async.SingleResultCallback; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; -import okhttp3.OkHttpClient; -import okhttp3.Request; -import okhttp3.Response; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import org.bson.Document; import java.util.UUID; @@ -12,30 +11,32 @@ import java.util.UUID; @UtilityClass public class MojangUtils { - private static OkHttpClient okHttpClient = new OkHttpClient.Builder().retryOnConnectionFailure(false).build(); - public static String getName(UUID id) { - Request.Builder builder = new Request.Builder(); + BlockingCallback callback = new BlockingCallback<>(); + getName(id, callback); + return callback.get(); + } - builder.get(); - builder.url("https://sessionserver.mojang.com/session/minecraft/profile/" + id.toString().replace("-", "")); + public static void getName(UUID id, SingleResultCallback callback) { + APIv3.getHttpClient().get("sessionserver.mojang.com", "session/minecraft/profile/" + id.toString().replace("-", ""), (response) -> { + response.bodyHandler((body) -> { + Document resJson = Document.parse(body.toString()); + String name = resJson.getString("name"); - try { - Response response = okHttpClient.newCall(builder.build()).execute(); - Document resJson = Document.parse(response.body().string()); + if (name == null) { + APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.rateLimited"); + callback.onResult(null, new RuntimeException("Hit Mojang API rate limit: " + resJson.toJson())); + } else { + APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.success"); + callback.onResult(name, null); + } + }); - String name = resJson.getString("name"); - - if (name == null) { - throw new RuntimeException("Hit Mojang API rate limit: " + resJson.toJson()); - } - - APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.success"); - return name; - } catch (Exception ex) { - APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.failure"); - throw new RuntimeException(ex); - } + response.exceptionHandler((error) -> { + APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.failure"); + callback.onResult(null, error); + }); + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java b/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java index e896299..4081811 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java @@ -25,7 +25,7 @@ public class PermissionUtils { public static Map mergeUpTo(Map> unmerged, Rank upTo) { Map result = new HashMap<>(); - for (Rank rank : Rank.values()) { + for (Rank rank : Rank.findAll()) { Map rankPermissions = convertToMap(unmerged.get(rank.getId())); // If there's no permissions defined for this rank just skip it. diff --git a/src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java b/src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java new file mode 100644 index 0000000..12c982a --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java @@ -0,0 +1,27 @@ +package net.frozenorb.apiv3.utils; + +import com.mongodb.async.client.MongoIterable; +import lombok.experimental.UtilityClass; +import net.frozenorb.apiv3.unsorted.BlockingCallback; + +import java.util.ArrayList; +import java.util.List; + +@UtilityClass +public class SyncUtils { + + public static T blockOne(MongoIterable mongoIterable) { + BlockingCallback callback = new BlockingCallback<>(); + + mongoIterable.first(callback); + return callback.get(); + } + + public static List blockMulti(MongoIterable mongoIterable) { + BlockingCallback> callback = new BlockingCallback<>(); + + mongoIterable.into(new ArrayList<>(), callback); + return callback.get(); + } + +} \ No newline at end of file From 7e462e1915a37a12a9d0fffabe98d135869ed8de Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Sun, 12 Jun 2016 16:36:11 -0400 Subject: [PATCH 3/8] Push a bunch of experimental code (this doesn't currently work) --- apiv3.properties | 3 - pom.xml | 27 +- src/main/java/net/frozenorb/apiv3/APIv3.java | 410 ++++++++++-------- src/main/java/net/frozenorb/apiv3/Main.java | 2 + .../apiv3/actors/BungeeCordActor.java | 3 + .../frozenorb/apiv3/actors/ServerActor.java | 4 + .../frozenorb/apiv3/actors/UnknownActor.java | 3 + .../net/frozenorb/apiv3/actors/UserActor.java | 15 +- .../frozenorb/apiv3/actors/WebsiteActor.java | 3 + .../ActorAttributeHandler.java} | 56 ++- .../AuthorizationHandler.java} | 5 +- .../{filters => handlers}/MetricsHandler.java | 3 +- .../frozenorb/apiv3/models/AuditLogEntry.java | 44 +- .../net/frozenorb/apiv3/models/Grant.java | 66 ++- .../frozenorb/apiv3/models/IPLogEntry.java | 53 ++- .../apiv3/models/NotificationTemplate.java | 19 +- .../frozenorb/apiv3/models/Punishment.java | 79 +++- .../java/net/frozenorb/apiv3/models/Rank.java | 4 +- .../net/frozenorb/apiv3/models/Server.java | 4 +- .../frozenorb/apiv3/models/ServerGroup.java | 9 +- .../java/net/frozenorb/apiv3/models/User.java | 86 +++- .../frozenorb/apiv3/models/UserMetaEntry.java | 32 +- .../net/frozenorb/apiv3/routes/GETDump.java | 5 +- .../apiv3/routes/auditLog/GETAuditLog.java | 8 +- .../apiv3/routes/grants/DELETEGrant.java | 4 +- .../apiv3/routes/grants/GETGrant.java | 2 +- .../apiv3/routes/grants/GETGrants.java | 8 +- .../apiv3/routes/grants/GETUserGrants.java | 4 +- .../apiv3/routes/grants/POSTUserGrant.java | 4 +- .../apiv3/routes/ipLog/GETUserIPLog.java | 4 +- .../DELETENotificationTemplate.java | 2 +- .../GETNotificationTemplate.java | 2 +- .../GETNotificationTemplates.java | 2 +- .../routes/punishments/DELETEPunishment.java | 4 +- .../routes/punishments/GETPunishment.java | 2 +- .../routes/punishments/GETPunishments.java | 8 +- .../punishments/GETUserPunishments.java | 4 +- .../routes/punishments/POSTUserPunish.java | 8 +- .../routes/serverGroups/POSTServerGroup.java | 3 +- .../routes/servers/POSTServerHeartbeat.java | 197 ++++++--- .../apiv3/routes/users/DELETEUserMeta.java | 4 +- .../routes/users/DELETEUserPunishment.java | 6 +- .../apiv3/routes/users/GETStaff.java | 4 +- .../frozenorb/apiv3/routes/users/GETUser.java | 2 +- .../apiv3/routes/users/GETUserDetails.java | 8 +- .../apiv3/routes/users/GETUserMeta.java | 4 +- .../routes/users/GETUserRequiresTOTP.java | 9 +- .../routes/users/GETUserVerifyPassword.java | 2 +- .../routes/users/POSTUserConfirmRegister.java | 2 +- .../apiv3/routes/users/POSTUserLeave.java | 2 +- .../apiv3/routes/users/POSTUserLogin.java | 17 +- .../apiv3/routes/users/POSTUserNotify.java | 10 +- .../apiv3/routes/users/POSTUserRegister.java | 9 +- .../apiv3/routes/users/POSTUserSetupTOTP.java | 2 +- .../routes/users/POSTUserVerifyTOTP.java | 18 +- .../apiv3/routes/users/PUTUserMeta.java | 13 +- .../serialization/MineHQCodecProvider.java | 40 ++ .../serialization/ObjectIdTypeAdapter.java | 23 - .../serialization/UUIDJsonDeserializer.java | 18 + .../serialization/UUIDJsonSerializer.java | 18 + .../apiv3/unsorted/BlockingCallback.java | 1 + .../apiv3/unsorted/Notification.java | 55 ++- .../frozenorb/apiv3/unsorted/Permissions.java | 1 + .../frozenorb/apiv3/utils/MojangUtils.java | 6 - .../net/frozenorb/apiv3/utils/TOTPUtils.java | 71 ++- 65 files changed, 1026 insertions(+), 520 deletions(-) rename src/main/java/net/frozenorb/apiv3/{filters/ActorAttributeFilter.java => handlers/ActorAttributeHandler.java} (57%) rename src/main/java/net/frozenorb/apiv3/{filters/AuthorizationFilter.java => handlers/AuthorizationHandler.java} (84%) rename src/main/java/net/frozenorb/apiv3/{filters => handlers}/MetricsHandler.java (85%) create mode 100644 src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java delete mode 100644 src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java create mode 100644 src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java create mode 100644 src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java diff --git a/apiv3.properties b/apiv3.properties index e307d26..74192b2 100644 --- a/apiv3.properties +++ b/apiv3.properties @@ -1,6 +1,4 @@ general.releaseStage=production -logging.level=info -logging.debug=true mongo.address=localhost mongo.port=27017 mongo.database=MineHQ @@ -13,6 +11,5 @@ twillio.accountSID=AC9e2f88c5690134d29a56f698de3cd740 twillio.authToken=982592505a171d3be6b0722f5ecacc0e mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ bugsnag.apiKey=0e47fba8b825416b7cbc839066184509 -auth.permittedUserRanks=developer,owner auth.websiteApiKey=RVbp4hY6sCFVaf auth.bungeeCordApiKey=6d9cf76dc9f0d23 \ No newline at end of file diff --git a/pom.xml b/pom.xml index 2ce866f..729b473 100644 --- a/pom.xml +++ b/pom.xml @@ -55,6 +55,10 @@ minehq-repo http://maven.minehq.com:8081/artifactory/minehq-all/ + + mongo-jackson-codec-repo + https://dl.bintray.com/ylemoigne/maven + @@ -62,12 +66,17 @@ io.vertx vertx-core - LATEST + 3.2.1 io.vertx vertx-web - LATEST + 3.2.1 + + + io.vertx + vertx-redis-client + 3.2.1 @@ -89,16 +98,14 @@ 3.0.4 - eu.dozd - mongo-mapper - 1.0.1 + fr.javatic.mongo + mongo-jackson-codec + 3.2.0__0.4 - - - redis.clients - jedis - 2.8.1 + de.undercouch + bson4jackson + 2.6.0 diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index a82c07c..08a02e2 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -1,39 +1,50 @@ package net.frozenorb.apiv3; import com.bugsnag.Client; +import com.fasterxml.jackson.annotation.JsonAutoDetect; +import com.fasterxml.jackson.annotation.JsonInclude; +import com.fasterxml.jackson.annotation.PropertyAccessor; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.module.SimpleModule; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mongodb.Block; +import com.mongodb.ConnectionString; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import com.mongodb.async.client.MongoClient; import com.mongodb.async.client.MongoClientSettings; import com.mongodb.async.client.MongoClients; import com.mongodb.async.client.MongoDatabase; +import com.mongodb.connection.ClusterConnectionMode; import com.mongodb.connection.ClusterSettings; import com.timgroup.statsd.NonBlockingStatsDClient; import com.timgroup.statsd.StatsDClient; -import eu.dozd.mongo.MongoMapper; +import fr.javatic.mongo.jacksonCodec.JacksonCodecProvider; +import fr.javatic.mongo.jacksonCodec.ObjectMapperFactory; import io.vertx.core.AbstractVerticle; +import io.vertx.core.Handler; +import io.vertx.core.Vertx; import io.vertx.core.http.HttpClient; import io.vertx.core.http.HttpServer; import io.vertx.ext.web.Router; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.handler.BodyHandler; import io.vertx.ext.web.handler.LoggerHandler; +import io.vertx.ext.web.impl.BlockingHandlerDecorator; +import io.vertx.ext.web.impl.RouteImpl; +import io.vertx.redis.RedisClient; +import io.vertx.redis.RedisOptions; import lombok.Getter; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.filters.ActorAttributeFilter; -import net.frozenorb.apiv3.filters.AuthorizationFilter; -import net.frozenorb.apiv3.filters.MetricsHandler; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.IPLogEntry; -import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.handlers.ActorAttributeHandler; +import net.frozenorb.apiv3.handlers.AuthorizationHandler; +import net.frozenorb.apiv3.handlers.MetricsHandler; +import net.frozenorb.apiv3.models.*; import net.frozenorb.apiv3.routes.GETDump; import net.frozenorb.apiv3.routes.GETWhoAmI; import net.frozenorb.apiv3.routes.POSTMetrics; @@ -57,19 +68,23 @@ import net.frozenorb.apiv3.routes.serverGroups.GETServerGroups; import net.frozenorb.apiv3.routes.serverGroups.POSTServerGroup; import net.frozenorb.apiv3.routes.servers.*; import net.frozenorb.apiv3.routes.users.*; -import net.frozenorb.apiv3.serialization.DateTypeAdapter; -import net.frozenorb.apiv3.serialization.FollowAnnotationExclusionStrategy; -import net.frozenorb.apiv3.serialization.ObjectIdTypeAdapter; +import net.frozenorb.apiv3.serialization.*; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.unsorted.BugsnagSLF4JLogger; import net.frozenorb.apiv3.utils.IPUtils; +import net.frozenorb.apiv3.utils.SyncUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; +import org.bson.codecs.BsonValueCodecProvider; +import org.bson.codecs.DocumentCodecProvider; +import org.bson.codecs.ValueCodecProvider; +import org.bson.codecs.configuration.CodecProvider; import org.bson.codecs.configuration.CodecRegistries; import org.bson.types.ObjectId; -import redis.clients.jedis.JedisPool; import java.io.FileInputStream; import java.io.InputStream; +import java.lang.reflect.Field; import java.util.*; import java.util.concurrent.TimeUnit; import java.util.concurrent.atomic.AtomicInteger; @@ -80,26 +95,27 @@ public final class APIv3 extends AbstractVerticle { @Getter private static HttpClient httpClient; @Getter private static MongoDatabase database; @Getter private static Properties config = new Properties(); - @Getter private static JedisPool redisPool; + @Getter private static RedisClient redisClient; @Getter private static StatsDClient statsD; + @Getter private static Vertx vertxInstance; @Getter private static final Gson gson = new GsonBuilder() - .registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()) .registerTypeAdapter(Date.class, new DateTypeAdapter()) .setExclusionStrategies(new FollowAnnotationExclusionStrategy()) .create(); @Override public void start() { - setupConfig(); - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", config.getProperty("logging.level")); + vertxInstance = vertx; + setupConfig(); setupDatabase(); setupRedis(); setupMetrics(); setupBugsnag(); - setupHttpServer(); + //setupHttpServer(); + setupHttpClient(); - //convertData("158.69.126.126", true); + convertData("mongodb://158.69.126.126", true); } private void setupConfig() { @@ -125,18 +141,37 @@ public final class APIv3 extends AbstractVerticle { ClusterSettings clusterSettings = ClusterSettings .builder() - .hosts(ImmutableList.of( - new ServerAddress( - config.getProperty("mongo.address"), - Integer.parseInt(config.getProperty("mongo.port")) - ) - )) + .applyConnectionString(new ConnectionString("mongodb://" + config.getProperty("mongo.address") + ":" + config.getProperty("mongo.port"))) .build(); + + List providers = new ArrayList<>(); + + // Our override codec + providers.add(new MineHQCodecProvider()); + + // Normal providers + providers.add(new ValueCodecProvider()); + providers.add(new DocumentCodecProvider()); + providers.add(new BsonValueCodecProvider()); + + ObjectMapper objectMapper = ObjectMapperFactory.createObjectMapper(); + SimpleModule simpleModule = new SimpleModule(); + + simpleModule.addSerializer(UUID.class, new UUIDJsonSerializer()); + simpleModule.addDeserializer(UUID.class, new UUIDJsonDeserializer()); + + objectMapper.registerModule(simpleModule); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); + objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + providers.add(new JacksonCodecProvider(objectMapper)); + MongoClientSettings settings = MongoClientSettings .builder() - .codecRegistry(CodecRegistries.fromProviders(MongoMapper.getProviders())) + .codecRegistry(CodecRegistries.fromProviders(providers)) .credentialList(credentials) - .clusterSettings(clusterSettings).build(); + .clusterSettings(clusterSettings) + .build(); MongoClient client = MongoClients.create(settings); database = client.getDatabase(config.getProperty("mongo.database")); @@ -144,9 +179,11 @@ public final class APIv3 extends AbstractVerticle { } private void setupRedis() { - redisPool = new JedisPool( - config.getProperty("redis.address"), - Integer.parseInt(config.getProperty("redis.port")) + redisClient = RedisClient.create( + vertx, + new RedisOptions() + .setAddress(config.getProperty("redis.address")) + .setPort(Integer.parseInt(config.getProperty("redis.port"))) ); } @@ -176,8 +213,8 @@ public final class APIv3 extends AbstractVerticle { Router mainRouter = Router.router(vertx); mainRouter.route().handler(new MetricsHandler()); - mainRouter.route().handler(new ActorAttributeFilter()); - mainRouter.route().handler(new AuthorizationFilter()); + mainRouter.route().handler(new ActorAttributeHandler()); + mainRouter.route().handler(new AuthorizationHandler()); mainRouter.route().handler(LoggerHandler.create()); mainRouter.route().handler(BodyHandler.create()); @@ -218,7 +255,7 @@ public final class APIv3 extends AbstractVerticle { mainRouter.get("/server/:id").blockingHandler(new GETServer()); mainRouter.get("/servers").blockingHandler(new GETServers()); - mainRouter.post("/server/heartbeat").blockingHandler(new POSTServerHeartbeat()); + mainRouter.post("/server/heartbeat").handler(new POSTServerHeartbeat()); mainRouter.post("/server").blockingHandler(new POSTServer()); //put("/server/:id").blockingHandler(new PUTServer()); mainRouter.delete("/server/:id").blockingHandler(new DELETEServer()); @@ -246,7 +283,22 @@ public final class APIv3 extends AbstractVerticle { mainRouter.delete("/user/:id/punishment").blockingHandler(new DELETEUserPunishment()); mainRouter.getRoutes().forEach((route) -> { - System.out.println(route.getClass() + "||" + route.getPath()); + try { + RouteImpl impl = (RouteImpl) route; + Field field = RouteImpl.class.getDeclaredField("contextHandler"); + field.setAccessible(true); + Handler handler = (Handler) field.get(impl); + + if (handler instanceof BlockingHandlerDecorator) { + field = BlockingHandlerDecorator.class.getDeclaredField("decoratedHandler"); + field.setAccessible(true); + handler = (Handler) field.get(handler); + } + + System.out.println(route.getPath() + " is handled by " + handler.getClass()); + } catch (Exception ex) { + + } }); int port = Integer.parseInt(config.getProperty("http.port")); @@ -276,174 +328,156 @@ public final class APIv3 extends AbstractVerticle { AtomicInteger skippedGrants = new AtomicInteger(); AtomicInteger skippedIpLogs = new AtomicInteger(); - importFrom.getCollection("user").find().forEach(new Block() { + SyncUtils.blockMulti(importFrom.getCollection("user").find()).forEach((user) -> { + String uuidString = String.valueOf(user.get("uuid")); - @Override - public void apply(Document user) { - String uuidString = String.valueOf(user.get("uuid")); - - if (uuidString == null || uuidString.length() != 32) { - return; - } - - UUID uuid = UUID.fromString(uuidString.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" )); - - if (!UUIDUtils.isAcceptableUUID(uuid)) { - skippedUsers.incrementAndGet(); - return; - } - - mongoIdToUUID.put(user.getObjectId("_id"), uuid); - - User created = new User( - uuid, - String.valueOf(user.get("name")).toString(), - ImmutableMap.of(), - null, - null, - null, - null, - user.getString("email"), - user.getString("phone"), - "INVALID", - user.getDate("joined"), - user.getDate("joined"), - false - ); - - if (forReal) { - created.insert(); - } - - log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")"); + if (uuidString == null || uuidString.length() != 32) { + return; } - }, (a, b) -> {}); - importFrom.getCollection("punishment").find().forEach(new Block() { + UUID uuid = UUID.fromString(uuidString.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")); - @Override - public void apply(Document punishment) { - UUID target = mongoIdToUUID.get(((DBRef) punishment.get("user")).getId()); - - if (target == null) { - skippedPunishments.incrementAndGet(); - return; - } - - // Old punishments have this value set to false to indicate they're not active anymore. - if (punishment.containsKey("active") && !punishment.getBoolean("active")) { - return; - } - - com.mongodb. - - Punishment created = new Punishment( - new ObjectId().toString(), - target, - punishment.getString("reason").toString(), - Punishment.PunishmentType.valueOf(punishment.getString("type").toUpperCase()), - punishment.getDate("expires"), - punishment.containsKey("meta") ? (punishment.get("meta") instanceof List ? ImmutableMap.of() : (Document) punishment.get("meta")) : ImmutableMap.of(), - punishment.containsKey("addedBy") ? mongoIdToUUID.get(((DBRef) punishment.get("addedBy")).getId()) : null, - (Date) punishment.getDate("created").clone(), - punishment.containsKey("createdOn") ? String.valueOf(((DBRef) punishment.get("createdOn")).getId()) : "Website", - punishment.containsKey("createdOn") ? ActorType.SERVER : ActorType.WEBSITE, - punishment.containsKey("removedBy") ? (((DBRef) punishment.get("removedBy")).getCollectionName().equals("user") ? mongoIdToUUID.get(((DBRef) punishment.get("removedBy")).getId()) : null) : null, - punishment.getDate("created"), - punishment.containsKey("removalReason") ? punishment.getString("removalReason").toString() : "" - ); - - if (forReal) { - created.insert(); - } - - log.info("Created punishment " + created.getId() + " (" + created.getType() + ")"); + if (!UUIDUtils.isAcceptableUUID(uuid)) { + skippedUsers.incrementAndGet(); + return; } - }, (a, b) -> {}); - importFrom.getCollection("grant").find().forEach(new Block() { + mongoIdToUUID.put(user.getObjectId("_id"), uuid); - @Override - public void apply(Document grant) { - UUID target = mongoIdToUUID.get(((DBRef) grant.get("target")).getId()); + User created = new User( + uuid, + String.valueOf(user.get("name")).toString(), + ImmutableMap.of(user.getString("name"), user.getDate("joined")), + null, + null, + null, + null, + user.getString("email"), + user.getString("phone"), + "INVALID", + user.getDate("joined"), + user.getDate("joined"), + false + ); - if (target == null) { - skippedGrants.incrementAndGet(); - return; - } - - String rank = grant.getString("role"); - - if (rank.equalsIgnoreCase("unban") || rank.equalsIgnoreCase("pass") || rank.equalsIgnoreCase("pink") || rank.equalsIgnoreCase("jrdev")) { - return; - } else if (rank.equalsIgnoreCase("high_roller")) { - rank = "high-roller"; - } else if (rank.equalsIgnoreCase("dev")) { - rank = "developer"; - } - - Grant created = new Grant( - new ObjectId().toString(), - target, - grant.containsKey("comment") ? grant.getString("comment") : "", - grant.containsKey("scope") ? ImmutableSet.copyOf((Collection) grant.get("scope")) : ImmutableSet.of(), - rank, - grant.getDate("expires"), - grant.containsKey("addedBy") ? mongoIdToUUID.get(((DBRef) grant.get("addedBy")).getId()) : null, - grant.containsKey("created") ? grant.getDate("created") : new Date(), - null, - null, - null - ); - - if (forReal) { - created.insert(); - } - - log.info("Created grant " + created.getId() + " (" + created.getRank() + ")"); + if (forReal) { + created.insert(); } - }, (a, b) -> {}); - importFrom.getCollection("iplog").find().forEach(new Block() { + log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")"); + }); - @Override - public void apply(Document ipLogEntry) { - UUID user = mongoIdToUUID.get(((DBRef) ipLogEntry.get("user")).getId()); + SyncUtils.blockMulti(importFrom.getCollection("punishment").find()).forEach((punishment) -> { + UUID target = mongoIdToUUID.get(((Map) punishment.get("user")).get("$id")); - if (user == null || ipLogEntry.getString("ip") == null) { - skippedIpLogs.incrementAndGet(); - return; - } - - String ip = ipLogEntry.getString("ip").replace("/", ""); - - if (!IPUtils.isValidIP(ip)) { - return; - } - - Date lastSeen = ipLogEntry.getDate("lastSeen"); - - if (lastSeen == null) { - lastSeen = new Date(); - } - - IPLogEntry created = new IPLogEntry( - new ObjectId().toString(), - user, - ip, - lastSeen, - lastSeen, - ((Number) ipLogEntry.get("uses")).intValue() - - ); - - if (forReal) { - created.insert(); - } - - log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")"); + if (target == null) { + skippedPunishments.incrementAndGet(); + return; } - }, (a, b) -> {}); + + // Old punishments have this value set to false to indicate they're not active anymore. + if (punishment.containsKey("active") && !punishment.getBoolean("active")) { + return; + } + + Punishment created = new Punishment( + new ObjectId().toString(), + target, + punishment.getString("reason").toString(), + Punishment.PunishmentType.valueOf(punishment.getString("type").toUpperCase()), + punishment.getDate("expires"), + punishment.containsKey("meta") ? (punishment.get("meta") instanceof List ? ImmutableMap.of() : (Document) punishment.get("meta")) : ImmutableMap.of(), + punishment.containsKey("addedBy") ? mongoIdToUUID.get(((Map) punishment.get("addedBy")).get("$id")) : null, + (Date) punishment.getDate("created").clone(), + punishment.containsKey("createdOn") ? String.valueOf(((Map) punishment.get("createdOn")).get("$id")) : "Website", + punishment.containsKey("createdOn") ? ActorType.SERVER : ActorType.WEBSITE, + punishment.containsKey("removedBy") ? (((Map) punishment.get("removedBy")).get("$ref").equals("user") ? mongoIdToUUID.get(((Map) punishment.get("removedBy")).get("$id")) : null) : null, + punishment.getDate("created"), + punishment.containsKey("removalReason") ? punishment.getString("removalReason").toString() : "" + ); + + if (forReal) { + created.insert(); + } + + log.info("Created punishment " + created.getId() + " (" + created.getType() + ")"); + }); + + SyncUtils.blockMulti(importFrom.getCollection("grant").find()).forEach((grant) -> { + UUID target = mongoIdToUUID.get(((Map) grant.get("target")).get("$id")); + + if (target == null) { + skippedGrants.incrementAndGet(); + return; + } + + String rank = grant.getString("role"); + + if (rank.equalsIgnoreCase("unban") || rank.equalsIgnoreCase("pass") || rank.equalsIgnoreCase("pink") || rank.equalsIgnoreCase("jrdev")) { + return; + } else if (rank.equalsIgnoreCase("high_roller")) { + rank = "high-roller"; + } else if (rank.equalsIgnoreCase("dev")) { + rank = "developer"; + } + + Grant created = new Grant( + new ObjectId().toString(), + target, + grant.containsKey("comment") ? grant.getString("comment") : "", + grant.containsKey("scope") ? ImmutableSet.copyOf((Collection) grant.get("scope")) : ImmutableSet.of(), + rank, + grant.getDate("expires"), + grant.containsKey("addedBy") ? mongoIdToUUID.get(((Map) grant.get("addedBy")).get("$id")) : null, + grant.containsKey("created") ? grant.getDate("created") : new Date(), + null, + null, + null + ); + + if (forReal) { + created.insert(); + } + + log.info("Created grant " + created.getId() + " (" + created.getRank() + ")"); + }); + + SyncUtils.blockMulti(importFrom.getCollection("iplog").find()).forEach((ipLogEntry) -> { + UUID user = mongoIdToUUID.get(((Map) ipLogEntry.get("user")).get("$id")); + + if (user == null || ipLogEntry.getString("ip") == null) { + skippedIpLogs.incrementAndGet(); + return; + } + + String ip = ipLogEntry.getString("ip").replace("/", ""); + + if (!IPUtils.isValidIP(ip)) { + return; + } + + Date lastSeen = ipLogEntry.getDate("lastSeen"); + + if (lastSeen == null) { + lastSeen = new Date(); + } + + IPLogEntry created = new IPLogEntry( + new ObjectId().toString(), + user, + ip, + lastSeen, + lastSeen, + ((Number) ipLogEntry.get("uses")).intValue() + + ); + + if (forReal) { + created.insert(); + } + + log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")"); + }); log.info("Skipped " + skippedUsers.get() + " users, " + skippedPunishments.get() + " punishments, " + skippedGrants.get() + " grants, and " + skippedIpLogs.get() + " ip logs"); } diff --git a/src/main/java/net/frozenorb/apiv3/Main.java b/src/main/java/net/frozenorb/apiv3/Main.java index 1c60617..d7b382a 100644 --- a/src/main/java/net/frozenorb/apiv3/Main.java +++ b/src/main/java/net/frozenorb/apiv3/Main.java @@ -5,6 +5,8 @@ import io.vertx.core.Vertx; final class Main { public static void main(String[] args) { + System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory"); + System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info"); Vertx.vertx().deployVerticle(new APIv3()); } diff --git a/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java b/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java index aa4734d..c1fa682 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java @@ -2,14 +2,17 @@ package net.frozenorb.apiv3.actors; public final class BungeeCordActor implements Actor { + @Override public boolean isAuthorized() { return true; } + @Override public String getName() { return "BungeeCord"; } + @Override public ActorType getType() { return ActorType.BUNGEECORD; } diff --git a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java b/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java index 43a3411..07347d8 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java @@ -1,5 +1,6 @@ package net.frozenorb.apiv3.actors; +import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.models.Server; @@ -11,14 +12,17 @@ public final class ServerActor implements Actor { this.server = server; } + @Override public boolean isAuthorized() { return true; } + @Override public String getName() { return server.getId(); } + @Override public ActorType getType() { return ActorType.SERVER; } diff --git a/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java b/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java index 9d89614..e275a80 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java @@ -2,14 +2,17 @@ package net.frozenorb.apiv3.actors; public final class UnknownActor implements Actor { + @Override public boolean isAuthorized() { return false; } + @Override public String getName() { return "Unknown"; } + @Override public ActorType getType() { return ActorType.UNKNOWN; } diff --git a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java index 0da25d3..3873270 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java @@ -4,35 +4,40 @@ import com.google.common.collect.ImmutableSet; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.Permissions; import java.util.Set; public final class UserActor implements Actor { - private static final Set permittedUserRanks = ImmutableSet.copyOf(APIv3.getConfig().getProperty("auth.permittedUserRanks").toLowerCase().split(",")); - @Getter private final User user; // We use Boolean here so we can have null = not calculated; + // Currently having this cached isn't important as we only check + // this once, but later on when we have non-logged in routes + // this will be important. private Boolean cachedAuthorized = null; public UserActor(User user) { this.user = user; } + @Override public boolean isAuthorized() { if (cachedAuthorized != null) { return cachedAuthorized; } else { - String highestRankId = user.getHighestRankAnywhere().getId(); - cachedAuthorized = permittedUserRanks.contains(highestRankId.toLowerCase()); - return cachedAuthorized; + boolean authorized = user.hasPermissionAnywhere(Permissions.SIGN_API_REQUEST); + cachedAuthorized = authorized; + return authorized; } } + @Override public String getName() { return user.getLastUsername(); } + @Override public ActorType getType() { return ActorType.USER; } diff --git a/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java b/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java index 939cf01..ae0e518 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java @@ -2,14 +2,17 @@ package net.frozenorb.apiv3.actors; public final class WebsiteActor implements Actor { + @Override public boolean isAuthorized() { return true; } + @Override public String getName() { return "Website"; } + @Override public ActorType getType() { return ActorType.WEBSITE; } diff --git a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java b/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java similarity index 57% rename from src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java rename to src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java index 3c47fbf..8fc1e86 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java +++ b/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.filters; +package net.frozenorb.apiv3.handlers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; @@ -10,41 +10,46 @@ import net.frozenorb.apiv3.utils.ErrorUtils; import java.util.Base64; -public final class ActorAttributeFilter implements Handler { +public final class ActorAttributeHandler implements Handler { - // TODO: MAKE THIS ASYNC + @Override public void handle(RoutingContext ctx) { - String authHeader = ctx.request().getHeader("Authorization"); - String mhqAuthHeader = ctx.request().getHeader("MHQ-Authorization"); + String authorizationHeader = ctx.request().getHeader("Authorization"); + String mhqAuthorizationHeader = ctx.request().getHeader("MHQ-Authorization"); - if (authHeader != null) { - processBasicAuthorization(authHeader, ctx); - } else if (mhqAuthHeader != null) { - processMHQAuthorization(mhqAuthHeader, ctx); + if (authorizationHeader != null) { + processBasicAuthorization(authorizationHeader, ctx); + } else if (mhqAuthorizationHeader != null) { + processMHQAuthorization(mhqAuthorizationHeader, ctx); } else { - ctx.put("actor", new UnknownActor()); - ctx.next(); + processNoAuthorization(ctx); } } - @SuppressWarnings("deprecation") // We purposely get the User by their last username. private void processBasicAuthorization(String authHeader, RoutingContext ctx) { String encodedHeader = authHeader.substring("Basic ".length()); - String[] credentials = new String(Base64.getDecoder().decode(encodedHeader.getBytes())).split(":"); + String decodedHeader = new String(Base64.getDecoder().decode(encodedHeader.getBytes())); + String[] credentials = decodedHeader.split(":"); if (credentials.length == 2) { - User user = User.findByLastUsername(credentials[0]); - String password = credentials[1]; + User.findByLastUsername(credentials[0], (user, error) -> { + if (error != null) { + String password = credentials[1]; - if (user != null && user.getPassword() != null && user.checkPassword(password)) { - ctx.put("actor", new UserActor(user)); - ctx.next(); - return; - } + if (user != null && user.getPassword() != null && user.checkPassword(password)) { + ctx.put("actor", new UserActor(user)); + ctx.next(); + return; + } + } + + ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); + ErrorUtils.respondGeneric(ctx, "Failed to authorize as " + credentials[0] + "."); + }); + } else { + ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); + ErrorUtils.respondGeneric(ctx, "Failed to authorize as " + credentials[0] + "."); } - - ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); - ErrorUtils.respondGeneric(ctx, "Failed to authorize as " + credentials[0] + "."); } private void processMHQAuthorization(String authHeader, RoutingContext ctx) { @@ -93,4 +98,9 @@ public final class ActorAttributeFilter implements Handler { ErrorUtils.respondGeneric(ctx, "Failed to authorize."); } + public void processNoAuthorization(RoutingContext ctx) { + ctx.put("actor", new UnknownActor()); + ctx.next(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java b/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java similarity index 84% rename from src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java rename to src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java index b078397..b25bf01 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java +++ b/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.filters; +package net.frozenorb.apiv3.handlers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; @@ -6,8 +6,9 @@ import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.utils.ErrorUtils; -public final class AuthorizationFilter implements Handler { +public final class AuthorizationHandler implements Handler { + @Override public void handle(RoutingContext ctx) { Actor actor = ctx.get("actor"); diff --git a/src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java b/src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java rename to src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java index 5d0fa69..1bb0839 100644 --- a/src/main/java/net/frozenorb/apiv3/filters/MetricsHandler.java +++ b/src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.filters; +package net.frozenorb.apiv3.handlers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; @@ -6,6 +6,7 @@ import net.frozenorb.apiv3.APIv3; public final class MetricsHandler implements Handler { + @Override public void handle(RoutingContext ctx) { APIv3.getStatsD().incrementCounter("apiv3.http.requests"); ctx.next(); diff --git a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java index fe6a990..49f7065 100644 --- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java @@ -1,9 +1,9 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.ImmutableMap; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; @@ -15,12 +15,8 @@ import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; -import java.util.Date; -import java.util.List; -import java.util.Map; -import java.util.UUID; +import java.util.*; -@Entity public final class AuditLogEntry { private static final MongoCollection auditLogCollection = APIv3.getDatabase().getCollection("auditLog", AuditLogEntry.class); @@ -34,22 +30,46 @@ public final class AuditLogEntry { @Getter private AuditLogActionType type; @Getter private Map metadata; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(auditLogCollection.find()); } - public static AuditLogEntry findById(String id) { + public static List findAllPaginatedSync(int skip, int pageSize) { + return SyncUtils.blockMulti(auditLogCollection.find().sort(new Document("performedAt", 1)).skip(skip).limit(pageSize)); + } + + public static AuditLogEntry findByIdSync(String id) { return SyncUtils.blockOne(auditLogCollection.find(new Document("_id", id))); } - public static List findByUser(User user) { - return findByUser(user.getId()); + public static List findByUserSync(User user) { + return findByUserSync(user.getId()); } - public static List findByUser(UUID user) { + public static List findByUserSync(UUID user) { return SyncUtils.blockMulti(auditLogCollection.find(new Document("user", user))); } + public static void findAll(SingleResultCallback> callback) { + auditLogCollection.find().into(new ArrayList<>(), callback); + } + + public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { + auditLogCollection.find().sort(new Document("performedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + auditLogCollection.find(new Document("_id", id)).first(callback); + } + + public static void findByUser(User user, SingleResultCallback> callback) { + findByUser(user.getId(), callback); + } + + public static void findByUser(UUID user, SingleResultCallback> callback) { + auditLogCollection.find(new Document("user", user)).into(new ArrayList<>(), callback); + } + public AuditLogEntry() {} // For Morphia public AuditLogEntry(User user, String userIp, Actor actor, AuditLogActionType type, Map metadata) { diff --git a/src/main/java/net/frozenorb/apiv3/models/Grant.java b/src/main/java/net/frozenorb/apiv3/models/Grant.java index 7960b16..cda879e 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Grant.java +++ b/src/main/java/net/frozenorb/apiv3/models/Grant.java @@ -1,11 +1,10 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.Collections2; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; -import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; @@ -16,7 +15,6 @@ import org.bson.types.ObjectId; import java.util.*; -@Entity @AllArgsConstructor public final class Grant { @@ -36,26 +34,74 @@ public final class Grant { @Getter private Date removedAt; @Getter private String removalReason; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(grantsCollection.find()); } - public static List findByRank(Iterable ranks) { + public static List findAllPaginatedSync(int skip, int pageSize) { + return SyncUtils.blockMulti(grantsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize)); + } + + public static List findByRankSync(Iterable ranks) { return SyncUtils.blockMulti(grantsCollection.find(new Document("rank", new Document("$in", ranks)))); } - public static Grant findById(String id) { + public static Grant findByIdSync(String id) { return SyncUtils.blockOne(grantsCollection.find(new Document("_id", id))); } - public static List findByUser(User user) { - return findByUser(user.getId()); + public static List findByUserSync(User user) { + return findByUserSync(user.getId()); } - public static List findByUser(UUID user) { + public static List findByUserSync(UUID user) { return SyncUtils.blockMulti(grantsCollection.find(new Document("user", user))); } + public static void findAll(SingleResultCallback> callback) { + grantsCollection.find().into(new ArrayList<>(), callback); + } + + public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { + grantsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + } + + public static void findByRank(Iterable ranks, SingleResultCallback> callback) { + grantsCollection.find(new Document("rank", new Document("$in", ranks))).into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + grantsCollection.find(new Document("_id", id)).first(callback); + } + + public static void findByUser(User user, SingleResultCallback> callback) { + findByUser(user.getId(), callback); + } + + public static void findByUser(UUID user, SingleResultCallback> callback) { + grantsCollection.find(new Document("user", user)).into(new ArrayList<>(), callback); + } + + public static void findByUserGrouped(Iterable users, SingleResultCallback>> callback) { + grantsCollection.find(new Document("user", new Document("$in", users))).into(new ArrayList<>(), (grants, error) -> { + if (error != null) { + callback.onResult(null, error); + } else { + Map> result = new HashMap<>(); + + for (UUID user : users) { + result.put(user, new ArrayList<>()); + } + + for (Grant grant : grants) { + result.get(grant.getUser()).add(grant); + } + + callback.onResult(result, null); + } + }); + } + public Grant() {} // For Morphia public Grant(User user, String reason, Set scopes, Rank rank, Date expiresAt, User addedBy) { diff --git a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java index 3a52456..98f20d7 100644 --- a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java @@ -1,8 +1,9 @@ package net.frozenorb.apiv3.models; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; @@ -11,11 +12,11 @@ import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; +import java.util.ArrayList; import java.util.Date; import java.util.List; import java.util.UUID; -@Entity @AllArgsConstructor public final class IPLogEntry { @@ -28,30 +29,54 @@ public final class IPLogEntry { @Getter private Date lastSeenAt; @Getter private int uses; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(ipLogCollection.find()); } - public static IPLogEntry findById(String id) { + public static IPLogEntry findByIdSync(String id) { return SyncUtils.blockOne(ipLogCollection.find(new Document("_id", id))); } - public static List findByUser(User user) { - return findByUser(user.getId()); + public static List findByUserSync(User user) { + return findByUserSync(user.getId()); } - public static List findByUser(UUID user) { + public static List findByUserSync(UUID user) { return SyncUtils.blockMulti(ipLogCollection.find(new Document("user", user))); } - public static IPLogEntry findByUserAndIp(User user, String userIp) { - return findByUserAndIp(user.getId(), userIp); + public static IPLogEntry findByUserAndIpSync(User user, String userIp) { + return findByUserAndIpSync(user.getId(), userIp); } - public static IPLogEntry findByUserAndIp(UUID user, String userIp) { + public static IPLogEntry findByUserAndIpSync(UUID user, String userIp) { return SyncUtils.blockOne(ipLogCollection.find(new Document("user", user).append("userIp", userIp))); } + public static void findAll(SingleResultCallback> callback) { + ipLogCollection.find().into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + ipLogCollection.find(new Document("_id", id)).first(callback); + } + + public static void findByUser(User user, SingleResultCallback> callback) { + findByUser(user.getId(), callback); + } + + public static void findByUser(UUID user, SingleResultCallback> callback) { + ipLogCollection.find(new Document("user", user)).into(new ArrayList<>(), callback); + } + + public static void findByUserAndIp(User user, String userIp, SingleResultCallback callback) { + findByUserAndIp(user.getId(), userIp, callback); + } + + public static void findByUserAndIp(UUID user, String userIp, SingleResultCallback callback) { + ipLogCollection.find(new Document("user", user).append("userIp", userIp)).first(callback); + } + public IPLogEntry() {} // For Morphia public IPLogEntry(User user, String userIp) { @@ -74,4 +99,10 @@ public final class IPLogEntry { callback.get(); } + public void save() { + BlockingCallback callback = new BlockingCallback<>(); + ipLogCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java index cf56f6c..8d000c5 100644 --- a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java @@ -1,21 +1,22 @@ package net.frozenorb.apiv3.models; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; +import java.util.ArrayList; import java.util.List; import java.util.Map; -@Entity public final class NotificationTemplate { private static final MongoCollection notificationTemplatesCollection = APIv3.getDatabase().getCollection("notificationTemplates", NotificationTemplate.class); @@ -24,14 +25,22 @@ public final class NotificationTemplate { @Getter @Setter private String subject; @Getter @Setter private String body; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(notificationTemplatesCollection.find()); } - public static NotificationTemplate findById(String id) { + public static NotificationTemplate findByIdSync(String id) { return SyncUtils.blockOne(notificationTemplatesCollection.find(new Document("_id", id))); } + public static void findAll(SingleResultCallback> callback) { + notificationTemplatesCollection.find().into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + notificationTemplatesCollection.find(new Document("_id", id)).first(callback); + } + public NotificationTemplate() {} // For Morphia public NotificationTemplate(String id, String subject, String body) { diff --git a/src/main/java/net/frozenorb/apiv3/models/Punishment.java b/src/main/java/net/frozenorb/apiv3/models/Punishment.java index 643ce5b..3a42564 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Punishment.java +++ b/src/main/java/net/frozenorb/apiv3/models/Punishment.java @@ -1,9 +1,9 @@ package net.frozenorb.apiv3.models; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; @@ -17,7 +17,6 @@ import org.bson.types.ObjectId; import java.util.*; -@Entity @AllArgsConstructor public final class Punishment { @@ -39,34 +38,90 @@ public final class Punishment { @Getter private Date removedAt; @Getter private String removalReason; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(punishmentsCollection.find()); } - public static List findByType(Iterable types) { + public static List findAllPaginatedSync(int skip, int pageSize) { + return SyncUtils.blockMulti(punishmentsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize)); + } + + public static List findByTypeSync(Iterable types) { return SyncUtils.blockMulti(punishmentsCollection.find(new Document("type", new Document("$in", types)))); } - public static Punishment findById(String id) { + public static Punishment findByIdSync(String id) { return SyncUtils.blockOne(punishmentsCollection.find(new Document("_id", id))); } - public static List findByUser(User user) { - return findByUser(user.getId()); + public static List findByUserSync(User user) { + return findByUserSync(user.getId()); } - public static List findByUser(UUID user) { + public static List findByUserSync(UUID user) { return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user))); } - public static List findByUserAndType(User user, Iterable types) { - return findByUserAndType(user.getId(), types); + public static List findByUserAndTypeSync(User user, Iterable types) { + return findByUserAndTypeSync(user.getId(), types); } - public static List findByUserAndType(UUID user, Iterable types) { + public static List findByUserAndTypeSync(UUID user, Iterable types) { return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", types)))); } + public static void findAll(SingleResultCallback> callback) { + punishmentsCollection.find().into(new ArrayList<>(), callback); + } + + public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { + punishmentsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + } + + public static void findByType(Iterable types, SingleResultCallback> callback) { + punishmentsCollection.find(new Document("type", new Document("$in", types))).into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + punishmentsCollection.find(new Document("_id", id)).first(callback); + } + + public static void findByUser(User user, SingleResultCallback> callback) { + findByUser(user.getId(), callback); + } + + public static void findByUser(UUID user, SingleResultCallback> callback) { + punishmentsCollection.find(new Document("user", user)).into(new ArrayList<>(), callback); + } + + public static void findByUserGrouped(Iterable users, SingleResultCallback>> callback) { + punishmentsCollection.find(new Document("user", new Document("$in", users))).into(new ArrayList<>(), (punishments, error) -> { + if (error != null) { + callback.onResult(null, error); + } else { + Map> result = new HashMap<>(); + + for (UUID user : users) { + result.put(user, new ArrayList<>()); + } + + for (Punishment punishment : punishments) { + result.get(punishment.getUser()).add(punishment); + } + + callback.onResult(result, null); + } + }); + } + + public static void findByUserAndType(User user, Iterable types, SingleResultCallback> callback) { + findByUserAndType(user.getId(), types, callback); + } + + public static void findByUserAndType(UUID user, Iterable types, SingleResultCallback> callback) { + punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", types))).into(new ArrayList<>(), callback); + } + public Punishment() {} // For Morphia public Punishment(User user, String reason, PunishmentType type, Date expiresAt, User addedBy, Actor actor, Map metadata) { diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/models/Rank.java index f035a7e..8ec7348 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Rank.java +++ b/src/main/java/net/frozenorb/apiv3/models/Rank.java @@ -5,8 +5,7 @@ import com.google.common.primitives.Ints; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; @@ -19,7 +18,6 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; -@Entity public final class Rank { private static final MongoCollection ranksCollection = APIv3.getDatabase().getCollection("ranks", Rank.class); diff --git a/src/main/java/net/frozenorb/apiv3/models/Server.java b/src/main/java/net/frozenorb/apiv3/models/Server.java index b5b9727..d666da9 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Server.java +++ b/src/main/java/net/frozenorb/apiv3/models/Server.java @@ -4,8 +4,7 @@ import com.google.common.collect.ImmutableSet; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; @@ -17,7 +16,6 @@ import org.bson.Document; import java.util.*; import java.util.concurrent.TimeUnit; -@Entity public final class Server { private static final MongoCollection serversCollection = APIv3.getDatabase().getCollection("servers", Server.class); diff --git a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java index 8c5ade2..5d41865 100644 --- a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java @@ -4,8 +4,7 @@ import com.google.gson.annotations.SerializedName; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; @@ -18,7 +17,6 @@ import org.bson.Document; import java.util.*; import java.util.concurrent.TimeUnit; -@Entity public final class ServerGroup { private static final MongoCollection serverGroupsCollection = APIv3.getDatabase().getCollection("serverGroups", ServerGroup.class); @@ -29,8 +27,6 @@ public final class ServerGroup { @Getter @Id private String id; @Getter private String image; - // We rename this to public (only to gson), we just can't name it that because it's a Java identifier. - @Getter @SerializedName("public") private boolean isPublic; // We define these HashSets up here because, in the event they're // empty, Morphia will load them as null, not empty sets. @Getter @Setter @ExcludeFromReplies private Set announcements = new HashSet<>(); @@ -48,10 +44,9 @@ public final class ServerGroup { public ServerGroup() {} // For Morphia - public ServerGroup(String id, String image, boolean isPublic) { + public ServerGroup(String id, String image) { this.id = id; this.image = image; - this.isPublic = isPublic; } public Map calculatePermissions(Rank userRank) { diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/models/User.java index 6e27e32..3b6ccb7 100644 --- a/src/main/java/net/frozenorb/apiv3/models/User.java +++ b/src/main/java/net/frozenorb/apiv3/models/User.java @@ -1,18 +1,22 @@ package net.frozenorb.apiv3.models; +import com.fasterxml.jackson.databind.annotation.JsonDeserialize; +import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.base.Charsets; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import com.google.common.hash.Hashing; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.ExcludeFromReplies; +import net.frozenorb.apiv3.serialization.UUIDJsonDeserializer; +import net.frozenorb.apiv3.serialization.UUIDJsonSerializer; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.MojangUtils; import net.frozenorb.apiv3.utils.PermissionUtils; @@ -22,13 +26,12 @@ import org.bson.Document; import java.util.*; -@Entity @AllArgsConstructor public final class User { private static final MongoCollection usersCollection = APIv3.getDatabase().getCollection("users", User.class); - @Getter @Id private UUID id; + @Getter @Id @JsonSerialize(using=UUIDJsonSerializer.class) @JsonDeserialize(using=UUIDJsonDeserializer.class) private UUID id; @Getter private String lastUsername; @Getter @ExcludeFromReplies private Map aliases = new HashMap<>(); @Getter @ExcludeFromReplies @Setter private String totpSecret; @@ -42,11 +45,11 @@ public final class User { @Getter private Date firstSeenAt; @Getter private boolean online; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(usersCollection.find()); } - public static User findById(String id) { + public static User findByIdSync(String id) { UUID uuid; try { @@ -55,10 +58,10 @@ public final class User { return null; } - return findById(uuid); + return findByIdSync(uuid); } - public static User findById(UUID id) { + public static User findByIdSync(UUID id) { if (UUIDUtils.isAcceptableUUID(id)) { return SyncUtils.blockOne(usersCollection.find(new Document("_id", id))); } else { @@ -66,14 +69,63 @@ public final class User { } } - public static User findByEmailToken(String emailToken) { + public static User findByEmailTokenSync(String emailToken) { return SyncUtils.blockOne(usersCollection.find(new Document("emailToken", emailToken))); } - public static User findByLastUsername(String lastUsername) { + public static User findByLastUsernameSync(String lastUsername) { return SyncUtils.blockOne(usersCollection.find(new Document("lastUsername", lastUsername))); } + public static void findAll(SingleResultCallback> callback) { + usersCollection.find().into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + try { + UUID uuid = UUID.fromString(id); + findById(uuid, callback); + } catch (IllegalArgumentException ex) { // from UUID parsing + callback.onResult(null, ex); + } + } + + public static void findById(UUID id, SingleResultCallback callback) { + if (UUIDUtils.isAcceptableUUID(id)) { + usersCollection.find(new Document("_id", id)).first(callback); + } else { + callback.onResult(null, null); + } + } + + public static void findByIdGrouped(Iterable search, SingleResultCallback> callback) { + usersCollection.find(new Document("_id", new Document("$in", search))).into(new ArrayList<>(), (users, error) -> { + if (error != null) { + callback.onResult(null, error); + } else { + Map result = new HashMap<>(); + + for (UUID user : search) { + result.put(user, null); + } + + for (User user : users) { + result.put(user.getId(), user); + } + + callback.onResult(result, null); + } + }); + } + + public static void findByEmailToken(String emailToken, SingleResultCallback callback) { + usersCollection.find(new Document("emailToken", emailToken)).first(callback); + } + + public static void findByLastUsername(String lastUsername, SingleResultCallback callback) { + usersCollection.find(new Document("lastUsername", lastUsername)).first(callback); + } + public User() {} // For Morphia public User(UUID id, String lastUsername) { @@ -134,8 +186,10 @@ public final class User { User withNewUsername; - while ((withNewUsername = User.findByLastUsername(username)) != null) { - String newUsername = MojangUtils.getName(withNewUsername.getId()); + while ((withNewUsername = User.findByLastUsernameSync(username)) != null) { + BlockingCallback callback = new BlockingCallback<>(); + MojangUtils.getName(withNewUsername.getId(), callback); + String newUsername = callback.get(); withNewUsername.updateUsername(newUsername); } } @@ -164,7 +218,7 @@ public final class User { } public Rank getHighestRankScoped(ServerGroup serverGroup) { - return getHighestRankScoped(serverGroup, Grant.findByUser(this)); + return getHighestRankScoped(serverGroup, Grant.findByUserSync(this)); } // TODO: Clean @@ -195,7 +249,7 @@ public final class User { public Map getHighestRanks() { Map highestRanks = new HashMap<>(); Rank defaultRank = Rank.findById("default"); - List userGrants = Grant.findByUser(this); + List userGrants = Grant.findByUserSync(this); for (ServerGroup serverGroup : ServerGroup.findAll()) { Rank highest = defaultRank; @@ -221,12 +275,12 @@ public final class User { public Map getLoginInfo(Server server) { return createLoginInfo( server, - Punishment.findByUserAndType(this, ImmutableSet.of( + Punishment.findByUserAndTypeSync(this, ImmutableSet.of( Punishment.PunishmentType.BLACKLIST, Punishment.PunishmentType.BAN, Punishment.PunishmentType.MUTE )), - Grant.findByUser(this) + Grant.findByUserSync(this) ); } diff --git a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java index bee4fed..5f1831d 100644 --- a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java @@ -1,11 +1,11 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.ImmutableMap; +import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; -import eu.dozd.mongo.annotation.Entity; -import eu.dozd.mongo.annotation.Id; +import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; @@ -14,11 +14,11 @@ import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; +import java.util.ArrayList; import java.util.List; import java.util.Map; import java.util.UUID; -@Entity public final class UserMetaEntry { private static final MongoCollection userMetaCollection = APIv3.getDatabase().getCollection("userMeta", UserMetaEntry.class); @@ -28,22 +28,38 @@ public final class UserMetaEntry { @Getter private String serverGroup; @Getter @Setter private Map data; - public static List findAll() { + public static List findAllSync() { return SyncUtils.blockMulti(userMetaCollection.find()); } - public static UserMetaEntry findById(String id) { + public static UserMetaEntry findByIdSync(String id) { return SyncUtils.blockOne(userMetaCollection.find(new Document("_id", id))); } - public static UserMetaEntry findByUserAndGroup(User user, ServerGroup serverGroup) { - return findByUserAndGroup(user.getId(), serverGroup); + public static UserMetaEntry findByUserAndGroupSync(User user, ServerGroup serverGroup) { + return findByUserAndGroupSync(user.getId(), serverGroup); } - public static UserMetaEntry findByUserAndGroup(UUID user, ServerGroup serverGroup) { + public static UserMetaEntry findByUserAndGroupSync(UUID user, ServerGroup serverGroup) { return SyncUtils.blockOne(userMetaCollection.find(new Document("user", user).append("serverGroup", serverGroup.getId()))); } + public static void findAll(SingleResultCallback> callback) { + userMetaCollection.find().into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + userMetaCollection.find(new Document("_id", id)).first(callback); + } + + public static void findByUserAndGroup(User user, ServerGroup serverGroup, SingleResultCallback callback) { + findByUserAndGroup(user.getId(), serverGroup, callback); + } + + public static void findByUserAndGroup(UUID user, ServerGroup serverGroup, SingleResultCallback callback) { + userMetaCollection.find(new Document("user", user).append("serverGroup", serverGroup.getId())).first(callback); + } + public UserMetaEntry() {} // For Morphia public UserMetaEntry(User user, ServerGroup serverGroup, Map data) { diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java index 449e054..27629a1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java @@ -29,8 +29,7 @@ public final class GETDump implements Handler { List banCache = new ArrayList<>(); List blacklistCache = new ArrayList<>(); - Punishment.findByType - (ImmutableSet.of( + Punishment.findByTypeSync(ImmutableSet.of( Punishment.PunishmentType.BAN, Punishment.PunishmentType.BLACKLIST )).forEach((punishment) -> { @@ -52,7 +51,7 @@ public final class GETDump implements Handler { if (tick == 0 || tick % 2 == 0) { Map> grantCache = new HashMap<>(); - Grant.findAll().forEach((grant) -> { + Grant.findAllSync().forEach((grant) -> { if (grant.isActive()) { List users = grantCache.get(grant.getRank()); diff --git a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java b/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java index 1f3ce08..ea1b639 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java @@ -10,12 +10,12 @@ public final class GETAuditLog implements Handler { public void handle(RoutingContext ctx) { try { - int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); - int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); + 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, APIv3.getDatastore().createQuery(AuditLogEntry.class).order("performedAt").limit(limit).offset(offset).asList()); + APIv3.respondJson(ctx, AuditLogEntry.findAllPaginatedSync(skip, pageSize)); } catch (NumberFormatException ex) { - ErrorUtils.respondInvalidInput(ctx, "limit/offset must be numerical inputs."); + ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java index 4dc0c67..d96e6bb 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java @@ -13,7 +13,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEGrant implements Handler { public void handle(RoutingContext ctx) { - Grant grant = Grant.findById(ctx.request().getParam("id")); + Grant grant = Grant.findByIdSync(ctx.request().getParam("id")); if (grant == null) { ErrorUtils.respondNotFound(ctx, "Grant", ctx.request().getParam("id")); @@ -23,7 +23,7 @@ public final class DELETEGrant implements Handler { return; } - User removedBy = User.findById(ctx.request().getParam("removedBy")); + User removedBy = User.findByIdSync(ctx.request().getParam("removedBy")); if (removedBy == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java index d544499..f9cd886 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.Grant; public final class GETGrant implements Handler { public void handle(RoutingContext ctx) { - APIv3.respondJson(ctx, Grant.findById(ctx.request().getParam("id"))); + APIv3.respondJson(ctx, Grant.findByIdSync(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java index f7120f0..021cdab 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java @@ -10,12 +10,12 @@ public final class GETGrants implements Handler { public void handle(RoutingContext ctx) { try { - int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); - int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); + 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, APIv3.getDatastore().createQuery(Grant.class).order("addedAt").limit(limit).offset(offset).asList()); + APIv3.respondJson(ctx, Grant.findAllPaginatedSync(skip, pageSize)); } catch (NumberFormatException ex) { - ErrorUtils.respondInvalidInput(ctx, "limit and offset must be numerical inputs."); + ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java index 36e392a..4313fac 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java @@ -10,14 +10,14 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserGrants implements Handler { public void handle(RoutingContext ctx) { - User target = User.findById(ctx.request().getParam("id")); + User target = User.findByIdSync(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); return; } - APIv3.respondJson(ctx, Grant.findByUser(target)); + APIv3.respondJson(ctx, Grant.findByUserSync(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java index 709bc5f..18976ac 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java @@ -16,7 +16,7 @@ import java.util.Set; public final class POSTUserGrant implements Handler { public void handle(RoutingContext ctx) { - User target = User.findById(ctx.request().getParam("id")); + User target = User.findByIdSync(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -67,7 +67,7 @@ public final class POSTUserGrant implements Handler { } // We purposely don't do a null check, grants don't have to have a source. - User addedBy = User.findById(ctx.request().getParam("addedBy")); + User addedBy = User.findByIdSync(ctx.request().getParam("addedBy")); Grant grant = new Grant(target, reason, scopes, rank, expiresAt, addedBy); grant.insert(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java index 1addce1..42e5310 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java @@ -10,14 +10,14 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserIPLog implements Handler { public void handle(RoutingContext ctx) { - User target = User.findById(ctx.request().getParam("id")); + User target = User.findByIdSync(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); return; } - APIv3.respondJson(ctx, IPLogEntry.findByUser(target)); + APIv3.respondJson(ctx, IPLogEntry.findByUserSync(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java index 8afc202..da8850f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java @@ -9,7 +9,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETENotificationTemplate implements Handler { public void handle(RoutingContext ctx) { - NotificationTemplate notificationTemplate = NotificationTemplate.findById(ctx.request().getParam("id")); + NotificationTemplate notificationTemplate = NotificationTemplate.findByIdSync(ctx.request().getParam("id")); if (notificationTemplate == null) { ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("id")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java index 58bf102..8e6632f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.NotificationTemplate; public final class GETNotificationTemplate implements Handler { public void handle(RoutingContext ctx) { - APIv3.respondJson(ctx, NotificationTemplate.findById(ctx.request().getParam("id"))); + APIv3.respondJson(ctx, NotificationTemplate.findByIdSync(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java index 2dcd2fc..16cdba6 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.NotificationTemplate; public final class GETNotificationTemplates implements Handler { public void handle(RoutingContext ctx) { - APIv3.respondJson(ctx, NotificationTemplate.findAll()); + APIv3.respondJson(ctx, NotificationTemplate.findAllSync()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java index c517ea4..33e07bc 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java @@ -13,7 +13,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEPunishment implements Handler { public void handle(RoutingContext ctx) { - Punishment punishment = Punishment.findById(ctx.request().getParam("id")); + Punishment punishment = Punishment.findByIdSync(ctx.request().getParam("id")); if (punishment == null) { ErrorUtils.respondNotFound(ctx, "Punishment", ctx.request().getParam("id")); @@ -23,7 +23,7 @@ public final class DELETEPunishment implements Handler { return; } - User removedBy = User.findById(ctx.request().getParam("removedBy")); + User removedBy = User.findByIdSync(ctx.request().getParam("removedBy")); if (removedBy == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java index f502ffa..8a61e6f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.Punishment; public final class GETPunishment implements Handler { public void handle(RoutingContext ctx) { - APIv3.respondJson(ctx, Punishment.findById(ctx.request().getParam("id"))); + APIv3.respondJson(ctx, Punishment.findByIdSync(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java index 1e0a41a..28b9109 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java @@ -10,12 +10,12 @@ public final class GETPunishments implements Handler { public void handle(RoutingContext ctx) { try { - int limit = ctx.request().getParam("limit") == null ? 100 : Integer.parseInt(ctx.request().getParam("limit")); - int offset = ctx.request().getParam("offset") == null ? 0 : Integer.parseInt(ctx.request().getParam("offset")); + 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, APIv3.getDatastore().createQuery(Punishment.class).order("addedAt").limit(limit).offset(offset).asList()); + APIv3.respondJson(ctx, Punishment.findAllPaginatedSync(skip, pageSize)); } catch (NumberFormatException ex) { - ErrorUtils.respondInvalidInput(ctx, "limit and offset must be numerical inputs."); + ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs."); } } diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java index f55ace0..15a7842 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java @@ -10,14 +10,14 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserPunishments implements Handler { public void handle(RoutingContext ctx) { - User target = User.findById(ctx.request().getParam("id")); + User target = User.findByIdSync(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); return; } - APIv3.respondJson(ctx, Punishment.findByUser(target)); + APIv3.respondJson(ctx, Punishment.findByUserSync(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java index 8cb4dd9..bd2ef45 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java @@ -17,7 +17,7 @@ import java.util.Map; public final class POSTUserPunish implements Handler { public void handle(RoutingContext ctx) { - User target = User.findById(ctx.request().getParam("id")); + User target = User.findByIdSync(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -34,9 +34,9 @@ public final class POSTUserPunish implements Handler { Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(ctx.request().getParam("type")); if (type != Punishment.PunishmentType.WARN) { - for (Punishment punishment : Punishment.findByUserAndType(target, ImmutableSet.of(type))) { + for (Punishment punishment : Punishment.findByUserAndTypeSync(target, ImmutableSet.of(type))) { if (punishment.isActive()) { - ErrorUtils.respondGeneric(ctx, "A punishment by " + User.findById(punishment.getAddedBy()).getLastUsername() + " already covers this user."); + ErrorUtils.respondGeneric(ctx, "A punishment by " + User.findByIdSync(punishment.getAddedBy()).getLastUsername() + " already covers this user."); return; } } @@ -63,7 +63,7 @@ public final class POSTUserPunish implements Handler { } // We purposely don't do a null check, grants don't have to have a source. - User addedBy = User.findById(ctx.request().getParam("addedBy")); + User addedBy = User.findByIdSync(ctx.request().getParam("addedBy")); if (target.hasPermissionAnywhere(Permissions.PROTECTED_PUNISHMENT)) { ErrorUtils.respondGeneric(ctx, target.getLastSeenOn() + " is protected from punishments."); diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java index 72de2c4..b6ba7b0 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java @@ -10,9 +10,8 @@ public final class POSTServerGroup implements Handler { public void handle(RoutingContext ctx) { String id = ctx.request().getParam("id"); String image = ctx.request().getParam("image"); - boolean isPublic = Boolean.valueOf(ctx.request().getParam("public")); - ServerGroup serverGroup = new ServerGroup(id, image, isPublic); + ServerGroup serverGroup = new ServerGroup(id, image); serverGroup.insert(); APIv3.respondJson(ctx, serverGroup); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java index 2a34f3e..341accd 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java @@ -1,6 +1,9 @@ package net.frozenorb.apiv3.routes.servers; +import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; +import io.vertx.core.CompositeFuture; +import io.vertx.core.Future; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import lombok.extern.slf4j.Slf4j; @@ -18,7 +21,6 @@ import java.util.*; @Slf4j public final class POSTServerHeartbeat implements Handler { - @SuppressWarnings("unchecked") public void handle(RoutingContext ctx) { Actor actor = ctx.get("actor"); @@ -27,57 +29,132 @@ public final class POSTServerHeartbeat implements Handler { return; } - Server actorServer = Server.byId(actor.getName()); - ServerGroup actorServerGroup = ServerGroup.byId(actorServer.getServerGroup()); + Server actorServer = Server.findById(actor.getName()); + ServerGroup actorServerGroup = ServerGroup.findById(actorServer.getServerGroup()); Document reqJson = Document.parse(ctx.getBodyAsString()); - Map onlinePlayersNames = new HashMap<>(); - Map onlinePlayersUsers; - Map> onlinePlayersGrants; - Map> onlinePlayersPunishments; - Map playersResponse = new HashMap<>(); + Map playerNames = extractPlayerNames(reqJson); - // This code is messy, but we have to do db ops in parallel to avoid - // spamming Mongo with queries, so we do this. - for (Object player : (List) reqJson.get("players")) { - Document playerJson = (Document) player; - UUID uuid = UUID.fromString(playerJson.getString("uuid")); - String username = playerJson.getString("username"); - - if (UUIDUtils.isAcceptableUUID(uuid)) { - onlinePlayersNames.put(uuid, username); + CompositeFuture.all( + createInfoResponse(actorServer, reqJson.getDouble("tps"), playerNames), + createPlayerResponse(actorServer, playerNames), + createPermissionsResponse(actorServerGroup), + createEventsResponse((List) reqJson.get("events")) + ).setHandler((result) -> { + if (result.succeeded()) { + APIv3.respondJson(ctx, ImmutableMap.of( + "info", result.result().result(0), + "players", result.result().result(1), + "permissions", result.result().result(2), + "events", result.result().result(3) + )); + } else { + ErrorUtils.respondGeneric(ctx, result.cause().getMessage()); } + }); + } + + public Future> createInfoResponse(Server server, double tps, Map playerNames) { + Future> callback = Future.future(); + + server.setPlayers(playerNames.keySet()); + server.setLastTps(tps); + server.setLastUpdatedAt(new Date()); + server.save(); + + return callback; + } + + public Future> createPlayerResponse(Server server, Map playerNames) { + Future> callback = Future.future(); + + Future> userLookupCallback = Future.future(); + Future>> grantLookupCallback = Future.future(); + Future>> punishmentLookupCallback = Future.future(); + + User.findByIdGrouped(playerNames.keySet(), (users, error) -> { + if (error != null) { + userLookupCallback.fail(error); + } else { + userLookupCallback.complete(users); + } + }); + + Grant.findByUserGrouped(playerNames.keySet(), (grants, error) -> { + if (error != null) { + grantLookupCallback.fail(error); + } else { + grantLookupCallback.complete(grants); + } + }); + + Punishment.findByUserGrouped(playerNames.keySet(), (punishments, error) -> { + if (error != null) { + punishmentLookupCallback.fail(error); + } else { + punishmentLookupCallback.complete(punishments); + } + }); + + CompositeFuture.all( + userLookupCallback, + grantLookupCallback, + punishmentLookupCallback + ).setHandler((result) -> { + if (result.failed()) { + callback.fail(result.cause()); + } else { + Map users = result.result().result(0); + Map> grants = result.result().result(1); + Map> punishments = result.result().result(2); + Map response = new HashMap<>(); + + for (Map.Entry userEntry : users.entrySet()) { + UUID uuid = userEntry.getKey(); + User user = userEntry.getValue(); + + if (user == null) { + String username = playerNames.get(uuid); + user = new User(uuid, username); + user.insert(); + users.put(uuid, user); + } + + // Only save if needed + if (user.seenOnServer(server)) { + user.save(); + } + + response.put(uuid.toString(), user.createLoginInfo(server, punishments.get(uuid), grants.get(uuid))); + } + + callback.complete(response); + } + }); + + return callback; + } + + public Future> createPermissionsResponse(ServerGroup serverGroup) { + Future> callback = Future.future(); + Map permissionsResponse = new HashMap<>(); + + for (Rank rank : Rank.findAll()) { + Map scopedPermissions = PermissionUtils.mergePermissions( + PermissionUtils.getDefaultPermissions(rank), + serverGroup.calculatePermissions(rank) + ); + + permissionsResponse.put(rank.getId(), scopedPermissions); } - onlinePlayersUsers = User.byIdGrouped(onlinePlayersNames.keySet()); + callback.complete(permissionsResponse); + return callback; + } - for (Map.Entry entry : new HashMap<>(onlinePlayersUsers).entrySet()) { - UUID uuid = entry.getKey(); - User user = entry.getValue(); + public Future> createEventsResponse(List eventsData) { + Future> callback = Future.future(); - if (user == null) { - // Will be saved in the User constructor - String username = onlinePlayersNames.get(uuid); - user = new User(uuid, username); - onlinePlayersUsers.put(uuid, user); - } - - // Only save if needed - if (user.seenOnServer(actorServer)) { - APIv3.getDatastore().save(user); - } - } - - onlinePlayersGrants = Grant.byUserGrouped(onlinePlayersUsers.keySet()); - onlinePlayersPunishments = Punishment.byUserGrouped(onlinePlayersUsers.keySet()); - - for (Map.Entry entry : onlinePlayersUsers.entrySet()) { - UUID uuid = entry.getKey(); - User user = entry.getValue(); - - playersResponse.put(uuid.toString(), user.prepareLoginInfo(actorServer, onlinePlayersPunishments.get(uuid), onlinePlayersGrants.get(uuid))); - } - - for (Object event : (List) reqJson.get("events")) { + for (Object event : eventsData) { Document eventJson = (Document) event; String type = eventJson.getString("type"); @@ -93,26 +170,24 @@ public final class POSTServerHeartbeat implements Handler { } } - Map> permissionsResponse = new HashMap<>(); + callback.complete(ImmutableMap.of()); + return callback; + } - for (Rank rank : Rank.findAll()) { - Map scopedPermissions = PermissionUtils.mergePermissions( - PermissionUtils.getDefaultPermissions(rank), - actorServerGroup.calculatePermissions(rank) - ); + public Map extractPlayerNames(Document reqJson) { + Map result = new HashMap<>(); - permissionsResponse.put(rank.getId(), scopedPermissions); + for (Object player : (List) reqJson.get("players")) { + Document playerJson = (Document) player; + UUID uuid = UUID.fromString(playerJson.getString("uuid")); + String username = playerJson.getString("username"); + + if (UUIDUtils.isAcceptableUUID(uuid)) { + result.put(uuid, username); + } } - actorServer.setPlayers(onlinePlayersNames.keySet()); - actorServer.setLastTps(reqJson.getDouble("lastTps")); - actorServer.setLastUpdatedAt(new Date()); - actorServer.save(); - - APIv3.respondJson(ctx, ImmutableMap.of( - "players", playersResponse, - "permissions", permissionsResponse - )); + return result; } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java index 03716b5..3593415 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java @@ -12,7 +12,7 @@ import org.bson.Document; public final class DELETEUserMeta implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -26,7 +26,7 @@ public final class DELETEUserMeta implements Handler { return; } - UserMetaEntry userMetaEntry = UserMetaEntry.findByUserAndGroup(user, serverGroup); + UserMetaEntry userMetaEntry = UserMetaEntry.findByUserAndGroupSync(user, serverGroup); if (userMetaEntry != null) { userMetaEntry.delete(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java index f35b6cb..b2f8a50 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java @@ -14,7 +14,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEUserPunishment implements Handler { public void handle(RoutingContext ctx) { - User target = User.findById(ctx.request().getParam("id")); + User target = User.findByIdSync(ctx.request().getParam("id")); if (target == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -22,7 +22,7 @@ public final class DELETEUserPunishment implements Handler { } Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(ctx.request().getParam("type").toUpperCase()); - User removedBy = User.findById(ctx.request().getParam("removedBy")); + User removedBy = User.findByIdSync(ctx.request().getParam("removedBy")); if (removedBy == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); @@ -36,7 +36,7 @@ public final class DELETEUserPunishment implements Handler { return; } - for (Punishment punishment : target.getPunishments(ImmutableSet.of(type))) { + for (Punishment punishment : Punishment.findByUserAndTypeSync(target, ImmutableSet.of(type))) { if (punishment.isActive()) { punishment.delete(removedBy, reason); AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java index 3a5a398..7a43f48 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java @@ -27,9 +27,9 @@ public final class GETStaff implements Handler { return Integer.compare(firstRank.getWeight(), secondRank.getWeight()); }); - Grant.findByRank(staffRanks.values()).forEach(grant -> { + Grant.findByRankSync(staffRanks.values()).forEach(grant -> { if (grant.isActive()) { - User user = User.findById(grant.getUser()); + User user = User.findByIdSync(grant.getUser()); Rank rank = staffRanks.get(grant.getRank()); if (!result.containsKey(rank.getId())) { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java index a0065e0..0684633 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java @@ -8,7 +8,7 @@ import net.frozenorb.apiv3.models.User; public final class GETUser implements Handler { public void handle(RoutingContext ctx) { - APIv3.respondJson(ctx, User.findById(ctx.request().getParam("id"))); + APIv3.respondJson(ctx, User.findByIdSync(ctx.request().getParam("id"))); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java index 4283ba3..d870bfa 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java @@ -13,7 +13,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserDetails implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -23,9 +23,9 @@ public final class GETUserDetails implements Handler { // Too many fields to use .of() APIv3.respondJson(ctx, ImmutableMap.builder() .put("user", user) - .put("grants", Grant.findByUser(user)) - .put("ipLog", IPLogEntry.findByUser(user)) - .put("punishments", Punishment.findByUser(user)) + .put("grants", Grant.findByUserSync(user)) + .put("ipLog", IPLogEntry.findByUserSync(user)) + .put("punishments", Punishment.findByUserSync(user)) .put("aliases", user.getAliases()) .put("totpSetup", user.getTotpSecret() != null) .build() diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java index 948dc60..678d4fb 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java @@ -11,7 +11,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserMeta implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -25,7 +25,7 @@ public final class GETUserMeta implements Handler { return; } - UserMetaEntry userMetaEntry = UserMetaEntry.findByUserAndGroup(user, serverGroup); + UserMetaEntry userMetaEntry = UserMetaEntry.findByUserAndGroupSync(user, serverGroup); APIv3.respondJson(ctx, userMetaEntry.getData()); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java index fefe302..40de6aa 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java @@ -2,9 +2,11 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; +import io.vertx.core.cli.converters.BooleanConverter; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.TOTPUtils; @@ -12,7 +14,7 @@ import net.frozenorb.apiv3.utils.TOTPUtils; public final class GETUserRequiresTOTP implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -34,7 +36,10 @@ public final class GETUserRequiresTOTP implements Handler { return; } - if (TOTPUtils.isPreAuthorized(user, userIp)) { + BlockingCallback preAuthorizedCallback = new BlockingCallback<>(); + TOTPUtils.isPreAuthorized(user, userIp, preAuthorizedCallback); + + if (preAuthorizedCallback.get()) { APIv3.respondJson(ctx, ImmutableMap.of( "required", false, "message", "User's IP has already been validated" diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java index fa362ab..c710f5e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java @@ -10,7 +10,7 @@ import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETUserVerifyPassword implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java index 39242a2..cfd569e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java @@ -22,7 +22,7 @@ public final class POSTUserConfirmRegister implements Handler { "nicole chelsea biteme matthew access yankees 987654321 dallas austin thunder taylor matrix").split(" ")); public void handle(RoutingContext ctx) { - User user = User.findByEmailToken(ctx.request().getParam("emailToken")); + User user = User.findByEmailTokenSync(ctx.request().getParam("emailToken")); if (user == null) { ErrorUtils.respondNotFound(ctx, "Email token", ctx.request().getParam("emailToken")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java index 802c71c..23285d2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java @@ -10,7 +10,7 @@ public class POSTUserLeave implements Handler { @Override public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java index 05264fc..2a01d7e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java @@ -5,6 +5,7 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.models.IPLogEntry; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -23,7 +24,7 @@ public final class POSTUserLogin implements Handler { return; } - User user = User.findById(uuid); + User user = User.findByIdSync(uuid); String username = ctx.request().getParam("username"); String userIp = ctx.request().getParam("userIp"); Actor actor = ctx.get("actor"); @@ -45,7 +46,19 @@ public final class POSTUserLogin implements Handler { Server actorServer = Server.findById(actor.getName()); - user.getIPLogEntry(userIp).used(); + 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); APIv3.respondJson(ctx, user.getLoginInfo(actorServer)); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java index f9454b7..65ebc15 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java @@ -6,6 +6,7 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -15,7 +16,7 @@ import java.util.Map; public final class POSTUserNotify implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -27,7 +28,7 @@ public final class POSTUserNotify implements Handler { return; } - NotificationTemplate template = NotificationTemplate.findById(ctx.request().getParam("template")); + NotificationTemplate template = NotificationTemplate.findByIdSync(ctx.request().getParam("template")); if (template == null) { ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("template")); @@ -49,7 +50,10 @@ public final class POSTUserNotify implements Handler { try { Notification notification = new Notification(template, subjectReplacements, bodyReplacements); - notification.sendAsEmail(user.getEmail()); + BlockingCallback callback = new BlockingCallback<>(); + notification.sendAsEmail(user.getEmail(), callback); + callback.get(); + APIv3.respondJson(ctx, ImmutableMap.of( "success", true )); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java index 3e3aad3..6aec42b 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java @@ -6,6 +6,7 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -24,7 +25,7 @@ public final class POSTUserRegister implements Handler { ); public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -59,10 +60,12 @@ public final class POSTUserRegister implements Handler { "emailToken", user.getEmailToken() ); - Notification notification = new Notification(NotificationTemplate.findById("email-confirmation"), replacements, replacements); + Notification notification = new Notification(NotificationTemplate.findByIdSync("email-confirmation"), replacements, replacements); try { - notification.sendAsEmail(user.getEmail()); + BlockingCallback callback = new BlockingCallback<>(); + notification.sendAsEmail(user.getEmail(), callback); + callback.get(); APIv3.respondJson(ctx, ImmutableMap.of( "success", true )); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java index 9b9f2bc..1725563 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java @@ -12,7 +12,7 @@ import net.frozenorb.apiv3.utils.TOTPUtils; public final class POSTUserSetupTOTP implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java index bc27b48..82964e6 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java @@ -2,9 +2,12 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; +import io.vertx.core.cli.converters.BooleanConverter; import io.vertx.ext.web.RoutingContext; +import io.vertx.ext.web.handler.BodyHandler; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; import net.frozenorb.apiv3.utils.IPUtils; import net.frozenorb.apiv3.utils.TOTPUtils; @@ -14,7 +17,7 @@ import java.util.concurrent.TimeUnit; public final class POSTUserVerifyTOTP implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -34,8 +37,10 @@ public final class POSTUserVerifyTOTP implements Handler { } int providedCode = Integer.parseInt(ctx.request().getParam("code")); + BlockingCallback recentlyUsedCallback = new BlockingCallback<>(); + TOTPUtils.wasRecentlyUsed(user, providedCode, recentlyUsedCallback); - if (TOTPUtils.wasRecentlyUsed(user, providedCode)) { + if (recentlyUsedCallback.get()) { APIv3.respondJson(ctx, ImmutableMap.of( "authorized", false, "message", "TOTP code was recently used." @@ -46,8 +51,13 @@ public final class POSTUserVerifyTOTP implements Handler { boolean authorized = TOTPUtils.authorizeUser(user, providedCode); if (authorized) { - TOTPUtils.markPreAuthorized(user, userIp, 3, TimeUnit.DAYS); - TOTPUtils.markRecentlyUsed(user, providedCode); + BlockingCallback markPreAuthorizedCallback = new BlockingCallback<>(); + TOTPUtils.markPreAuthorized(user, userIp, 3, TimeUnit.DAYS, markPreAuthorizedCallback); + markPreAuthorizedCallback.get(); + + BlockingCallback markRecentlyUsedCallback = new BlockingCallback<>(); + TOTPUtils.markRecentlyUsed(user, providedCode, markRecentlyUsedCallback); + markRecentlyUsedCallback.get(); APIv3.respondJson(ctx, ImmutableMap.of( "authorized", true, diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java index 3fa80a8..f18d2e7 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java @@ -5,13 +5,14 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.models.UserMetaEntry; import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; public final class PUTUserMeta implements Handler { public void handle(RoutingContext ctx) { - User user = User.findById(ctx.request().getParam("id")); + User user = User.findByIdSync(ctx.request().getParam("id")); if (user == null) { ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); @@ -26,8 +27,16 @@ public final class PUTUserMeta implements Handler { } Document data = Document.parse(ctx.getBodyAsString()); + UserMetaEntry metaEntry = UserMetaEntry.findByUserAndGroupSync(user, serverGroup); + + if (metaEntry == null) { + metaEntry = new UserMetaEntry(user, serverGroup, data); + metaEntry.insert(); + } else { + metaEntry.setData(data); + metaEntry.save(); + } - user.saveMeta(serverGroup, data); APIv3.respondJson(ctx, data); } diff --git a/src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java b/src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java new file mode 100644 index 0000000..3f405aa --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java @@ -0,0 +1,40 @@ +package net.frozenorb.apiv3.serialization; + +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; + +import java.util.UUID; + +public final class MineHQCodecProvider implements CodecProvider { + + public Codec get(Class clazz, CodecRegistry codecRegistry) { + if (clazz == UUID.class) { + return (Codec) new Codec() { + + @Override + public UUID decode(BsonReader bsonReader, DecoderContext decoderContext) { + return UUID.fromString(bsonReader.readString()); + } + + @Override + public void encode(BsonWriter bsonWriter, UUID uuid, EncoderContext encoderContext) { + bsonWriter.writeString(uuid == null ? null : uuid.toString()); + } + + @Override + public Class getEncoderClass() { + return UUID.class; + } + + }; + } else { + return null; + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java b/src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java deleted file mode 100644 index 78337fa..0000000 --- a/src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java +++ /dev/null @@ -1,23 +0,0 @@ -package net.frozenorb.apiv3.serialization; - -import com.google.gson.TypeAdapter; -import com.google.gson.stream.JsonReader; -import com.google.gson.stream.JsonWriter; -import org.bson.types.ObjectId; - -import java.io.IOException; - -public final class ObjectIdTypeAdapter extends TypeAdapter { - - public void write(JsonWriter writer, ObjectId write) throws IOException { - writer.value(write.toString()); - } - - // This is used with Gson, which is only used - // to serialize outgoing responses, thus we - // don't need to have a read method. - public ObjectId read(JsonReader reader) { - throw new IllegalArgumentException(); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java b/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java new file mode 100644 index 0000000..155737a --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java @@ -0,0 +1,18 @@ +package net.frozenorb.apiv3.serialization; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; + +import java.io.IOException; +import java.util.UUID; + +public class UUIDJsonDeserializer extends JsonDeserializer { + + @Override + public UUID deserialize(JsonParser jsonParser, DeserializationContext deserializationContext) throws IOException, JsonProcessingException { + return UUID.fromString(jsonParser.getValueAsString()); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java b/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java new file mode 100644 index 0000000..5f18aa4 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java @@ -0,0 +1,18 @@ +package net.frozenorb.apiv3.serialization; + +import com.fasterxml.jackson.core.JsonGenerator; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonSerializer; +import com.fasterxml.jackson.databind.SerializerProvider; + +import java.io.IOException; +import java.util.UUID; + +public final class UUIDJsonSerializer extends JsonSerializer { + + @Override + public void serialize(UUID uuid, JsonGenerator jsonGenerator, SerializerProvider serializerProvider) throws IOException, JsonProcessingException { + jsonGenerator.writeString(uuid.toString()); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java b/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java index 939de9c..5db6d1b 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/BlockingCallback.java @@ -9,6 +9,7 @@ public final class BlockingCallback implements SingleResultCallback { private final SettableFuture future = SettableFuture.create(); + @Override public void onResult(T val, Throwable error) { if (error != null) { future.setException(error); diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java index 1813cba..08ea50b 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java @@ -5,6 +5,7 @@ import com.cribbstechnologies.clients.mandrill.model.MandrillHtmlMessage; import com.cribbstechnologies.clients.mandrill.model.MandrillMessageRequest; import com.cribbstechnologies.clients.mandrill.model.MandrillRecipient; import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest; +import com.mongodb.async.SingleResultCallback; import com.twilio.sdk.TwilioRestException; import com.twilio.sdk.resource.factory.MessageFactory; import net.frozenorb.apiv3.APIv3; @@ -32,7 +33,7 @@ public final class Notification { this.body = template.fillBody(bodyReplacements); } - public void sendAsEmail(String email) throws IOException { + public void sendAsEmail(String email, SingleResultCallback callback) throws IOException { MandrillHtmlMessage message = new MandrillHtmlMessage(); message.setFrom_email("no-reply@minehq.com"); @@ -43,31 +44,49 @@ public final class Notification { new MandrillRecipient(null, email) }); - try { - MandrillMessageRequest request = new MandrillMessageRequest(); - request.setMessage(message); - mandrillMessagesRequest.sendMessage(request); - APIv3.getStatsD().incrementCounter("apiv3.notification.email.success"); - } catch (RequestFailedException ex) { - APIv3.getStatsD().incrementCounter("apiv3.notification.email.failure"); - throw new IOException("Failed to send notification to user", ex); - } + APIv3.getVertxInstance().executeBlocking((future) -> { + try { + MandrillMessageRequest request = new MandrillMessageRequest(); + request.setMessage(message); + mandrillMessagesRequest.sendMessage(request); + APIv3.getStatsD().incrementCounter("apiv3.notification.email.success"); + future.succeeded(); + } catch (RequestFailedException ex) { + APIv3.getStatsD().incrementCounter("apiv3.notification.email.failure"); + future.fail(new IOException("Failed to send notification to user", ex)); + } + }, (result) -> { + if (result.succeeded()) { + callback.onResult(null, null); + } else { + callback.onResult(null, result.cause()); + } + }); } - public void sendAsText(String phoneNumber) throws IOException { + public void sendAsText(String phoneNumber, SingleResultCallback callback) throws IOException { List params = new ArrayList<>(); params.add(new BasicNameValuePair("To", phoneNumber)); params.add(new BasicNameValuePair("From", "+13108795180")); params.add(new BasicNameValuePair("Body", body)); - try { - twillioMessageFactory.create(params); - APIv3.getStatsD().incrementCounter("apiv3.notification.text.success"); - } catch (TwilioRestException ex) { - APIv3.getStatsD().incrementCounter("apiv3.notification.text.failure"); - throw new IOException("Failed to send notification to user", ex); - } + APIv3.getVertxInstance().executeBlocking((future) -> { + try { + twillioMessageFactory.create(params); + APIv3.getStatsD().incrementCounter("apiv3.notification.text.success"); + future.succeeded(); + } catch (TwilioRestException ex) { + APIv3.getStatsD().incrementCounter("apiv3.notification.text.failure"); + future.fail(new IOException("Failed to send notification to user", ex)); + } + }, (result) -> { + if (result.succeeded()) { + callback.onResult(null, null); + } else { + callback.onResult(null, result.cause()); + } + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java b/src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java index 15708bf..5f711c9 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java @@ -6,5 +6,6 @@ import lombok.experimental.UtilityClass; public class Permissions { public static final String PROTECTED_PUNISHMENT = "minehq.punishment.protected"; + public static final String SIGN_API_REQUEST = "apiv3.signRequest"; } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java index fd25359..f297395 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java @@ -11,12 +11,6 @@ import java.util.UUID; @UtilityClass public class MojangUtils { - public static String getName(UUID id) { - BlockingCallback callback = new BlockingCallback<>(); - getName(id, callback); - return callback.get(); - } - public static void getName(UUID id, SingleResultCallback callback) { APIv3.getHttpClient().get("sessionserver.mojang.com", "session/minecraft/profile/" + id.toString().replace("-", ""), (response) -> { response.bodyHandler((body) -> { diff --git a/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java b/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java index 5af89ef..1f8b6b3 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java @@ -1,15 +1,18 @@ package net.frozenorb.apiv3.utils; +import com.mongodb.async.SingleResultCallback; import com.warrenstrange.googleauth.GoogleAuthenticator; import com.warrenstrange.googleauth.GoogleAuthenticatorConfig; import com.warrenstrange.googleauth.GoogleAuthenticatorKey; import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator; +import io.vertx.redis.RedisClient; +import io.vertx.redis.RedisOptions; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; -import redis.clients.jedis.Jedis; import java.util.concurrent.TimeUnit; +import java.util.function.BooleanSupplier; @UtilityClass public class TOTPUtils { @@ -38,34 +41,60 @@ public class TOTPUtils { ); } - public static boolean isPreAuthorized(User user, String ip) { - try (Jedis redis = APIv3.getRedisPool().getResource()) { - return redis.exists(user.getId() + ":preAuthorizedIP:" + ip.toLowerCase()); - } + public static void isPreAuthorized(User user, String ip, SingleResultCallback callback) { + APIv3.getRedisClient().exists(user.getId() + ":preAuthorizedIP:" + ip.toLowerCase(), (result) -> { + if (result.succeeded()) { + callback.onResult(result.result() == 1 , null); + } else { + callback.onResult(null, result.cause()); + } + }); } - public static void markPreAuthorized(User user, String ip, long duration, TimeUnit unit) { - try (Jedis redis = APIv3.getRedisPool().getResource()) { - String key = user.getId() + ":preAuthorizedIP:" + ip.toLowerCase(); + public static void markPreAuthorized(User user, String ip, long duration, TimeUnit unit, SingleResultCallback callback) { + String key = user.getId() + ":preAuthorizedIP:" + ip.toLowerCase(); - redis.set(key, ""); - redis.expire(key, (int) unit.toSeconds(duration)); - } + APIv3.getRedisClient().set(key, "", (result) -> { + if (result.succeeded()) { + APIv3.getRedisClient().expire(key, (int) unit.toSeconds(duration), (result2) -> { + if (result2.succeeded()) { + callback.onResult(null, null); + } else { + callback.onResult(null, result.cause()); + } + }); + } else { + callback.onResult(null, result.cause()); + } + }); } - public static boolean wasRecentlyUsed(User user, int code) { - try (Jedis redis = APIv3.getRedisPool().getResource()) { - return redis.exists(user.getId() + ":recentTOTPCodes:" + code); - } + public static void wasRecentlyUsed(User user, int code, SingleResultCallback callback) { + APIv3.getRedisClient().exists(user.getId() + ":recentTOTPCodes:" + code, (result) -> { + if (result.succeeded()) { + callback.onResult(result.result() == 1 , null); + } else { + callback.onResult(null, result.cause()); + } + }); } - public static void markRecentlyUsed(User user, int code) { - try (Jedis redis = APIv3.getRedisPool().getResource()) { - String key = user.getId() + ":recentTOTPCodes:" + code; + public static void markRecentlyUsed(User user, int code, SingleResultCallback callback) { + String key = user.getId() + ":recentTOTPCodes:" + code; - redis.set(key, ""); - redis.expire(key, (int) TimeUnit.MINUTES.toSeconds(5)); - } + APIv3.getRedisClient().set(key, "", (result) -> { + if (result.succeeded()) { + APIv3.getRedisClient().expire(key, (int) TimeUnit.MINUTES.toSeconds(5), (result2) -> { + if (result2.succeeded()) { + callback.onResult(null, null); + } else { + callback.onResult(null, result.cause()); + } + }); + } else { + callback.onResult(null, result.cause()); + } + }); } } \ No newline at end of file From 7018a3c5e21555135efeb1670c6f1648f686a613 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 16 Jun 2016 00:08:44 -0400 Subject: [PATCH 4/8] ayy last fake commit --- apiv3.properties | 2 - pom.xml | 19 +- src/main/java/net/frozenorb/apiv3/APIv3.java | 368 +++++------------- src/main/java/net/frozenorb/apiv3/Main.java | 1 - .../frozenorb/apiv3/actors/ServerActor.java | 1 - .../net/frozenorb/apiv3/actors/UserActor.java | 4 - .../frozenorb/apiv3/auditLog/AuditLog.java | 17 +- .../apiv3/auditLog/AuditLogActionType.java | 13 +- .../apiv3/conversion/GrantConverter.java | 60 +++ .../apiv3/conversion/IpLogConverter.java | 57 +++ .../apiv3/conversion/PunishmentConverter.java | 59 +++ .../apiv3/conversion/UserConverter.java | 59 +++ .../apiv3/conversion/V2Converter.java | 69 ++++ .../apiv3/handlers/ActorAttributeHandler.java | 30 +- .../apiv3/handlers/AuthorizationHandler.java | 5 +- .../apiv3/handlers/MetricsHandler.java | 15 - .../frozenorb/apiv3/models/AuditLogEntry.java | 16 +- .../net/frozenorb/apiv3/models/Grant.java | 27 +- .../net/frozenorb/apiv3/models/IPBan.java | 171 ++++++++ .../frozenorb/apiv3/models/IPLogEntry.java | 42 +- .../apiv3/models/NotificationTemplate.java | 3 +- .../frozenorb/apiv3/models/Punishment.java | 46 ++- .../java/net/frozenorb/apiv3/models/Rank.java | 2 + .../net/frozenorb/apiv3/models/Server.java | 4 +- .../frozenorb/apiv3/models/ServerGroup.java | 6 +- .../java/net/frozenorb/apiv3/models/User.java | 116 ++++-- .../frozenorb/apiv3/models/UserMetaEntry.java | 2 + .../net/frozenorb/apiv3/routes/GETDump.java | 3 +- .../announcements/GETAnnouncements.java | 15 +- .../announcements/PUTAnnouncements.java | 33 ++ .../auditLog/POSTUserAuditLogEntry.java | 47 +++ .../chatFilterList/GETChatFilterList.java | 6 +- .../apiv3/routes/grants/DELETEGrant.java | 6 +- .../apiv3/routes/ipBans/DELETEIpBan.java | 49 +++ .../apiv3/routes/ipBans/GETIpBan.java | 14 + .../apiv3/routes/ipBans/GETIpBans.java | 22 ++ .../apiv3/routes/ipBans/GETIpIpBans.java | 24 ++ .../apiv3/routes/ipBans/POSTIpIpBan.java | 57 +++ .../apiv3/routes/ipLog/GETUserIPLog.java | 6 +- .../PUTNotificationTemplate.java | 4 - .../DELETENotificationTemplate.java | 2 +- .../GETNotificationTemplate.java | 2 +- .../GETNotificationTemplates.java | 2 +- .../POSTNotificationTemplate.java | 2 +- .../PUTNotificationTemplate.java | 4 + .../routes/punishments/DELETEPunishment.java | 6 +- .../DELETEUserPunishment.java | 10 +- .../routes/punishments/POSTUserPunish.java | 6 +- .../apiv3/routes/servers/POSTServer.java | 13 +- .../routes/servers/POSTServerHeartbeat.java | 14 +- .../apiv3/routes/users/GETUserDetails.java | 4 +- .../routes/users/GETUserRequiresTOTP.java | 9 +- .../routes/users/POSTUserConfirmRegister.java | 8 +- .../apiv3/routes/users/POSTUserLeave.java | 26 +- .../apiv3/routes/users/POSTUserLogin.java | 70 ++-- .../apiv3/routes/users/POSTUserNotify.java | 26 +- .../apiv3/routes/users/POSTUserRegister.java | 25 +- .../apiv3/routes/users/POSTUserSetupTOTP.java | 2 +- .../routes/users/POSTUserVerifyTOTP.java | 8 +- .../apiv3/routes/users/PUTUserMeta.java | 8 +- .../serialization/MineHQCodecProvider.java | 40 -- .../{ => gson}/DateTypeAdapter.java | 2 +- .../{ => gson}/ExcludeFromReplies.java | 2 +- .../FollowAnnotationExclusionStrategy.java | 2 +- .../{ => jackson}/UUIDJsonDeserializer.java | 2 +- .../{ => jackson}/UUIDJsonSerializer.java | 2 +- .../serialization/mongodb/UUIDCodec.java | 28 ++ .../mongodb/UUIDCodecProvider.java | 19 + .../apiv3/unsorted/Notification.java | 93 ++--- .../net/frozenorb/apiv3/utils/ErrorUtils.java | 17 +- .../net/frozenorb/apiv3/utils/IPUtils.java | 4 +- .../frozenorb/apiv3/utils/MandrillUtils.java | 32 -- .../frozenorb/apiv3/utils/MojangUtils.java | 9 +- .../apiv3/utils/PermissionUtils.java | 48 --- .../net/frozenorb/apiv3/utils/TOTPUtils.java | 21 +- .../frozenorb/apiv3/utils/TwillioUtils.java | 22 -- .../net/frozenorb/apiv3/utils/UUIDUtils.java | 9 +- 77 files changed, 1289 insertions(+), 810 deletions(-) create mode 100644 src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java create mode 100644 src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java create mode 100644 src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java create mode 100644 src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java create mode 100644 src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java delete mode 100644 src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java create mode 100644 src/main/java/net/frozenorb/apiv3/models/IPBan.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/PUTNotificationTemplate.java rename src/main/java/net/frozenorb/apiv3/routes/{notificationTemplate => notificationTemplates}/DELETENotificationTemplate.java (92%) rename src/main/java/net/frozenorb/apiv3/routes/{notificationTemplate => notificationTemplates}/GETNotificationTemplate.java (87%) rename src/main/java/net/frozenorb/apiv3/routes/{notificationTemplate => notificationTemplates}/GETNotificationTemplates.java (86%) rename src/main/java/net/frozenorb/apiv3/routes/{notificationTemplate => notificationTemplates}/POSTNotificationTemplate.java (91%) create mode 100644 src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java rename src/main/java/net/frozenorb/apiv3/routes/{users => punishments}/DELETEUserPunishment.java (79%) delete mode 100644 src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java rename src/main/java/net/frozenorb/apiv3/serialization/{ => gson}/DateTypeAdapter.java (93%) rename src/main/java/net/frozenorb/apiv3/serialization/{ => gson}/ExcludeFromReplies.java (84%) rename src/main/java/net/frozenorb/apiv3/serialization/{ => gson}/FollowAnnotationExclusionStrategy.java (90%) rename src/main/java/net/frozenorb/apiv3/serialization/{ => jackson}/UUIDJsonDeserializer.java (91%) rename src/main/java/net/frozenorb/apiv3/serialization/{ => jackson}/UUIDJsonSerializer.java (91%) create mode 100644 src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodec.java create mode 100644 src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodecProvider.java delete mode 100644 src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java delete mode 100644 src/main/java/net/frozenorb/apiv3/utils/TwillioUtils.java diff --git a/apiv3.properties b/apiv3.properties index 74192b2..a00fa41 100644 --- a/apiv3.properties +++ b/apiv3.properties @@ -7,8 +7,6 @@ mongo.password= redis.address=localhost redis.port=6379 http.port=80 -twillio.accountSID=AC9e2f88c5690134d29a56f698de3cd740 -twillio.authToken=982592505a171d3be6b0722f5ecacc0e mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ bugsnag.apiKey=0e47fba8b825416b7cbc839066184509 auth.websiteApiKey=RVbp4hY6sCFVaf diff --git a/pom.xml b/pom.xml index 729b473..f691e55 100644 --- a/pom.xml +++ b/pom.xml @@ -19,6 +19,7 @@ org.apache.maven.plugins maven-jar-plugin + 3.0.1 @@ -33,9 +34,9 @@ 2.3 - - *:* - + + org.projectlombok:lombok + @@ -108,18 +109,6 @@ 2.6.0 - - - com.cribbstechnologies.clients - mandrillClient - 1.1 - - - com.twilio.sdk - twilio-java-sdk - 6.3.0 - - com.warrenstrange diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 08a02e2..062bdd7 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -7,56 +7,49 @@ import com.fasterxml.jackson.annotation.PropertyAccessor; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.module.SimpleModule; import com.google.common.collect.ImmutableList; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; +import com.google.common.net.MediaType; import com.google.gson.Gson; import com.google.gson.GsonBuilder; -import com.mongodb.Block; import com.mongodb.ConnectionString; import com.mongodb.MongoCredential; -import com.mongodb.ServerAddress; -import com.mongodb.async.client.MongoClient; import com.mongodb.async.client.MongoClientSettings; import com.mongodb.async.client.MongoClients; import com.mongodb.async.client.MongoDatabase; -import com.mongodb.connection.ClusterConnectionMode; +import com.mongodb.client.model.IndexModel; import com.mongodb.connection.ClusterSettings; -import com.timgroup.statsd.NonBlockingStatsDClient; -import com.timgroup.statsd.StatsDClient; import fr.javatic.mongo.jacksonCodec.JacksonCodecProvider; import fr.javatic.mongo.jacksonCodec.ObjectMapperFactory; import io.vertx.core.AbstractVerticle; -import io.vertx.core.Handler; -import io.vertx.core.Vertx; 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.ext.web.Router; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.handler.BodyHandler; +import io.vertx.ext.web.handler.LoggerFormat; import io.vertx.ext.web.handler.LoggerHandler; -import io.vertx.ext.web.impl.BlockingHandlerDecorator; -import io.vertx.ext.web.impl.RouteImpl; import io.vertx.redis.RedisClient; import io.vertx.redis.RedisOptions; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.actors.ActorType; import net.frozenorb.apiv3.handlers.ActorAttributeHandler; import net.frozenorb.apiv3.handlers.AuthorizationHandler; -import net.frozenorb.apiv3.handlers.MetricsHandler; -import net.frozenorb.apiv3.models.*; import net.frozenorb.apiv3.routes.GETDump; import net.frozenorb.apiv3.routes.GETWhoAmI; import net.frozenorb.apiv3.routes.POSTMetrics; import net.frozenorb.apiv3.routes.announcements.GETAnnouncements; +import net.frozenorb.apiv3.routes.announcements.PUTAnnouncements; import net.frozenorb.apiv3.routes.auditLog.GETAuditLog; +import net.frozenorb.apiv3.routes.auditLog.POSTUserAuditLogEntry; import net.frozenorb.apiv3.routes.chatFilterList.GETChatFilterList; import net.frozenorb.apiv3.routes.grants.*; -import net.frozenorb.apiv3.routes.ipLog.GETUserIPLog; -import net.frozenorb.apiv3.routes.notificationTemplate.DELETENotificationTemplate; -import net.frozenorb.apiv3.routes.notificationTemplate.GETNotificationTemplate; -import net.frozenorb.apiv3.routes.notificationTemplate.GETNotificationTemplates; -import net.frozenorb.apiv3.routes.notificationTemplate.POSTNotificationTemplate; +import net.frozenorb.apiv3.routes.ipBans.*; +import net.frozenorb.apiv3.routes.ipLog.GETUserIpLog; +import net.frozenorb.apiv3.routes.notificationTemplates.DELETENotificationTemplate; +import net.frozenorb.apiv3.routes.notificationTemplates.GETNotificationTemplate; +import net.frozenorb.apiv3.routes.notificationTemplates.GETNotificationTemplates; +import net.frozenorb.apiv3.routes.notificationTemplates.POSTNotificationTemplate; import net.frozenorb.apiv3.routes.punishments.*; import net.frozenorb.apiv3.routes.ranks.DELETERank; import net.frozenorb.apiv3.routes.ranks.GETRank; @@ -68,26 +61,23 @@ import net.frozenorb.apiv3.routes.serverGroups.GETServerGroups; import net.frozenorb.apiv3.routes.serverGroups.POSTServerGroup; import net.frozenorb.apiv3.routes.servers.*; import net.frozenorb.apiv3.routes.users.*; -import net.frozenorb.apiv3.serialization.*; -import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.serialization.gson.DateTypeAdapter; +import net.frozenorb.apiv3.serialization.gson.FollowAnnotationExclusionStrategy; +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.utils.IPUtils; -import net.frozenorb.apiv3.utils.SyncUtils; -import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; import org.bson.codecs.BsonValueCodecProvider; import org.bson.codecs.DocumentCodecProvider; import org.bson.codecs.ValueCodecProvider; import org.bson.codecs.configuration.CodecProvider; import org.bson.codecs.configuration.CodecRegistries; -import org.bson.types.ObjectId; import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStream; -import java.lang.reflect.Field; import java.util.*; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; @Slf4j public final class APIv3 extends AbstractVerticle { @@ -96,38 +86,39 @@ public final class APIv3 extends AbstractVerticle { @Getter private static MongoDatabase database; @Getter private static Properties config = new Properties(); @Getter private static RedisClient redisClient; - @Getter private static StatsDClient statsD; - @Getter private static Vertx vertxInstance; - @Getter private static final Gson gson = new GsonBuilder() + private static final Gson gson = new GsonBuilder() .registerTypeAdapter(Date.class, new DateTypeAdapter()) .setExclusionStrategies(new FollowAnnotationExclusionStrategy()) .create(); @Override public void start() { - vertxInstance = vertx; - setupConfig(); setupDatabase(); setupRedis(); - setupMetrics(); setupBugsnag(); - //setupHttpServer(); + setupHttpServer(); setupHttpClient(); - convertData("mongodb://158.69.126.126", true); + /*V2Converter converter = new V2Converter("mongodb://158.69.126.126", "minehq"); + + converter.startConversion((ignored, error) -> { + if (error != null) { + error.printStackTrace(); + } + });*/ } private void setupConfig() { try (InputStream in = new FileInputStream("apiv3.properties")) { config.load(in); - } catch (Exception ex) { + } catch (IOException ex) { throw new RuntimeException(ex); } } private void setupDatabase() { - ImmutableList credentials = ImmutableList.of(); + List credentials = ImmutableList.of(); if (!config.getProperty("mongo.username").isEmpty()) { credentials = ImmutableList.of( @@ -146,8 +137,8 @@ public final class APIv3 extends AbstractVerticle { List providers = new ArrayList<>(); - // Our override codec - providers.add(new MineHQCodecProvider()); + // Our fixed uuid codec + providers.add(new UUIDCodecProvider()); // Normal providers providers.add(new ValueCodecProvider()); @@ -173,9 +164,34 @@ public final class APIv3 extends AbstractVerticle { .clusterSettings(clusterSettings) .build(); - MongoClient client = MongoClients.create(settings); - database = client.getDatabase(config.getProperty("mongo.database")); - // TODO: Indexes + database = MongoClients.create(settings).getDatabase(config.getProperty("mongo.database")); + database.getCollection("auditLog").createIndexes(ImmutableList.of( + new IndexModel(new Document("user", 1)), + new IndexModel(new Document("performedAt", 1)), + new IndexModel(new Document("type", 1)) + ), (a, b) -> {}); + database.getCollection("grants").createIndexes(ImmutableList.of( + new IndexModel(new Document("user", 1)), + new IndexModel(new Document("rank", 1)), + new IndexModel(new Document("addedAt", 1)) + ), (a, b) -> {}); + database.getCollection("ipLog").createIndexes(ImmutableList.of( + new IndexModel(new Document("user", 1)), + new IndexModel(new Document("user", 1).append("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)) + ), (a, b) -> {}); + database.getCollection("users").createIndexes(ImmutableList.of( + new IndexModel(new Document("lastUsername", 1)), + new IndexModel(new Document("emailToken", 1)) + ), (a, b) -> {}); + database.getCollection("userMeta").createIndexes(ImmutableList.of( + new IndexModel(new Document("user", 1).append("serverGroup", 1)) + ), (a, b) -> {}); } private void setupRedis() { @@ -187,20 +203,6 @@ public final class APIv3 extends AbstractVerticle { ); } - private void setupMetrics() { - statsD = new NonBlockingStatsDClient(null, "localhost", 8125); - - new Timer("Metrics Task").scheduleAtFixedRate(new TimerTask() { - - @Override - public void run() { - statsD.recordGaugeValue("apiv3.memory.usage", Runtime.getRuntime().totalMemory() / (1024 * 1024)); - statsD.recordGaugeValue("apiv3.memory.max", Runtime.getRuntime().maxMemory() / (1024 * 1024)); - } - - }, TimeUnit.SECONDS.toMillis(5), TimeUnit.SECONDS.toMillis(5)); - } - private void setupBugsnag() { Client bugsnag = new Client(config.getProperty("bugsnag.apiKey")); bugsnag.setReleaseStage(config.getProperty("general.releaseStage")); @@ -208,29 +210,40 @@ public final class APIv3 extends AbstractVerticle { bugsnag.setLogger(new BugsnagSLF4JLogger()); } + // TODO: blockingHandler -> handler private void setupHttpServer() { HttpServer webServer = vertx.createHttpServer(); Router mainRouter = Router.router(vertx); - mainRouter.route().handler(new MetricsHandler()); mainRouter.route().handler(new ActorAttributeHandler()); mainRouter.route().handler(new AuthorizationHandler()); - mainRouter.route().handler(LoggerHandler.create()); - mainRouter.route().handler(BodyHandler.create()); + mainRouter.route().handler(LoggerHandler.create(LoggerFormat.TINY)); + mainRouter.route().method(HttpMethod.PUT).method(HttpMethod.POST).handler(BodyHandler.create()); // TODO: The commented out routes - mainRouter.post("/metrics").blockingHandler(new POSTMetrics()); - mainRouter.get("/announcements").blockingHandler(new GETAnnouncements()); + mainRouter.get("/announcements/:id").blockingHandler(new GETAnnouncements()); + mainRouter.put("/announcements/:id").blockingHandler(new PUTAnnouncements()); + mainRouter.get("/auditLog").blockingHandler(new GETAuditLog()); - mainRouter.get("/chatFilterList").blockingHandler(new GETChatFilterList()); - mainRouter.get("/dump/:type").blockingHandler(new GETDump()); - mainRouter.get("/whoami").blockingHandler(new GETWhoAmI()); + mainRouter.post("/user/:id/auditLogEntry").blockingHandler(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("/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("/user/:id/ipLog").blockingHandler(new GETUserIpLog()); + mainRouter.get("/notificationTemplate/:id").blockingHandler(new GETNotificationTemplate()); mainRouter.get("/notificationTemplates").blockingHandler(new GETNotificationTemplates()); mainRouter.post("/notificationTemplate").blockingHandler(new POSTNotificationTemplate()); @@ -239,67 +252,49 @@ public final class APIv3 extends AbstractVerticle { 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("/rank/:id").blockingHandler(new GETRank()); - mainRouter.get("/ranks").blockingHandler(new GETRanks()); + mainRouter.get("/rank/:id").handler(new GETRank()); + mainRouter.get("/ranks").handler(new GETRanks()); mainRouter.post("/rank").blockingHandler(new POSTRank()); - //put("/rank/:id").blockingHandler(new PUTRank()); + //mainRouter.put("/rank/:id").blockingHandler(new PUTRank()); mainRouter.delete("/rank/:id").blockingHandler(new DELETERank()); - mainRouter.get("/serverGroup/:id").blockingHandler(new GETServerGroup()); - mainRouter.get("/serverGroups").blockingHandler(new GETServerGroups()); + mainRouter.get("/serverGroup/:id").handler(new GETServerGroup()); + mainRouter.get("/serverGroups").handler(new GETServerGroups()); mainRouter.post("/serverGroup").blockingHandler(new POSTServerGroup()); - //put("/serverGroup/:id").blockingHandler(new PUTServerGroup()); + //mainRouter.put("/serverGroup/:id").blockingHandler(new PUTServerGroup()); mainRouter.delete("/serverGroup/:id").blockingHandler(new DELETEServerGroup()); - mainRouter.get("/server/:id").blockingHandler(new GETServer()); - mainRouter.get("/servers").blockingHandler(new GETServers()); + 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()); - //put("/server/:id").blockingHandler(new PUTServer()); + //mainRouter.put("/server/:id").blockingHandler(new PUTServer()); mainRouter.delete("/server/:id").blockingHandler(new DELETEServer()); 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/grants").blockingHandler(new GETUserGrants()); - mainRouter.get("/user/:id/punishments").blockingHandler(new GETUserPunishments()); - mainRouter.get("/user/:id/ipLog").blockingHandler(new GETUserIPLog()); mainRouter.get("/user/:id/requiresTOTP").blockingHandler(new GETUserRequiresTOTP()); mainRouter.get("/user/:id/verifyPassword").blockingHandler(new GETUserVerifyPassword()); - mainRouter.get("/user/:id").blockingHandler(new GETUser()); - mainRouter.post("/user/:id/verifyTOTP").blockingHandler(new POSTUserVerifyTOTP()); - mainRouter.post("/user/:id/grant").blockingHandler(new POSTUserGrant()); - mainRouter.post("/user/:id/punish").blockingHandler(new POSTUserPunish()); - mainRouter.post("/user/:id/login").blockingHandler(new POSTUserLogin()); - mainRouter.post("/user/:id/leave").blockingHandler(new POSTUserLeave()); + mainRouter.post("/user/confirmRegister/:emailToken").blockingHandler(new POSTUserConfirmRegister()); + 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/confirmRegister/:emailToken").blockingHandler(new POSTUserConfirmRegister()); + 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.delete("/user/:id/punishment").blockingHandler(new DELETEUserPunishment()); - mainRouter.getRoutes().forEach((route) -> { - try { - RouteImpl impl = (RouteImpl) route; - Field field = RouteImpl.class.getDeclaredField("contextHandler"); - field.setAccessible(true); - Handler handler = (Handler) field.get(impl); - - if (handler instanceof BlockingHandlerDecorator) { - field = BlockingHandlerDecorator.class.getDeclaredField("decoratedHandler"); - field.setAccessible(true); - handler = (Handler) field.get(handler); - } - - System.out.println(route.getPath() + " is handled by " + handler.getClass()); - } catch (Exception ex) { - - } - }); + mainRouter.get("/dump/:type").handler(new GETDump()); + mainRouter.get("/whoami").handler(new GETWhoAmI()); + mainRouter.post("/metrics").blockingHandler(new POSTMetrics()); int port = Integer.parseInt(config.getProperty("http.port")); webServer.requestHandler(mainRouter::accept).listen(port); @@ -314,172 +309,9 @@ public final class APIv3 extends AbstractVerticle { } public static void respondJson(RoutingContext ctx, int code, Object response) { - ctx.response().putHeader("Content-Type", "application/json"); + ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()); ctx.response().setStatusCode(code); ctx.response().end(gson.toJson(response)); } - private void convertData(String oldIp, boolean forReal) { - // A lot of unneeded .toString()'s and cloning objects is our ghetto null validation. - MongoDatabase importFrom = MongoClients.create(oldIp).getDatabase("minehq"); - Map mongoIdToUUID = new HashMap<>(); - AtomicInteger skippedUsers = new AtomicInteger(); - AtomicInteger skippedPunishments = new AtomicInteger(); - AtomicInteger skippedGrants = new AtomicInteger(); - AtomicInteger skippedIpLogs = new AtomicInteger(); - - SyncUtils.blockMulti(importFrom.getCollection("user").find()).forEach((user) -> { - String uuidString = String.valueOf(user.get("uuid")); - - if (uuidString == null || uuidString.length() != 32) { - return; - } - - UUID uuid = UUID.fromString(uuidString.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")); - - if (!UUIDUtils.isAcceptableUUID(uuid)) { - skippedUsers.incrementAndGet(); - return; - } - - mongoIdToUUID.put(user.getObjectId("_id"), uuid); - - User created = new User( - uuid, - String.valueOf(user.get("name")).toString(), - ImmutableMap.of(user.getString("name"), user.getDate("joined")), - null, - null, - null, - null, - user.getString("email"), - user.getString("phone"), - "INVALID", - user.getDate("joined"), - user.getDate("joined"), - false - ); - - if (forReal) { - created.insert(); - } - - log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")"); - }); - - SyncUtils.blockMulti(importFrom.getCollection("punishment").find()).forEach((punishment) -> { - UUID target = mongoIdToUUID.get(((Map) punishment.get("user")).get("$id")); - - if (target == null) { - skippedPunishments.incrementAndGet(); - return; - } - - // Old punishments have this value set to false to indicate they're not active anymore. - if (punishment.containsKey("active") && !punishment.getBoolean("active")) { - return; - } - - Punishment created = new Punishment( - new ObjectId().toString(), - target, - punishment.getString("reason").toString(), - Punishment.PunishmentType.valueOf(punishment.getString("type").toUpperCase()), - punishment.getDate("expires"), - punishment.containsKey("meta") ? (punishment.get("meta") instanceof List ? ImmutableMap.of() : (Document) punishment.get("meta")) : ImmutableMap.of(), - punishment.containsKey("addedBy") ? mongoIdToUUID.get(((Map) punishment.get("addedBy")).get("$id")) : null, - (Date) punishment.getDate("created").clone(), - punishment.containsKey("createdOn") ? String.valueOf(((Map) punishment.get("createdOn")).get("$id")) : "Website", - punishment.containsKey("createdOn") ? ActorType.SERVER : ActorType.WEBSITE, - punishment.containsKey("removedBy") ? (((Map) punishment.get("removedBy")).get("$ref").equals("user") ? mongoIdToUUID.get(((Map) punishment.get("removedBy")).get("$id")) : null) : null, - punishment.getDate("created"), - punishment.containsKey("removalReason") ? punishment.getString("removalReason").toString() : "" - ); - - if (forReal) { - created.insert(); - } - - log.info("Created punishment " + created.getId() + " (" + created.getType() + ")"); - }); - - SyncUtils.blockMulti(importFrom.getCollection("grant").find()).forEach((grant) -> { - UUID target = mongoIdToUUID.get(((Map) grant.get("target")).get("$id")); - - if (target == null) { - skippedGrants.incrementAndGet(); - return; - } - - String rank = grant.getString("role"); - - if (rank.equalsIgnoreCase("unban") || rank.equalsIgnoreCase("pass") || rank.equalsIgnoreCase("pink") || rank.equalsIgnoreCase("jrdev")) { - return; - } else if (rank.equalsIgnoreCase("high_roller")) { - rank = "high-roller"; - } else if (rank.equalsIgnoreCase("dev")) { - rank = "developer"; - } - - Grant created = new Grant( - new ObjectId().toString(), - target, - grant.containsKey("comment") ? grant.getString("comment") : "", - grant.containsKey("scope") ? ImmutableSet.copyOf((Collection) grant.get("scope")) : ImmutableSet.of(), - rank, - grant.getDate("expires"), - grant.containsKey("addedBy") ? mongoIdToUUID.get(((Map) grant.get("addedBy")).get("$id")) : null, - grant.containsKey("created") ? grant.getDate("created") : new Date(), - null, - null, - null - ); - - if (forReal) { - created.insert(); - } - - log.info("Created grant " + created.getId() + " (" + created.getRank() + ")"); - }); - - SyncUtils.blockMulti(importFrom.getCollection("iplog").find()).forEach((ipLogEntry) -> { - UUID user = mongoIdToUUID.get(((Map) ipLogEntry.get("user")).get("$id")); - - if (user == null || ipLogEntry.getString("ip") == null) { - skippedIpLogs.incrementAndGet(); - return; - } - - String ip = ipLogEntry.getString("ip").replace("/", ""); - - if (!IPUtils.isValidIP(ip)) { - return; - } - - Date lastSeen = ipLogEntry.getDate("lastSeen"); - - if (lastSeen == null) { - lastSeen = new Date(); - } - - IPLogEntry created = new IPLogEntry( - new ObjectId().toString(), - user, - ip, - lastSeen, - lastSeen, - ((Number) ipLogEntry.get("uses")).intValue() - - ); - - if (forReal) { - created.insert(); - } - - log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")"); - }); - - log.info("Skipped " + skippedUsers.get() + " users, " + skippedPunishments.get() + " punishments, " + skippedGrants.get() + " grants, and " + skippedIpLogs.get() + " ip logs"); - } - } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/Main.java b/src/main/java/net/frozenorb/apiv3/Main.java index d7b382a..d9a2f36 100644 --- a/src/main/java/net/frozenorb/apiv3/Main.java +++ b/src/main/java/net/frozenorb/apiv3/Main.java @@ -6,7 +6,6 @@ final class Main { public static void main(String[] args) { System.setProperty("vertx.logger-delegate-factory-class-name", "io.vertx.core.logging.SLF4JLogDelegateFactory"); - System.setProperty("org.slf4j.simpleLogger.defaultLogLevel", "info"); Vertx.vertx().deployVerticle(new APIv3()); } diff --git a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java b/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java index 07347d8..30bbdb9 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java @@ -1,6 +1,5 @@ package net.frozenorb.apiv3.actors; -import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.models.Server; diff --git a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java index 3873270..41530ba 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java +++ b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java @@ -1,13 +1,9 @@ package net.frozenorb.apiv3.actors; -import com.google.common.collect.ImmutableSet; import lombok.Getter; -import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.Permissions; -import java.util.Set; - public final class UserActor implements Actor { @Getter private final User user; diff --git a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java index 24a33c1..77b6504 100644 --- a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java @@ -1,8 +1,8 @@ package net.frozenorb.apiv3.auditLog; import com.google.common.collect.ImmutableMap; +import com.mongodb.async.SingleResultCallback; import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.models.AuditLogEntry; import net.frozenorb.apiv3.models.User; @@ -12,14 +12,19 @@ import java.util.Map; @UtilityClass public class AuditLog { - public static void log(User performedBy, String performedByIp, Actor actor, AuditLogActionType actionType) { - log(performedBy, performedByIp, actor, actionType, ImmutableMap.of()); + public static void log(User performedBy, String performedByIp, Actor actor, AuditLogActionType actionType, SingleResultCallback callback) { + log(performedBy, performedByIp, actor, actionType, ImmutableMap.of(), callback); } - public static void log(User performedBy, String performedByIp, Actor actor, AuditLogActionType actionType, Map actionData) { + public static void log(User performedBy, String performedByIp, Actor actor, AuditLogActionType actionType, Map actionData, SingleResultCallback callback) { AuditLogEntry entry = new AuditLogEntry(performedBy, performedByIp, actor, actionType, actionData); - entry.insert(); - APIv3.getStatsD().incrementCounter("apiv3.auditLog.insertions"); + entry.insert((ignored, error) -> { + if (error != null) { + callback.onResult(null, error); + } else { + callback.onResult(entry, null); + } + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java index a661093..d066eb6 100644 --- a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java +++ b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java @@ -1,5 +1,6 @@ package net.frozenorb.apiv3.auditLog; +import com.mongodb.async.SingleResultCallback; import net.frozenorb.apiv3.models.AuditLogEntry; public enum AuditLogActionType { @@ -7,20 +8,22 @@ public enum AuditLogActionType { DELETE_PUNISHMENT { @Override - public void revert(AuditLogEntry entry) { - + public void revert(AuditLogEntry entry, SingleResultCallback callback) { + callback.onResult(false, null); } }, DELETE_GRANT { @Override - public void revert(AuditLogEntry entry) { - + public void revert(AuditLogEntry entry, SingleResultCallback callback) { + callback.onResult(false, null); } }; - public void revert(AuditLogEntry entry) {} + public void revert(AuditLogEntry entry, SingleResultCallback callback) { + callback.onResult(null, new UnsupportedOperationException()); + } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java b/src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java new file mode 100644 index 0000000..ab24c1c --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java @@ -0,0 +1,60 @@ +package net.frozenorb.apiv3.conversion; + +import com.google.common.collect.ImmutableSet; +import com.mongodb.Block; +import lombok.extern.slf4j.Slf4j; +import net.frozenorb.apiv3.models.Grant; +import org.bson.Document; +import org.bson.types.ObjectId; + +import java.util.Collection; +import java.util.Date; +import java.util.Map; +import java.util.UUID; + +@Slf4j +public final class GrantConverter implements Block { + + private Map mongoIdToUUID; + + public GrantConverter(Map mongoIdToUUID) { + this.mongoIdToUUID = mongoIdToUUID; + } + + @Override + public void apply(Document grant) { + UUID target = mongoIdToUUID.get(((Map) grant.get("target")).get("$id")); + + if (target == null) { + return; + } + + String rank = grant.getString("role"); + + if (rank.equalsIgnoreCase("unban") || rank.equalsIgnoreCase("pass") || rank.equalsIgnoreCase("pink") || rank.equalsIgnoreCase("jrdev")) { + return; + } else if (rank.equalsIgnoreCase("high_roller")) { + rank = "high-roller"; + } else if (rank.equalsIgnoreCase("dev")) { + rank = "developer"; + } + + Grant created = new Grant( + new ObjectId().toString(), + target, + grant.containsKey("comment") ? grant.getString("comment") : "", + grant.containsKey("scope") ? ImmutableSet.copyOf((Collection) grant.get("scope")) : ImmutableSet.of(), + rank, + grant.getDate("expires"), + grant.containsKey("addedBy") ? mongoIdToUUID.get(((Map) grant.get("addedBy")).get("$id")) : null, + grant.containsKey("created") ? grant.getDate("created") : new Date(), + null, + null, + null + ); + + created.insert(); + log.info("Created grant " + created.getId() + " (" + created.getRank() + ")"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java b/src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java new file mode 100644 index 0000000..ad80c21 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java @@ -0,0 +1,57 @@ +package net.frozenorb.apiv3.conversion; + +import com.mongodb.Block; +import lombok.extern.slf4j.Slf4j; +import net.frozenorb.apiv3.models.IpLogEntry; +import net.frozenorb.apiv3.utils.IpUtils; +import org.bson.Document; +import org.bson.types.ObjectId; + +import java.util.Date; +import java.util.Map; +import java.util.UUID; + +@Slf4j +public final class IpLogConverter implements Block { + + private Map mongoIdToUUID; + + public IpLogConverter(Map mongoIdToUUID) { + this.mongoIdToUUID = mongoIdToUUID; + } + + @Override + public void apply(Document ipLogEntry) { + UUID user = mongoIdToUUID.get(((Map) ipLogEntry.get("user")).get("$id")); + + if (user == null || ipLogEntry.getString("ip") == null) { + return; + } + + String ip = ipLogEntry.getString("ip").replace("/", ""); + + if (!IpUtils.isValidIp(ip)) { + return; + } + + Date lastSeen = ipLogEntry.getDate("lastSeen"); + + if (lastSeen == null) { + lastSeen = new Date(); + } + + IpLogEntry created = new IpLogEntry( + new ObjectId().toString(), + user, + ip, + lastSeen, + lastSeen, + ((Number) ipLogEntry.get("uses")).intValue() + + ); + + created.insert(); + log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java b/src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java new file mode 100644 index 0000000..317851d --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java @@ -0,0 +1,59 @@ +package net.frozenorb.apiv3.conversion; + +import com.google.common.collect.ImmutableMap; +import com.mongodb.Block; +import lombok.extern.slf4j.Slf4j; +import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.models.Punishment; +import org.bson.Document; +import org.bson.types.ObjectId; + +import java.util.Date; +import java.util.List; +import java.util.Map; +import java.util.UUID; + +@Slf4j +public final class PunishmentConverter implements Block { + + private Map mongoIdToUUID; + + public PunishmentConverter(Map mongoIdToUUID) { + this.mongoIdToUUID = mongoIdToUUID; + } + + @Override + public void apply(Document punishment) { + UUID target = mongoIdToUUID.get(((Map) punishment.get("user")).get("$id")); + + if (target == null) { + return; + } + + // Old punishments have this value set to false to indicate they're not active anymore. + if (punishment.containsKey("active") && !punishment.getBoolean("active")) { + return; + } + + Punishment created = new Punishment( + new ObjectId().toString(), + target, + punishment.getString("reason").toString(), + Punishment.PunishmentType.valueOf(punishment.getString("type").toUpperCase()), + punishment.getDate("expires"), + punishment.containsKey("meta") ? (punishment.get("meta") instanceof List ? ImmutableMap.of() : (Document) punishment.get("meta")) : ImmutableMap.of(), + null, + punishment.containsKey("addedBy") ? mongoIdToUUID.get(((Map) punishment.get("addedBy")).get("$id")) : null, + (Date) punishment.getDate("created").clone(), + punishment.containsKey("createdOn") ? String.valueOf(((Map) punishment.get("createdOn")).get("$id")) : "Website", + punishment.containsKey("createdOn") ? ActorType.SERVER : ActorType.WEBSITE, + punishment.containsKey("removedBy") ? (((Map) punishment.get("removedBy")).get("$ref").equals("user") ? mongoIdToUUID.get(((Map) punishment.get("removedBy")).get("$id")) : null) : null, + punishment.containsKey("removedBy") ? (punishment.containsKey("removedAt") ? punishment.getDate("removedAt") : punishment.getDate("created")) : null, + punishment.containsKey("removedBy") ? punishment.getString("removalReason").toString() : null + ); + + created.insert(); + log.info("Created punishment " + created.getId() + " (" + created.getType() + ")"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java b/src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java new file mode 100644 index 0000000..ffb9223 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java @@ -0,0 +1,59 @@ +package net.frozenorb.apiv3.conversion; + +import com.google.common.collect.ImmutableMap; +import com.mongodb.Block; +import lombok.extern.slf4j.Slf4j; +import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.utils.UUIDUtils; +import org.bson.Document; +import org.bson.types.ObjectId; + +import java.util.Map; +import java.util.UUID; + +@Slf4j +public final class UserConverter implements Block { + + private Map mongoIdToUUID; + + public UserConverter(Map mongoIdToUUID) { + this.mongoIdToUUID = mongoIdToUUID; + } + + @Override + public void apply(Document user) { + String uuidString = String.valueOf(user.get("uuid")); + + if (uuidString == null || uuidString.length() != 32 || user.get("name") == null) { + return; + } + + UUID uuid = UUID.fromString(uuidString.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")); + + if (!UUIDUtils.isAcceptableUUID(uuid)) { + return; + } + + mongoIdToUUID.put(user.getObjectId("_id"), uuid); + + User created = new User( + uuid, + user.get("name").toString(), + ImmutableMap.of(user.get("name").toString(), user.getDate("joined")), + null, + null, + null, + null, + user.getString("email"), + user.getString("phone"), + "INVALID", + user.getDate("joined"), + user.getDate("joined"), + false + ); + + created.insert(); + log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")"); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java b/src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java new file mode 100644 index 0000000..8aaa316 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java @@ -0,0 +1,69 @@ +package net.frozenorb.apiv3.conversion; + +import com.mongodb.async.SingleResultCallback; +import com.mongodb.async.client.MongoClients; +import com.mongodb.async.client.MongoDatabase; +import io.vertx.core.CompositeFuture; +import io.vertx.core.Future; +import lombok.extern.slf4j.Slf4j; +import org.bson.types.ObjectId; + +import java.util.HashMap; +import java.util.Map; +import java.util.UUID; + +@Slf4j +public final class V2Converter { + + private MongoDatabase importFrom; + + public V2Converter(String mongoIp, String database) { + importFrom = MongoClients.create(mongoIp).getDatabase(database); + } + + public void startConversion(SingleResultCallback callback) { + Map mongoIdToUUID = new HashMap<>(); + + importFrom.getCollection("user").find().forEach(new UserConverter(mongoIdToUUID), (ignored, error) -> { + if (error != null) { + callback.onResult(null, error); + return; + } + + Future punishmentsFuture = Future.future(); + Future grantsFuture = Future.future(); + Future ipLogFuture = Future.future(); + + importFrom.getCollection("punishment").find().forEach(new PunishmentConverter(mongoIdToUUID), new FutureCompatibilityCallback<>(punishmentsFuture)); + importFrom.getCollection("grant").find().forEach(new GrantConverter(mongoIdToUUID), new FutureCompatibilityCallback<>(grantsFuture)); + importFrom.getCollection("iplog").find().forEach(new IpLogConverter(mongoIdToUUID), new FutureCompatibilityCallback<>(ipLogFuture)); + + CompositeFuture.all(punishmentsFuture, grantsFuture, ipLogFuture).setHandler((result) -> { + if (result.succeeded()) { + callback.onResult(null, null); + } else { + callback.onResult(null, result.cause()); + } + }); + }); + } + + private static class FutureCompatibilityCallback implements SingleResultCallback { + + private Future future; + + public FutureCompatibilityCallback(Future future) { + this.future = future; + } + + public void onResult(T val, Throwable error) { + if (error != null) { + future.fail(error); + } else { + future.complete(val); + } + } + + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java b/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java index 8fc1e86..0446ca9 100644 --- a/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java +++ b/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java @@ -26,6 +26,7 @@ public final class ActorAttributeHandler implements Handler { } } + // TODO: Cleanup private void processBasicAuthorization(String authHeader, RoutingContext ctx) { String encodedHeader = authHeader.substring("Basic ".length()); String decodedHeader = new String(Base64.getDecoder().decode(encodedHeader.getBytes())); @@ -34,24 +35,27 @@ public final class ActorAttributeHandler implements Handler { if (credentials.length == 2) { User.findByLastUsername(credentials[0], (user, error) -> { if (error != null) { - String password = credentials[1]; - - if (user != null && user.getPassword() != null && user.checkPassword(password)) { - ctx.put("actor", new UserActor(user)); - ctx.next(); - return; - } + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + credentials[0] + "."); + return; } - ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); - ErrorUtils.respondGeneric(ctx, "Failed to authorize as " + credentials[0] + "."); + String password = credentials[1]; + + if (user != null && user.getPassword() != null && user.checkPassword(password)) { + ctx.put("actor", new UserActor(user)); + ctx.next(); + return; + } else { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + credentials[0] + "."); + return; + } }); } else { - ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); - ErrorUtils.respondGeneric(ctx, "Failed to authorize as " + credentials[0] + "."); + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + credentials[0] + "."); } } + // TODO: Cleanup private void processMHQAuthorization(String authHeader, RoutingContext ctx) { String[] split = authHeader.split(" "); @@ -71,7 +75,7 @@ public final class ActorAttributeHandler implements Handler { Server server = Server.findById(split[1]); if (server == null) { - ErrorUtils.respondNotFound(ctx, "Server", split[1]); + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize: Server " + split[1] + " not found"); return; } @@ -95,7 +99,7 @@ public final class ActorAttributeHandler implements Handler { } } - ErrorUtils.respondGeneric(ctx, "Failed to authorize."); + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize."); } public void processNoAuthorization(RoutingContext ctx) { diff --git a/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java b/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java index b25bf01..31f1a6a 100644 --- a/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java +++ b/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java @@ -2,7 +2,6 @@ package net.frozenorb.apiv3.handlers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; -import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -13,9 +12,7 @@ public final class AuthorizationHandler implements Handler { Actor actor = ctx.get("actor"); if (!actor.isAuthorized()) { - APIv3.getStatsD().incrementCounter("apiv3.http.unauthorized"); - ctx.response().putHeader("WWW-Authenticate", "Basic realm=\"MineHQ\""); - ErrorUtils.respondGeneric(ctx, "Unauthorized access: Please authorize as an approved actor. You're currently authorized as " + actor.getName()); + ErrorUtils.respondGeneric(ctx, 403, "Please authorize as an approved actor. You're currently authorized as " + actor.getName() + " (" + actor.getType() + ")"); } else { ctx.next(); } diff --git a/src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java b/src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java deleted file mode 100644 index 1bb0839..0000000 --- a/src/main/java/net/frozenorb/apiv3/handlers/MetricsHandler.java +++ /dev/null @@ -1,15 +0,0 @@ -package net.frozenorb.apiv3.handlers; - -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; -import net.frozenorb.apiv3.APIv3; - -public final class MetricsHandler implements Handler { - - @Override - public void handle(RoutingContext ctx) { - APIv3.getStatsD().incrementCounter("apiv3.http.requests"); - ctx.next(); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java index 49f7065..e7ea316 100644 --- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java @@ -3,20 +3,20 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.ImmutableMap; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; import java.util.*; +@Entity public final class AuditLogEntry { private static final MongoCollection auditLogCollection = APIv3.getDatabase().getCollection("auditLog", AuditLogEntry.class); @@ -31,11 +31,11 @@ public final class AuditLogEntry { @Getter private Map metadata; public static List findAllSync() { - return SyncUtils.blockMulti(auditLogCollection.find()); + return SyncUtils.blockMulti(auditLogCollection.find().sort(new Document("performedAt", -1))); } public static List findAllPaginatedSync(int skip, int pageSize) { - return SyncUtils.blockMulti(auditLogCollection.find().sort(new Document("performedAt", 1)).skip(skip).limit(pageSize)); + return SyncUtils.blockMulti(auditLogCollection.find().sort(new Document("performedAt", -1)).skip(skip).limit(pageSize)); } public static AuditLogEntry findByIdSync(String id) { @@ -51,11 +51,11 @@ public final class AuditLogEntry { } public static void findAll(SingleResultCallback> callback) { - auditLogCollection.find().into(new ArrayList<>(), callback); + auditLogCollection.find().sort(new Document("performedAt", -1)).into(new ArrayList<>(), callback); } public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { - auditLogCollection.find().sort(new Document("performedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + auditLogCollection.find().sort(new Document("performedAt", -1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); } public static void findById(String id, SingleResultCallback callback) { @@ -83,10 +83,8 @@ public final class AuditLogEntry { this.metadata = ImmutableMap.copyOf(metadata); } - public void insert() { - BlockingCallback callback = new BlockingCallback<>(); + public void insert(SingleResultCallback callback) { auditLogCollection.insertOne(this, callback); - callback.get(); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/Grant.java b/src/main/java/net/frozenorb/apiv3/models/Grant.java index cda879e..86d30d0 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Grant.java +++ b/src/main/java/net/frozenorb/apiv3/models/Grant.java @@ -3,7 +3,8 @@ package net.frozenorb.apiv3.models; import com.google.common.collect.Collections2; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; -import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; @@ -14,7 +15,9 @@ import org.bson.Document; import org.bson.types.ObjectId; import java.util.*; +import java.util.stream.Collectors; +@Entity @AllArgsConstructor public final class Grant { @@ -35,15 +38,16 @@ public final class Grant { @Getter private String removalReason; public static List findAllSync() { - return SyncUtils.blockMulti(grantsCollection.find()); + return SyncUtils.blockMulti(grantsCollection.find().sort(new Document("addedAt", -1))); } public static List findAllPaginatedSync(int skip, int pageSize) { - return SyncUtils.blockMulti(grantsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize)); + return SyncUtils.blockMulti(grantsCollection.find().sort(new Document("addedAt", -1)).skip(skip).limit(pageSize)); } - public static List findByRankSync(Iterable ranks) { - return SyncUtils.blockMulti(grantsCollection.find(new Document("rank", new Document("$in", ranks)))); + public static List findByRankSync(Collection ranks) { + Collection convertedRanks = ranks.stream().map(Rank::getId).collect(Collectors.toList()); + return SyncUtils.blockMulti(grantsCollection.find(new Document("rank", new Document("$in", convertedRanks)))); } public static Grant findByIdSync(String id) { @@ -59,15 +63,16 @@ public final class Grant { } public static void findAll(SingleResultCallback> callback) { - grantsCollection.find().into(new ArrayList<>(), callback); + grantsCollection.find().sort(new Document("addedAt", -1)).into(new ArrayList<>(), callback); } public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { - grantsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + grantsCollection.find().sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); } - public static void findByRank(Iterable ranks, SingleResultCallback> callback) { - grantsCollection.find(new Document("rank", new Document("$in", ranks))).into(new ArrayList<>(), callback); + public static void findByRank(Collection ranks, SingleResultCallback> callback) { + Collection convertedRanks = ranks.stream().map(Rank::getId).collect(Collectors.toList()); + grantsCollection.find(new Document("rank", new Document("$in", convertedRanks))).into(new ArrayList<>(), callback); } public static void findById(String id, SingleResultCallback callback) { @@ -150,8 +155,8 @@ public final class Grant { this.removedAt = new Date(); this.removalReason = reason; - BlockingCallback callback = new BlockingCallback<>(); - grantsCollection.deleteOne(new Document("_id", id), callback); + BlockingCallback callback = new BlockingCallback<>(); + grantsCollection.replaceOne(new Document("_id", id), this, callback); callback.get(); } diff --git a/src/main/java/net/frozenorb/apiv3/models/IPBan.java b/src/main/java/net/frozenorb/apiv3/models/IPBan.java new file mode 100644 index 0000000..6dc3fe4 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/models/IPBan.java @@ -0,0 +1,171 @@ +package net.frozenorb.apiv3.models; + +import com.mongodb.async.SingleResultCallback; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; +import fr.javatic.mongo.jacksonCodec.objectId.Id; +import lombok.AllArgsConstructor; +import lombok.Getter; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.actors.Actor; +import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.utils.TimeUtils; +import org.bson.Document; +import org.bson.types.ObjectId; + +import java.util.*; + +@Entity +@AllArgsConstructor +public final class IpBan { + + private static final MongoCollection ipBansCollection = APIv3.getDatabase().getCollection("ipBans", IpBan.class); + + @Getter @Id private String id; + @Getter private String userIp; + @Getter private String reason; + @Getter private Date expiresAt; + + @Getter private UUID addedBy; + @Getter private Date addedAt; + @Getter private String actorName; + @Getter private ActorType actorType; + + @Getter private UUID removedBy; + @Getter private Date removedAt; + @Getter private String removalReason; + + public static List findAllSync() { + return SyncUtils.blockMulti(ipBansCollection.find().sort(new Document("addedAt", -1))); + } + + public static List findAllPaginatedSync(int skip, int pageSize) { + return SyncUtils.blockMulti(ipBansCollection.find().sort(new Document("addedAt", -1)).skip(skip).limit(pageSize)); + } + + public static IpBan findByIdSync(String id) { + return SyncUtils.blockOne(ipBansCollection.find(new Document("_id", id))); + } + + public static List findByIpSync(String userIp) { + return SyncUtils.blockMulti(ipBansCollection.find(new Document("userIp", userIp))); + } + + public static void findAll(SingleResultCallback> callback) { + ipBansCollection.find().sort(new Document("addedAt", -1)).into(new ArrayList<>(), callback); + } + + public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { + ipBansCollection.find().sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + } + + public static void findById(String id, SingleResultCallback callback) { + ipBansCollection.find(new Document("_id", id)).first(callback); + } + + public static void findByIp(String userIp, SingleResultCallback> callback) { + ipBansCollection.find(new Document("userIp", userIp)).into(new ArrayList<>(), callback); + } + + public static void findByIpGrouped(Iterable userIps, SingleResultCallback>> callback) { + ipBansCollection.find(new Document("userIp", new Document("$in", userIps))).into(new ArrayList<>(), (ipBans, error) -> { + if (error != null) { + callback.onResult(null, error); + } else { + Map> result = new HashMap<>(); + + for (String userIp : userIps) { + result.put(userIp, new ArrayList<>()); + } + + for (IpBan ipBan : ipBans) { + result.get(ipBan.getUserIp()).add(ipBan); + } + + callback.onResult(result, null); + } + }); + } + + public IpBan() {} // For Morphia + + public IpBan(String userIp, Punishment linked) { + this.id = new ObjectId().toString(); + this.userIp = userIp; + this.reason = linked.getReason(); + this.expiresAt = linked.getExpiresAt(); + this.addedBy = linked.getAddedBy(); + this.addedAt = new Date(); + this.actorName = linked.getActorName(); + this.actorType = linked.getActorType(); + } + + public IpBan(String userIp, String reason, Date expiresAt, User addedBy, Actor actor) { + this.id = new ObjectId().toString(); + this.userIp = userIp; + this.reason = reason; + this.expiresAt = expiresAt; + this.addedBy = addedBy == null ? null : addedBy.getId(); + this.addedAt = new Date(); + this.actorName = actor.getName(); + this.actorType = actor.getType(); + } + + public boolean isActive() { + return !(isExpired() || isRemoved()); + } + + public boolean isExpired() { + if (expiresAt == null) { + return false; // Never expires + } else { + return expiresAt.before(new Date()); + } + } + + public boolean isRemoved() { + return removedBy != null; + } + + public String getAccessDenialReason() { + String accessDenialReason = "Your ip address has been suspended from the MineHQ Network. \n\n"; + + if (getExpiresAt() != null) { + accessDenialReason += "Expires in " + TimeUtils.formatIntoDetailedString(TimeUtils.getSecondsBetween(getExpiresAt(), new Date())); + } else { + accessDenialReason += "Appeal at MineHQ.com/appeal"; + } + + return accessDenialReason; + } + + public void insert() { + BlockingCallback callback = new BlockingCallback<>(); + ipBansCollection.insertOne(this, callback); + callback.get(); + } + + public void delete(User removedBy, String reason) { + this.removedBy = removedBy.getId(); + this.removedAt = new Date(); + this.removalReason = reason; + + BlockingCallback callback = new BlockingCallback<>(); + ipBansCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + + public void delete(Punishment linkedPunishment) { + this.removedBy = linkedPunishment.getRemovedBy(); + this.removedAt = new Date(); + this.removalReason = "Linked punishment removed: " + linkedPunishment.getRemovalReason(); + + BlockingCallback callback = new BlockingCallback<>(); + ipBansCollection.replaceOne(new Document("_id", id), this, callback); + callback.get(); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java index 98f20d7..7e9bfd0 100644 --- a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java @@ -3,6 +3,7 @@ package net.frozenorb.apiv3.models; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; @@ -17,10 +18,11 @@ import java.util.Date; import java.util.List; import java.util.UUID; +@Entity @AllArgsConstructor -public final class IPLogEntry { +public final class IpLogEntry { - private static final MongoCollection ipLogCollection = APIv3.getDatabase().getCollection("ipLog", IPLogEntry.class); + private static final MongoCollection ipLogCollection = APIv3.getDatabase().getCollection("ipLog", IpLogEntry.class); @Getter @Id private String id; @Getter private UUID user; @@ -29,57 +31,57 @@ public final class IPLogEntry { @Getter private Date lastSeenAt; @Getter private int uses; - public static List findAllSync() { - return SyncUtils.blockMulti(ipLogCollection.find()); + public static List findAllSync() { + return SyncUtils.blockMulti(ipLogCollection.find().sort(new Document("lastSeenAt", -1))); } - public static IPLogEntry findByIdSync(String id) { + public static IpLogEntry findByIdSync(String id) { return SyncUtils.blockOne(ipLogCollection.find(new Document("_id", id))); } - public static List findByUserSync(User user) { + public static List findByUserSync(User user) { return findByUserSync(user.getId()); } - public static List findByUserSync(UUID user) { - return SyncUtils.blockMulti(ipLogCollection.find(new Document("user", user))); + public static List findByUserSync(UUID user) { + return SyncUtils.blockMulti(ipLogCollection.find(new Document("user", user)).sort(new Document("lastSeenAt", -1))); } - public static IPLogEntry findByUserAndIpSync(User user, String userIp) { + public static IpLogEntry findByUserAndIpSync(User user, String userIp) { return findByUserAndIpSync(user.getId(), userIp); } - public static IPLogEntry findByUserAndIpSync(UUID user, String userIp) { + public static IpLogEntry findByUserAndIpSync(UUID user, String userIp) { return SyncUtils.blockOne(ipLogCollection.find(new Document("user", user).append("userIp", userIp))); } - public static void findAll(SingleResultCallback> callback) { - ipLogCollection.find().into(new ArrayList<>(), callback); + public static void findAll(SingleResultCallback> callback) { + ipLogCollection.find().sort(new Document("lastSeenAt", -1)).into(new ArrayList<>(), callback); } - public static void findById(String id, SingleResultCallback callback) { + public static void findById(String id, SingleResultCallback callback) { ipLogCollection.find(new Document("_id", id)).first(callback); } - public static void findByUser(User user, SingleResultCallback> callback) { + public static void findByUser(User user, SingleResultCallback> callback) { findByUser(user.getId(), callback); } - public static void findByUser(UUID user, SingleResultCallback> callback) { - ipLogCollection.find(new Document("user", user)).into(new ArrayList<>(), callback); + public static void findByUser(UUID user, SingleResultCallback> callback) { + ipLogCollection.find(new Document("user", user)).sort(new Document("lastSeenAt", -1)).into(new ArrayList<>(), callback); } - public static void findByUserAndIp(User user, String userIp, SingleResultCallback callback) { + public static void findByUserAndIp(User user, String userIp, SingleResultCallback callback) { findByUserAndIp(user.getId(), userIp, callback); } - public static void findByUserAndIp(UUID user, String userIp, SingleResultCallback callback) { + public static void findByUserAndIp(UUID user, String userIp, SingleResultCallback callback) { ipLogCollection.find(new Document("user", user).append("userIp", userIp)).first(callback); } - public IPLogEntry() {} // For Morphia + public IpLogEntry() {} // For Morphia - public IPLogEntry(User user, String userIp) { + public IpLogEntry(User user, String userIp) { this.id = new ObjectId().toString(); this.user = user.getId(); this.userIp = userIp; diff --git a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java index 8d000c5..f1fffa2 100644 --- a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java @@ -4,12 +4,12 @@ import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; @@ -17,6 +17,7 @@ import java.util.ArrayList; import java.util.List; import java.util.Map; +@Entity public final class NotificationTemplate { private static final MongoCollection notificationTemplatesCollection = APIv3.getDatabase().getCollection("notificationTemplates", NotificationTemplate.class); diff --git a/src/main/java/net/frozenorb/apiv3/models/Punishment.java b/src/main/java/net/frozenorb/apiv3/models/Punishment.java index 3a42564..ce093e8 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Punishment.java +++ b/src/main/java/net/frozenorb/apiv3/models/Punishment.java @@ -2,7 +2,8 @@ package net.frozenorb.apiv3.models; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; -import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; @@ -16,7 +17,9 @@ import org.bson.Document; import org.bson.types.ObjectId; import java.util.*; +import java.util.stream.Collectors; +@Entity @AllArgsConstructor public final class Punishment { @@ -28,6 +31,7 @@ public final class Punishment { @Getter private PunishmentType type; @Getter private Date expiresAt; @Getter private Map metadata; + @Getter private String linkedIpBanId; @Getter private UUID addedBy; @Getter private Date addedAt; @@ -39,15 +43,16 @@ public final class Punishment { @Getter private String removalReason; public static List findAllSync() { - return SyncUtils.blockMulti(punishmentsCollection.find()); + return SyncUtils.blockMulti(punishmentsCollection.find().sort(new Document("addedAt", -1))); } public static List findAllPaginatedSync(int skip, int pageSize) { - return SyncUtils.blockMulti(punishmentsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize)); + return SyncUtils.blockMulti(punishmentsCollection.find().sort(new Document("addedAt", -1)).skip(skip).limit(pageSize)); } - public static List findByTypeSync(Iterable types) { - return SyncUtils.blockMulti(punishmentsCollection.find(new Document("type", new Document("$in", types)))); + public static List findByTypeSync(Collection types) { + Collection convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList()); + return SyncUtils.blockMulti(punishmentsCollection.find(new Document("type", new Document("$in", convertedTypes)))); } public static Punishment findByIdSync(String id) { @@ -62,24 +67,26 @@ public final class Punishment { return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user))); } - public static List findByUserAndTypeSync(User user, Iterable types) { + public static List findByUserAndTypeSync(User user, Collection types) { return findByUserAndTypeSync(user.getId(), types); } - public static List findByUserAndTypeSync(UUID user, Iterable types) { - return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", types)))); + public static List findByUserAndTypeSync(UUID user, Collection types) { + Collection convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList()); + return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", convertedTypes)))); } public static void findAll(SingleResultCallback> callback) { - punishmentsCollection.find().into(new ArrayList<>(), callback); + punishmentsCollection.find().sort(new Document("addedAt", -1)).into(new ArrayList<>(), callback); } public static void findAllPaginated(int skip, int pageSize, SingleResultCallback> callback) { - punishmentsCollection.find().sort(new Document("addedAt", 1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); + punishmentsCollection.find().sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new ArrayList<>(), callback); } - public static void findByType(Iterable types, SingleResultCallback> callback) { - punishmentsCollection.find(new Document("type", new Document("$in", types))).into(new ArrayList<>(), callback); + public static void findByType(Collection types, SingleResultCallback> callback) { + Collection convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList()); + punishmentsCollection.find(new Document("type", new Document("$in", convertedTypes))).into(new ArrayList<>(), callback); } public static void findById(String id, SingleResultCallback callback) { @@ -114,12 +121,13 @@ public final class Punishment { }); } - public static void findByUserAndType(User user, Iterable types, SingleResultCallback> callback) { + public static void findByUserAndType(User user, Collection types, SingleResultCallback> callback) { findByUserAndType(user.getId(), types, callback); } - public static void findByUserAndType(UUID user, Iterable types, SingleResultCallback> callback) { - punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", types))).into(new ArrayList<>(), callback); + public static void findByUserAndType(UUID user, Collection types, SingleResultCallback> callback) { + Collection convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList()); + punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", convertedTypes))).into(new ArrayList<>(), callback); } public Punishment() {} // For Morphia @@ -172,6 +180,10 @@ public final class Punishment { } } + public void linkIpBan(IpBan ipBan) { + + } + public void insert() { BlockingCallback callback = new BlockingCallback<>(); punishmentsCollection.insertOne(this, callback); @@ -183,8 +195,8 @@ public final class Punishment { this.removedAt = new Date(); this.removalReason = reason; - BlockingCallback callback = new BlockingCallback<>(); - punishmentsCollection.deleteOne(new Document("_id", id), callback); + BlockingCallback callback = new BlockingCallback<>(); + punishmentsCollection.replaceOne(new Document("_id", id), this, callback); callback.get(); } diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/models/Rank.java index 8ec7348..5af8936 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Rank.java +++ b/src/main/java/net/frozenorb/apiv3/models/Rank.java @@ -5,6 +5,7 @@ import com.google.common.primitives.Ints; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; @@ -18,6 +19,7 @@ import java.util.List; import java.util.Map; import java.util.concurrent.TimeUnit; +@Entity public final class Rank { private static final MongoCollection ranksCollection = APIv3.getDatabase().getCollection("ranks", Rank.class); diff --git a/src/main/java/net/frozenorb/apiv3/models/Server.java b/src/main/java/net/frozenorb/apiv3/models/Server.java index d666da9..8898cce 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Server.java +++ b/src/main/java/net/frozenorb/apiv3/models/Server.java @@ -4,11 +4,12 @@ import com.google.common.collect.ImmutableSet; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.serialization.ExcludeFromReplies; +import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.SyncUtils; import org.bson.Document; @@ -16,6 +17,7 @@ import org.bson.Document; import java.util.*; import java.util.concurrent.TimeUnit; +@Entity public final class Server { private static final MongoCollection serversCollection = APIv3.getDatabase().getCollection("servers", Server.class); diff --git a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java index 5d41865..92a1d29 100644 --- a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java @@ -1,14 +1,14 @@ package net.frozenorb.apiv3.models; -import com.google.gson.annotations.SerializedName; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.serialization.ExcludeFromReplies; +import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.PermissionUtils; import net.frozenorb.apiv3.utils.SyncUtils; @@ -17,6 +17,7 @@ import org.bson.Document; import java.util.*; import java.util.concurrent.TimeUnit; +@Entity public final class ServerGroup { private static final MongoCollection serverGroupsCollection = APIv3.getDatabase().getCollection("serverGroups", ServerGroup.class); @@ -32,6 +33,7 @@ public final class ServerGroup { @Getter @Setter @ExcludeFromReplies private Set announcements = new HashSet<>(); @Getter @Setter @ExcludeFromReplies private Map> permissions = new HashMap<>(); + // make this and other stuff async public static List findAll() { updateCacheIfNeeded(); return serverGroupAltCache; diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/models/User.java index 3b6ccb7..ba43809 100644 --- a/src/main/java/net/frozenorb/apiv3/models/User.java +++ b/src/main/java/net/frozenorb/apiv3/models/User.java @@ -1,5 +1,6 @@ package net.frozenorb.apiv3.models; +import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.base.Charsets; @@ -9,14 +10,17 @@ import com.google.common.hash.Hashing; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; +import io.vertx.core.CompositeFuture; +import io.vertx.core.Future; import lombok.AllArgsConstructor; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.serialization.ExcludeFromReplies; -import net.frozenorb.apiv3.serialization.UUIDJsonDeserializer; -import net.frozenorb.apiv3.serialization.UUIDJsonSerializer; +import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; +import net.frozenorb.apiv3.serialization.jackson.UUIDJsonDeserializer; +import net.frozenorb.apiv3.serialization.jackson.UUIDJsonSerializer; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.MojangUtils; import net.frozenorb.apiv3.utils.PermissionUtils; @@ -24,8 +28,10 @@ import net.frozenorb.apiv3.utils.SyncUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import org.bson.Document; +import java.io.IOException; import java.util.*; +@Entity @AllArgsConstructor public final class User { @@ -46,7 +52,7 @@ public final class User { @Getter private boolean online; public static List findAllSync() { - return SyncUtils.blockMulti(usersCollection.find()); + return SyncUtils.blockMulti(usersCollection.find().sort(new Document("lastSeenAt", -1))); } public static User findByIdSync(String id) { @@ -78,7 +84,7 @@ public final class User { } public static void findAll(SingleResultCallback> callback) { - usersCollection.find().into(new ArrayList<>(), callback); + usersCollection.find().sort(new Document("lastSeenAt", -1)).into(new ArrayList<>(), callback); } public static void findById(String id, SingleResultCallback callback) { @@ -140,7 +146,10 @@ public final class User { this.lastSeenAt = new Date(); this.firstSeenAt = new Date(); - updateUsername(lastUsername); + // TODO: MAKE THIS ASYNC? SOMEHOW? + BlockingCallback blockingCallback = new BlockingCallback<>(); + updateUsername(lastUsername, blockingCallback); + blockingCallback.get(); } public boolean hasPermissionAnywhere(String permission) { @@ -180,21 +189,31 @@ public final class User { this.online = false; } - public void updateUsername(String username) { - if (!username.equals(lastUsername)) { - this.lastUsername = username; + public void updateUsername(String newUsername, SingleResultCallback callback) { + this.aliases.put(newUsername, new Date()); - User withNewUsername; - - while ((withNewUsername = User.findByLastUsernameSync(username)) != null) { - BlockingCallback callback = new BlockingCallback<>(); - MojangUtils.getName(withNewUsername.getId(), callback); - String newUsername = callback.get(); - withNewUsername.updateUsername(newUsername); - } + if (newUsername.equalsIgnoreCase(lastUsername)) { + callback.onResult(null, null); + return; } - this.aliases.put(username, new Date()); + this.lastUsername = newUsername; + + User.findByLastUsername(newUsername, (otherUser, error) -> { + if (error != null) { + callback.onResult(null, error); + } else if (otherUser != null) { + MojangUtils.getName(otherUser.getId(), (newName, error2) -> { + if (error2 != null) { + callback.onResult(null, error2); + } else { + otherUser.updateUsername(newName, callback); + } + }); + } else { + callback.onResult(null, null); + } + }); } public void setPassword(String input) { @@ -272,22 +291,46 @@ public final class User { return highestRanks; } - public Map getLoginInfo(Server server) { - return createLoginInfo( - server, - Punishment.findByUserAndTypeSync(this, ImmutableSet.of( - Punishment.PunishmentType.BLACKLIST, - Punishment.PunishmentType.BAN, - Punishment.PunishmentType.MUTE - )), - Grant.findByUserSync(this) - ); + public void getLoginInfo(Server server, SingleResultCallback> callback) { + Future> punishmentsFuture = Future.future(); + Future> grantsFuture = Future.future(); + + Punishment.findByUserAndType(this, ImmutableSet.of( + Punishment.PunishmentType.BLACKLIST, + Punishment.PunishmentType.BAN, + Punishment.PunishmentType.MUTE + ), (punishments, error) -> { + if (error != null) { + punishmentsFuture.fail(error); + } else { + punishmentsFuture.complete(punishments); + } + }); + + Grant.findByUser(this, (grants, error) -> { + if (error != null) { + grantsFuture.fail(error); + } else { + grantsFuture.complete(grants); + } + }); + + CompositeFuture.all(punishmentsFuture, grantsFuture).setHandler((result) -> { + if (result.succeeded()) { + Iterable punishments = result.result().result(0); + Iterable grants = result.result().result(1); + + callback.onResult(createLoginInfo(server, punishments, grants), null); + } else { + callback.onResult(null, result.cause()); + } + }); } // This is only used to help batch requests to mongo public Map createLoginInfo(Server server, Iterable punishments, Iterable grants) { Punishment activeMute = null; - String accessDenialReason = null; + Punishment activeBan = null; for (Punishment punishment : punishments) { if (!punishment.isActive()) { @@ -296,8 +339,8 @@ public final class User { if (punishment.getType() == Punishment.PunishmentType.MUTE) { activeMute = punishment; - } else { - accessDenialReason = punishment.getAccessDenialReason(); + } else if (punishment.getType() == Punishment.PunishmentType.BAN || punishment.getType() == Punishment.PunishmentType.BLACKLIST) { + activeBan = punishment; } } @@ -307,8 +350,9 @@ public final class User { ImmutableMap.Builder result = ImmutableMap.builder() .put("user", this) .put("access", ImmutableMap.of( - "allowed", accessDenialReason == null, - "message", accessDenialReason == null ? "Public server" : accessDenialReason + "allowed", activeBan == null, + "message", activeBan == null ? "Public server" : activeBan.getAccessDenialReason(), + "activeBanId", activeBan == null ? "" : activeBan.getId() )) .put("rank", highestRank.getId()) .put("totpSetup", getTotpSecret() != null); @@ -328,8 +372,12 @@ public final class User { public void save() { BlockingCallback callback = new BlockingCallback<>(); - usersCollection.replaceOne(new Document("_id", id), this, callback); + save(callback); callback.get(); } + public void save(SingleResultCallback callback) { + usersCollection.replaceOne(new Document("_id", id), this, callback); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java index 5f1831d..839d1d2 100644 --- a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java @@ -5,6 +5,7 @@ import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import lombok.Setter; @@ -19,6 +20,7 @@ import java.util.List; import java.util.Map; import java.util.UUID; +@Entity public final class UserMetaEntry { private static final MongoCollection userMetaCollection = APIv3.getDatabase().getCollection("userMeta", UserMetaEntry.class); diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java index 27629a1..b5d7f70 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java @@ -18,6 +18,7 @@ public final class GETDump implements Handler { private Map> grantCache = new HashMap<>(); public GETDump() { + // TODO: Use vertx scheduler Thread dumpUpdater = new Thread() { @Override @@ -69,7 +70,7 @@ public final class GETDump implements Handler { try { Thread.sleep(TimeUnit.MINUTES.toMillis(3)); - } catch (Exception ex) { + } catch (InterruptedException ex) { throw new RuntimeException(ex); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java index dd6b553..23d19ba 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java +++ b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java @@ -3,27 +3,20 @@ package net.frozenorb.apiv3.routes.announcements; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.actors.ServerActor; -import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.utils.ErrorUtils; public final class GETAnnouncements implements Handler { public void handle(RoutingContext ctx) { - Actor actor = ctx.get("actor"); + ServerGroup serverGroup = ServerGroup.findById(ctx.request().getParam("id")); - if (actor.getType() != ActorType.SERVER) { - ErrorUtils.respondServerOnly(ctx); + if (serverGroup == null) { + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("id")); return; } - Server sender = ((ServerActor) actor).getServer(); - ServerGroup senderGroup = ServerGroup.findById(sender.getServerGroup()); - - APIv3.respondJson(ctx, senderGroup.getAnnouncements()); + APIv3.respondJson(ctx, serverGroup.getAnnouncements()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java b/src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java new file mode 100644 index 0000000..d42dd2f --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java @@ -0,0 +1,33 @@ +package net.frozenorb.apiv3.routes.announcements; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.ServerGroup; +import net.frozenorb.apiv3.utils.ErrorUtils; + +import java.util.HashSet; +import java.util.Set; + +public final class PUTAnnouncements implements Handler { + + public void handle(RoutingContext ctx) { + ServerGroup serverGroup = ServerGroup.findById(ctx.request().getParam("id")); + + if (serverGroup == null) { + ErrorUtils.respondNotFound(ctx, "Server group", ctx.request().getParam("id")); + return; + } + + Set announcements = new HashSet<>(); + + for (Object announcement : ctx.getBodyAsJsonArray()) { + announcements.add((String) announcement); + } + + serverGroup.setAnnouncements(announcements); + serverGroup.save(); + APIv3.respondJson(ctx, serverGroup.getAnnouncements()); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java new file mode 100644 index 0000000..336ea66 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java @@ -0,0 +1,47 @@ +package net.frozenorb.apiv3.routes.auditLog; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.models.AuditLogEntry; +import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.utils.IpUtils; +import org.bson.Document; + +public final class POSTUserAuditLogEntry implements Handler { + + public void handle(RoutingContext ctx) { + User user = User.findByIdSync(ctx.request().getParam("id")); + + if (user == null) { + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); + return; + } + + String userIp = ctx.request().getParam("userIp"); + + if (!IpUtils.isValidIp(userIp)) { + ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid."); + 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 blockingCallback = new BlockingCallback<>(); + AuditLog.log(user, userIp, ctx.get("actor"), type, Document.parse(ctx.getBodyAsString()), blockingCallback); + AuditLogEntry entry = blockingCallback.get(); + APIv3.respondJson(ctx, entry); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java b/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java index 879edbf..972b000 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java +++ b/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java @@ -1,6 +1,6 @@ package net.frozenorb.apiv3.routes.chatFilterList; -import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableList; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; @@ -8,7 +8,9 @@ import net.frozenorb.apiv3.APIv3; public final class GETChatFilterList implements Handler { public void handle(RoutingContext ctx) { - APIv3.respondJson(ctx, ImmutableMap.of()); + // TODO + // WARNING: THIS IS REGISTERED ASYNC SO DONT MESS IT UP + APIv3.respondJson(ctx, ImmutableList.of()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java index d96e6bb..9eeb99a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java @@ -6,8 +6,10 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.models.AuditLogEntry; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEGrant implements Handler { @@ -38,7 +40,9 @@ public final class DELETEGrant implements Handler { } grant.delete(removedBy, reason); - AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of()); + BlockingCallback blockingCallback = new BlockingCallback<>(); + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of(), blockingCallback); + blockingCallback.get(); APIv3.respondJson(ctx, grant); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java b/src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java new file mode 100644 index 0000000..7682520 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java @@ -0,0 +1,49 @@ +package net.frozenorb.apiv3.routes.ipBans; + +import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.models.AuditLogEntry; +import net.frozenorb.apiv3.models.IpBan; +import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.utils.ErrorUtils; + +public final class DELETEIpBan implements Handler { + + public void handle(RoutingContext ctx) { + IpBan ipBan = IpBan.findByIdSync(ctx.request().getParam("id")); + + if (ipBan == null) { + ErrorUtils.respondNotFound(ctx, "IpBan", ctx.request().getParam("id")); + return; + } else if (!ipBan.isActive()) { + ErrorUtils.respondInvalidInput(ctx, "Cannot remove an inactive ip ban."); + return; + } + + User removedBy = User.findByIdSync(ctx.request().getParam("removedBy")); + + if (removedBy == null) { + ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("removedBy")); + return; + } + + String reason = ctx.request().getParam("reason"); + + if (reason == null || reason.trim().isEmpty()) { + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; + } + + ipBan.delete(removedBy, reason); + BlockingCallback blockingCallback = new BlockingCallback<>(); + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback); + blockingCallback.get(); + APIv3.respondJson(ctx, ipBan); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java b/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java new file mode 100644 index 0000000..268b46d --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java @@ -0,0 +1,14 @@ +package net.frozenorb.apiv3.routes.ipBans; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.IpBan; + +public final class GETIpBan implements Handler { + + public void handle(RoutingContext ctx) { + APIv3.respondJson(ctx, IpBan.findByIdSync(ctx.request().getParam("id"))); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java b/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java new file mode 100644 index 0000000..36cf2d3 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java @@ -0,0 +1,22 @@ +package net.frozenorb.apiv3.routes.ipBans; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.IpBan; +import net.frozenorb.apiv3.utils.ErrorUtils; + +public final class GETIpBans implements Handler { + + public void handle(RoutingContext ctx) { + try { + 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)); + } catch (NumberFormatException ex) { + ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs."); + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java b/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java new file mode 100644 index 0000000..f798a00 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java @@ -0,0 +1,24 @@ +package net.frozenorb.apiv3.routes.ipBans; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.IpBan; +import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.utils.IpUtils; + +public final class GETIpIpBans implements Handler { + + public void handle(RoutingContext ctx) { + String userIp = ctx.request().getParam("id"); + + if (!IpUtils.isValidIp(userIp)) { + ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid."); + return; + } + + APIv3.respondJson(ctx, IpBan.findByIpSync(userIp)); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java b/src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java new file mode 100644 index 0000000..b478731 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java @@ -0,0 +1,57 @@ +package net.frozenorb.apiv3.routes.ipBans; + +import com.google.common.collect.ImmutableMap; +import com.google.common.collect.ImmutableSet; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.models.IpBan; +import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.Permissions; +import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.utils.IpUtils; +import org.bson.Document; + +import java.util.Date; +import java.util.Map; + +public final class POSTIpIpBan implements Handler { + + public void handle(RoutingContext ctx) { + String userIp = ctx.request().getParam("id"); + + if (!IpUtils.isValidIp(userIp)) { + ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid."); + return; + } + + String reason = ctx.request().getParam("reason"); + + if (reason == null || reason.trim().isEmpty()) { + ErrorUtils.respondRequiredInput(ctx, "reason"); + return; + } + + Date expiresAt; + + try { + expiresAt = new Date(Long.parseLong(ctx.request().getParam("expiresAt"))); + } catch (NumberFormatException ex) { + expiresAt = null; + } + + if (expiresAt != null && expiresAt.before(new Date())) { + ErrorUtils.respondInvalidInput(ctx, "Expiration date cannot be in the past."); + return; + } + + // We purposely don't do a null check, ip bans don't have to have a source. + User addedBy = User.findByIdSync(ctx.request().getParam("addedBy")); + + IpBan ipBan = new IpBan(userIp, reason, expiresAt, addedBy, ctx.get("actor")); + ipBan.insert(); + + APIv3.respondJson(ctx, ipBan); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java index 42e5310..a36f49a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java @@ -3,11 +3,11 @@ package net.frozenorb.apiv3.routes.ipLog; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.IPLogEntry; +import net.frozenorb.apiv3.models.IpLogEntry; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -public final class GETUserIPLog implements Handler { +public final class GETUserIpLog implements Handler { public void handle(RoutingContext ctx) { User target = User.findByIdSync(ctx.request().getParam("id")); @@ -17,7 +17,7 @@ public final class GETUserIPLog implements Handler { return; } - APIv3.respondJson(ctx, IPLogEntry.findByUserSync(target)); + APIv3.respondJson(ctx, IpLogEntry.findByUserSync(target)); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/PUTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/PUTNotificationTemplate.java deleted file mode 100644 index 03c9431..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/PUTNotificationTemplate.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.frozenorb.apiv3.routes.notificationTemplate; - -public class PUTNotificationTemplate { -} diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/DELETENotificationTemplate.java similarity index 92% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/DELETENotificationTemplate.java index da8850f..59e7d58 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/DELETENotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/DELETENotificationTemplate.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.notificationTemplate; +package net.frozenorb.apiv3.routes.notificationTemplates; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplate.java similarity index 87% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplate.java index 8e6632f..d7425eb 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplate.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.notificationTemplate; +package net.frozenorb.apiv3.routes.notificationTemplates; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplates.java similarity index 86% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java rename to src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplates.java index 16cdba6..f91ee86 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/GETNotificationTemplates.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplates.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.notificationTemplate; +package net.frozenorb.apiv3.routes.notificationTemplates; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/POSTNotificationTemplate.java similarity index 91% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/POSTNotificationTemplate.java index d913b96..09ee2e9 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplate/POSTNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/POSTNotificationTemplate.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.notificationTemplate; +package net.frozenorb.apiv3.routes.notificationTemplates; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java new file mode 100644 index 0000000..c07f9a9 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java @@ -0,0 +1,4 @@ +package net.frozenorb.apiv3.routes.notificationTemplates; + +public class PUTNotificationTemplate { +} diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java index 33e07bc..d545ed3 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java @@ -6,8 +6,10 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.models.AuditLogEntry; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEPunishment implements Handler { @@ -38,7 +40,9 @@ public final class DELETEPunishment implements Handler { } punishment.delete(removedBy, reason); - AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); + BlockingCallback blockingCallback = new BlockingCallback<>(); + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback); + blockingCallback.get(); APIv3.respondJson(ctx, punishment); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEUserPunishment.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java rename to src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEUserPunishment.java index b2f8a50..76e9828 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEUserPunishment.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.routes.punishments; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -7,8 +7,10 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.models.AuditLogEntry; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; public final class DELETEUserPunishment implements Handler { @@ -39,13 +41,15 @@ public final class DELETEUserPunishment implements Handler { for (Punishment punishment : Punishment.findByUserAndTypeSync(target, ImmutableSet.of(type))) { if (punishment.isActive()) { punishment.delete(removedBy, reason); - AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of()); + BlockingCallback blockingCallback = new BlockingCallback<>(); + AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback); + blockingCallback.get(); APIv3.respondJson(ctx, punishment); return; } } - ErrorUtils.respondGeneric(ctx, "User provided has no active punishments"); + ErrorUtils.respondGeneric(ctx, 404, "User provided has no active punishments"); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java index bd2ef45..5c8433c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java @@ -36,7 +36,7 @@ public final class POSTUserPunish implements Handler { if (type != Punishment.PunishmentType.WARN) { for (Punishment punishment : Punishment.findByUserAndTypeSync(target, ImmutableSet.of(type))) { if (punishment.isActive()) { - ErrorUtils.respondGeneric(ctx, "A punishment by " + User.findByIdSync(punishment.getAddedBy()).getLastUsername() + " already covers this user."); + ErrorUtils.respondGeneric(ctx, 200, "A punishment by " + User.findByIdSync(punishment.getAddedBy()).getLastUsername() + " already covers this user."); return; } } @@ -62,11 +62,11 @@ public final class POSTUserPunish implements Handler { return; } - // We purposely don't do a null check, grants don't have to have a source. + // We purposely don't do a null check, punishments don't have to have a source. User addedBy = User.findByIdSync(ctx.request().getParam("addedBy")); if (target.hasPermissionAnywhere(Permissions.PROTECTED_PUNISHMENT)) { - ErrorUtils.respondGeneric(ctx, target.getLastSeenOn() + " is protected from punishments."); + ErrorUtils.respondGeneric(ctx, 200, target.getLastSeenOn() + " is protected from punishments."); return; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java index 69e2f5f..03a079d 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java @@ -6,14 +6,16 @@ import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IPUtils; +import net.frozenorb.apiv3.utils.IpUtils; + +import java.math.BigInteger; +import java.util.Random; public final class POSTServer implements Handler { public void handle(RoutingContext ctx) { String id = ctx.request().getParam("id"); String displayName = ctx.request().getParam("displayName"); - String apiKey = ctx.request().getParam("apiKey"); ServerGroup group = ServerGroup.findById(ctx.request().getParam("group")); String ip = ctx.request().getParam("ip"); @@ -22,12 +24,13 @@ public final class POSTServer implements Handler { return; } - if (!IPUtils.isValidIP(ip)) { - ErrorUtils.respondInvalidInput(ctx, "IP address \"" + ip + "\" is not valid."); + if (!IpUtils.isValidIp(ip)) { + ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + ip + "\" is not valid."); return; } - Server server = new Server(id, displayName, apiKey, group, ip); + String generatedApiKey = new BigInteger(130, new Random()).toString(32); + Server server = new Server(id, displayName, generatedApiKey, group, ip); server.insert(); APIv3.respondJson(ctx, server); } diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java index 341accd..00414a1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java @@ -1,6 +1,5 @@ package net.frozenorb.apiv3.routes.servers; -import com.fasterxml.jackson.databind.ObjectMapper; import com.google.common.collect.ImmutableMap; import io.vertx.core.CompositeFuture; import io.vertx.core.Future; @@ -35,32 +34,35 @@ public final class POSTServerHeartbeat implements Handler { Map playerNames = extractPlayerNames(reqJson); CompositeFuture.all( - createInfoResponse(actorServer, reqJson.getDouble("tps"), playerNames), + createInfoResponse(actorServer, reqJson.getDouble("lastTps"), playerNames), createPlayerResponse(actorServer, playerNames), createPermissionsResponse(actorServerGroup), createEventsResponse((List) reqJson.get("events")) ).setHandler((result) -> { if (result.succeeded()) { + // We don't do anything with the info callback, as + // it's just to update our database. APIv3.respondJson(ctx, ImmutableMap.of( - "info", result.result().result(0), "players", result.result().result(1), "permissions", result.result().result(2), "events", result.result().result(3) )); } else { - ErrorUtils.respondGeneric(ctx, result.cause().getMessage()); + ErrorUtils.respondInternalError(ctx, result.cause()); } }); } - public Future> createInfoResponse(Server server, double tps, Map playerNames) { - Future> callback = Future.future(); + // TODO: ASYNC (MAKE ALL SAVES/INSERTS/ETC USED HERE ASYNC + public Future createInfoResponse(Server server, double tps, Map playerNames) { + Future callback = Future.future(); server.setPlayers(playerNames.keySet()); server.setLastTps(tps); server.setLastUpdatedAt(new Date()); server.save(); + callback.complete(); return callback; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java index d870bfa..e25367b 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java @@ -5,7 +5,7 @@ import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.IPLogEntry; +import net.frozenorb.apiv3.models.IpLogEntry; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -24,7 +24,7 @@ public final class GETUserDetails implements Handler { APIv3.respondJson(ctx, ImmutableMap.builder() .put("user", user) .put("grants", Grant.findByUserSync(user)) - .put("ipLog", IPLogEntry.findByUserSync(user)) + .put("ipLog", IpLogEntry.findByUserSync(user)) .put("punishments", Punishment.findByUserSync(user)) .put("aliases", user.getAliases()) .put("totpSetup", user.getTotpSecret() != null) diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java index 40de6aa..3c53fdc 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java @@ -2,13 +2,12 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; -import io.vertx.core.cli.converters.BooleanConverter; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IPUtils; +import net.frozenorb.apiv3.utils.IpUtils; import net.frozenorb.apiv3.utils.TOTPUtils; public final class GETUserRequiresTOTP implements Handler { @@ -31,8 +30,8 @@ public final class GETUserRequiresTOTP implements Handler { String userIp = ctx.request().getParam("userIp"); - if (!IPUtils.isValidIP(userIp)) { - ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid."); + if (!IpUtils.isValidIp(userIp)) { + ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid."); return; } @@ -42,7 +41,7 @@ public final class GETUserRequiresTOTP implements Handler { if (preAuthorizedCallback.get()) { APIv3.respondJson(ctx, ImmutableMap.of( "required", false, - "message", "User's IP has already been validated" + "message", "User's ip has already been validated" )); } else { APIv3.respondJson(ctx, ImmutableMap.of( diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java index cfd569e..bdf4fc2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java @@ -32,22 +32,22 @@ public final class POSTUserConfirmRegister implements Handler { // We can't check email != null as that's set while we're pending // confirmation, we have to check the token. if (user.getEmailToken() == null) { - ErrorUtils.respondGeneric(ctx, "User provided already has email set."); + ErrorUtils.respondGeneric(ctx, 400, "User provided already has email set."); return; } if ((System.currentTimeMillis() - user.getEmailTokenSetAt().getTime()) > TimeUnit.DAYS.toMillis(2)) { - ErrorUtils.respondGeneric(ctx, "Email token is expired"); + ErrorUtils.respondGeneric(ctx, 200, "Email token is expired"); return; } String password = ctx.request().getParam("password"); if (password.length() < 8) { - ErrorUtils.respondGeneric(ctx, "Your password is too short."); + ErrorUtils.respondGeneric(ctx, 200, "Your password is too short."); return; } else if (commonPasswords.contains(password)) { - ErrorUtils.respondGeneric(ctx, "Your password is too common. Please use a more secure password."); + ErrorUtils.respondGeneric(ctx, 200, "Your password is too common. Please use a more secure password."); return; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java index 23285d2..f728372 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java @@ -10,16 +10,22 @@ public class POSTUserLeave implements Handler { @Override public void handle(RoutingContext ctx) { - User user = User.findByIdSync(ctx.request().getParam("id")); - - if (user == null) { - ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id")); - return; - } - - user.leftServer(); - user.save(); - APIv3.respondJson(ctx, user); + 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 { + user.leftServer(); + user.save((ignored, error2) -> { + if (error2 != null) { + ErrorUtils.respondInternalError(ctx, error2); + } else { + APIv3.respondJson(ctx, user); + } + }); + } + })); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java index 2a01d7e..e90b3ba 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java @@ -5,11 +5,12 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.actors.Actor; import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.models.IPLogEntry; +import net.frozenorb.apiv3.actors.ServerActor; +import net.frozenorb.apiv3.models.IpLogEntry; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IPUtils; +import net.frozenorb.apiv3.utils.IpUtils; import net.frozenorb.apiv3.utils.UUIDUtils; import java.util.UUID; @@ -24,9 +25,6 @@ public final class POSTUserLogin implements Handler { return; } - User user = User.findByIdSync(uuid); - String username = ctx.request().getParam("username"); - String userIp = ctx.request().getParam("userIp"); Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { @@ -34,33 +32,53 @@ public final class POSTUserLogin implements Handler { return; } - if (!IPUtils.isValidIP(userIp)) { - ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid."); + 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."); return; } - if (user == null) { - // Will be saved in the User constructor - user = new User(uuid, username); - } + User.findById(uuid, (user, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + return; + } else if (user == null) { + user = new User(uuid, username); + user.insert(); // TODO + } - Server actorServer = Server.findById(actor.getName()); + User finalUser = user; - IPLogEntry ipLogEntry = IPLogEntry.findByUserAndIpSync(user, userIp); + 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 + } - // 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); - APIv3.respondJson(ctx, user.getLoginInfo(actorServer)); + finalUser.updateUsername(username, (ignored, error3) -> { + if (error3 != null) { + ErrorUtils.respondInternalError(ctx, error3); + } else { + finalUser.getLoginInfo(((ServerActor) actor).getServer(), (loginInfo, error4) -> { + if (error4 != null) { + ErrorUtils.respondInternalError(ctx, error4); + } else { + APIv3.respondJson(ctx, loginInfo); + } + }); + } + }); + }); + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java index 65ebc15..f2a93b4 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java @@ -6,7 +6,6 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -24,7 +23,7 @@ public final class POSTUserNotify implements Handler { } if (user.getEmail() == null) { - ErrorUtils.respondGeneric(ctx, "User provided does not have email set."); + ErrorUtils.respondInvalidInput(ctx, "User provided does not have email set."); return; } @@ -47,20 +46,17 @@ public final class POSTUserNotify implements Handler { bodyReplacements.put(key, values[0]); });*/ - try { - Notification notification = new Notification(template, subjectReplacements, bodyReplacements); + Notification notification = new Notification(template, subjectReplacements, bodyReplacements); - BlockingCallback callback = new BlockingCallback<>(); - notification.sendAsEmail(user.getEmail(), callback); - callback.get(); - - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true - )); - } catch (Exception ex) { - ex.printStackTrace(); - ErrorUtils.respondGeneric(ctx, "Failed to send notification"); - } + notification.sendAsEmail(user.getEmail(), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true + )); + } + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java index 6aec42b..9a28e22 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java @@ -6,7 +6,6 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.unsorted.Notification; import net.frozenorb.apiv3.utils.ErrorUtils; @@ -40,12 +39,12 @@ public final class POSTUserRegister implements Handler { String email = ctx.request().getParam("email"); if (!VALID_EMAIL_PATTERN.matcher(email).matches()) { - ErrorUtils.respondGeneric(ctx, email + " is not a valid email."); + ErrorUtils.respondInvalidInput(ctx, email + " is not a valid email."); return; } if (user.getEmailToken() != null && (System.currentTimeMillis() - user.getEmailTokenSetAt().getTime()) < TimeUnit.DAYS.toMillis(2)) { - ErrorUtils.respondGeneric(ctx, "We just recently sent you a confirmation email. Please wait before trying to register again."); + ErrorUtils.respondGeneric(ctx, 200, "We just recently sent you a confirmation email. Please wait before trying to register again."); return; } @@ -62,17 +61,15 @@ public final class POSTUserRegister implements Handler { Notification notification = new Notification(NotificationTemplate.findByIdSync("email-confirmation"), replacements, replacements); - try { - BlockingCallback callback = new BlockingCallback<>(); - notification.sendAsEmail(user.getEmail(), callback); - callback.get(); - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true - )); - } catch (Exception ex) { - ex.printStackTrace(); - ErrorUtils.respondGeneric(ctx, "Failed to send confirmation email. Please contact a MineHQ staff member."); - } + notification.sendAsEmail(user.getEmail(), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true + )); + } + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java index 1725563..386e406 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java @@ -24,7 +24,7 @@ public final class POSTUserSetupTOTP implements Handler { return; } - GoogleAuthenticatorKey generated = TOTPUtils.generateTOTPKey(); + GoogleAuthenticatorKey generated = TOTPUtils.generateTOTPSecret(); user.setTotpSecret(generated.getKey()); user.save(); diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java index 82964e6..bf1a163 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java @@ -2,14 +2,12 @@ package net.frozenorb.apiv3.routes.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; -import io.vertx.core.cli.converters.BooleanConverter; import io.vertx.ext.web.RoutingContext; -import io.vertx.ext.web.handler.BodyHandler; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IPUtils; +import net.frozenorb.apiv3.utils.IpUtils; import net.frozenorb.apiv3.utils.TOTPUtils; import java.util.concurrent.TimeUnit; @@ -31,8 +29,8 @@ public final class POSTUserVerifyTOTP implements Handler { String userIp = ctx.request().getParam("userIp"); - if (!IPUtils.isValidIP(userIp)) { - ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid."); + if (!IpUtils.isValidIp(userIp)) { + ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid."); return; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java index f18d2e7..3ab4719 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java @@ -26,18 +26,18 @@ public final class PUTUserMeta implements Handler { return; } - Document data = Document.parse(ctx.getBodyAsString()); + Document reqJson = Document.parse(ctx.getBodyAsString()); UserMetaEntry metaEntry = UserMetaEntry.findByUserAndGroupSync(user, serverGroup); if (metaEntry == null) { - metaEntry = new UserMetaEntry(user, serverGroup, data); + metaEntry = new UserMetaEntry(user, serverGroup, reqJson); metaEntry.insert(); } else { - metaEntry.setData(data); + metaEntry.setData(reqJson); metaEntry.save(); } - APIv3.respondJson(ctx, data); + APIv3.respondJson(ctx, reqJson); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java b/src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java deleted file mode 100644 index 3f405aa..0000000 --- a/src/main/java/net/frozenorb/apiv3/serialization/MineHQCodecProvider.java +++ /dev/null @@ -1,40 +0,0 @@ -package net.frozenorb.apiv3.serialization; - -import org.bson.BsonReader; -import org.bson.BsonWriter; -import org.bson.codecs.Codec; -import org.bson.codecs.DecoderContext; -import org.bson.codecs.EncoderContext; -import org.bson.codecs.configuration.CodecProvider; -import org.bson.codecs.configuration.CodecRegistry; - -import java.util.UUID; - -public final class MineHQCodecProvider implements CodecProvider { - - public Codec get(Class clazz, CodecRegistry codecRegistry) { - if (clazz == UUID.class) { - return (Codec) new Codec() { - - @Override - public UUID decode(BsonReader bsonReader, DecoderContext decoderContext) { - return UUID.fromString(bsonReader.readString()); - } - - @Override - public void encode(BsonWriter bsonWriter, UUID uuid, EncoderContext encoderContext) { - bsonWriter.writeString(uuid == null ? null : uuid.toString()); - } - - @Override - public Class getEncoderClass() { - return UUID.class; - } - - }; - } else { - return null; - } - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/serialization/DateTypeAdapter.java b/src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java similarity index 93% rename from src/main/java/net/frozenorb/apiv3/serialization/DateTypeAdapter.java rename to src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java index 23373ed..a2c5db7 100644 --- a/src/main/java/net/frozenorb/apiv3/serialization/DateTypeAdapter.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.serialization; +package net.frozenorb.apiv3.serialization.gson; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; diff --git a/src/main/java/net/frozenorb/apiv3/serialization/ExcludeFromReplies.java b/src/main/java/net/frozenorb/apiv3/serialization/gson/ExcludeFromReplies.java similarity index 84% rename from src/main/java/net/frozenorb/apiv3/serialization/ExcludeFromReplies.java rename to src/main/java/net/frozenorb/apiv3/serialization/gson/ExcludeFromReplies.java index eb45468..3e46528 100644 --- a/src/main/java/net/frozenorb/apiv3/serialization/ExcludeFromReplies.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/gson/ExcludeFromReplies.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.serialization; +package net.frozenorb.apiv3.serialization.gson; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/net/frozenorb/apiv3/serialization/FollowAnnotationExclusionStrategy.java b/src/main/java/net/frozenorb/apiv3/serialization/gson/FollowAnnotationExclusionStrategy.java similarity index 90% rename from src/main/java/net/frozenorb/apiv3/serialization/FollowAnnotationExclusionStrategy.java rename to src/main/java/net/frozenorb/apiv3/serialization/gson/FollowAnnotationExclusionStrategy.java index 77d116f..6deee9b 100644 --- a/src/main/java/net/frozenorb/apiv3/serialization/FollowAnnotationExclusionStrategy.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/gson/FollowAnnotationExclusionStrategy.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.serialization; +package net.frozenorb.apiv3.serialization.gson; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; diff --git a/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java b/src/main/java/net/frozenorb/apiv3/serialization/jackson/UUIDJsonDeserializer.java similarity index 91% rename from src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java rename to src/main/java/net/frozenorb/apiv3/serialization/jackson/UUIDJsonDeserializer.java index 155737a..35c1af5 100644 --- a/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonDeserializer.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/jackson/UUIDJsonDeserializer.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.serialization; +package net.frozenorb.apiv3.serialization.jackson; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java b/src/main/java/net/frozenorb/apiv3/serialization/jackson/UUIDJsonSerializer.java similarity index 91% rename from src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java rename to src/main/java/net/frozenorb/apiv3/serialization/jackson/UUIDJsonSerializer.java index 5f18aa4..c81e401 100644 --- a/src/main/java/net/frozenorb/apiv3/serialization/UUIDJsonSerializer.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/jackson/UUIDJsonSerializer.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.serialization; +package net.frozenorb.apiv3.serialization.jackson; import com.fasterxml.jackson.core.JsonGenerator; import com.fasterxml.jackson.core.JsonProcessingException; diff --git a/src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodec.java b/src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodec.java new file mode 100644 index 0000000..211956b --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodec.java @@ -0,0 +1,28 @@ +package net.frozenorb.apiv3.serialization.mongodb; + +import org.bson.BsonReader; +import org.bson.BsonWriter; +import org.bson.codecs.Codec; +import org.bson.codecs.DecoderContext; +import org.bson.codecs.EncoderContext; + +import java.util.UUID; + +public final class UUIDCodec implements Codec { + + @Override + public UUID decode(BsonReader bsonReader, DecoderContext decoderContext) { + return UUID.fromString(bsonReader.readString()); + } + + @Override + public void encode(BsonWriter bsonWriter, UUID uuid, EncoderContext encoderContext) { + bsonWriter.writeString(uuid == null ? null : uuid.toString()); + } + + @Override + public Class getEncoderClass() { + return UUID.class; + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodecProvider.java b/src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodecProvider.java new file mode 100644 index 0000000..b5bd0b8 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/serialization/mongodb/UUIDCodecProvider.java @@ -0,0 +1,19 @@ +package net.frozenorb.apiv3.serialization.mongodb; + +import org.bson.codecs.Codec; +import org.bson.codecs.configuration.CodecProvider; +import org.bson.codecs.configuration.CodecRegistry; + +import java.util.UUID; + +public final class UUIDCodecProvider implements CodecProvider { + + public Codec get(Class clazz, CodecRegistry codecRegistry) { + if (clazz == UUID.class) { + return (Codec) new UUIDCodec(); + } else { + return null; + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java index 08ea50b..70e967d 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java @@ -1,30 +1,17 @@ package net.frozenorb.apiv3.unsorted; -import com.cribbstechnologies.clients.mandrill.exception.RequestFailedException; -import com.cribbstechnologies.clients.mandrill.model.MandrillHtmlMessage; -import com.cribbstechnologies.clients.mandrill.model.MandrillMessageRequest; -import com.cribbstechnologies.clients.mandrill.model.MandrillRecipient; -import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest; +import com.google.common.collect.ImmutableList; +import com.google.common.net.MediaType; import com.mongodb.async.SingleResultCallback; -import com.twilio.sdk.TwilioRestException; -import com.twilio.sdk.resource.factory.MessageFactory; +import io.vertx.core.http.HttpHeaders; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.NotificationTemplate; -import net.frozenorb.apiv3.utils.MandrillUtils; -import net.frozenorb.apiv3.utils.TwillioUtils; -import org.apache.http.NameValuePair; -import org.apache.http.message.BasicNameValuePair; +import org.bson.Document; -import java.io.IOException; -import java.util.ArrayList; -import java.util.List; import java.util.Map; public final class Notification { - private static final MandrillMessagesRequest mandrillMessagesRequest = MandrillUtils.createMessagesRequest(); - private static final MessageFactory twillioMessageFactory = TwillioUtils.createMessageFactory(); - private final String subject; private final String body; @@ -33,60 +20,34 @@ public final class Notification { this.body = template.fillBody(bodyReplacements); } - public void sendAsEmail(String email, SingleResultCallback callback) throws IOException { - MandrillHtmlMessage message = new MandrillHtmlMessage(); + public void sendAsEmail(String email, SingleResultCallback callback) { + Document messageJson = new Document(); - message.setFrom_email("no-reply@minehq.com"); - message.setFrom_name("MineHQ Network"); - message.setSubject(subject); - message.setHtml(body); - message.setTo(new MandrillRecipient[] { - new MandrillRecipient(null, email) - }); + messageJson.put("html", body); + messageJson.put("subject", subject); + messageJson.put("from_email", "no-reply@minehq.com"); + messageJson.put("from_name", "MineHQ Network"); + messageJson.put("to", ImmutableList.of( + new Document("email", email).append("name", null).append("type", "to") + )); - APIv3.getVertxInstance().executeBlocking((future) -> { - try { - MandrillMessageRequest request = new MandrillMessageRequest(); - request.setMessage(message); - mandrillMessagesRequest.sendMessage(request); - APIv3.getStatsD().incrementCounter("apiv3.notification.email.success"); - future.succeeded(); - } catch (RequestFailedException ex) { - APIv3.getStatsD().incrementCounter("apiv3.notification.email.failure"); - future.fail(new IOException("Failed to send notification to user", ex)); - } - }, (result) -> { - if (result.succeeded()) { + Document bodyJson = new Document(); + bodyJson.put("key", APIv3.getConfig().getProperty("mandrill.apiKey")); + bodyJson.put("message", messageJson); + + APIv3.getHttpClient().post("mandrillapp.com", "/api/1.0/messages/send.json", (response) -> { + response.bodyHandler((body) -> { callback.onResult(null, null); - } else { - callback.onResult(null, result.cause()); - } - }); + }); + + response.exceptionHandler((error) -> { + callback.onResult(null, error); + }); + }).putHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString()).end(bodyJson.toJson()); } - public void sendAsText(String phoneNumber, SingleResultCallback callback) throws IOException { - List params = new ArrayList<>(); - - params.add(new BasicNameValuePair("To", phoneNumber)); - params.add(new BasicNameValuePair("From", "+13108795180")); - params.add(new BasicNameValuePair("Body", body)); - - APIv3.getVertxInstance().executeBlocking((future) -> { - try { - twillioMessageFactory.create(params); - APIv3.getStatsD().incrementCounter("apiv3.notification.text.success"); - future.succeeded(); - } catch (TwilioRestException ex) { - APIv3.getStatsD().incrementCounter("apiv3.notification.text.failure"); - future.fail(new IOException("Failed to send notification to user", ex)); - } - }, (result) -> { - if (result.succeeded()) { - callback.onResult(null, null); - } else { - callback.onResult(null, result.cause()); - } - }); + public void sendAsText(String phoneNumber, SingleResultCallback callback) { + callback.onResult(null, new UnsupportedOperationException()); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java index decc5b5..fb09d76 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java @@ -9,24 +9,27 @@ import net.frozenorb.apiv3.APIv3; public class ErrorUtils { public static void respondServerOnly(RoutingContext ctx) { - respondGeneric(ctx, "This action can only be performed when requested by a server."); + respondGeneric(ctx, 400, "This action can only be performed when requested by a server."); } public static void respondNotFound(RoutingContext ctx, String itemType, String id) { - respondGeneric(ctx, "Not found: " + itemType + " with id " + id + " cannot be found."); + respondGeneric(ctx, 404, "Not found: " + itemType + " with id " + id + " cannot be found."); } public static void respondInvalidInput(RoutingContext ctx, String message) { - respondGeneric(ctx, "Invalid input: " + message + "."); + respondGeneric(ctx, 400, "Invalid input: " + message + "."); } public static void respondRequiredInput(RoutingContext ctx, String field) { - respondGeneric(ctx, "Field \"" + field + "\" is required."); + respondGeneric(ctx, 400, "Field \"" + field + "\" is required."); } - public static void respondGeneric(RoutingContext ctx, String message) { - // TODO: Proper status codes - APIv3.respondJson(ctx, 400, ImmutableMap.of( + public static void respondInternalError(RoutingContext ctx, Throwable error) { + respondGeneric(ctx, 500, "Internal error: " + error.getClass().getSimpleName()); + } + + public static void respondGeneric(RoutingContext ctx, int code, String message) { + APIv3.respondJson(ctx, code, ImmutableMap.of( "success", false, "message", message )); diff --git a/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java b/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java index 7f868e9..b4d9be1 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java @@ -5,7 +5,7 @@ import lombok.experimental.UtilityClass; import java.util.regex.Pattern; @UtilityClass -public class IPUtils { +public class IpUtils { private static final Pattern VALID_IP_PATTERN = Pattern.compile( "^([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + @@ -13,7 +13,7 @@ public class IPUtils { "([01]?\\d\\d?|2[0-4]\\d|25[0-5])\\." + "([01]?\\d\\d?|2[0-4]\\d|25[0-5])$"); - public static boolean isValidIP(String ip) { + public static boolean isValidIp(String ip) { return ip != null && VALID_IP_PATTERN.matcher(ip).matches(); } diff --git a/src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java deleted file mode 100644 index 5ba1de2..0000000 --- a/src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java +++ /dev/null @@ -1,32 +0,0 @@ -package net.frozenorb.apiv3.utils; - -import com.cribbstechnologies.clients.mandrill.request.MandrillMessagesRequest; -import com.cribbstechnologies.clients.mandrill.request.MandrillRESTRequest; -import com.cribbstechnologies.clients.mandrill.util.MandrillConfiguration; -import com.fasterxml.jackson.databind.ObjectMapper; -import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.APIv3; -import org.apache.http.impl.client.HttpClientBuilder; - -@UtilityClass -public class MandrillUtils { - - public static MandrillMessagesRequest createMessagesRequest() { - MandrillConfiguration config = new MandrillConfiguration(); - - config.setApiKey(APIv3.getConfig().getProperty("mandrill.apiKey")); - config.setApiVersion("1.0"); - config.setBaseURL("https://mandrillapp.com/api"); - - MandrillRESTRequest request = new MandrillRESTRequest(); - - request.setConfig(config); - request.setObjectMapper(new ObjectMapper()); - request.setHttpClient(HttpClientBuilder.create().build()); - - MandrillMessagesRequest messagesRequest = new MandrillMessagesRequest(); - messagesRequest.setRequest(request); - return messagesRequest; - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java index f297395..271c219 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java @@ -3,9 +3,9 @@ package net.frozenorb.apiv3.utils; import com.mongodb.async.SingleResultCallback; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.unsorted.BlockingCallback; import org.bson.Document; +import java.io.IOException; import java.util.UUID; @UtilityClass @@ -18,19 +18,16 @@ public class MojangUtils { String name = resJson.getString("name"); if (name == null) { - APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.rateLimited"); - callback.onResult(null, new RuntimeException("Hit Mojang API rate limit: " + resJson.toJson())); + callback.onResult(null, new IOException("Hit Mojang API rate limit: " + resJson.toJson())); } else { - APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.success"); callback.onResult(name, null); } }); response.exceptionHandler((error) -> { - APIv3.getStatsD().incrementCounter("apiv3.mojang.sessionServer.failure"); callback.onResult(null, error); }); - }); + }).end(); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java b/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java index 4081811..f097566 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java @@ -1,12 +1,9 @@ package net.frozenorb.apiv3.utils; import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Rank; -import java.util.ArrayList; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -66,49 +63,4 @@ public class PermissionUtils { return result; } - public static Map> fromLegacy(String defaultGroup, String customGroup) { - Map> defaultPerms = legacyServerGroupToPerms(APIv3.getGson().fromJson(defaultGroup, HashMap.class)); - Map> customPerms = legacyServerGroupToPerms(APIv3.getGson().fromJson(customGroup, HashMap.class)); - - for (Map.Entry> customPerm : customPerms.entrySet()) { - List original = defaultPerms.get(customPerm.getKey()); - - original.addAll(customPerm.getValue()); - - defaultPerms.put(customPerm.getKey(), new ArrayList<>(ImmutableSet.copyOf(original))); - } - - defaultPerms.remove("coowner"); - defaultPerms.remove("allow-vpns"); - defaultPerms.remove("head-admin"); - defaultPerms.remove("registered"); - defaultPerms.remove("mvp"); - defaultPerms.remove("super-head-admin"); - defaultPerms.remove("trial-mod"); - defaultPerms.remove("forcedeathkick"); - return defaultPerms; - } - - private static Map> legacyServerGroupToPerms(Map group) { - Map> result = new HashMap<>(); - Map permissions = (Map) group.get("permissions"); - - for (Map.Entry entry : permissions.entrySet()) { - List perms = (List) ((Map) entry.getValue()).get("grant"); - String rank = entry.getKey(); - - if (rank.equalsIgnoreCase("unban") || rank.equalsIgnoreCase("pass") || rank.equalsIgnoreCase("pink") || rank.equalsIgnoreCase("jrdev")) { - continue; - } else if (rank.equalsIgnoreCase("high_roller")) { - rank = "high-roller"; - } else if (rank.equalsIgnoreCase("dev")) { - rank = "developer"; - } - - result.put(rank, perms); - } - - return result; - } - } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java b/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java index 1f8b6b3..12feba0 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java @@ -5,44 +5,35 @@ import com.warrenstrange.googleauth.GoogleAuthenticator; import com.warrenstrange.googleauth.GoogleAuthenticatorConfig; import com.warrenstrange.googleauth.GoogleAuthenticatorKey; import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator; -import io.vertx.redis.RedisClient; -import io.vertx.redis.RedisOptions; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; import java.util.concurrent.TimeUnit; -import java.util.function.BooleanSupplier; @UtilityClass public class TOTPUtils { private static GoogleAuthenticator googleAuthenticator = new GoogleAuthenticator(new GoogleAuthenticatorConfig.GoogleAuthenticatorConfigBuilder().setWindowSize(10).build()); - public static GoogleAuthenticatorKey generateTOTPKey() { + public static GoogleAuthenticatorKey generateTOTPSecret() { return googleAuthenticator.createCredentials(); } public static boolean authorizeUser(User user, int code) { - boolean authorized = googleAuthenticator.authorize(user.getTotpSecret(), code); - - if (!authorized) { - APIv3.getStatsD().incrementCounter("apiv3.totp.failure"); - } - - return authorized; + return googleAuthenticator.authorize(user.getTotpSecret(), code); } - public static String getQRCodeURL(User user, GoogleAuthenticatorKey key) { + public static String getQRCodeURL(User user, GoogleAuthenticatorKey secret) { return GoogleAuthenticatorQRGenerator.getOtpAuthURL( "MineHQ Network", user.getLastUsername(), - key + secret ); } public static void isPreAuthorized(User user, String ip, SingleResultCallback callback) { - APIv3.getRedisClient().exists(user.getId() + ":preAuthorizedIP:" + ip.toLowerCase(), (result) -> { + APIv3.getRedisClient().exists(user.getId() + ":preAuthorizedIp:" + ip.toLowerCase(), (result) -> { if (result.succeeded()) { callback.onResult(result.result() == 1 , null); } else { @@ -52,7 +43,7 @@ public class TOTPUtils { } public static void markPreAuthorized(User user, String ip, long duration, TimeUnit unit, SingleResultCallback callback) { - String key = user.getId() + ":preAuthorizedIP:" + ip.toLowerCase(); + String key = user.getId() + ":preAuthorizedIp:" + ip.toLowerCase(); APIv3.getRedisClient().set(key, "", (result) -> { if (result.succeeded()) { diff --git a/src/main/java/net/frozenorb/apiv3/utils/TwillioUtils.java b/src/main/java/net/frozenorb/apiv3/utils/TwillioUtils.java deleted file mode 100644 index 9021c6a..0000000 --- a/src/main/java/net/frozenorb/apiv3/utils/TwillioUtils.java +++ /dev/null @@ -1,22 +0,0 @@ -package net.frozenorb.apiv3.utils; - -import com.twilio.sdk.TwilioRestClient; -import com.twilio.sdk.resource.factory.MessageFactory; -import com.twilio.sdk.resource.instance.Account; -import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.APIv3; - -@UtilityClass -public class TwillioUtils { - - public static MessageFactory createMessageFactory() { - TwilioRestClient twillioClient = new TwilioRestClient( - APIv3.getConfig().getProperty("twillio.accountSID"), - APIv3.getConfig().getProperty("twillio.authToken") - ); - - Account account = twillioClient.getAccount(); - return account.getMessageFactory(); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java b/src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java index 9a50a64..341dc57 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java @@ -1,7 +1,6 @@ package net.frozenorb.apiv3.utils; import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.APIv3; import java.util.UUID; @@ -9,13 +8,7 @@ import java.util.UUID; public class UUIDUtils { public static boolean isAcceptableUUID(UUID uuid) { - boolean acceptable = uuid.version() == 4; - - if (!acceptable) { - APIv3.getStatsD().incrementCounter("apiv3.uuid.invalid"); - } - - return acceptable; + return uuid.version() == 4; } } \ No newline at end of file From 78762262c76eb48bb7aebf86c23e46d618b2902b Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 16 Jun 2016 10:29:33 -0400 Subject: [PATCH 5/8] Refactor package names, add ip bans --- apiv3.properties | 2 +- src/main/java/net/frozenorb/apiv3/APIv3.java | 61 ++++----- .../apiv3/{actors => actor}/Actor.java | 2 +- .../net/frozenorb/apiv3/actor/ActorType.java | 7 + .../apiv3/actor/actors/BungeeActor.java | 23 ++++ .../apiv3/{ => actor}/actors/ServerActor.java | 6 +- .../{ => actor}/actors/UnknownActor.java | 5 +- .../apiv3/{ => actor}/actors/UserActor.java | 6 +- .../{ => actor}/actors/WebsiteActor.java | 5 +- .../net/frozenorb/apiv3/actors/ActorType.java | 7 - .../apiv3/actors/BungeeCordActor.java | 20 --- .../frozenorb/apiv3/auditLog/AuditLog.java | 6 +- .../apiv3/auditLog/AuditLogActionType.java | 2 +- .../V2Importer.java} | 26 ++-- .../converters}/GrantConverter.java | 14 +- .../converters}/IpLogConverter.java | 14 +- .../converters}/PunishmentConverter.java | 18 +-- .../converters}/UserConverter.java | 14 +- .../apiv3/handler/ActorAttributeHandler.java | 123 ++++++++++++++++++ .../apiv3/handler/AuthorizationHandler.java | 37 ++++++ .../apiv3/handlers/ActorAttributeHandler.java | 110 ---------------- .../apiv3/handlers/AuthorizationHandler.java | 21 --- .../{models => model}/AuditLogEntry.java | 8 +- .../apiv3/{models => model}/Grant.java | 4 +- .../{models/IPBan.java => model/IpBan.java} | 20 +-- .../IPLogEntry.java => model/IpLogEntry.java} | 4 +- .../NotificationTemplate.java | 4 +- .../apiv3/{models => model}/Punishment.java | 18 ++- .../apiv3/{models => model}/Rank.java | 4 +- .../apiv3/{models => model}/Server.java | 4 +- .../apiv3/{models => model}/ServerGroup.java | 6 +- .../apiv3/{models => model}/User.java | 70 +++++++--- .../{models => model}/UserMetaEntry.java | 4 +- .../apiv3/{routes => route}/GETDump.java | 8 +- .../apiv3/{routes => route}/GETWhoAmI.java | 4 +- .../apiv3/{routes => route}/POSTMetrics.java | 2 +- .../announcements/GETAnnouncements.java | 6 +- .../announcements/PUTAnnouncements.java | 6 +- .../auditLog/GETAuditLog.java | 6 +- .../auditLog/POSTUserAuditLogEntry.java | 10 +- .../chatFilterList/GETChatFilterList.java | 2 +- .../{routes => route}/grants/DELETEGrant.java | 10 +- .../{routes => route}/grants/GETGrant.java | 4 +- .../{routes => route}/grants/GETGrants.java | 6 +- .../grants/GETUserGrants.java | 8 +- .../grants/POSTUserGrant.java | 12 +- .../{routes => route}/ipBans/DELETEIpBan.java | 10 +- .../{routes => route}/ipBans/GETIpBan.java | 4 +- .../{routes => route}/ipBans/GETIpBans.java | 6 +- .../{routes => route}/ipBans/GETIpIpBans.java | 9 +- .../{routes => route}/ipBans/POSTIpIpBan.java | 15 +-- .../ipLog/GETUserIpLog.java} | 8 +- .../DELETENotificationTemplate.java | 6 +- .../GETNotificationTemplate.java | 4 +- .../GETNotificationTemplates.java | 4 +- .../POSTNotificationTemplate.java | 4 +- .../PUTNotificationTemplate.java | 4 + .../punishments/DELETEPunishment.java | 10 +- .../punishments/DELETEUserPunishment.java | 10 +- .../punishments/GETPunishment.java | 4 +- .../punishments/GETPunishments.java | 6 +- .../punishments/GETUserPunishments.java | 8 +- .../punishments/POSTUserPunish.java | 18 ++- .../{routes => route}/ranks/DELETERank.java | 6 +- .../{routes => route}/ranks/GETRank.java | 4 +- .../{routes => route}/ranks/GETRanks.java | 4 +- .../{routes => route}/ranks/POSTRank.java | 4 +- .../frozenorb/apiv3/route/ranks/PUTRank.java | 4 + .../serverGroups/DELETEServerGroup.java | 6 +- .../serverGroups/GETServerGroup.java | 4 +- .../serverGroups/GETServerGroups.java | 4 +- .../serverGroups/POSTServerGroup.java | 4 +- .../route/serverGroups/PUTServerGroup.java | 4 + .../servers/DELETEServer.java | 6 +- .../{routes => route}/servers/GETServer.java | 4 +- .../{routes => route}/servers/GETServers.java | 4 +- .../{routes => route}/servers/POSTServer.java | 10 +- .../servers/POSTServerHeartbeat.java | 18 +-- .../apiv3/route/servers/PUTServer.java | 4 + .../users/DELETEUserMeta.java | 10 +- .../{routes => route}/users/GETStaff.java | 8 +- .../{routes => route}/users/GETUser.java | 4 +- .../users/GETUserDetails.java | 12 +- .../{routes => route}/users/GETUserMeta.java | 10 +- .../users/GETUserRequiresTOTP.java | 10 +- .../users/GETUserVerifyPassword.java | 6 +- .../users/POSTUserConfirmRegister.java | 6 +- .../users/POSTUserLeave.java | 6 +- .../users/POSTUserLogin.java | 35 +++-- .../users/POSTUserNotify.java | 8 +- .../users/POSTUserRegister.java | 8 +- .../users/POSTUserSetupTOTP.java | 8 +- .../users/POSTUserVerifyTOTP.java | 10 +- .../{routes => route}/users/PUTUserMeta.java | 10 +- .../PUTNotificationTemplate.java | 4 - .../frozenorb/apiv3/routes/ranks/PUTRank.java | 4 - .../routes/serverGroups/PUTServerGroup.java | 4 - .../apiv3/routes/servers/PUTServer.java | 4 - .../apiv3/unsorted/Notification.java | 2 +- .../apiv3/{utils => util}/ErrorUtils.java | 2 +- .../{utils/IPUtils.java => util/IpUtils.java} | 2 +- .../apiv3/{utils => util}/MojangUtils.java | 2 +- .../{utils => util}/PermissionUtils.java | 4 +- .../apiv3/{utils => util}/SyncUtils.java | 2 +- .../apiv3/{utils => util}/TOTPUtils.java | 4 +- .../apiv3/{utils => util}/TimeUtils.java | 2 +- .../apiv3/{utils => util}/UUIDUtils.java | 2 +- 107 files changed, 630 insertions(+), 538 deletions(-) rename src/main/java/net/frozenorb/apiv3/{actors => actor}/Actor.java (74%) create mode 100644 src/main/java/net/frozenorb/apiv3/actor/ActorType.java create mode 100644 src/main/java/net/frozenorb/apiv3/actor/actors/BungeeActor.java rename src/main/java/net/frozenorb/apiv3/{ => actor}/actors/ServerActor.java (72%) rename src/main/java/net/frozenorb/apiv3/{ => actor}/actors/UnknownActor.java (70%) rename src/main/java/net/frozenorb/apiv3/{ => actor}/actors/UserActor.java (85%) rename src/main/java/net/frozenorb/apiv3/{ => actor}/actors/WebsiteActor.java (70%) delete mode 100644 src/main/java/net/frozenorb/apiv3/actors/ActorType.java delete mode 100644 src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java rename src/main/java/net/frozenorb/apiv3/{conversion/V2Converter.java => dataImport/V2Importer.java} (68%) rename src/main/java/net/frozenorb/apiv3/{conversion => dataImport/converters}/GrantConverter.java (81%) rename src/main/java/net/frozenorb/apiv3/{conversion => dataImport/converters}/IpLogConverter.java (75%) rename src/main/java/net/frozenorb/apiv3/{conversion => dataImport/converters}/PunishmentConverter.java (79%) rename src/main/java/net/frozenorb/apiv3/{conversion => dataImport/converters}/UserConverter.java (79%) create mode 100644 src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java create mode 100644 src/main/java/net/frozenorb/apiv3/handler/AuthorizationHandler.java delete mode 100644 src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java delete mode 100644 src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java rename src/main/java/net/frozenorb/apiv3/{models => model}/AuditLogEntry.java (95%) rename src/main/java/net/frozenorb/apiv3/{models => model}/Grant.java (98%) rename src/main/java/net/frozenorb/apiv3/{models/IPBan.java => model/IpBan.java} (89%) rename src/main/java/net/frozenorb/apiv3/{models/IPLogEntry.java => model/IpLogEntry.java} (97%) rename src/main/java/net/frozenorb/apiv3/{models => model}/NotificationTemplate.java (97%) rename src/main/java/net/frozenorb/apiv3/{models => model}/Punishment.java (94%) rename src/main/java/net/frozenorb/apiv3/{models => model}/Rank.java (97%) rename src/main/java/net/frozenorb/apiv3/{models => model}/Server.java (97%) rename src/main/java/net/frozenorb/apiv3/{models => model}/ServerGroup.java (96%) rename src/main/java/net/frozenorb/apiv3/{models => model}/User.java (86%) rename src/main/java/net/frozenorb/apiv3/{models => model}/UserMetaEntry.java (97%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/GETDump.java (95%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/GETWhoAmI.java (86%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/POSTMetrics.java (90%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/announcements/GETAnnouncements.java (79%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/announcements/PUTAnnouncements.java (85%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/auditLog/GETAuditLog.java (84%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/auditLog/POSTUserAuditLogEntry.java (86%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/chatFilterList/GETChatFilterList.java (89%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/grants/DELETEGrant.java (87%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/grants/GETGrant.java (78%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/grants/GETGrants.java (84%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/grants/GETUserGrants.java (75%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/grants/POSTUserGrant.java (89%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ipBans/DELETEIpBan.java (87%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ipBans/GETIpBan.java (78%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ipBans/GETIpBans.java (84%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ipBans/GETIpIpBans.java (70%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ipBans/POSTIpIpBan.java (77%) rename src/main/java/net/frozenorb/apiv3/{routes/ipLog/GETUserIPLog.java => route/ipLog/GETUserIpLog.java} (74%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/notificationTemplates/DELETENotificationTemplate.java (79%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/notificationTemplates/GETNotificationTemplate.java (74%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/notificationTemplates/GETNotificationTemplates.java (73%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/notificationTemplates/POSTNotificationTemplate.java (83%) create mode 100644 src/main/java/net/frozenorb/apiv3/route/notificationTemplates/PUTNotificationTemplate.java rename src/main/java/net/frozenorb/apiv3/{routes => route}/punishments/DELETEPunishment.java (87%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/punishments/DELETEUserPunishment.java (89%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/punishments/GETPunishment.java (77%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/punishments/GETPunishments.java (84%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/punishments/GETUserPunishments.java (74%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/punishments/POSTUserPunish.java (86%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ranks/DELETERank.java (79%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ranks/GETRank.java (78%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ranks/GETRanks.java (76%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/ranks/POSTRank.java (90%) create mode 100644 src/main/java/net/frozenorb/apiv3/route/ranks/PUTRank.java rename src/main/java/net/frozenorb/apiv3/{routes => route}/serverGroups/DELETEServerGroup.java (79%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/serverGroups/GETServerGroup.java (76%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/serverGroups/GETServerGroups.java (74%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/serverGroups/POSTServerGroup.java (83%) create mode 100644 src/main/java/net/frozenorb/apiv3/route/serverGroups/PUTServerGroup.java rename src/main/java/net/frozenorb/apiv3/{routes => route}/servers/DELETEServer.java (79%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/servers/GETServer.java (78%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/servers/GETServers.java (76%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/servers/POSTServer.java (83%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/servers/POSTServerHeartbeat.java (93%) create mode 100644 src/main/java/net/frozenorb/apiv3/route/servers/PUTServer.java rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/DELETEUserMeta.java (82%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/GETStaff.java (88%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/GETUser.java (78%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/GETUserDetails.java (78%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/GETUserMeta.java (79%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/GETUserRequiresTOTP.java (88%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/GETUserVerifyPassword.java (87%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserConfirmRegister.java (95%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserLeave.java (87%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserLogin.java (71%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserNotify.java (91%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserRegister.java (93%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserSetupTOTP.java (85%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/POSTUserVerifyTOTP.java (91%) rename src/main/java/net/frozenorb/apiv3/{routes => route}/users/PUTUserMeta.java (83%) delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/ranks/PUTRank.java delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/serverGroups/PUTServerGroup.java delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/servers/PUTServer.java rename src/main/java/net/frozenorb/apiv3/{utils => util}/ErrorUtils.java (97%) rename src/main/java/net/frozenorb/apiv3/{utils/IPUtils.java => util/IpUtils.java} (94%) rename src/main/java/net/frozenorb/apiv3/{utils => util}/MojangUtils.java (96%) rename src/main/java/net/frozenorb/apiv3/{utils => util}/PermissionUtils.java (95%) rename src/main/java/net/frozenorb/apiv3/{utils => util}/SyncUtils.java (95%) rename src/main/java/net/frozenorb/apiv3/{utils => util}/TOTPUtils.java (97%) rename src/main/java/net/frozenorb/apiv3/{utils => util}/TimeUtils.java (96%) rename src/main/java/net/frozenorb/apiv3/{utils => util}/UUIDUtils.java (85%) diff --git a/apiv3.properties b/apiv3.properties index a00fa41..436214b 100644 --- a/apiv3.properties +++ b/apiv3.properties @@ -10,4 +10,4 @@ http.port=80 mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ bugsnag.apiKey=0e47fba8b825416b7cbc839066184509 auth.websiteApiKey=RVbp4hY6sCFVaf -auth.bungeeCordApiKey=6d9cf76dc9f0d23 \ No newline at end of file +auth.bungeeApiKey=6d9cf76dc9f0d23 \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 062bdd7..5a3e208 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -33,34 +33,35 @@ import io.vertx.redis.RedisClient; import io.vertx.redis.RedisOptions; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.handlers.ActorAttributeHandler; -import net.frozenorb.apiv3.handlers.AuthorizationHandler; -import net.frozenorb.apiv3.routes.GETDump; -import net.frozenorb.apiv3.routes.GETWhoAmI; -import net.frozenorb.apiv3.routes.POSTMetrics; -import net.frozenorb.apiv3.routes.announcements.GETAnnouncements; -import net.frozenorb.apiv3.routes.announcements.PUTAnnouncements; -import net.frozenorb.apiv3.routes.auditLog.GETAuditLog; -import net.frozenorb.apiv3.routes.auditLog.POSTUserAuditLogEntry; -import net.frozenorb.apiv3.routes.chatFilterList.GETChatFilterList; -import net.frozenorb.apiv3.routes.grants.*; -import net.frozenorb.apiv3.routes.ipBans.*; -import net.frozenorb.apiv3.routes.ipLog.GETUserIpLog; -import net.frozenorb.apiv3.routes.notificationTemplates.DELETENotificationTemplate; -import net.frozenorb.apiv3.routes.notificationTemplates.GETNotificationTemplate; -import net.frozenorb.apiv3.routes.notificationTemplates.GETNotificationTemplates; -import net.frozenorb.apiv3.routes.notificationTemplates.POSTNotificationTemplate; -import net.frozenorb.apiv3.routes.punishments.*; -import net.frozenorb.apiv3.routes.ranks.DELETERank; -import net.frozenorb.apiv3.routes.ranks.GETRank; -import net.frozenorb.apiv3.routes.ranks.GETRanks; -import net.frozenorb.apiv3.routes.ranks.POSTRank; -import net.frozenorb.apiv3.routes.serverGroups.DELETEServerGroup; -import net.frozenorb.apiv3.routes.serverGroups.GETServerGroup; -import net.frozenorb.apiv3.routes.serverGroups.GETServerGroups; -import net.frozenorb.apiv3.routes.serverGroups.POSTServerGroup; -import net.frozenorb.apiv3.routes.servers.*; -import net.frozenorb.apiv3.routes.users.*; +import net.frozenorb.apiv3.dataImport.V2Importer; +import net.frozenorb.apiv3.handler.ActorAttributeHandler; +import net.frozenorb.apiv3.handler.AuthorizationHandler; +import net.frozenorb.apiv3.route.GETDump; +import net.frozenorb.apiv3.route.GETWhoAmI; +import net.frozenorb.apiv3.route.POSTMetrics; +import net.frozenorb.apiv3.route.announcements.GETAnnouncements; +import net.frozenorb.apiv3.route.announcements.PUTAnnouncements; +import net.frozenorb.apiv3.route.auditLog.GETAuditLog; +import net.frozenorb.apiv3.route.auditLog.POSTUserAuditLogEntry; +import net.frozenorb.apiv3.route.chatFilterList.GETChatFilterList; +import net.frozenorb.apiv3.route.grants.*; +import net.frozenorb.apiv3.route.ipBans.*; +import net.frozenorb.apiv3.route.ipLog.GETUserIpLog; +import net.frozenorb.apiv3.route.notificationTemplates.DELETENotificationTemplate; +import net.frozenorb.apiv3.route.notificationTemplates.GETNotificationTemplate; +import net.frozenorb.apiv3.route.notificationTemplates.GETNotificationTemplates; +import net.frozenorb.apiv3.route.notificationTemplates.POSTNotificationTemplate; +import net.frozenorb.apiv3.route.punishments.*; +import net.frozenorb.apiv3.route.ranks.DELETERank; +import net.frozenorb.apiv3.route.ranks.GETRank; +import net.frozenorb.apiv3.route.ranks.GETRanks; +import net.frozenorb.apiv3.route.ranks.POSTRank; +import net.frozenorb.apiv3.route.serverGroups.DELETEServerGroup; +import net.frozenorb.apiv3.route.serverGroups.GETServerGroup; +import net.frozenorb.apiv3.route.serverGroups.GETServerGroups; +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.DateTypeAdapter; import net.frozenorb.apiv3.serialization.gson.FollowAnnotationExclusionStrategy; import net.frozenorb.apiv3.serialization.jackson.UUIDJsonDeserializer; @@ -100,9 +101,9 @@ public final class APIv3 extends AbstractVerticle { setupHttpServer(); setupHttpClient(); - /*V2Converter converter = new V2Converter("mongodb://158.69.126.126", "minehq"); + /*V2Importer converter = new V2Importer("mongodb://158.69.126.126", "minehq"); - converter.startConversion((ignored, error) -> { + converter.startImport((ignored, error) -> { if (error != null) { error.printStackTrace(); } diff --git a/src/main/java/net/frozenorb/apiv3/actors/Actor.java b/src/main/java/net/frozenorb/apiv3/actor/Actor.java similarity index 74% rename from src/main/java/net/frozenorb/apiv3/actors/Actor.java rename to src/main/java/net/frozenorb/apiv3/actor/Actor.java index 909b8b1..d41495d 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/Actor.java +++ b/src/main/java/net/frozenorb/apiv3/actor/Actor.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.actors; +package net.frozenorb.apiv3.actor; public interface Actor { diff --git a/src/main/java/net/frozenorb/apiv3/actor/ActorType.java b/src/main/java/net/frozenorb/apiv3/actor/ActorType.java new file mode 100644 index 0000000..84d6771 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/actor/ActorType.java @@ -0,0 +1,7 @@ +package net.frozenorb.apiv3.actor; + +public enum ActorType { + + WEBSITE, BUNGEE, SERVER, USER, UNKNOWN + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/actor/actors/BungeeActor.java b/src/main/java/net/frozenorb/apiv3/actor/actors/BungeeActor.java new file mode 100644 index 0000000..9237855 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/actor/actors/BungeeActor.java @@ -0,0 +1,23 @@ +package net.frozenorb.apiv3.actor.actors; + +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; + +public final class BungeeActor implements Actor { + + @Override + public boolean isAuthorized() { + return true; + } + + @Override + public String getName() { + return "Bungee"; + } + + @Override + public ActorType getType() { + return ActorType.BUNGEE; + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java b/src/main/java/net/frozenorb/apiv3/actor/actors/ServerActor.java similarity index 72% rename from src/main/java/net/frozenorb/apiv3/actors/ServerActor.java rename to src/main/java/net/frozenorb/apiv3/actor/actors/ServerActor.java index 30bbdb9..8e69fe6 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java +++ b/src/main/java/net/frozenorb/apiv3/actor/actors/ServerActor.java @@ -1,7 +1,9 @@ -package net.frozenorb.apiv3.actors; +package net.frozenorb.apiv3.actor.actors; import lombok.Getter; -import net.frozenorb.apiv3.models.Server; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; +import net.frozenorb.apiv3.model.Server; public final class ServerActor implements Actor { diff --git a/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java b/src/main/java/net/frozenorb/apiv3/actor/actors/UnknownActor.java similarity index 70% rename from src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java rename to src/main/java/net/frozenorb/apiv3/actor/actors/UnknownActor.java index e275a80..39705c1 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java +++ b/src/main/java/net/frozenorb/apiv3/actor/actors/UnknownActor.java @@ -1,4 +1,7 @@ -package net.frozenorb.apiv3.actors; +package net.frozenorb.apiv3.actor.actors; + +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; public final class UnknownActor implements Actor { diff --git a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java b/src/main/java/net/frozenorb/apiv3/actor/actors/UserActor.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/actors/UserActor.java rename to src/main/java/net/frozenorb/apiv3/actor/actors/UserActor.java index 41530ba..1f2ddeb 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java +++ b/src/main/java/net/frozenorb/apiv3/actor/actors/UserActor.java @@ -1,7 +1,9 @@ -package net.frozenorb.apiv3.actors; +package net.frozenorb.apiv3.actor.actors; import lombok.Getter; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.Permissions; public final class UserActor implements Actor { diff --git a/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java b/src/main/java/net/frozenorb/apiv3/actor/actors/WebsiteActor.java similarity index 70% rename from src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java rename to src/main/java/net/frozenorb/apiv3/actor/actors/WebsiteActor.java index ae0e518..9abed7d 100644 --- a/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java +++ b/src/main/java/net/frozenorb/apiv3/actor/actors/WebsiteActor.java @@ -1,4 +1,7 @@ -package net.frozenorb.apiv3.actors; +package net.frozenorb.apiv3.actor.actors; + +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; public final class WebsiteActor implements Actor { diff --git a/src/main/java/net/frozenorb/apiv3/actors/ActorType.java b/src/main/java/net/frozenorb/apiv3/actors/ActorType.java deleted file mode 100644 index 0307167..0000000 --- a/src/main/java/net/frozenorb/apiv3/actors/ActorType.java +++ /dev/null @@ -1,7 +0,0 @@ -package net.frozenorb.apiv3.actors; - -public enum ActorType { - - WEBSITE, BUNGEECORD, SERVER, USER, UNKNOWN - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java b/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java deleted file mode 100644 index c1fa682..0000000 --- a/src/main/java/net/frozenorb/apiv3/actors/BungeeCordActor.java +++ /dev/null @@ -1,20 +0,0 @@ -package net.frozenorb.apiv3.actors; - -public final class BungeeCordActor implements Actor { - - @Override - public boolean isAuthorized() { - return true; - } - - @Override - public String getName() { - return "BungeeCord"; - } - - @Override - public ActorType getType() { - return ActorType.BUNGEECORD; - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java index 77b6504..6dad953 100644 --- a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLog.java @@ -3,9 +3,9 @@ package net.frozenorb.apiv3.auditLog; import com.google.common.collect.ImmutableMap; import com.mongodb.async.SingleResultCallback; import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.model.User; import java.util.Map; diff --git a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java index d066eb6..c8f2d4e 100644 --- a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java +++ b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java @@ -1,7 +1,7 @@ package net.frozenorb.apiv3.auditLog; import com.mongodb.async.SingleResultCallback; -import net.frozenorb.apiv3.models.AuditLogEntry; +import net.frozenorb.apiv3.model.AuditLogEntry; public enum AuditLogActionType { diff --git a/src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java b/src/main/java/net/frozenorb/apiv3/dataImport/V2Importer.java similarity index 68% rename from src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java rename to src/main/java/net/frozenorb/apiv3/dataImport/V2Importer.java index 8aaa316..dc29a29 100644 --- a/src/main/java/net/frozenorb/apiv3/conversion/V2Converter.java +++ b/src/main/java/net/frozenorb/apiv3/dataImport/V2Importer.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.conversion; +package net.frozenorb.apiv3.dataImport; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoClients; @@ -6,6 +6,10 @@ import com.mongodb.async.client.MongoDatabase; import io.vertx.core.CompositeFuture; import io.vertx.core.Future; import lombok.extern.slf4j.Slf4j; +import net.frozenorb.apiv3.dataImport.converters.GrantConverter; +import net.frozenorb.apiv3.dataImport.converters.IpLogConverter; +import net.frozenorb.apiv3.dataImport.converters.PunishmentConverter; +import net.frozenorb.apiv3.dataImport.converters.UserConverter; import org.bson.types.ObjectId; import java.util.HashMap; @@ -13,18 +17,18 @@ import java.util.Map; import java.util.UUID; @Slf4j -public final class V2Converter { +public final class V2Importer { - private MongoDatabase importFrom; + private final MongoDatabase importFrom; - public V2Converter(String mongoIp, String database) { + public V2Importer(String mongoIp, String database) { importFrom = MongoClients.create(mongoIp).getDatabase(database); } - public void startConversion(SingleResultCallback callback) { - Map mongoIdToUUID = new HashMap<>(); + public void startImport(SingleResultCallback callback) { + Map oidToUniqueId = new HashMap<>(); - importFrom.getCollection("user").find().forEach(new UserConverter(mongoIdToUUID), (ignored, error) -> { + importFrom.getCollection("user").find().forEach(new UserConverter(oidToUniqueId), (ignored, error) -> { if (error != null) { callback.onResult(null, error); return; @@ -34,9 +38,9 @@ public final class V2Converter { Future grantsFuture = Future.future(); Future ipLogFuture = Future.future(); - importFrom.getCollection("punishment").find().forEach(new PunishmentConverter(mongoIdToUUID), new FutureCompatibilityCallback<>(punishmentsFuture)); - importFrom.getCollection("grant").find().forEach(new GrantConverter(mongoIdToUUID), new FutureCompatibilityCallback<>(grantsFuture)); - importFrom.getCollection("iplog").find().forEach(new IpLogConverter(mongoIdToUUID), new FutureCompatibilityCallback<>(ipLogFuture)); + importFrom.getCollection("punishment").find().forEach(new PunishmentConverter(oidToUniqueId), new FutureCompatibilityCallback<>(punishmentsFuture)); + importFrom.getCollection("grant").find().forEach(new GrantConverter(oidToUniqueId), new FutureCompatibilityCallback<>(grantsFuture)); + importFrom.getCollection("iplog").find().forEach(new IpLogConverter(oidToUniqueId), new FutureCompatibilityCallback<>(ipLogFuture)); CompositeFuture.all(punishmentsFuture, grantsFuture, ipLogFuture).setHandler((result) -> { if (result.succeeded()) { @@ -50,7 +54,7 @@ public final class V2Converter { private static class FutureCompatibilityCallback implements SingleResultCallback { - private Future future; + private final Future future; public FutureCompatibilityCallback(Future future) { this.future = future; diff --git a/src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java b/src/main/java/net/frozenorb/apiv3/dataImport/converters/GrantConverter.java similarity index 81% rename from src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java rename to src/main/java/net/frozenorb/apiv3/dataImport/converters/GrantConverter.java index ab24c1c..9f1bb24 100644 --- a/src/main/java/net/frozenorb/apiv3/conversion/GrantConverter.java +++ b/src/main/java/net/frozenorb/apiv3/dataImport/converters/GrantConverter.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.conversion; +package net.frozenorb.apiv3.dataImport.converters; import com.google.common.collect.ImmutableSet; import com.mongodb.Block; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.models.Grant; +import net.frozenorb.apiv3.model.Grant; import org.bson.Document; import org.bson.types.ObjectId; @@ -15,15 +15,15 @@ import java.util.UUID; @Slf4j public final class GrantConverter implements Block { - private Map mongoIdToUUID; + private final Map oidToUniqueId; - public GrantConverter(Map mongoIdToUUID) { - this.mongoIdToUUID = mongoIdToUUID; + public GrantConverter(Map oidToUniqueId) { + this.oidToUniqueId = oidToUniqueId; } @Override public void apply(Document grant) { - UUID target = mongoIdToUUID.get(((Map) grant.get("target")).get("$id")); + UUID target = oidToUniqueId.get(((Map) grant.get("target")).get("$id")); if (target == null) { return; @@ -46,7 +46,7 @@ public final class GrantConverter implements Block { grant.containsKey("scope") ? ImmutableSet.copyOf((Collection) grant.get("scope")) : ImmutableSet.of(), rank, grant.getDate("expires"), - grant.containsKey("addedBy") ? mongoIdToUUID.get(((Map) grant.get("addedBy")).get("$id")) : null, + grant.containsKey("addedBy") ? oidToUniqueId.get(((Map) grant.get("addedBy")).get("$id")) : null, grant.containsKey("created") ? grant.getDate("created") : new Date(), null, null, diff --git a/src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java b/src/main/java/net/frozenorb/apiv3/dataImport/converters/IpLogConverter.java similarity index 75% rename from src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java rename to src/main/java/net/frozenorb/apiv3/dataImport/converters/IpLogConverter.java index ad80c21..dcf648f 100644 --- a/src/main/java/net/frozenorb/apiv3/conversion/IpLogConverter.java +++ b/src/main/java/net/frozenorb/apiv3/dataImport/converters/IpLogConverter.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.conversion; +package net.frozenorb.apiv3.dataImport.converters; import com.mongodb.Block; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.models.IpLogEntry; -import net.frozenorb.apiv3.utils.IpUtils; +import net.frozenorb.apiv3.model.IpLogEntry; +import net.frozenorb.apiv3.util.IpUtils; import org.bson.Document; import org.bson.types.ObjectId; @@ -14,15 +14,15 @@ import java.util.UUID; @Slf4j public final class IpLogConverter implements Block { - private Map mongoIdToUUID; + private final Map oidToUniqueId; - public IpLogConverter(Map mongoIdToUUID) { - this.mongoIdToUUID = mongoIdToUUID; + public IpLogConverter(Map oidToUniqueId) { + this.oidToUniqueId = oidToUniqueId; } @Override public void apply(Document ipLogEntry) { - UUID user = mongoIdToUUID.get(((Map) ipLogEntry.get("user")).get("$id")); + UUID user = oidToUniqueId.get(((Map) ipLogEntry.get("user")).get("$id")); if (user == null || ipLogEntry.getString("ip") == null) { return; diff --git a/src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java b/src/main/java/net/frozenorb/apiv3/dataImport/converters/PunishmentConverter.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java rename to src/main/java/net/frozenorb/apiv3/dataImport/converters/PunishmentConverter.java index 317851d..e260107 100644 --- a/src/main/java/net/frozenorb/apiv3/conversion/PunishmentConverter.java +++ b/src/main/java/net/frozenorb/apiv3/dataImport/converters/PunishmentConverter.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.conversion; +package net.frozenorb.apiv3.dataImport.converters; import com.google.common.collect.ImmutableMap; import com.mongodb.Block; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.models.Punishment; +import net.frozenorb.apiv3.actor.ActorType; +import net.frozenorb.apiv3.model.Punishment; import org.bson.Document; import org.bson.types.ObjectId; @@ -16,15 +16,15 @@ import java.util.UUID; @Slf4j public final class PunishmentConverter implements Block { - private Map mongoIdToUUID; + private final Map oidToUniqueId; - public PunishmentConverter(Map mongoIdToUUID) { - this.mongoIdToUUID = mongoIdToUUID; + public PunishmentConverter(Map oidToUniqueId) { + this.oidToUniqueId = oidToUniqueId; } @Override public void apply(Document punishment) { - UUID target = mongoIdToUUID.get(((Map) punishment.get("user")).get("$id")); + UUID target = oidToUniqueId.get(((Map) punishment.get("user")).get("$id")); if (target == null) { return; @@ -43,11 +43,11 @@ public final class PunishmentConverter implements Block { punishment.getDate("expires"), punishment.containsKey("meta") ? (punishment.get("meta") instanceof List ? ImmutableMap.of() : (Document) punishment.get("meta")) : ImmutableMap.of(), null, - punishment.containsKey("addedBy") ? mongoIdToUUID.get(((Map) punishment.get("addedBy")).get("$id")) : null, + punishment.containsKey("addedBy") ? oidToUniqueId.get(((Map) punishment.get("addedBy")).get("$id")) : null, (Date) punishment.getDate("created").clone(), punishment.containsKey("createdOn") ? String.valueOf(((Map) punishment.get("createdOn")).get("$id")) : "Website", punishment.containsKey("createdOn") ? ActorType.SERVER : ActorType.WEBSITE, - punishment.containsKey("removedBy") ? (((Map) punishment.get("removedBy")).get("$ref").equals("user") ? mongoIdToUUID.get(((Map) punishment.get("removedBy")).get("$id")) : null) : null, + punishment.containsKey("removedBy") ? (((Map) punishment.get("removedBy")).get("$ref").equals("user") ? oidToUniqueId.get(((Map) punishment.get("removedBy")).get("$id")) : null) : null, punishment.containsKey("removedBy") ? (punishment.containsKey("removedAt") ? punishment.getDate("removedAt") : punishment.getDate("created")) : null, punishment.containsKey("removedBy") ? punishment.getString("removalReason").toString() : null ); diff --git a/src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java b/src/main/java/net/frozenorb/apiv3/dataImport/converters/UserConverter.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java rename to src/main/java/net/frozenorb/apiv3/dataImport/converters/UserConverter.java index ffb9223..9b1a47e 100644 --- a/src/main/java/net/frozenorb/apiv3/conversion/UserConverter.java +++ b/src/main/java/net/frozenorb/apiv3/dataImport/converters/UserConverter.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.conversion; +package net.frozenorb.apiv3.dataImport.converters; import com.google.common.collect.ImmutableMap; import com.mongodb.Block; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.UUIDUtils; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.UUIDUtils; import org.bson.Document; import org.bson.types.ObjectId; @@ -14,10 +14,10 @@ import java.util.UUID; @Slf4j public final class UserConverter implements Block { - private Map mongoIdToUUID; + private final Map oidToUniqueId; - public UserConverter(Map mongoIdToUUID) { - this.mongoIdToUUID = mongoIdToUUID; + public UserConverter(Map oidToUniqueId) { + this.oidToUniqueId = oidToUniqueId; } @Override @@ -34,7 +34,7 @@ public final class UserConverter implements Block { return; } - mongoIdToUUID.put(user.getObjectId("_id"), uuid); + oidToUniqueId.put(user.getObjectId("_id"), uuid); User created = new User( uuid, diff --git a/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java b/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java new file mode 100644 index 0000000..ad776c0 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java @@ -0,0 +1,123 @@ +package net.frozenorb.apiv3.handler; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.actor.actors.*; +import net.frozenorb.apiv3.model.Server; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.Base64; + +public final class ActorAttributeHandler implements Handler { + + @Override + public void handle(RoutingContext ctx) { + String authorizationHeader = ctx.request().getHeader("Authorization"); + String mhqAuthorizationHeader = ctx.request().getHeader("MHQ-Authorization"); + + if (authorizationHeader != null) { + processBasicAuthorization(authorizationHeader, ctx); + } else if (mhqAuthorizationHeader != null) { + processMHQAuthorization(mhqAuthorizationHeader, ctx); + } else { + processNoAuthorization(ctx); + } + } + + private void processBasicAuthorization(String authHeader, RoutingContext ctx) { + String encodedHeader = authHeader.substring("Basic ".length()); + String decodedHeader = new String(Base64.getDecoder().decode(encodedHeader.getBytes())); + String[] splitHeader = decodedHeader.split(":"); + + if (splitHeader.length != 2) { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize."); + return; + } + + String username = splitHeader[0]; + String password = splitHeader[1]; + + User.findByLastUsername(username, (user, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + return; + } + + if (user != null && user.checkPassword(password)) { + ctx.put("actor", new UserActor(user)); + ctx.next(); + } else { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + username + "."); + } + }); + } + + private void processMHQAuthorization(String authHeader, RoutingContext ctx) { + String[] splitHeader = authHeader.split(" "); + + if (splitHeader.length < 2) { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize."); + return; + } + + String type = splitHeader[0]; + + switch (type.toLowerCase()) { + case "website": + String givenWebsiteKey = splitHeader[1]; + String properWebsiteKey = APIv3.getConfig().getProperty("auth.websiteApiKey"); + + if (givenWebsiteKey.equals(properWebsiteKey)) { + ctx.put("actor", new WebsiteActor()); + ctx.next(); + } else { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as website."); + } + + break; + case "server": + Server server = Server.findById(splitHeader[1]); + + if (server == null) { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize: Server " + splitHeader[1] + " not found"); + return; + } + + if (splitHeader.length != 3) { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize: Key not provided"); + return; + } + + String givenServerKey = splitHeader[2]; + + if (givenServerKey.equals(server.getApiKey())) { + ctx.put("actor", new ServerActor(server)); + ctx.next(); + } else { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + server.getId() + "."); + } + + break; + case "bungee": + String givenBungeeKey = splitHeader[1]; + String properBungeeKey = APIv3.getConfig().getProperty("auth.bungeeApiKey"); + + if (givenBungeeKey.equals(properBungeeKey)) { + ctx.put("actor", new BungeeActor()); + ctx.next(); + } else { + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as bungee."); + } + + break; + } + } + + public void processNoAuthorization(RoutingContext ctx) { + ctx.put("actor", new UnknownActor()); + ctx.next(); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/handler/AuthorizationHandler.java b/src/main/java/net/frozenorb/apiv3/handler/AuthorizationHandler.java new file mode 100644 index 0000000..e14a97f --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/handler/AuthorizationHandler.java @@ -0,0 +1,37 @@ +package net.frozenorb.apiv3.handler; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; +import net.frozenorb.apiv3.actor.actors.ServerActor; +import net.frozenorb.apiv3.model.Server; +import net.frozenorb.apiv3.util.ErrorUtils; + +public final class AuthorizationHandler implements Handler { + + @Override + public void handle(RoutingContext ctx) { + Actor actor = ctx.get("actor"); + + if (!actor.isAuthorized()) { + ErrorUtils.respondGeneric(ctx, 403, "Please authorize as an approved actor. You're currently authorized as " + actor.getName() + " (" + actor.getType() + ")"); + return; + } + + if (actor.getType() == ActorType.SERVER) { + Server server = ((ServerActor) actor).getServer(); + String[] serverAddress = server.getServerIp().split(":"); + String expectedHost = serverAddress[0]; + String remoteHost = ctx.request().remoteAddress().host(); + + if (!expectedHost.equals(remoteHost)) { + ErrorUtils.respondGeneric(ctx, 403, "Failed to authorize: Cannot authorize as " + server.getId() + " from given ip."); + return; + } + } + + ctx.next(); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java b/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java deleted file mode 100644 index 0446ca9..0000000 --- a/src/main/java/net/frozenorb/apiv3/handlers/ActorAttributeHandler.java +++ /dev/null @@ -1,110 +0,0 @@ -package net.frozenorb.apiv3.handlers; - -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; -import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.*; -import net.frozenorb.apiv3.models.Server; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; - -import java.util.Base64; - -public final class ActorAttributeHandler implements Handler { - - @Override - public void handle(RoutingContext ctx) { - String authorizationHeader = ctx.request().getHeader("Authorization"); - String mhqAuthorizationHeader = ctx.request().getHeader("MHQ-Authorization"); - - if (authorizationHeader != null) { - processBasicAuthorization(authorizationHeader, ctx); - } else if (mhqAuthorizationHeader != null) { - processMHQAuthorization(mhqAuthorizationHeader, ctx); - } else { - processNoAuthorization(ctx); - } - } - - // TODO: Cleanup - private void processBasicAuthorization(String authHeader, RoutingContext ctx) { - String encodedHeader = authHeader.substring("Basic ".length()); - String decodedHeader = new String(Base64.getDecoder().decode(encodedHeader.getBytes())); - String[] credentials = decodedHeader.split(":"); - - if (credentials.length == 2) { - User.findByLastUsername(credentials[0], (user, error) -> { - if (error != null) { - ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + credentials[0] + "."); - return; - } - - String password = credentials[1]; - - if (user != null && user.getPassword() != null && user.checkPassword(password)) { - ctx.put("actor", new UserActor(user)); - ctx.next(); - return; - } else { - ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + credentials[0] + "."); - return; - } - }); - } else { - ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + credentials[0] + "."); - } - } - - // TODO: Cleanup - private void processMHQAuthorization(String authHeader, RoutingContext ctx) { - String[] split = authHeader.split(" "); - - if (split.length >= 2) { - String type = split[0]; - - if (type.equals("Website") && split.length == 2) { - String givenKey = split[1]; - String properKey = APIv3.getConfig().getProperty("auth.websiteApiKey"); - - if (givenKey.equals(properKey)) { - ctx.put("actor", new WebsiteActor()); - ctx.next(); - return; - } - } else if (type.equals("Server") && split.length == 3) { - Server server = Server.findById(split[1]); - - if (server == null) { - ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize: Server " + split[1] + " not found"); - return; - } - - String givenKey = split[2]; - String properKey = server.getApiKey(); - - if (givenKey.equals(properKey)) { - ctx.put("actor", new ServerActor(server)); - ctx.next(); - return; - } - } else if (type.equals("BungeeCord") && split.length == 2) { - String givenKey = split[1]; - String properKey = APIv3.getConfig().getProperty("auth.bungeeCordApiKey"); - - if (givenKey.equals(properKey)) { - ctx.put("actor", new BungeeCordActor()); - ctx.next(); - return; - } - } - } - - ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize."); - } - - public void processNoAuthorization(RoutingContext ctx) { - ctx.put("actor", new UnknownActor()); - ctx.next(); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java b/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java deleted file mode 100644 index 31f1a6a..0000000 --- a/src/main/java/net/frozenorb/apiv3/handlers/AuthorizationHandler.java +++ /dev/null @@ -1,21 +0,0 @@ -package net.frozenorb.apiv3.handlers; - -import io.vertx.core.Handler; -import io.vertx.ext.web.RoutingContext; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.utils.ErrorUtils; - -public final class AuthorizationHandler implements Handler { - - @Override - public void handle(RoutingContext ctx) { - Actor actor = ctx.get("actor"); - - if (!actor.isAuthorized()) { - ErrorUtils.respondGeneric(ctx, 403, "Please authorize as an approved actor. You're currently authorized as " + actor.getName() + " (" + actor.getType() + ")"); - } else { - ctx.next(); - } - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java similarity index 95% rename from src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java rename to src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java index e7ea316..1161e3e 100644 --- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.google.common.collect.ImmutableMap; import com.mongodb.async.SingleResultCallback; @@ -7,10 +7,10 @@ import fr.javatic.mongo.jacksonCodec.Entity; import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; diff --git a/src/main/java/net/frozenorb/apiv3/models/Grant.java b/src/main/java/net/frozenorb/apiv3/model/Grant.java similarity index 98% rename from src/main/java/net/frozenorb/apiv3/models/Grant.java rename to src/main/java/net/frozenorb/apiv3/model/Grant.java index 86d30d0..bb5e882 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Grant.java +++ b/src/main/java/net/frozenorb/apiv3/model/Grant.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.google.common.collect.Collections2; import com.mongodb.async.SingleResultCallback; @@ -10,7 +10,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; diff --git a/src/main/java/net/frozenorb/apiv3/models/IPBan.java b/src/main/java/net/frozenorb/apiv3/model/IpBan.java similarity index 89% rename from src/main/java/net/frozenorb/apiv3/models/IPBan.java rename to src/main/java/net/frozenorb/apiv3/model/IpBan.java index 6dc3fe4..cf71079 100644 --- a/src/main/java/net/frozenorb/apiv3/models/IPBan.java +++ b/src/main/java/net/frozenorb/apiv3/model/IpBan.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; @@ -8,11 +8,11 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; -import net.frozenorb.apiv3.utils.TimeUtils; +import net.frozenorb.apiv3.util.SyncUtils; +import net.frozenorb.apiv3.util.TimeUtils; import org.bson.Document; import org.bson.types.ObjectId; @@ -158,14 +158,4 @@ public final class IpBan { callback.get(); } - public void delete(Punishment linkedPunishment) { - this.removedBy = linkedPunishment.getRemovedBy(); - this.removedAt = new Date(); - this.removalReason = "Linked punishment removed: " + linkedPunishment.getRemovalReason(); - - BlockingCallback callback = new BlockingCallback<>(); - ipBansCollection.replaceOne(new Document("_id", id), this, callback); - callback.get(); - } - } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java b/src/main/java/net/frozenorb/apiv3/model/IpLogEntry.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java rename to src/main/java/net/frozenorb/apiv3/model/IpLogEntry.java index 7e9bfd0..94f805c 100644 --- a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/model/IpLogEntry.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; @@ -9,7 +9,7 @@ import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; diff --git a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/model/NotificationTemplate.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/model/NotificationTemplate.java index f1fffa2..fb748d6 100644 --- a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/model/NotificationTemplate.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; @@ -10,7 +10,7 @@ import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import java.util.ArrayList; diff --git a/src/main/java/net/frozenorb/apiv3/models/Punishment.java b/src/main/java/net/frozenorb/apiv3/model/Punishment.java similarity index 94% rename from src/main/java/net/frozenorb/apiv3/models/Punishment.java rename to src/main/java/net/frozenorb/apiv3/model/Punishment.java index ce093e8..4b80d74 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Punishment.java +++ b/src/main/java/net/frozenorb/apiv3/model/Punishment.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.mongodb.async.SingleResultCallback; import com.mongodb.async.client.MongoCollection; @@ -8,11 +8,11 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.AllArgsConstructor; import lombok.Getter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.actors.ActorType; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; -import net.frozenorb.apiv3.utils.TimeUtils; +import net.frozenorb.apiv3.util.SyncUtils; +import net.frozenorb.apiv3.util.TimeUtils; import org.bson.Document; import org.bson.types.ObjectId; @@ -195,6 +195,14 @@ public final class Punishment { this.removedAt = new Date(); this.removalReason = reason; + if (linkedIpBanId != null) { + IpBan ipBan = IpBan.findByIdSync(linkedIpBanId); + + if (ipBan != null && ipBan.isActive()) { + ipBan.delete(removedBy, "Linked punishment removed: " + reason); + } + } + BlockingCallback callback = new BlockingCallback<>(); punishmentsCollection.replaceOne(new Document("_id", id), this, callback); callback.get(); diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/model/Rank.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/models/Rank.java rename to src/main/java/net/frozenorb/apiv3/model/Rank.java index 5af8936..44c9933 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Rank.java +++ b/src/main/java/net/frozenorb/apiv3/model/Rank.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.google.common.collect.ImmutableList; import com.google.common.primitives.Ints; @@ -10,7 +10,7 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id; import lombok.Getter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import java.util.ArrayList; diff --git a/src/main/java/net/frozenorb/apiv3/models/Server.java b/src/main/java/net/frozenorb/apiv3/model/Server.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/models/Server.java rename to src/main/java/net/frozenorb/apiv3/model/Server.java index 8898cce..4cc11f3 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Server.java +++ b/src/main/java/net/frozenorb/apiv3/model/Server.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.google.common.collect.ImmutableSet; import com.mongodb.async.client.MongoCollection; @@ -11,7 +11,7 @@ import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import java.util.*; diff --git a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/model/ServerGroup.java similarity index 96% rename from src/main/java/net/frozenorb/apiv3/models/ServerGroup.java rename to src/main/java/net/frozenorb/apiv3/model/ServerGroup.java index 92a1d29..6ca53b0 100644 --- a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/model/ServerGroup.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.mongodb.async.client.MongoCollection; import com.mongodb.client.result.DeleteResult; @@ -10,8 +10,8 @@ import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.PermissionUtils; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.PermissionUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import java.util.*; diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/model/User.java similarity index 86% rename from src/main/java/net/frozenorb/apiv3/models/User.java rename to src/main/java/net/frozenorb/apiv3/model/User.java index ba43809..9a105a6 100644 --- a/src/main/java/net/frozenorb/apiv3/models/User.java +++ b/src/main/java/net/frozenorb/apiv3/model/User.java @@ -1,6 +1,5 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; -import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.annotation.JsonDeserialize; import com.fasterxml.jackson.databind.annotation.JsonSerialize; import com.google.common.base.Charsets; @@ -22,13 +21,12 @@ import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies; import net.frozenorb.apiv3.serialization.jackson.UUIDJsonDeserializer; import net.frozenorb.apiv3.serialization.jackson.UUIDJsonSerializer; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.MojangUtils; -import net.frozenorb.apiv3.utils.PermissionUtils; -import net.frozenorb.apiv3.utils.SyncUtils; -import net.frozenorb.apiv3.utils.UUIDUtils; +import net.frozenorb.apiv3.util.MojangUtils; +import net.frozenorb.apiv3.util.PermissionUtils; +import net.frozenorb.apiv3.util.SyncUtils; +import net.frozenorb.apiv3.util.UUIDUtils; import org.bson.Document; -import java.io.IOException; import java.util.*; @Entity @@ -229,7 +227,7 @@ public final class User { .hashString(input + "$" + id.toString(), Charsets.UTF_8) .toString(); - return hashed.equals(password); + return password != null && hashed.equals(password); } public Rank getHighestRankAnywhere() { @@ -291,8 +289,9 @@ public final class User { return highestRanks; } - public void getLoginInfo(Server server, SingleResultCallback> callback) { + public void getLoginInfo(Server server, String userIp, SingleResultCallback> callback) { Future> punishmentsFuture = Future.future(); + Future> ipBansFuture = Future.future(); Future> grantsFuture = Future.future(); Punishment.findByUserAndType(this, ImmutableSet.of( @@ -307,6 +306,18 @@ public final class User { } }); + if (userIp != null) { + IpBan.findByIp(userIp, (ipBans, error) -> { + if (error != null) { + ipBansFuture.fail(error); + } else { + ipBansFuture.complete(ipBans); + } + }); + } else { + ipBansFuture.complete(ImmutableSet.of()); + } + Grant.findByUser(this, (grants, error) -> { if (error != null) { grantsFuture.fail(error); @@ -315,12 +326,13 @@ public final class User { } }); - CompositeFuture.all(punishmentsFuture, grantsFuture).setHandler((result) -> { + CompositeFuture.all(punishmentsFuture, ipBansFuture, grantsFuture).setHandler((result) -> { if (result.succeeded()) { Iterable punishments = result.result().result(0); - Iterable grants = result.result().result(1); + Iterable ipBans = result.result().result(1); + Iterable grants = result.result().result(2); - callback.onResult(createLoginInfo(server, punishments, grants), null); + callback.onResult(createLoginInfo(server, punishments, ipBans, grants), null); } else { callback.onResult(null, result.cause()); } @@ -328,9 +340,10 @@ public final class User { } // This is only used to help batch requests to mongo - public Map createLoginInfo(Server server, Iterable punishments, Iterable grants) { + public Map createLoginInfo(Server server, Iterable punishments, Iterable ipBans, Iterable grants) { Punishment activeMute = null; Punishment activeBan = null; + IpBan activeIpBan = null; for (Punishment punishment : punishments) { if (!punishment.isActive()) { @@ -344,16 +357,37 @@ public final class User { } } + for (IpBan ipBan : ipBans) { + if (ipBan.isActive()) { + activeIpBan = ipBan; + break; + } + } + Rank highestRank = getHighestRankScoped(ServerGroup.findById(server.getServerGroup()), grants); + Map access = ImmutableMap.of( + "allowed", true, + "message", "Public server" + ); + + if (activeBan != null) { + access = ImmutableMap.of( + "allowed", false, + "message", activeBan.getAccessDenialReason(), + "activeBanId", activeBan.getId() + ); + } else if (activeIpBan != null) { + access = ImmutableMap.of( + "allowed", false, + "message", activeIpBan.getAccessDenialReason(), + "activeIpBanId", activeIpBan.getId() + ); + } // Generics are weird, yes we have to do this. ImmutableMap.Builder result = ImmutableMap.builder() .put("user", this) - .put("access", ImmutableMap.of( - "allowed", activeBan == null, - "message", activeBan == null ? "Public server" : activeBan.getAccessDenialReason(), - "activeBanId", activeBan == null ? "" : activeBan.getId() - )) + .put("access", access) .put("rank", highestRank.getId()) .put("totpSetup", getTotpSecret() != null); diff --git a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java b/src/main/java/net/frozenorb/apiv3/model/UserMetaEntry.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java rename to src/main/java/net/frozenorb/apiv3/model/UserMetaEntry.java index 839d1d2..4e6a40a 100644 --- a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java +++ b/src/main/java/net/frozenorb/apiv3/model/UserMetaEntry.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.models; +package net.frozenorb.apiv3.model; import com.google.common.collect.ImmutableMap; import com.mongodb.async.SingleResultCallback; @@ -11,7 +11,7 @@ import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.SyncUtils; +import net.frozenorb.apiv3.util.SyncUtils; import org.bson.Document; import org.bson.types.ObjectId; diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java b/src/main/java/net/frozenorb/apiv3/route/GETDump.java similarity index 95% rename from src/main/java/net/frozenorb/apiv3/routes/GETDump.java rename to src/main/java/net/frozenorb/apiv3/route/GETDump.java index b5d7f70..890c1ce 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/route/GETDump.java @@ -1,12 +1,12 @@ -package net.frozenorb.apiv3.routes; +package net.frozenorb.apiv3.route; import com.google.common.collect.ImmutableSet; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Grant; +import net.frozenorb.apiv3.model.Punishment; +import net.frozenorb.apiv3.util.ErrorUtils; import java.util.*; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java b/src/main/java/net/frozenorb/apiv3/route/GETWhoAmI.java similarity index 86% rename from src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java rename to src/main/java/net/frozenorb/apiv3/route/GETWhoAmI.java index 0649b92..042ed19 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETWhoAmI.java +++ b/src/main/java/net/frozenorb/apiv3/route/GETWhoAmI.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes; +package net.frozenorb.apiv3.route; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.Actor; +import net.frozenorb.apiv3.actor.Actor; public final class GETWhoAmI implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java b/src/main/java/net/frozenorb/apiv3/route/POSTMetrics.java similarity index 90% rename from src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java rename to src/main/java/net/frozenorb/apiv3/route/POSTMetrics.java index 1756ee9..f4cc292 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/POSTMetrics.java +++ b/src/main/java/net/frozenorb/apiv3/route/POSTMetrics.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes; +package net.frozenorb.apiv3.route; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; diff --git a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java b/src/main/java/net/frozenorb/apiv3/route/announcements/GETAnnouncements.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java rename to src/main/java/net/frozenorb/apiv3/route/announcements/GETAnnouncements.java index 23d19ba..85b6dc7 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java +++ b/src/main/java/net/frozenorb/apiv3/route/announcements/GETAnnouncements.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.announcements; +package net.frozenorb.apiv3.route.announcements; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.ServerGroup; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETAnnouncements implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java b/src/main/java/net/frozenorb/apiv3/route/announcements/PUTAnnouncements.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java rename to src/main/java/net/frozenorb/apiv3/route/announcements/PUTAnnouncements.java index d42dd2f..a6cd155 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/announcements/PUTAnnouncements.java +++ b/src/main/java/net/frozenorb/apiv3/route/announcements/PUTAnnouncements.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.announcements; +package net.frozenorb.apiv3.route.announcements; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.ServerGroup; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.util.ErrorUtils; import java.util.HashSet; import java.util.Set; diff --git a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java b/src/main/java/net/frozenorb/apiv3/route/auditLog/GETAuditLog.java similarity index 84% rename from src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java rename to src/main/java/net/frozenorb/apiv3/route/auditLog/GETAuditLog.java index ea1b639..d07cce2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/auditLog/GETAuditLog.java +++ b/src/main/java/net/frozenorb/apiv3/route/auditLog/GETAuditLog.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.auditLog; +package net.frozenorb.apiv3.route.auditLog; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETAuditLog implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/route/auditLog/POSTUserAuditLogEntry.java similarity index 86% rename from src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java rename to src/main/java/net/frozenorb/apiv3/route/auditLog/POSTUserAuditLogEntry.java index 336ea66..d449420 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/auditLog/POSTUserAuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/route/auditLog/POSTUserAuditLogEntry.java @@ -1,15 +1,15 @@ -package net.frozenorb.apiv3.routes.auditLog; +package net.frozenorb.apiv3.route.auditLog; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.IpUtils; import org.bson.Document; public final class POSTUserAuditLogEntry implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java b/src/main/java/net/frozenorb/apiv3/route/chatFilterList/GETChatFilterList.java similarity index 89% rename from src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java rename to src/main/java/net/frozenorb/apiv3/route/chatFilterList/GETChatFilterList.java index 972b000..b4427d1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/chatFilterList/GETChatFilterList.java +++ b/src/main/java/net/frozenorb/apiv3/route/chatFilterList/GETChatFilterList.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.chatFilterList; +package net.frozenorb.apiv3.route.chatFilterList; import com.google.common.collect.ImmutableList; import io.vertx.core.Handler; diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java b/src/main/java/net/frozenorb/apiv3/route/grants/DELETEGrant.java similarity index 87% rename from src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java rename to src/main/java/net/frozenorb/apiv3/route/grants/DELETEGrant.java index 9eeb99a..c9b88d9 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java +++ b/src/main/java/net/frozenorb/apiv3/route/grants/DELETEGrant.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.grants; +package net.frozenorb.apiv3.route.grants; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; @@ -6,11 +6,11 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.model.Grant; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETEGrant implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java b/src/main/java/net/frozenorb/apiv3/route/grants/GETGrant.java similarity index 78% rename from src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java rename to src/main/java/net/frozenorb/apiv3/route/grants/GETGrant.java index f9cd886..91588b2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrant.java +++ b/src/main/java/net/frozenorb/apiv3/route/grants/GETGrant.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.grants; +package net.frozenorb.apiv3.route.grants; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Grant; +import net.frozenorb.apiv3.model.Grant; public final class GETGrant implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java b/src/main/java/net/frozenorb/apiv3/route/grants/GETGrants.java similarity index 84% rename from src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java rename to src/main/java/net/frozenorb/apiv3/route/grants/GETGrants.java index 021cdab..f7a2dc5 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETGrants.java +++ b/src/main/java/net/frozenorb/apiv3/route/grants/GETGrants.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.grants; +package net.frozenorb.apiv3.route.grants; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Grant; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETGrants implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java b/src/main/java/net/frozenorb/apiv3/route/grants/GETUserGrants.java similarity index 75% rename from src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java rename to src/main/java/net/frozenorb/apiv3/route/grants/GETUserGrants.java index 4313fac..c78954b 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java +++ b/src/main/java/net/frozenorb/apiv3/route/grants/GETUserGrants.java @@ -1,11 +1,11 @@ -package net.frozenorb.apiv3.routes.grants; +package net.frozenorb.apiv3.route.grants; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Grant; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETUserGrants implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java b/src/main/java/net/frozenorb/apiv3/route/grants/POSTUserGrant.java similarity index 89% rename from src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java rename to src/main/java/net/frozenorb/apiv3/route/grants/POSTUserGrant.java index 18976ac..f55e72f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java +++ b/src/main/java/net/frozenorb/apiv3/route/grants/POSTUserGrant.java @@ -1,13 +1,13 @@ -package net.frozenorb.apiv3.routes.grants; +package net.frozenorb.apiv3.route.grants; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.Rank; -import net.frozenorb.apiv3.models.ServerGroup; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Grant; +import net.frozenorb.apiv3.model.Rank; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; import java.util.Date; import java.util.HashSet; diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java b/src/main/java/net/frozenorb/apiv3/route/ipBans/DELETEIpBan.java similarity index 87% rename from src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java rename to src/main/java/net/frozenorb/apiv3/route/ipBans/DELETEIpBan.java index 7682520..e3f3f98 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipBans/DELETEIpBan.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipBans/DELETEIpBan.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.ipBans; +package net.frozenorb.apiv3.route.ipBans; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; @@ -6,11 +6,11 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.models.IpBan; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.model.IpBan; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETEIpBan implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java b/src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpBan.java similarity index 78% rename from src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java rename to src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpBan.java index 268b46d..bce6429 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBan.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpBan.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.ipBans; +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.models.IpBan; +import net.frozenorb.apiv3.model.IpBan; public final class GETIpBan implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java b/src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpBans.java similarity index 84% rename from src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java rename to src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpBans.java index 36cf2d3..42e1ef8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpBans.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpBans.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.ipBans; +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.models.IpBan; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.IpBan; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETIpBans implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java b/src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpIpBans.java similarity index 70% rename from src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java rename to src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpIpBans.java index f798a00..d22664c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipBans/GETIpIpBans.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipBans/GETIpIpBans.java @@ -1,12 +1,11 @@ -package net.frozenorb.apiv3.routes.ipBans; +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.models.IpBan; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; +import net.frozenorb.apiv3.model.IpBan; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.IpUtils; public final class GETIpIpBans implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java b/src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpIpBan.java similarity index 77% rename from src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java rename to src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpIpBan.java index b478731..d8d9105 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipBans/POSTIpIpBan.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpIpBan.java @@ -1,19 +1,14 @@ -package net.frozenorb.apiv3.routes.ipBans; +package net.frozenorb.apiv3.route.ipBans; -import com.google.common.collect.ImmutableMap; -import com.google.common.collect.ImmutableSet; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.IpBan; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.unsorted.Permissions; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; -import org.bson.Document; +import net.frozenorb.apiv3.model.IpBan; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.IpUtils; import java.util.Date; -import java.util.Map; public final class POSTIpIpBan implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java b/src/main/java/net/frozenorb/apiv3/route/ipLog/GETUserIpLog.java similarity index 74% rename from src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java rename to src/main/java/net/frozenorb/apiv3/route/ipLog/GETUserIpLog.java index a36f49a..6655259 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipLog/GETUserIpLog.java @@ -1,11 +1,11 @@ -package net.frozenorb.apiv3.routes.ipLog; +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.models.IpLogEntry; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.IpLogEntry; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETUserIpLog implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/DELETENotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplate.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/DELETENotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplate.java index 59e7d58..2b0b472 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/DELETENotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplate.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.notificationTemplates; +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.models.NotificationTemplate; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.NotificationTemplate; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETENotificationTemplate implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/GETNotificationTemplate.java similarity index 74% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/route/notificationTemplates/GETNotificationTemplate.java index d7425eb..1dc2d64 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/GETNotificationTemplate.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.notificationTemplates; +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.models.NotificationTemplate; +import net.frozenorb.apiv3.model.NotificationTemplate; public final class GETNotificationTemplate implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplates.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/GETNotificationTemplates.java similarity index 73% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplates.java rename to src/main/java/net/frozenorb/apiv3/route/notificationTemplates/GETNotificationTemplates.java index f91ee86..4bc315c 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/GETNotificationTemplates.java +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/GETNotificationTemplates.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.notificationTemplates; +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.models.NotificationTemplate; +import net.frozenorb.apiv3.model.NotificationTemplate; public final class GETNotificationTemplates implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/POSTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplate.java similarity index 83% rename from src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/POSTNotificationTemplate.java rename to src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplate.java index 09ee2e9..3ee8ccf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/POSTNotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplate.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.notificationTemplates; +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.models.NotificationTemplate; +import net.frozenorb.apiv3.model.NotificationTemplate; public final class POSTNotificationTemplate implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/PUTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/PUTNotificationTemplate.java new file mode 100644 index 0000000..a3397ca --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/PUTNotificationTemplate.java @@ -0,0 +1,4 @@ +package net.frozenorb.apiv3.route.notificationTemplates; + +public class PUTNotificationTemplate { +} diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java b/src/main/java/net/frozenorb/apiv3/route/punishments/DELETEPunishment.java similarity index 87% rename from src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java rename to src/main/java/net/frozenorb/apiv3/route/punishments/DELETEPunishment.java index d545ed3..4200481 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/DELETEPunishment.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.punishments; +package net.frozenorb.apiv3.route.punishments; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; @@ -6,11 +6,11 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.model.Punishment; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETEPunishment implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEUserPunishment.java b/src/main/java/net/frozenorb/apiv3/route/punishments/DELETEUserPunishment.java similarity index 89% rename from src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEUserPunishment.java rename to src/main/java/net/frozenorb/apiv3/route/punishments/DELETEUserPunishment.java index 76e9828..9d2bab3 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEUserPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/DELETEUserPunishment.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.routes.punishments; +package net.frozenorb.apiv3.route.punishments; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; @@ -7,11 +7,11 @@ import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.auditLog.AuditLog; import net.frozenorb.apiv3.auditLog.AuditLogActionType; -import net.frozenorb.apiv3.models.AuditLogEntry; -import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.AuditLogEntry; +import net.frozenorb.apiv3.model.Punishment; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETEUserPunishment implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java b/src/main/java/net/frozenorb/apiv3/route/punishments/GETPunishment.java similarity index 77% rename from src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java rename to src/main/java/net/frozenorb/apiv3/route/punishments/GETPunishment.java index 8a61e6f..876c091 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/GETPunishment.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.punishments; +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.models.Punishment; +import net.frozenorb.apiv3.model.Punishment; public final class GETPunishment implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java b/src/main/java/net/frozenorb/apiv3/route/punishments/GETPunishments.java similarity index 84% rename from src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java rename to src/main/java/net/frozenorb/apiv3/route/punishments/GETPunishments.java index 28b9109..ff07bc8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/GETPunishments.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.punishments; +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.models.Punishment; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Punishment; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETPunishments implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java b/src/main/java/net/frozenorb/apiv3/route/punishments/GETUserPunishments.java similarity index 74% rename from src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java rename to src/main/java/net/frozenorb/apiv3/route/punishments/GETUserPunishments.java index 15a7842..a094b38 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/GETUserPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/GETUserPunishments.java @@ -1,11 +1,11 @@ -package net.frozenorb.apiv3.routes.punishments; +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.models.Punishment; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Punishment; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETUserPunishments implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java b/src/main/java/net/frozenorb/apiv3/route/punishments/POSTUserPunish.java similarity index 86% rename from src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java rename to src/main/java/net/frozenorb/apiv3/route/punishments/POSTUserPunish.java index 5c8433c..9e5354f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/POSTUserPunish.java @@ -1,14 +1,15 @@ -package net.frozenorb.apiv3.routes.punishments; +package net.frozenorb.apiv3.route.punishments; import com.google.common.collect.ImmutableMap; import com.google.common.collect.ImmutableSet; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.IpBan; +import net.frozenorb.apiv3.model.Punishment; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.Permissions; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; import org.bson.Document; import java.util.Date; @@ -72,6 +73,15 @@ public final class POSTUserPunish implements Handler { Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, ctx.get("actor"), meta); String accessDenialReason = punishment.getAccessDenialReason(); + String userIp = ctx.request().getParam("userIp"); + + if (userIp != null) { + IpBan ipBan = new IpBan(userIp, punishment); + ipBan.insert(); + + punishment.linkIpBan(ipBan); + } + punishment.insert(); APIv3.respondJson(ctx, ImmutableMap.of( diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java b/src/main/java/net/frozenorb/apiv3/route/ranks/DELETERank.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java rename to src/main/java/net/frozenorb/apiv3/route/ranks/DELETERank.java index ed97e39..3ce134a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/DELETERank.java +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/DELETERank.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.ranks; +package net.frozenorb.apiv3.route.ranks; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Rank; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Rank; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETERank implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java b/src/main/java/net/frozenorb/apiv3/route/ranks/GETRank.java similarity index 78% rename from src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java rename to src/main/java/net/frozenorb/apiv3/route/ranks/GETRank.java index f80c8ba..44e4df0 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRank.java +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/GETRank.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.ranks; +package net.frozenorb.apiv3.route.ranks; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Rank; +import net.frozenorb.apiv3.model.Rank; public final class GETRank implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java b/src/main/java/net/frozenorb/apiv3/route/ranks/GETRanks.java similarity index 76% rename from src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java rename to src/main/java/net/frozenorb/apiv3/route/ranks/GETRanks.java index 637b65e..fc503b3 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/GETRanks.java +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/GETRanks.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.ranks; +package net.frozenorb.apiv3.route.ranks; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Rank; +import net.frozenorb.apiv3.model.Rank; public final class GETRanks implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java b/src/main/java/net/frozenorb/apiv3/route/ranks/POSTRank.java similarity index 90% rename from src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java rename to src/main/java/net/frozenorb/apiv3/route/ranks/POSTRank.java index 0ad21c9..b4869e5 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/POSTRank.java +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/POSTRank.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.ranks; +package net.frozenorb.apiv3.route.ranks; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Rank; +import net.frozenorb.apiv3.model.Rank; public final class POSTRank implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/route/ranks/PUTRank.java b/src/main/java/net/frozenorb/apiv3/route/ranks/PUTRank.java new file mode 100644 index 0000000..56a08a4 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/PUTRank.java @@ -0,0 +1,4 @@ +package net.frozenorb.apiv3.route.ranks; + +public class PUTRank { +} diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroup.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java rename to src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroup.java index f8d3315..f6d1f86 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/DELETEServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroup.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.serverGroups; +package net.frozenorb.apiv3.route.serverGroups; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.ServerGroup; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETEServerGroup implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/GETServerGroup.java similarity index 76% rename from src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java rename to src/main/java/net/frozenorb/apiv3/route/serverGroups/GETServerGroup.java index 0f288ce..1d1fc32 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/GETServerGroup.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.serverGroups; +package net.frozenorb.apiv3.route.serverGroups; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.ServerGroup; +import net.frozenorb.apiv3.model.ServerGroup; public final class GETServerGroup implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/GETServerGroups.java similarity index 74% rename from src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java rename to src/main/java/net/frozenorb/apiv3/route/serverGroups/GETServerGroups.java index a5e9e72..48ca748 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/GETServerGroups.java +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/GETServerGroups.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.serverGroups; +package net.frozenorb.apiv3.route.serverGroups; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.ServerGroup; +import net.frozenorb.apiv3.model.ServerGroup; public final class GETServerGroups implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroup.java similarity index 83% rename from src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java rename to src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroup.java index b6ba7b0..3aad7cf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/POSTServerGroup.java +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroup.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.serverGroups; +package net.frozenorb.apiv3.route.serverGroups; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.ServerGroup; +import net.frozenorb.apiv3.model.ServerGroup; public final class POSTServerGroup implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/route/serverGroups/PUTServerGroup.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/PUTServerGroup.java new file mode 100644 index 0000000..4752a88 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/PUTServerGroup.java @@ -0,0 +1,4 @@ +package net.frozenorb.apiv3.route.serverGroups; + +public class PUTServerGroup { +} diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java b/src/main/java/net/frozenorb/apiv3/route/servers/DELETEServer.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java rename to src/main/java/net/frozenorb/apiv3/route/servers/DELETEServer.java index 24ff866..32245fb 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/DELETEServer.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/DELETEServer.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.servers; +package net.frozenorb.apiv3.route.servers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Server; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Server; +import net.frozenorb.apiv3.util.ErrorUtils; public final class DELETEServer implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java b/src/main/java/net/frozenorb/apiv3/route/servers/GETServer.java similarity index 78% rename from src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java rename to src/main/java/net/frozenorb/apiv3/route/servers/GETServer.java index 0a1b3e8..b7fcaf7 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServer.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/GETServer.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.servers; +package net.frozenorb.apiv3.route.servers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Server; +import net.frozenorb.apiv3.model.Server; public final class GETServer implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java b/src/main/java/net/frozenorb/apiv3/route/servers/GETServers.java similarity index 76% rename from src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java rename to src/main/java/net/frozenorb/apiv3/route/servers/GETServers.java index 8dc2452..bab8fc8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/GETServers.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/GETServers.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.servers; +package net.frozenorb.apiv3.route.servers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Server; +import net.frozenorb.apiv3.model.Server; public final class GETServers implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServer.java similarity index 83% rename from src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java rename to src/main/java/net/frozenorb/apiv3/route/servers/POSTServer.java index 03a079d..19e5ff0 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServer.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServer.java @@ -1,12 +1,12 @@ -package net.frozenorb.apiv3.routes.servers; +package net.frozenorb.apiv3.route.servers; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Server; -import net.frozenorb.apiv3.models.ServerGroup; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; +import net.frozenorb.apiv3.model.Server; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.IpUtils; import java.math.BigInteger; import java.util.Random; diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java similarity index 93% rename from src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java rename to src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java index 00414a1..d133ade 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java @@ -1,5 +1,6 @@ -package net.frozenorb.apiv3.routes.servers; +package net.frozenorb.apiv3.route.servers; +import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.vertx.core.CompositeFuture; import io.vertx.core.Future; @@ -7,12 +8,12 @@ import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import lombok.extern.slf4j.Slf4j; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.actors.Actor; -import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.models.*; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.PermissionUtils; -import net.frozenorb.apiv3.utils.UUIDUtils; +import net.frozenorb.apiv3.actor.Actor; +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 org.bson.Document; import java.util.*; @@ -126,7 +127,8 @@ public final class POSTServerHeartbeat implements Handler { user.save(); } - response.put(uuid.toString(), user.createLoginInfo(server, punishments.get(uuid), grants.get(uuid))); + // TODO: Provide IPs for ip ban lookup + response.put(uuid.toString(), user.createLoginInfo(server, punishments.get(uuid), ImmutableList.of(), grants.get(uuid))); } callback.complete(response); diff --git a/src/main/java/net/frozenorb/apiv3/route/servers/PUTServer.java b/src/main/java/net/frozenorb/apiv3/route/servers/PUTServer.java new file mode 100644 index 0000000..a2ec38d --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/servers/PUTServer.java @@ -0,0 +1,4 @@ +package net.frozenorb.apiv3.route.servers; + +public class PUTServer { +} diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java b/src/main/java/net/frozenorb/apiv3/route/users/DELETEUserMeta.java similarity index 82% rename from src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java rename to src/main/java/net/frozenorb/apiv3/route/users/DELETEUserMeta.java index 3593415..7461fe3 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/DELETEUserMeta.java @@ -1,12 +1,12 @@ -package net.frozenorb.apiv3.routes.users; +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.models.ServerGroup; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.models.UserMetaEntry; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.model.UserMetaEntry; +import net.frozenorb.apiv3.util.ErrorUtils; import org.bson.Document; public final class DELETEUserMeta implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java b/src/main/java/net/frozenorb/apiv3/route/users/GETStaff.java similarity index 88% rename from src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java rename to src/main/java/net/frozenorb/apiv3/route/users/GETStaff.java index 7a43f48..3e63f62 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETStaff.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/GETStaff.java @@ -1,11 +1,11 @@ -package net.frozenorb.apiv3.routes.users; +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.models.Grant; -import net.frozenorb.apiv3.models.Rank; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.Grant; +import net.frozenorb.apiv3.model.Rank; +import net.frozenorb.apiv3.model.User; import java.util.*; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java b/src/main/java/net/frozenorb/apiv3/route/users/GETUser.java similarity index 78% rename from src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java rename to src/main/java/net/frozenorb/apiv3/route/users/GETUser.java index 0684633..1323359 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUser.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/GETUser.java @@ -1,9 +1,9 @@ -package net.frozenorb.apiv3.routes.users; +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.models.User; +import net.frozenorb.apiv3.model.User; public final class GETUser implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java b/src/main/java/net/frozenorb/apiv3/route/users/GETUserDetails.java similarity index 78% rename from src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java rename to src/main/java/net/frozenorb/apiv3/route/users/GETUserDetails.java index e25367b..0245d3e 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/GETUserDetails.java @@ -1,14 +1,14 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.Grant; -import net.frozenorb.apiv3.models.IpLogEntry; -import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.Grant; +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 GETUserDetails implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java b/src/main/java/net/frozenorb/apiv3/route/users/GETUserMeta.java similarity index 79% rename from src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java rename to src/main/java/net/frozenorb/apiv3/route/users/GETUserMeta.java index 678d4fb..91221a1 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/GETUserMeta.java @@ -1,12 +1,12 @@ -package net.frozenorb.apiv3.routes.users; +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.models.ServerGroup; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.models.UserMetaEntry; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.model.UserMetaEntry; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETUserMeta implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java b/src/main/java/net/frozenorb/apiv3/route/users/GETUserRequiresTOTP.java similarity index 88% rename from src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java rename to src/main/java/net/frozenorb/apiv3/route/users/GETUserRequiresTOTP.java index 3c53fdc..abc04f4 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserRequiresTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/GETUserRequiresTOTP.java @@ -1,14 +1,14 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; -import net.frozenorb.apiv3.utils.TOTPUtils; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.IpUtils; +import net.frozenorb.apiv3.util.TOTPUtils; public final class GETUserRequiresTOTP implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java b/src/main/java/net/frozenorb/apiv3/route/users/GETUserVerifyPassword.java similarity index 87% rename from src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java rename to src/main/java/net/frozenorb/apiv3/route/users/GETUserVerifyPassword.java index c710f5e..5de1c1a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyPassword.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/GETUserVerifyPassword.java @@ -1,11 +1,11 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; public final class GETUserVerifyPassword implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserConfirmRegister.java similarity index 95% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserConfirmRegister.java index bdf4fc2..c71ec5f 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserConfirmRegister.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserConfirmRegister.java @@ -1,12 +1,12 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; import java.util.List; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserLeave.java similarity index 87% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserLeave.java index f728372..dcb19dd 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLeave.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserLeave.java @@ -1,10 +1,10 @@ -package net.frozenorb.apiv3.routes.users; +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.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; public class POSTUserLeave implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserLogin.java similarity index 71% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserLogin.java index e90b3ba..359aac9 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserLogin.java @@ -1,17 +1,17 @@ -package net.frozenorb.apiv3.routes.users; +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.actors.Actor; -import net.frozenorb.apiv3.actors.ActorType; -import net.frozenorb.apiv3.actors.ServerActor; -import net.frozenorb.apiv3.models.IpLogEntry; -import net.frozenorb.apiv3.models.Server; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; -import net.frozenorb.apiv3.utils.UUIDUtils; +import net.frozenorb.apiv3.actor.Actor; +import net.frozenorb.apiv3.actor.ActorType; +import net.frozenorb.apiv3.actor.actors.ServerActor; +import net.frozenorb.apiv3.model.IpLogEntry; +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 java.util.UUID; @@ -26,10 +26,17 @@ public final class POSTUserLogin implements Handler { } Actor actor = ctx.get("actor"); + Server server; - if (actor.getType() != ActorType.SERVER) { - ErrorUtils.respondServerOnly(ctx); - return; + if (actor.getType() == ActorType.SERVER) { + server = ((ServerActor) actor).getServer(); + } else { + server = Server.findById(ctx.request().getParam("server")); + + if (server == null) { + ErrorUtils.respondNotFound(ctx, "Server", ctx.request().getParam("server")); + return; + } } String username = ctx.request().getParam("username"); @@ -68,7 +75,7 @@ public final class POSTUserLogin implements Handler { if (error3 != null) { ErrorUtils.respondInternalError(ctx, error3); } else { - finalUser.getLoginInfo(((ServerActor) actor).getServer(), (loginInfo, error4) -> { + finalUser.getLoginInfo(server, userIp, (loginInfo, error4) -> { if (error4 != null) { ErrorUtils.respondInternalError(ctx, error4); } else { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserNotify.java similarity index 91% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserNotify.java index f2a93b4..24f3adf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserNotify.java @@ -1,13 +1,13 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.NotificationTemplate; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.NotificationTemplate; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.Notification; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; import java.util.HashMap; import java.util.Map; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserRegister.java similarity index 93% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserRegister.java index 9a28e22..811cf77 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserRegister.java @@ -1,13 +1,13 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.NotificationTemplate; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.NotificationTemplate; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.Notification; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.util.ErrorUtils; import java.math.BigInteger; import java.util.Date; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java index 386e406..8135b7d 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserSetupTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java @@ -1,13 +1,13 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import com.warrenstrange.googleauth.GoogleAuthenticatorKey; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.TOTPUtils; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.TOTPUtils; public final class POSTUserSetupTOTP implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java similarity index 91% rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java rename to src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java index bf1a163..72e0faf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java @@ -1,14 +1,14 @@ -package net.frozenorb.apiv3.routes.users; +package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; -import net.frozenorb.apiv3.utils.ErrorUtils; -import net.frozenorb.apiv3.utils.IpUtils; -import net.frozenorb.apiv3.utils.TOTPUtils; +import net.frozenorb.apiv3.util.ErrorUtils; +import net.frozenorb.apiv3.util.IpUtils; +import net.frozenorb.apiv3.util.TOTPUtils; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java b/src/main/java/net/frozenorb/apiv3/route/users/PUTUserMeta.java similarity index 83% rename from src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java rename to src/main/java/net/frozenorb/apiv3/route/users/PUTUserMeta.java index 3ab4719..8a5ea09 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/PUTUserMeta.java @@ -1,12 +1,12 @@ -package net.frozenorb.apiv3.routes.users; +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.models.ServerGroup; -import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.models.UserMetaEntry; -import net.frozenorb.apiv3.utils.ErrorUtils; +import net.frozenorb.apiv3.model.ServerGroup; +import net.frozenorb.apiv3.model.User; +import net.frozenorb.apiv3.model.UserMetaEntry; +import net.frozenorb.apiv3.util.ErrorUtils; import org.bson.Document; public final class PUTUserMeta implements Handler { diff --git a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java deleted file mode 100644 index c07f9a9..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/notificationTemplates/PUTNotificationTemplate.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.frozenorb.apiv3.routes.notificationTemplates; - -public class PUTNotificationTemplate { -} diff --git a/src/main/java/net/frozenorb/apiv3/routes/ranks/PUTRank.java b/src/main/java/net/frozenorb/apiv3/routes/ranks/PUTRank.java deleted file mode 100644 index 5d5bd2f..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/ranks/PUTRank.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.frozenorb.apiv3.routes.ranks; - -public class PUTRank { -} diff --git a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/PUTServerGroup.java b/src/main/java/net/frozenorb/apiv3/routes/serverGroups/PUTServerGroup.java deleted file mode 100644 index c530135..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/serverGroups/PUTServerGroup.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.frozenorb.apiv3.routes.serverGroups; - -public class PUTServerGroup { -} diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/PUTServer.java b/src/main/java/net/frozenorb/apiv3/routes/servers/PUTServer.java deleted file mode 100644 index a39509a..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/servers/PUTServer.java +++ /dev/null @@ -1,4 +0,0 @@ -package net.frozenorb.apiv3.routes.servers; - -public class PUTServer { -} diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java index 70e967d..02742df 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java @@ -5,7 +5,7 @@ import com.google.common.net.MediaType; import com.mongodb.async.SingleResultCallback; import io.vertx.core.http.HttpHeaders; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.NotificationTemplate; +import net.frozenorb.apiv3.model.NotificationTemplate; import org.bson.Document; import java.util.Map; diff --git a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java rename to src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java index fb09d76..13ce3cd 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import com.google.common.collect.ImmutableMap; import io.vertx.ext.web.RoutingContext; diff --git a/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java b/src/main/java/net/frozenorb/apiv3/util/IpUtils.java similarity index 94% rename from src/main/java/net/frozenorb/apiv3/utils/IPUtils.java rename to src/main/java/net/frozenorb/apiv3/util/IpUtils.java index b4d9be1..b834862 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/IPUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/IpUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import lombok.experimental.UtilityClass; diff --git a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java b/src/main/java/net/frozenorb/apiv3/util/MojangUtils.java similarity index 96% rename from src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java rename to src/main/java/net/frozenorb/apiv3/util/MojangUtils.java index 271c219..b37e4d1 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/MojangUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import com.mongodb.async.SingleResultCallback; import lombok.experimental.UtilityClass; diff --git a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java b/src/main/java/net/frozenorb/apiv3/util/PermissionUtils.java similarity index 95% rename from src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java rename to src/main/java/net/frozenorb/apiv3/util/PermissionUtils.java index f097566..e490279 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/PermissionUtils.java @@ -1,8 +1,8 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import com.google.common.collect.ImmutableMap; import lombok.experimental.UtilityClass; -import net.frozenorb.apiv3.models.Rank; +import net.frozenorb.apiv3.model.Rank; import java.util.HashMap; import java.util.List; diff --git a/src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java b/src/main/java/net/frozenorb/apiv3/util/SyncUtils.java similarity index 95% rename from src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java rename to src/main/java/net/frozenorb/apiv3/util/SyncUtils.java index 12c982a..701a845 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/SyncUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/SyncUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import com.mongodb.async.client.MongoIterable; import lombok.experimental.UtilityClass; diff --git a/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java b/src/main/java/net/frozenorb/apiv3/util/TOTPUtils.java similarity index 97% rename from src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java rename to src/main/java/net/frozenorb/apiv3/util/TOTPUtils.java index 12feba0..9c29844 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/TOTPUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/TOTPUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import com.mongodb.async.SingleResultCallback; import com.warrenstrange.googleauth.GoogleAuthenticator; @@ -7,7 +7,7 @@ import com.warrenstrange.googleauth.GoogleAuthenticatorKey; import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator; import lombok.experimental.UtilityClass; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.models.User; +import net.frozenorb.apiv3.model.User; import java.util.concurrent.TimeUnit; diff --git a/src/main/java/net/frozenorb/apiv3/utils/TimeUtils.java b/src/main/java/net/frozenorb/apiv3/util/TimeUtils.java similarity index 96% rename from src/main/java/net/frozenorb/apiv3/utils/TimeUtils.java rename to src/main/java/net/frozenorb/apiv3/util/TimeUtils.java index 09dce32..2d4228e 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/TimeUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/TimeUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import lombok.experimental.UtilityClass; diff --git a/src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java b/src/main/java/net/frozenorb/apiv3/util/UUIDUtils.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java rename to src/main/java/net/frozenorb/apiv3/util/UUIDUtils.java index 341dc57..01529ef 100644 --- a/src/main/java/net/frozenorb/apiv3/utils/UUIDUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/UUIDUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.utils; +package net.frozenorb.apiv3.util; import lombok.experimental.UtilityClass; From 3a1b68b6b6d54f073fde09b56a20db63c1128acc Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 16 Jun 2016 10:49:57 -0400 Subject: [PATCH 6/8] Cleanup some small bits of code --- src/main/java/net/frozenorb/apiv3/APIv3.java | 73 +++++++++++-------- .../apiv3/handler/ActorAttributeHandler.java | 3 + .../route/servers/POSTServerHeartbeat.java | 2 +- .../serialization/gson/DateTypeAdapter.java | 2 +- .../apiv3/unsorted/Notification.java | 4 +- .../net/frozenorb/apiv3/util/ErrorUtils.java | 4 - 6 files changed, 49 insertions(+), 39 deletions(-) diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 5a3e208..96e690b 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -12,6 +12,7 @@ import com.google.gson.Gson; import com.google.gson.GsonBuilder; import com.mongodb.ConnectionString; import com.mongodb.MongoCredential; +import com.mongodb.async.client.MongoClient; import com.mongodb.async.client.MongoClientSettings; import com.mongodb.async.client.MongoClients; import com.mongodb.async.client.MongoDatabase; @@ -74,6 +75,7 @@ import org.bson.codecs.DocumentCodecProvider; import org.bson.codecs.ValueCodecProvider; import org.bson.codecs.configuration.CodecProvider; import org.bson.codecs.configuration.CodecRegistries; +import org.bson.codecs.configuration.CodecRegistry; import java.io.FileInputStream; import java.io.IOException; @@ -131,41 +133,20 @@ public final class APIv3 extends AbstractVerticle { ); } - ClusterSettings clusterSettings = ClusterSettings + ConnectionString connectionString = new ConnectionString("mongodb://" + config.getProperty("mongo.address") + ":" + config.getProperty("mongo.port")); + + MongoClient mongoClient = MongoClients.create(MongoClientSettings .builder() - .applyConnectionString(new ConnectionString("mongodb://" + config.getProperty("mongo.address") + ":" + config.getProperty("mongo.port"))) - .build(); - - List providers = new ArrayList<>(); - - // Our fixed uuid codec - providers.add(new UUIDCodecProvider()); - - // Normal providers - providers.add(new ValueCodecProvider()); - providers.add(new DocumentCodecProvider()); - providers.add(new BsonValueCodecProvider()); - - ObjectMapper objectMapper = ObjectMapperFactory.createObjectMapper(); - SimpleModule simpleModule = new SimpleModule(); - - simpleModule.addSerializer(UUID.class, new UUIDJsonSerializer()); - simpleModule.addDeserializer(UUID.class, new UUIDJsonDeserializer()); - - objectMapper.registerModule(simpleModule); - objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); - objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); - objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); - providers.add(new JacksonCodecProvider(objectMapper)); - - MongoClientSettings settings = MongoClientSettings - .builder() - .codecRegistry(CodecRegistries.fromProviders(providers)) + .codecRegistry(createCodecRegistry()) .credentialList(credentials) - .clusterSettings(clusterSettings) - .build(); + .clusterSettings(ClusterSettings.builder() + .applyConnectionString(connectionString) + .build() + ) + .build() + ); - database = MongoClients.create(settings).getDatabase(config.getProperty("mongo.database")); + database = mongoClient.getDatabase(config.getProperty("mongo.database")); database.getCollection("auditLog").createIndexes(ImmutableList.of( new IndexModel(new Document("user", 1)), new IndexModel(new Document("performedAt", 1)), @@ -195,6 +176,34 @@ public final class APIv3 extends AbstractVerticle { ), (a, b) -> {}); } + private CodecRegistry createCodecRegistry() { + ObjectMapper objectMapper = ObjectMapperFactory.createObjectMapper(); + SimpleModule simpleModule = new SimpleModule(); + + simpleModule.addSerializer(UUID.class, new UUIDJsonSerializer()); + simpleModule.addDeserializer(UUID.class, new UUIDJsonDeserializer()); + + objectMapper.registerModule(simpleModule); + objectMapper.setVisibility(PropertyAccessor.ALL, JsonAutoDetect.Visibility.NONE); + objectMapper.setVisibility(PropertyAccessor.FIELD, JsonAutoDetect.Visibility.ANY); + objectMapper.setSerializationInclusion(JsonInclude.Include.NON_NULL); + + List providers = new ArrayList<>(); + + // Our fixed uuid codec + providers.add(new UUIDCodecProvider()); + + // Normal providers + providers.add(new ValueCodecProvider()); + providers.add(new DocumentCodecProvider()); + providers.add(new BsonValueCodecProvider()); + + // Jackson parser codec + providers.add(new JacksonCodecProvider(objectMapper)); + + return CodecRegistries.fromProviders(providers); + } + private void setupRedis() { redisClient = RedisClient.create( vertx, diff --git a/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java b/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java index ad776c0..c0652ec 100644 --- a/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java +++ b/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java @@ -111,6 +111,9 @@ public final class ActorAttributeHandler implements Handler { ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as bungee."); } + break; + default: + ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + type + "."); break; } } diff --git a/src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java index d133ade..0ad2b64 100644 --- a/src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServerHeartbeat.java @@ -25,7 +25,7 @@ public final class POSTServerHeartbeat implements Handler { Actor actor = ctx.get("actor"); if (actor.getType() != ActorType.SERVER) { - ErrorUtils.respondServerOnly(ctx); + ErrorUtils.respondGeneric(ctx, 400, "This action can only be performed when requested by a server."); return; } diff --git a/src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java b/src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java index a2c5db7..813a274 100644 --- a/src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/gson/DateTypeAdapter.java @@ -11,7 +11,7 @@ public final class DateTypeAdapter extends TypeAdapter { public void write(JsonWriter writer, Date write) throws IOException { if (write == null) { - writer.value(-1); + writer.nullValue(); } else { writer.value(write.getTime()); } diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java index 02742df..a8954a9 100644 --- a/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java @@ -28,7 +28,9 @@ public final class Notification { messageJson.put("from_email", "no-reply@minehq.com"); messageJson.put("from_name", "MineHQ Network"); messageJson.put("to", ImmutableList.of( - new Document("email", email).append("name", null).append("type", "to") + new Document("email", email) + .append("name", null) + .append("type", "to") )); Document bodyJson = new Document(); diff --git a/src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java index 13ce3cd..ebb7dbd 100644 --- a/src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/ErrorUtils.java @@ -8,10 +8,6 @@ import net.frozenorb.apiv3.APIv3; @UtilityClass public class ErrorUtils { - public static void respondServerOnly(RoutingContext ctx) { - respondGeneric(ctx, 400, "This action can only be performed when requested by a server."); - } - public static void respondNotFound(RoutingContext ctx, String itemType, String id) { respondGeneric(ctx, 404, "Not found: " + itemType + " with id " + id + " cannot be found."); } From c99052d8f1c7a494923f96dfb22d0f9b915c7b02 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 16 Jun 2016 10:50:24 -0400 Subject: [PATCH 7/8] Optimize imports --- src/main/java/net/frozenorb/apiv3/APIv3.java | 1 - 1 file changed, 1 deletion(-) diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 96e690b..8d393ea 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -34,7 +34,6 @@ import io.vertx.redis.RedisClient; import io.vertx.redis.RedisOptions; import lombok.Getter; import lombok.extern.slf4j.Slf4j; -import net.frozenorb.apiv3.dataImport.V2Importer; import net.frozenorb.apiv3.handler.ActorAttributeHandler; import net.frozenorb.apiv3.handler.AuthorizationHandler; import net.frozenorb.apiv3.route.GETDump; From fac4d50501c4646b1810f4a8e40735fb73484bb1 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 16 Jun 2016 10:58:23 -0400 Subject: [PATCH 8/8] Fix possible issues presented by FindBugs --- .../net/frozenorb/apiv3/handler/ActorAttributeHandler.java | 4 +++- src/main/java/net/frozenorb/apiv3/route/GETDump.java | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java b/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java index c0652ec..21dd9f3 100644 --- a/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java +++ b/src/main/java/net/frozenorb/apiv3/handler/ActorAttributeHandler.java @@ -1,5 +1,6 @@ package net.frozenorb.apiv3.handler; +import com.google.common.base.Charsets; import io.vertx.core.Handler; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; @@ -8,6 +9,7 @@ import net.frozenorb.apiv3.model.Server; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.util.ErrorUtils; +import java.nio.charset.Charset; import java.util.Base64; public final class ActorAttributeHandler implements Handler { @@ -28,7 +30,7 @@ public final class ActorAttributeHandler implements Handler { private void processBasicAuthorization(String authHeader, RoutingContext ctx) { String encodedHeader = authHeader.substring("Basic ".length()); - String decodedHeader = new String(Base64.getDecoder().decode(encodedHeader.getBytes())); + String decodedHeader = new String(Base64.getDecoder().decode(encodedHeader.getBytes(Charsets.UTF_8)), Charsets.UTF_8); String[] splitHeader = decodedHeader.split(":"); if (splitHeader.length != 2) { diff --git a/src/main/java/net/frozenorb/apiv3/route/GETDump.java b/src/main/java/net/frozenorb/apiv3/route/GETDump.java index 890c1ce..c972f87 100644 --- a/src/main/java/net/frozenorb/apiv3/route/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/route/GETDump.java @@ -26,7 +26,7 @@ public final class GETDump implements Handler { int tick = 0; while (true) { - if (tick == 0 || tick % 2 == 1) { + if (tick == 0 || tick % 2 != 0) { List banCache = new ArrayList<>(); List blacklistCache = new ArrayList<>();