diff --git a/pom.xml b/pom.xml
index 8551651..5fd7fa3 100644
--- a/pom.xml
+++ b/pom.xml
@@ -67,6 +67,11 @@
mongo-java-driver
3.2.2
+
+ com.cribbstechnologies.clients
+ mandrillClient
+ 1.1
+
org.mongodb.morphia
morphia
diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java
index ece63e3..77bf0d7 100644
--- a/src/main/java/net/frozenorb/apiv3/APIv3.java
+++ b/src/main/java/net/frozenorb/apiv3/APIv3.java
@@ -7,22 +7,25 @@ import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import lombok.Getter;
-import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.routes.GETDump;
+import net.frozenorb.apiv3.routes.GETRoutes;
import net.frozenorb.apiv3.routes.announcements.GETAnnouncements;
import net.frozenorb.apiv3.routes.chatFilterList.GETChatFilterList;
import net.frozenorb.apiv3.routes.grants.DELETEGrant;
import net.frozenorb.apiv3.routes.grants.GETGrants;
+import net.frozenorb.apiv3.routes.grants.GETUserGrants;
import net.frozenorb.apiv3.routes.grants.POSTUserGrant;
+import net.frozenorb.apiv3.routes.ipLog.GETUserIPLog;
import net.frozenorb.apiv3.routes.punishments.DELETEPunishment;
import net.frozenorb.apiv3.routes.punishments.GETPunishment;
import net.frozenorb.apiv3.routes.punishments.GETPunishments;
import net.frozenorb.apiv3.routes.punishments.POSTUserPunish;
+import net.frozenorb.apiv3.routes.ranks.GETRanks;
+import net.frozenorb.apiv3.routes.serverGroups.GETServerGroup;
+import net.frozenorb.apiv3.routes.serverGroups.GETServerGroups;
import net.frozenorb.apiv3.routes.servers.GETServer;
import net.frozenorb.apiv3.routes.servers.GETServers;
-import net.frozenorb.apiv3.routes.users.GETStaff;
-import net.frozenorb.apiv3.routes.users.GETUser;
-import net.frozenorb.apiv3.routes.users.GETUsers;
+import net.frozenorb.apiv3.routes.users.*;
import net.frozenorb.apiv3.weirdStuff.ActorAttributeFilter;
import net.frozenorb.apiv3.weirdStuff.ContentTypeFilter;
import net.frozenorb.apiv3.weirdStuff.FollowAnnotationExclusionStrategy;
@@ -54,10 +57,6 @@ public final class APIv3 {
datastore = morphia.createDatastore(mongoClient, "minehqapi");
datastore.ensureIndexes();
-
- if (ServerGroup.byId("Website") == null) {
- datastore.save(new ServerGroup("Website", "Website"));
- }
}
private void setupHttp() {
@@ -70,21 +69,35 @@ public final class APIv3 {
delete("/grant/:id", new DELETEGrant(), gson::toJson);
get("/grants", new GETGrants(), gson::toJson);
+ get("/user/:id/grants", new GETUserGrants(), gson::toJson);
post("/user/:id:/grant", new POSTUserGrant(), gson::toJson);
+ get("/user/:id/ipLog", new GETUserIPLog(), gson::toJson);
+
delete("/punishment/:id", new DELETEPunishment(), gson::toJson);
get("/punishment/:id", new GETPunishment(), gson::toJson);
get("/punishments", new GETPunishments(), gson::toJson);
- post("/user/:id:/punish", new erPunish(), gson::toJson);
+ post("/user/:id:/punish", new POSTUserPunish(), gson::toJson);
+
+ get("/ranks", new GETRanks(), gson::toJson);
+
+ get("/serverGroup/:id", new GETServerGroup(), gson::toJson);
+ get("/serverGroups", new GETServerGroups(), gson::toJson);
get("/server/:id", new GETServer(), gson::toJson);
get("/servers", new GETServers(), gson::toJson);
- get("/user/:id", new GETUser(), gson::toJson);
- get("/users", new GETUsers(), gson::toJson);
get("/staff", new GETStaff(), gson::toJson);
+ get("/user/:id", new GETUser(), gson::toJson);
+ get("/user/:id/details", new GETUserDetails(), gson::toJson);
+ get("/user/:id/meta/:serverGroup", new GETUserMeta(), gson::toJson);
+ get("/users", new GETUsers(), gson::toJson);
+ post("/user/:id/notify", new POSTUserNotify(), gson::toJson);
+ post("/user/:id/register", new POSTUserRegister(), gson::toJson);
+ put("/user/:id/meta/:serverGroup", new PUTUserMeta(), gson::toJson);
get("/dump/:type", new GETDump(), gson::toJson);
+ get("/routes", new GETRoutes());
after(new ContentTypeFilter());
}
diff --git a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java
index 11b89c2..4848d40 100644
--- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java
+++ b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java
@@ -1,12 +1,14 @@
package net.frozenorb.apiv3.models;
import lombok.Getter;
+import net.frozenorb.apiv3.APIv3;
import org.bson.Document;
import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.Date;
+import java.util.List;
import java.util.UUID;
@Entity(value = "auditLog", noClassnameStored = true)
@@ -20,6 +22,14 @@ public final class AuditLogEntry {
@Getter private String description;
@Getter private Document actionData;
+ public static AuditLogEntry byId(String id) {
+ return APIv3.getDatastore().createQuery(AuditLogEntry.class).field("id").equal(new ObjectId(id)).get();
+ }
+
+ public static List values() {
+ return APIv3.getDatastore().createQuery(AuditLogEntry.class).asList();
+ }
+
public AuditLogEntry() {} // For Morphia
public AuditLogEntry(User performedBy, String performedFrom, String actionType, String description, Document actionData) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/Grant.java b/src/main/java/net/frozenorb/apiv3/models/Grant.java
index 1017616..2945a15 100644
--- a/src/main/java/net/frozenorb/apiv3/models/Grant.java
+++ b/src/main/java/net/frozenorb/apiv3/models/Grant.java
@@ -7,10 +7,7 @@ import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
@Entity(value = "grants", noClassnameStored = true)
public final class Grant {
@@ -33,6 +30,10 @@ public final class Grant {
return APIv3.getDatastore().createQuery(Grant.class).field("id").equal(new ObjectId(id)).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(Grant.class).asList();
+ }
+
public Grant() {} // For Morphia
public Grant(User target, 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 8007a4d..f498c1e 100644
--- a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java
+++ b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java
@@ -7,6 +7,7 @@ import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.Date;
+import java.util.List;
import java.util.UUID;
@Entity(value = "ipLog", noClassnameStored = true)
@@ -19,6 +20,14 @@ public final class IPLogEntry {
@Getter private Date lastSeen;
@Getter private int uses;
+ public static IPLogEntry byId(String id) {
+ return APIv3.getDatastore().createQuery(IPLogEntry.class).field("id").equal(new ObjectId(id)).get();
+ }
+
+ public static List values() {
+ return APIv3.getDatastore().createQuery(IPLogEntry.class).asList();
+ }
+
public IPLogEntry() {} // For Morphia
public IPLogEntry(User user, String ip) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/NotificationLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/NotificationLogEntry.java
deleted file mode 100644
index 28370b5..0000000
--- a/src/main/java/net/frozenorb/apiv3/models/NotificationLogEntry.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package net.frozenorb.apiv3.models;
-
-import lombok.Getter;
-import org.bson.types.ObjectId;
-import org.mongodb.morphia.annotations.Entity;
-import org.mongodb.morphia.annotations.Id;
-
-import java.util.Date;
-import java.util.UUID;
-
-@Entity(value = "notificationLog", noClassnameStored = true)
-public final class NotificationLogEntry {
-
- @Getter @Id private ObjectId id;
- @Getter private UUID target;
- @Getter private Date sentAt;
- @Getter private NotificationType type;
- @Getter private String title;
- @Getter private String body;
-
- public NotificationLogEntry() {} // For Morphia
-
- public NotificationLogEntry(User target, NotificationType type, String title, String body) {
- this.target = target.getId();
- this.sentAt = new Date();
- this.type = type;
- this.title = title;
- this.body = body;
- }
-
- public enum NotificationType {
-
- EMAIL, SMS
-
- }
-
-}
\ 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 3245c8d..6154b50 100644
--- a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java
+++ b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java
@@ -6,6 +6,7 @@ import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.Date;
+import java.util.List;
import java.util.Map;
import java.util.UUID;
@@ -13,7 +14,7 @@ import java.util.UUID;
public final class NotificationTemplate {
@Getter @Id private String id;
- @Getter private String title;
+ @Getter private String subject;
@Getter private String body;
@Getter private Date lastUpdatedAt;
@Getter private UUID lastUpdatedBy;
@@ -22,17 +23,21 @@ public final class NotificationTemplate {
return APIv3.getDatastore().createQuery(NotificationTemplate.class).field("id").equalIgnoreCase(id).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(NotificationTemplate.class).asList();
+ }
+
public NotificationTemplate() {} // For Morphia
- public NotificationTemplate(String title, String body, User creator) {
- this.title = title;
+ public NotificationTemplate(String subject, String body, User creator) {
+ this.subject = subject;
this.body = body;
this.lastUpdatedAt = new Date();
this.lastUpdatedBy = creator.getId();
}
- public void update(String title, String body, User updatedBy) {
- this.title = title;
+ public void update(String subject, String body, User updatedBy) {
+ this.subject = subject;
this.body = body;
this.lastUpdatedAt = new Date();
this.lastUpdatedBy = updatedBy.getId();
@@ -44,8 +49,8 @@ public final class NotificationTemplate {
APIv3.getDatastore().delete(this);
}
- public String fillTitle(Map replacements) {
- return fill(title, replacements);
+ public String fillSubject(Map replacements) {
+ return fill(subject, replacements);
}
public String fillBody(Map replacements) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/Punishment.java b/src/main/java/net/frozenorb/apiv3/models/Punishment.java
index 1d5a34a..589c88f 100644
--- a/src/main/java/net/frozenorb/apiv3/models/Punishment.java
+++ b/src/main/java/net/frozenorb/apiv3/models/Punishment.java
@@ -7,6 +7,7 @@ import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.Date;
+import java.util.List;
import java.util.UUID;
@Entity(value = "punishments", noClassnameStored = true)
@@ -30,6 +31,10 @@ public final class Punishment {
return APIv3.getDatastore().createQuery(Punishment.class).field("id").equal(new ObjectId(id)).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(Punishment.class).asList();
+ }
+
public Punishment() {} // For Morphia
public Punishment(User target, String reason, PunishmentType type, Date expiresAt, User addedBy, Server addedOn) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/models/Rank.java
index 416c68e..49c5775 100644
--- a/src/main/java/net/frozenorb/apiv3/models/Rank.java
+++ b/src/main/java/net/frozenorb/apiv3/models/Rank.java
@@ -5,6 +5,8 @@ import net.frozenorb.apiv3.APIv3;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
+import java.util.List;
+
@Entity(value = "ranks", noClassnameStored = true)
public final class Rank {
@@ -19,6 +21,10 @@ public final class Rank {
return APIv3.getDatastore().createQuery(Rank.class).field("id").equalIgnoreCase(id).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(Rank.class).asList();
+ }
+
public Rank() {} // For Morphia
public Rank(String id, int weight, String displayName, String gameColor, String websiteColor, boolean staffRank) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/Server.java b/src/main/java/net/frozenorb/apiv3/models/Server.java
index 33b089e..4d0fea4 100644
--- a/src/main/java/net/frozenorb/apiv3/models/Server.java
+++ b/src/main/java/net/frozenorb/apiv3/models/Server.java
@@ -5,10 +5,7 @@ import net.frozenorb.apiv3.APIv3;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
-import java.util.Date;
-import java.util.HashSet;
-import java.util.Set;
-import java.util.UUID;
+import java.util.*;
@Entity(value = "servers", noClassnameStored = true)
public final class Server {
@@ -27,6 +24,10 @@ public final class Server {
return APIv3.getDatastore().createQuery(Server.class).field("id").equalIgnoreCase(id).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(Server.class).asList();
+ }
+
public Server() {} // For Morphia
public Server(String id, String bungeeId, String displayName, String secret, ServerGroup group, String ip) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java
index 6001c41..91497dd 100644
--- a/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java
+++ b/src/main/java/net/frozenorb/apiv3/models/ServerGroup.java
@@ -6,6 +6,7 @@ import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.HashSet;
+import java.util.List;
import java.util.Set;
@Entity(value = "serverGroups", noClassnameStored = true)
@@ -20,6 +21,10 @@ public final class ServerGroup {
return APIv3.getDatastore().createQuery(ServerGroup.class).field("id").equalIgnoreCase(id).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(ServerGroup.class).asList();
+ }
+
public ServerGroup() {} // For Morphia
public ServerGroup(String id, String displayName) {
diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/models/User.java
index 97594f2..be8deca 100644
--- a/src/main/java/net/frozenorb/apiv3/models/User.java
+++ b/src/main/java/net/frozenorb/apiv3/models/User.java
@@ -3,13 +3,11 @@ package net.frozenorb.apiv3.models;
import lombok.Getter;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.weirdStuff.ExcludeFromReplies;
+import org.bson.Document;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
-import java.util.Date;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.UUID;
+import java.util.*;
@Entity(value = "users", noClassnameStored = true)
public final class User {
@@ -26,6 +24,14 @@ public final class User {
@Getter private Date lastSeenAt;
@Getter private Date firstSeen;
+ public static User byId(String id) {
+ try {
+ return byId(UUID.fromString(id));
+ } catch (Exception ex) {
+ throw new IllegalArgumentException("Invalid UUID string " + id, ex);
+ }
+ }
+
public static User byId(UUID id) {
return APIv3.getDatastore().createQuery(User.class).field("id").equal(id).get();
}
@@ -46,6 +52,10 @@ public final class User {
return APIv3.getDatastore().createQuery(User.class).field("lastName").equalIgnoreCase(name).get();
}
+ public static List values() {
+ return APIv3.getDatastore().createQuery(User.class).asList();
+ }
+
public User() {} // For Morphia
public User(UUID id, String lastName) {
@@ -75,4 +85,39 @@ public final class User {
return 1 > 0;
}
+ public List getGrants() {
+ return APIv3.getDatastore().createQuery(Grant.class).field("target").equal(id).asList();
+ }
+
+ public List getGrants(ServerGroup scope) {
+ return APIv3.getDatastore().createQuery(Grant.class).field("target").equal(id).field("scopes").equalIgnoreCase(scope.getId()).asList();
+ }
+
+ public List getIPLog() {
+ return APIv3.getDatastore().createQuery(IPLogEntry.class).field("user").equal(id).asList();
+ }
+
+ public List getPunishments() {
+ return APIv3.getDatastore().createQuery(Punishment.class).field("target").equal(id).asList();
+ }
+
+ public List getPunishments(Punishment.PunishmentType type) {
+ return APIv3.getDatastore().createQuery(Punishment.class).field("target").equal(id).field("type").equal(type).asList();
+ }
+
+ public UserMetaEntry getMeta(ServerGroup group) {
+ return APIv3.getDatastore().createQuery(UserMetaEntry.class).field("user").equal(id).field("serverGroup").equalIgnoreCase(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);
+ }
+ }
+
}
\ 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
new file mode 100644
index 0000000..cb75528
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java
@@ -0,0 +1,42 @@
+package net.frozenorb.apiv3.models;
+
+import lombok.Getter;
+import lombok.Setter;
+import net.frozenorb.apiv3.APIv3;
+import org.bson.Document;
+import org.bson.types.ObjectId;
+import org.mongodb.morphia.annotations.Entity;
+import org.mongodb.morphia.annotations.Id;
+
+import java.util.List;
+import java.util.UUID;
+
+@Entity(value = "userMeta", noClassnameStored = true)
+public final class UserMetaEntry {
+
+ @Getter @Id private ObjectId id;
+ @Getter private UUID user;
+ @Getter private String serverGroup;
+ @Getter @Setter private Document data;
+
+ public static UserMetaEntry byId(String id) {
+ return APIv3.getDatastore().createQuery(UserMetaEntry.class).field("id").equal(new ObjectId(id)).get();
+ }
+
+ public static List values() {
+ return APIv3.getDatastore().createQuery(UserMetaEntry.class).asList();
+ }
+
+ public UserMetaEntry() {} // For Morphia
+
+ public UserMetaEntry(User user, ServerGroup serverGroup, Document data) {
+ this.user = user.getId();
+ this.serverGroup = serverGroup.getId();
+ this.data = data;
+ }
+
+ public void delete() {
+ APIv3.getDatastore().delete(this);
+ }
+
+}
\ No newline at end of file
diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETRoutes.java b/src/main/java/net/frozenorb/apiv3/routes/GETRoutes.java
new file mode 100644
index 0000000..eb8bbc6
--- /dev/null
+++ b/src/main/java/net/frozenorb/apiv3/routes/GETRoutes.java
@@ -0,0 +1,71 @@
+package net.frozenorb.apiv3.routes;
+
+import spark.Request;
+import spark.Response;
+import spark.Route;
+import spark.Spark;
+import spark.route.HttpMethod;
+import spark.route.SimpleRouteMatcher;
+
+import java.lang.reflect.Field;
+import java.util.List;
+
+import static spark.Spark.halt;
+
+public final class GETRoutes implements Route {
+
+ private List