Whoa even more changes

This commit is contained in:
Colin McDonald 2016-04-26 20:46:34 -04:00
parent 39817d154c
commit 1f5663ab89
37 changed files with 613 additions and 88 deletions

View File

@ -67,6 +67,11 @@
<artifactId>mongo-java-driver</artifactId>
<version>3.2.2</version>
</dependency>
<dependency>
<groupId>com.cribbstechnologies.clients</groupId>
<artifactId>mandrillClient</artifactId>
<version>1.1</version>
</dependency>
<dependency>
<groupId>org.mongodb.morphia</groupId>
<artifactId>morphia</artifactId>

View File

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

View File

@ -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<AuditLogEntry> values() {
return APIv3.getDatastore().createQuery(AuditLogEntry.class).asList();
}
public AuditLogEntry() {} // For Morphia
public AuditLogEntry(User performedBy, String performedFrom, String actionType, String description, Document actionData) {

View File

@ -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<Grant> values() {
return APIv3.getDatastore().createQuery(Grant.class).asList();
}
public Grant() {} // For Morphia
public Grant(User target, String reason, Set<ServerGroup> scopes, Rank rank, Date expiresAt, User addedBy) {

View File

@ -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<IPLogEntry> values() {
return APIv3.getDatastore().createQuery(IPLogEntry.class).asList();
}
public IPLogEntry() {} // For Morphia
public IPLogEntry(User user, String ip) {

View File

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

View File

@ -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<NotificationTemplate> 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<String, Object> replacements) {
return fill(title, replacements);
public String fillSubject(Map<String, Object> replacements) {
return fill(subject, replacements);
}
public String fillBody(Map<String, Object> replacements) {

View File

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

View File

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

View File

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

View File

@ -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<ServerGroup> values() {
return APIv3.getDatastore().createQuery(ServerGroup.class).asList();
}
public ServerGroup() {} // For Morphia
public ServerGroup(String id, String displayName) {

View File

@ -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<User> 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<Grant> getGrants() {
return APIv3.getDatastore().createQuery(Grant.class).field("target").equal(id).asList();
}
public List<Grant> getGrants(ServerGroup scope) {
return APIv3.getDatastore().createQuery(Grant.class).field("target").equal(id).field("scopes").equalIgnoreCase(scope.getId()).asList();
}
public List<IPLogEntry> getIPLog() {
return APIv3.getDatastore().createQuery(IPLogEntry.class).field("user").equal(id).asList();
}
public List<Punishment> getPunishments() {
return APIv3.getDatastore().createQuery(Punishment.class).field("target").equal(id).asList();
}
public List<Punishment> 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);
}
}
}

View File

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

View File

@ -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<Object> routes;
private Field httpMethodField;
private Field pathField;
private Field targetField;
public GETRoutes() {
try {
Object spark = Spark.getInstance();
Field routeMatcherField = spark.getClass().getDeclaredField("routeMatcher");
routeMatcherField.setAccessible(true);
SimpleRouteMatcher routeMatcher = (SimpleRouteMatcher) routeMatcherField.get(spark);
Field routesField = routeMatcher.getClass().getDeclaredField("routes");
routesField.setAccessible(true);
routes = (List<Object>) routesField.get(routeMatcher);
Class<?> routeEntryClass = Class.forName("spark.route.RouteEntry");
httpMethodField = routeEntryClass.getDeclaredField("httpMethod");
httpMethodField.setAccessible(true);
pathField = routeEntryClass.getDeclaredField("path");
pathField.setAccessible(true);
targetField = routeEntryClass.getDeclaredField("target");
targetField.setAccessible(true);
} catch (Exception ex) {
throw new RuntimeException(ex);
}
}
public Object handle(Request req, Response res) {
try {
String response = "";
for (Object route : routes) {
HttpMethod httpMethod = (HttpMethod) httpMethodField.get(route);
String path = (String) pathField.get(route);
Object target = targetField.get(route);
if (httpMethod == HttpMethod.before || httpMethod == HttpMethod.after) {
continue;
}
String append = httpMethod.name().toUpperCase() + " " + path + " (" + target + ")<br />";
response += append;
}
halt(response); // We use halt to avoid our content type filter (gson serialization is already avoided because we don't have the filter on this route)
return null; // Return is required but will never be reached
} catch (IllegalAccessException ex) { // If we use a generic Exception we'd catch the halt() call (it throws an exception)
ex.printStackTrace();
return ex;
}
}
}

View File

@ -10,8 +10,6 @@ import spark.Request;
import spark.Response;
import spark.Route;
import java.util.UUID;
public final class DELETEGrant implements Route {
public Object handle(Request req, Response res) {
@ -23,7 +21,7 @@ public final class DELETEGrant implements Route {
return ErrorUtils.error("Cannot remove an inactive grant.");
}
User removedBy = User.byId(UUID.fromString(req.queryParams("removedBy")));
User removedBy = User.byId(req.queryParams("removedBy"));
String requiredPermission = Permissions.REMOVE_GRANT + "." + grant.getRank();
if (removedBy == null) {

View File

@ -1,7 +1,5 @@
package net.frozenorb.apiv3.routes.grants;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.Grant;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import spark.Request;
@ -17,7 +15,7 @@ public final class GETUserGrants implements Route {
return ErrorUtils.notFound("User", req.params("id"));
}
return APIv3.getDatastore().createQuery(Grant.class).order("addedAt").limit(limit).offset(offset).asList();
return target.getGrants();
}
}

View File

@ -14,7 +14,6 @@ import spark.Route;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
public final class POSTUserGrant implements Route {
@ -46,7 +45,7 @@ public final class POSTUserGrant implements Route {
return ErrorUtils.invalidInput("Expiration date cannot be in the past.");
}
User addedBy = User.byId(UUID.fromString(req.queryParams("addedBy")));
User addedBy = User.byId(req.queryParams("addedBy"));
String requiredPermission = Permissions.CREATE_GRANT + "." + rank.getId();
if (addedBy == null) {

View File

@ -0,0 +1,21 @@
package net.frozenorb.apiv3.routes.ipLog;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import spark.Request;
import spark.Response;
import spark.Route;
public final class GETUserIPLog implements Route {
public Object handle(Request req, Response res) {
User target = User.byIdOrName(req.params("id"));
if (target == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
return target.getIPLog();
}
}

View File

@ -10,8 +10,6 @@ import spark.Request;
import spark.Response;
import spark.Route;
import java.util.UUID;
public final class DELETEPunishment implements Route {
public Object handle(Request req, Response res) {
@ -23,7 +21,7 @@ public final class DELETEPunishment implements Route {
return ErrorUtils.error("Cannot remove an inactive punishment.");
}
User removedBy = User.byId(UUID.fromString(req.queryParams("removedBy")));
User removedBy = User.byId(req.queryParams("removedBy"));
String requiredPermission = Permissions.REMOVE_PUNISHMENT + "." + punishment.getType().name();
if (removedBy == null) {

View File

@ -1,7 +1,6 @@
package net.frozenorb.apiv3.routes.punishments;
import net.frozenorb.apiv3.models.Punishment;
import net.frozenorb.apiv3.models.Server;
import spark.Request;
import spark.Response;
import spark.Route;

View File

@ -11,7 +11,6 @@ import spark.Response;
import spark.Route;
import java.util.Date;
import java.util.UUID;
public final class POSTUserPunish implements Route {
@ -35,7 +34,7 @@ public final class POSTUserPunish implements Route {
return ErrorUtils.invalidInput("Expiration date cannot be in the past.");
}
User addedBy = User.byId(UUID.fromString(req.queryParams("addedBy")));
User addedBy = User.byId(req.queryParams("addedBy"));
String requiredPermission = Permissions.CREATE_PUNISHMENT + "." + type.name();
if (addedBy == null) {

View File

@ -0,0 +1,14 @@
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 Object handle(Request req, Response res) {
return Rank.values();
}
}

View File

@ -0,0 +1,14 @@
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 Object handle(Request req, Response res) {
return ServerGroup.byId(req.params("id"));
}
}

View File

@ -0,0 +1,14 @@
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 Object handle(Request req, Response res) {
return ServerGroup.values();
}
}

View File

@ -1,6 +1,5 @@
package net.frozenorb.apiv3.routes.servers;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.Server;
import spark.Request;
import spark.Response;
@ -9,7 +8,7 @@ import spark.Route;
public final class GETServers implements Route {
public Object handle(Request req, Response res) {
return APIv3.getDatastore().createQuery(Server.class).asList();
return Server.values();
}
}

View File

@ -0,0 +1,32 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.models.UserMetaEntry;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import spark.Request;
import spark.Response;
import spark.Route;
public final class DELETEUserMeta implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
ServerGroup serverGroup = ServerGroup.byId(req.params("serverGroup"));
if (serverGroup == null) {
return ErrorUtils.notFound("Server group", req.params("serverGroup"));
}
UserMetaEntry userMetaEntry = user.getMeta(serverGroup);
userMetaEntry.delete();
return userMetaEntry.getData();
}
}

View File

@ -18,7 +18,7 @@ public final class GETStaff implements Route {
public Object handle(Request req, Response res) {
Map<String, Rank> staffRanks = new HashMap<>();
APIv3.getDatastore().createQuery(Rank.class).forEach(rank -> {
Rank.values().forEach(rank -> {
if (rank.isStaffRank()) {
staffRanks.put(rank.getId(), rank);
}

View File

@ -0,0 +1,27 @@
package net.frozenorb.apiv3.routes.users;
import com.google.common.collect.ImmutableMap;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import spark.Request;
import spark.Response;
import spark.Route;
public final class GETUserDetails implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
return ImmutableMap.of(
"user", user,
"grants", user.getGrants(),
"ipLog", user.getIPLog(),
"punishments", user.getPunishments()
);
}
}

View File

@ -0,0 +1,30 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.models.UserMetaEntry;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import spark.Request;
import spark.Response;
import spark.Route;
public final class GETUserMeta implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
ServerGroup serverGroup = ServerGroup.byId(req.params("serverGroup"));
if (serverGroup == null) {
return ErrorUtils.notFound("Server group", req.params("serverGroup"));
}
UserMetaEntry userMetaEntry = user.getMeta(serverGroup);
return userMetaEntry.getData();
}
}

View File

@ -1,6 +1,5 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.User;
import spark.Request;
import spark.Response;
@ -9,7 +8,7 @@ import spark.Route;
public final class GETUsers implements Route {
public Object handle(Request req, Response res) {
return APIv3.getDatastore().createQuery(User.class).asList();
return User.values();
}
}

View File

@ -0,0 +1,55 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.NotificationTemplate;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import net.frozenorb.apiv3.weirdStuff.Notification;
import org.bson.Document;
import spark.Request;
import spark.Response;
import spark.Route;
import java.util.HashMap;
import java.util.Map;
public final class POSTUserNotify implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
if (user.getEmail() == null || user.getEmail().isEmpty()) {
return ErrorUtils.error("User provided does not have email set.");
}
NotificationTemplate template = NotificationTemplate.byId(req.queryParams("template"));
if (template == null) {
return ErrorUtils.notFound("Notification template", req.queryParams("template"));
}
Map<String, Object> subjectReplacements = new HashMap<>();
Map<String, Object> bodyReplacements = new HashMap<>();
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 new Document("success", true);
} catch (Exception ex) {
return ErrorUtils.error("Failed to send notification");
}
}
}

View File

@ -0,0 +1,25 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import spark.Request;
import spark.Response;
import spark.Route;
public final class POSTUserRegister implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
if (user.getEmail() == null || user.getEmail().isEmpty()) {
return ErrorUtils.error("User provided does not have email set.");
}
return null;
}
}

View File

@ -0,0 +1,32 @@
package net.frozenorb.apiv3.routes.users;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import org.bson.Document;
import spark.Request;
import spark.Response;
import spark.Route;
public final class PUTUserMeta implements Route {
public Object handle(Request req, Response res) {
User user = User.byIdOrName(req.params("id"));
if (user == null) {
return ErrorUtils.notFound("User", req.params("id"));
}
ServerGroup serverGroup = ServerGroup.byId(req.params("serverGroup"));
if (serverGroup == null) {
return ErrorUtils.notFound("Server group", req.params("serverGroup"));
}
Document data = Document.parse(req.body());
user.saveMeta(serverGroup, data);
return data;
}
}

View File

@ -1,6 +1,5 @@
package net.frozenorb.apiv3.weirdStuff;
import net.frozenorb.apiv3.models.Server;
import spark.Filter;
import spark.Request;
import spark.Response;
@ -8,7 +7,7 @@ import spark.Response;
public final class ActorAttributeFilter implements Filter {
public void handle(Request req, Response res) {
req.attribute("server", Server.byId(req.queryParams("server")));
//req.attribute("server", Server.byId(req.queryParams("server")));
}
}

View File

@ -0,0 +1,41 @@
package net.frozenorb.apiv3.weirdStuff;
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 org.apache.http.impl.client.DefaultHttpClient;
import java.util.Properties;
@UtilityClass
public class MandrillUtils {
public static MandrillMessagesRequest createMessagesRequest() {
Properties props = new Properties();
try {
props.load(MandrillUtils.class.getClassLoader().getResourceAsStream("mandrill.properties"));
} catch (Exception ex) {
throw new RuntimeException(ex);
}
MandrillConfiguration config = new MandrillConfiguration();
config.setApiKey(props.getProperty("apiKey"));
config.setApiVersion("1.0");
config.setBaseURL("https://mandrillapp.com/api");
MandrillRESTRequest request = new MandrillRESTRequest();
request.setConfig(config);
request.setObjectMapper(new ObjectMapper());
request.setHttpClient(new DefaultHttpClient());
MandrillMessagesRequest messagesRequest = new MandrillMessagesRequest();
messagesRequest.setRequest(request);
return messagesRequest;
}
}

View File

@ -0,0 +1,50 @@
package net.frozenorb.apiv3.weirdStuff;
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 net.frozenorb.apiv3.models.NotificationTemplate;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;
import java.io.IOException;
import java.util.Map;
public final class Notification {
private static MandrillMessagesRequest messagesRequest = MandrillUtils.createMessagesRequest();
private String subject;
private String body;
public Notification(NotificationTemplate template, Map<String, Object> subjectReplacements, Map<String, Object> bodyReplacements) {
this.subject = template.fillSubject(subjectReplacements);
this.body = template.fillSubject(bodyReplacements);
}
public void sendAsEmail(String email) throws IOException {
MandrillHtmlMessage message = new MandrillHtmlMessage();
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)
});
try {
MandrillMessageRequest request = new MandrillMessageRequest();
request.setMessage(message);
messagesRequest.sendMessage(request);
} catch (RequestFailedException ex) {
throw new IOException("Failed to send notification to user", ex);
}
}
public void sendAsText(String phoneNumber) throws IOException {
throw new IOException(new NotImplementedException());
}
}

View File

@ -0,0 +1 @@
apiKey=0OYtwymqJP6oqvszeJu0vQ