Vertx prototyping

This commit is contained in:
Colin McDonald 2016-06-01 14:23:37 -04:00
parent 2248788961
commit 7d626afa20
58 changed files with 348 additions and 440 deletions

11
pom.xml
View File

@ -59,9 +59,14 @@
<dependencies>
<dependency>
<groupId>com.sparkjava</groupId>
<artifactId>spark-core</artifactId>
<version>2.5</version>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>LATEST</version>
</dependency>
<dependency>
<groupId>com.google.guava</groupId>

View File

@ -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");

View File

@ -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];

View File

@ -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");

View File

@ -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() : ""));
}

View File

@ -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)

View File

@ -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<RoutingContext> {
private List<UUID> banCache = new ArrayList<>();
private List<UUID> 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
}
}

View File

@ -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<RoutingContext> {
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(),

View File

@ -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<RoutingContext> {
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;
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
public void handle(RoutingContext ctx) {
//LibratoBatch batch = new LibratoBatch();
return ImmutableMap.of();

View File

@ -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<RoutingContext> {
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());
}
}

View File

@ -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<RoutingContext> {
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.");
}
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
return ImmutableSet.of();
public void handle(RoutingContext ctx) {
APIv3.respond(ctx, ImmutableMap.of());
}
}

View File

@ -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<RoutingContext> {
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);
}
}

View File

@ -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<RoutingContext> {
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")));
}
}

View File

@ -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<RoutingContext> {
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.");
}
}

View File

@ -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<RoutingContext> {
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());
}
}

View File

@ -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<RoutingContext> {
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<ServerGroup> 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);

View File

@ -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<RoutingContext> {
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());
}
}

View File

@ -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<RoutingContext> {
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);
}
}

View File

@ -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<RoutingContext> {
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")));
}
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
return NotificationTemplate.values();
public void handle(RoutingContext ctx) {
APIv3.respond(ctx, NotificationTemplate.values());
}
}

View File

@ -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<RoutingContext> {
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);
}
}

View File

@ -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<RoutingContext> {
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;
}

View File

@ -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<RoutingContext> {
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"));
}
}

View File

@ -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<RoutingContext> {
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.");
}
}

View File

@ -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<RoutingContext> {
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();

View File

@ -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<RoutingContext> {
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<String, Object> 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);

View File

@ -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<RoutingContext> {
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();

View File

@ -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<RoutingContext> {
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"));
}
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
public void handle(RoutingContext ctx) {
return Rank.values();
}

View File

@ -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<RoutingContext> {
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);

View File

@ -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<RoutingContext> {
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();

View File

@ -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<RoutingContext> {
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"));
}
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
public void handle(RoutingContext ctx) {
return ServerGroup.values();
}

View File

@ -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<RoutingContext> {
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);

View File

@ -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<RoutingContext> {
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();

View File

@ -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<RoutingContext> {
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"));
}
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
public void handle(RoutingContext ctx) {
return Server.values();
}

View File

@ -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<RoutingContext> {
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);

View File

@ -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<RoutingContext> {
@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());

View File

@ -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<RoutingContext> {
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);

View File

@ -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<RoutingContext> {
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;
}
}

View File

@ -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<RoutingContext> {
public Object handle(Request req, Response res) {
public void handle(RoutingContext ctx) {
Map<String, Rank> staffRanks = new HashMap<>();
Rank.values().forEach(rank -> {

View File

@ -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<RoutingContext> {
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"));
}
}

View File

@ -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<RoutingContext> {
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()

View File

@ -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<RoutingContext> {
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);

View File

@ -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<RoutingContext> {
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)) {

View File

@ -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<RoutingContext> {
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

View File

@ -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<RoutingContext> {
private final List<String> 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.");

View File

@ -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<RoutingContext> {
@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();

View File

@ -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<RoutingContext> {
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) {

View File

@ -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<RoutingContext> {
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<String, Object> subjectReplacements = new HashMap<>();

View File

@ -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<RoutingContext> {
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.");

View File

@ -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<RoutingContext> {
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();

View File

@ -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<RoutingContext> {
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(

View File

@ -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<RoutingContext> {
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());

View File

@ -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<String, Object> 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<String, Object> 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<String, Object> invalidInput(String message) {
return error("Invalid input: " + message);
public static void respondInvalidInput(RoutingContext ctx, String message) {
error(ctx, "Invalid input: " + message + ".");
}
public static Map<String, Object> 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<String, Object> error(String message) {
return ImmutableMap.of(
public static void error(RoutingContext ctx, String message) {
APIv3.respond(ctx, ImmutableMap.of(
"success", false,
"message", message
);
));
}
}