diff --git a/pom.xml b/pom.xml
index b9edb8b..c2a3a58 100644
--- a/pom.xml
+++ b/pom.xml
@@ -50,18 +50,33 @@
com.sparkjava
spark-core
- 2.3
+ 2.4
com.google.guava
guava
19.0
+
+ redis.clients
+ jedis
+ 2.8.1
+
com.google.code.gson
gson
2.6.2
+
+ com.librato.metrics
+ metrics-librato
+ 4.1.2.5
+
+
+ io.dropwizard.metrics
+ metrics-core
+ 3.1.2
+
org.mongodb
mongo-java-driver
diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java
index 69d5e17..0bbcfee 100644
--- a/src/main/java/net/frozenorb/apiv3/APIv3.java
+++ b/src/main/java/net/frozenorb/apiv3/APIv3.java
@@ -132,15 +132,16 @@ public final class APIv3 {
//put("/rank/:id", new PUTRank(), gson::toJson);
delete("/rank/:id", new DELETERank(), gson::toJson);
- delete("/serverGroup/:id", new DELETEServerGroup(), gson::toJson);
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);
get("/server/:id", new GETServer(), gson::toJson);
get("/servers", new GETServers(), gson::toJson);
post("/server/heartbeat", new POSTServerHeartbeat(), gson::toJson);
+ post("/server/metrics", new POSTServerMetrics(), gson::toJson);
post("/server", new POSTServer(), gson::toJson);
//put("/server/:id", new PUTServer(), gson::toJson);
delete("/server/:id", new DELETEServer(), gson::toJson);
@@ -150,17 +151,17 @@ public final class APIv3 {
get("/user/:id/meta/:serverGroup", new GETUserMeta(), gson::toJson);
get("/user/:id/grants", new GETUserGrants(), gson::toJson);
get("/user/:id/ipLog", new GETUserIPLog(), gson::toJson);
- get("/user/:id/verifyTOTP", new GETUserVerifyTOTP(), gson::toJson);
+ post("/user/:id/verifyTOTP", new POSTUserVerifyTOTP(), gson::toJson);
get("/user/:id", new GETUser(), gson::toJson);
post("/user/:id:/grant", new POSTUserGrant(), gson::toJson);
post("/user/:id:/punish", new POSTUserPunish(), gson::toJson);
- post("/user/:id/loginInfo", new POSTUserLoginInfo(), gson::toJson);
+ post("/user/:id/login", new POSTUserLogin(), 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", new DELETEUserMeta(), gson::toJson);
+ delete("/user/:id/meta/:serverGroup", new DELETEUserMeta(), gson::toJson);
// There's no way to do a JSON 404 page w/o doing this :(
get("/*", new NotFound(), gson::toJson);
diff --git a/src/main/java/net/frozenorb/apiv3/actors/Actor.java b/src/main/java/net/frozenorb/apiv3/actors/Actor.java
index 4fdb98b..909b8b1 100644
--- a/src/main/java/net/frozenorb/apiv3/actors/Actor.java
+++ b/src/main/java/net/frozenorb/apiv3/actors/Actor.java
@@ -4,12 +4,6 @@ public interface Actor {
boolean isAuthorized();
String getName();
- Actor.Type getType();
-
- enum Type {
-
- WEBSITE, SERVER, USER, UNKNOWN
-
- }
+ ActorType getType();
}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/actors/ActorType.java b/src/main/java/net/frozenorb/apiv3/actors/ActorType.java
new file mode 100644
index 0000000..6974e4f
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/actors/ActorType.java
@@ -0,0 +1,7 @@
+package net.frozenorb.apiv3.actors;
+
+public enum ActorType {
+
+ WEBSITE, SERVER, USER, UNKNOWN
+
+}
\ 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/actors/ServerActor.java
index b03cd64..10f36e1 100644
--- a/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java
+++ b/src/main/java/net/frozenorb/apiv3/actors/ServerActor.java
@@ -18,8 +18,8 @@ public final class ServerActor implements Actor {
return server.getId();
}
- public Actor.Type getType() {
- return Actor.Type.SERVER;
+ public ActorType getType() {
+ return ActorType.SERVER;
}
}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java b/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java
index 154c402..9d89614 100644
--- a/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java
+++ b/src/main/java/net/frozenorb/apiv3/actors/UnknownActor.java
@@ -10,8 +10,8 @@ public final class UnknownActor implements Actor {
return "Unknown";
}
- public Actor.Type getType() {
- return Actor.Type.UNKNOWN;
+ public ActorType getType() {
+ return ActorType.UNKNOWN;
}
}
\ 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 7652ee7..3e8c78c 100644
--- a/src/main/java/net/frozenorb/apiv3/actors/UserActor.java
+++ b/src/main/java/net/frozenorb/apiv3/actors/UserActor.java
@@ -32,8 +32,8 @@ public final class UserActor implements Actor {
return user.getLastUsername();
}
- public Actor.Type getType() {
- return Actor.Type.USER;
+ public ActorType getType() {
+ return ActorType.USER;
}
}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java b/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java
index e87ad9c..939cf01 100644
--- a/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java
+++ b/src/main/java/net/frozenorb/apiv3/actors/WebsiteActor.java
@@ -10,8 +10,8 @@ public final class WebsiteActor implements Actor {
return "Website";
}
- public Actor.Type getType() {
- return Actor.Type.WEBSITE;
+ public ActorType getType() {
+ return ActorType.WEBSITE;
}
}
\ 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 32d2d07..6a15bc1 100644
--- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java
+++ b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java
@@ -3,6 +3,7 @@ package net.frozenorb.apiv3.models;
import com.google.common.collect.ImmutableMap;
import lombok.Getter;
import net.frozenorb.apiv3.actors.Actor;
+import net.frozenorb.apiv3.actors.ActorType;
import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
@@ -21,7 +22,7 @@ public final class AuditLogEntry {
@Getter private String performedByIp;
@Getter @Indexed private Date performedAt;
@Getter private String actorName;
- @Getter private Actor.Type actorType;
+ @Getter private ActorType actorType;
@Getter private AuditLogActionType actionType;
@Getter private Map actionData;
diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/models/User.java
index ec85bf3..622c110 100644
--- a/src/main/java/net/frozenorb/apiv3/models/User.java
+++ b/src/main/java/net/frozenorb/apiv3/models/User.java
@@ -197,7 +197,8 @@ public final class User {
"reason", accessDenialReason == null ? "Public server" : accessDenialReason
),
"rank", rank,
- "permissions", rankPermissions
+ "permissions", rankPermissions,
+ "totpRequired", getTotpSecret() != null
);
}
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 5f3cdea..4f29d93 100644
--- a/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java
+++ b/src/main/java/net/frozenorb/apiv3/routes/announcements/GETAnnouncements.java
@@ -1,6 +1,7 @@
package net.frozenorb.apiv3.routes.announcements;
import net.frozenorb.apiv3.actors.Actor;
+import net.frozenorb.apiv3.actors.ActorType;
import net.frozenorb.apiv3.models.Server;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.utils.ErrorUtils;
@@ -13,7 +14,7 @@ public final class GETAnnouncements implements Route {
public Object handle(Request req, Response res) {
Actor actor = req.attribute("actor");
- if (actor.getType() != Actor.Type.SERVER) {
+ if (actor.getType() != ActorType.SERVER) {
return ErrorUtils.serverOnly();
}
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 6f670e8..36807c3 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,7 @@
package net.frozenorb.apiv3.routes.chatFilterList;
import net.frozenorb.apiv3.actors.Actor;
+import net.frozenorb.apiv3.actors.ActorType;
import net.frozenorb.apiv3.models.Server;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.utils.ErrorUtils;
@@ -13,7 +14,7 @@ public final class GETChatFilterList implements Route {
public Object handle(Request req, Response res) {
Actor actor = req.attribute("actor");
- if (actor.getType() != Actor.Type.SERVER) {
+ if (actor.getType() != ActorType.SERVER) {
return ErrorUtils.serverOnly();
}
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 3a6e8b7..bb5732a 100644
--- a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java
+++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerHeartbeat.java
@@ -3,6 +3,7 @@ package net.frozenorb.apiv3.routes.servers;
import com.google.common.collect.ImmutableMap;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.actors.Actor;
+import net.frozenorb.apiv3.actors.ActorType;
import net.frozenorb.apiv3.models.Server;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.utils.ErrorUtils;
@@ -19,7 +20,7 @@ public final class POSTServerHeartbeat implements Route {
public Object handle(Request req, Response res) {
Actor actor = req.attribute("actor");
- if (actor.getType() != Actor.Type.SERVER) {
+ if (actor.getType() != ActorType.SERVER) {
return ErrorUtils.serverOnly();
}
diff --git a/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerMetrics.java b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerMetrics.java
new file mode 100644
index 0000000..2ae3429
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/routes/servers/POSTServerMetrics.java
@@ -0,0 +1,34 @@
+package net.frozenorb.apiv3.routes.servers;
+
+import com.google.common.collect.ImmutableMap;
+import com.librato.metrics.LibratoBatch;
+import net.frozenorb.apiv3.APIv3;
+import net.frozenorb.apiv3.actors.Actor;
+import net.frozenorb.apiv3.actors.ActorType;
+import net.frozenorb.apiv3.models.Server;
+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;
+
+import java.util.*;
+
+public final class POSTServerMetrics implements Route {
+
+ public Object handle(Request req, Response res) {
+ Actor actor = req.attribute("actor");
+
+ if (actor.getType() != ActorType.SERVER) {
+ return ErrorUtils.serverOnly();
+ }
+
+ Server actorServer = Server.byId(actor.getName());
+
+ //LibratoBatch batch = new LibratoBatch();
+
+ return ImmutableMap.of();
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLoginInfo.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java
similarity index 86%
rename from src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLoginInfo.java
rename to src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java
index 9597fc3..f3c16b9 100644
--- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLoginInfo.java
+++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java
@@ -2,6 +2,7 @@ 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;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.utils.ErrorUtils;
@@ -11,7 +12,7 @@ import spark.Route;
import java.util.UUID;
-public final class POSTUserLoginInfo implements Route {
+public final class POSTUserLogin implements Route {
public Object handle(Request req, Response res) {
User user = User.byId(req.params("id"));
@@ -19,7 +20,7 @@ public final class POSTUserLoginInfo implements Route {
String userIp = req.queryParams("userIp");
Actor actor = req.attribute("actor");
- if (actor.getType() != Actor.Type.SERVER) {
+ if (actor.getType() != ActorType.SERVER) {
return ErrorUtils.serverOnly();
}
diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java
similarity index 93%
rename from src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyTOTP.java
rename to src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java
index 4b8167f..529f585 100644
--- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserVerifyTOTP.java
+++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserVerifyTOTP.java
@@ -8,7 +8,7 @@ import spark.Request;
import spark.Response;
import spark.Route;
-public final class GETUserVerifyTOTP implements Route {
+public final class POSTUserVerifyTOTP implements Route {
public Object handle(Request req, Response res) {
User user = User.byId(req.params("id"));
diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java b/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java
index 3ac1f92..4eb4d47 100644
--- a/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java
+++ b/src/main/java/net/frozenorb/apiv3/unsorted/LoggingExceptionHandler.java
@@ -14,9 +14,7 @@ public final class LoggingExceptionHandler implements ExceptionHandler {
public void handle(Exception ex, Request req, Response res) {
String code = new ObjectId().toHexString();
- log.error(code + ":");
- ex.printStackTrace();
-
+ log.error(code + ":", ex);
res.body(APIv3.getGson().toJson(ErrorUtils.error("An unknown error has occurred. Please contact a developer with the code \"" + code + "\".")));
}