Push a bunch of changes

This commit is contained in:
Colin McDonald 2016-04-17 15:23:02 -04:00
parent 922357fc7f
commit fb12a13528
22 changed files with 131 additions and 37 deletions

View File

@ -7,7 +7,7 @@ import com.mongodb.MongoClient;
import com.mongodb.MongoCredential;
import com.mongodb.ServerAddress;
import lombok.Getter;
import net.frozenorb.apiv3.models.*;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.routes.announcements.GETAnnouncements;
import net.frozenorb.apiv3.routes.chatFilterList.GETChatFilterList;
import net.frozenorb.apiv3.routes.grants.DELETEGrant;
@ -18,9 +18,9 @@ import net.frozenorb.apiv3.routes.punishments.GETPunishments;
import net.frozenorb.apiv3.routes.punishments.POSTUserPunish;
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.GETStaff;
import net.frozenorb.apiv3.weirdStuff.ActorAttributeFilter;
import net.frozenorb.apiv3.weirdStuff.ContentTypeFilter;
import net.frozenorb.apiv3.weirdStuff.FollowAnnotationExclusionStrategy;
@ -29,8 +29,6 @@ import org.bson.types.ObjectId;
import org.mongodb.morphia.Datastore;
import org.mongodb.morphia.Morphia;
import java.util.*;
import static spark.Spark.*;
public final class APIv3 {
@ -54,6 +52,10 @@ 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() {
@ -76,7 +78,7 @@ public final class APIv3 {
get("/servers", new GETServers(), gson::toJson);
get("/user/:id", new GETUser(), gson::toJson);
get("/users", new GETUsers() gson::toJson);
get("/users", new GETUsers(), gson::toJson);
get("/staff", new GETStaff(), gson::toJson);
after(new ContentTypeFilter());

View File

@ -12,24 +12,22 @@ import java.util.UUID;
@Entity(value = "auditLog", noClassnameStored = true)
public final class AuditLogEntry {
@Id private ObjectId id;
@Getter @Id private ObjectId id;
@Getter private UUID performedBy;
@Getter private Date performedAt;
@Getter private String performedFrom;
@Getter private String actionType;
@Getter private String description;
@Getter private Document actionData;
public AuditLogEntry() {} // For Morphia
public AuditLogEntry(User performedBy, String performedFromIp, String actionType) {
this(performedBy, performedFromIp, actionType, new Document());
}
public AuditLogEntry(User performedBy, String performedFrom, String actionType, Document actionData) {
public AuditLogEntry(User performedBy, String performedFrom, String actionType, String description, Document actionData) {
this.performedBy = performedBy.getId();
this.performedAt = new Date();
this.performedFrom = performedFrom;
this.actionType = actionType;
this.description = description;
this.actionData = actionData;
}

View File

@ -7,12 +7,15 @@ import org.bson.types.ObjectId;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Entity(value = "grants", noClassnameStored = true)
public final class Grant {
@Id private ObjectId id;
@Getter @Id private ObjectId id;
@Getter private UUID target;
@Getter private String reason;
@Getter private Set<String> scopes;

View File

@ -1,5 +1,6 @@
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;
@ -7,7 +8,7 @@ import org.mongodb.morphia.annotations.Id;
@Entity(value = "ipBans", noClassnameStored = true)
public final class IPBan {
@Id private ObjectId id;
@Getter @Id private ObjectId id;
public IPBan() {} // For Morphia

View File

@ -12,7 +12,7 @@ import java.util.UUID;
@Entity(value = "ipLog", noClassnameStored = true)
public final class IPLogEntry {
@Id private ObjectId id;
@Getter @Id private ObjectId id;
@Getter private UUID user;
@Getter private String ip;
@Getter private Date firstSeen;

View File

@ -11,7 +11,7 @@ import java.util.UUID;
@Entity(value = "notificationLog", noClassnameStored = true)
public final class NotificationLogEntry {
@Id private ObjectId id;
@Getter @Id private ObjectId id;
@Getter private UUID target;
@Getter private Date sentAt;
@Getter private NotificationType type;
@ -20,8 +20,8 @@ public final class NotificationLogEntry {
public NotificationLogEntry() {} // For Morphia
public NotificationLogEntry(UUID target, NotificationType type, String title, String body) {
this.target = target;
public NotificationLogEntry(User target, NotificationType type, String title, String body) {
this.target = target.getId();
this.sentAt = new Date();
this.type = type;
this.title = title;

View File

@ -12,14 +12,14 @@ import java.util.UUID;
@Entity(value = "notificationTemplates", noClassnameStored = true)
public final class NotificationTemplate {
@Id private String id;
@Getter @Id private String id;
@Getter private String title;
@Getter private String body;
@Getter private Date lastUpdatedAt;
@Getter private UUID lastUpdatedBy;
public static NotificationTemplate byId(String id) {
return APIv3.getDatastore().createQuery(NotificationTemplate.class).field("id").equal(id).get();
return APIv3.getDatastore().createQuery(NotificationTemplate.class).field("id").equalIgnoreCase(id).get();
}
public NotificationTemplate() {} // For Morphia

View File

@ -12,7 +12,7 @@ import java.util.UUID;
@Entity(value = "punishments", noClassnameStored = true)
public final class Punishment {
@Id private ObjectId id;
@Getter @Id private ObjectId id;
@Getter private UUID target;
@Getter private String reason;
@Getter private PunishmentType type;
@ -42,8 +42,8 @@ public final class Punishment {
this.addedOn = addedOn.getId();
}
public void delete(UUID removedBy, String reason) {
this.removedBy = removedBy;
public void delete(User removedBy, String reason) {
this.removedBy = removedBy.getId();
this.removedAt = new Date();
this.removalReason = reason;

View File

@ -16,7 +16,7 @@ public final class Rank {
@Getter private boolean staffRank;
public static Rank byId(String id) {
return APIv3.getDatastore().createQuery(Rank.class).field("id").equal(id).get();
return APIv3.getDatastore().createQuery(Rank.class).field("id").equalIgnoreCase(id).get();
}
public Rank() {} // For Morphia

View File

@ -5,7 +5,10 @@ import net.frozenorb.apiv3.APIv3;
import org.mongodb.morphia.annotations.Entity;
import org.mongodb.morphia.annotations.Id;
import java.util.*;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;
import java.util.UUID;
@Entity(value = "servers", noClassnameStored = true)
public final class Server {
@ -21,7 +24,7 @@ public final class Server {
@Getter private Set<UUID> players;
public static Server byId(String id) {
return APIv3.getDatastore().createQuery(Server.class).field("id").equal(id).get();
return APIv3.getDatastore().createQuery(Server.class).field("id").equalIgnoreCase(id).get();
}
public Server() {} // For Morphia

View File

@ -17,7 +17,7 @@ public final class ServerGroup {
@Getter private Set<String> chatFilterList;
public static ServerGroup byId(String id) {
return APIv3.getDatastore().createQuery(ServerGroup.class).field("id").equal(id).get();
return APIv3.getDatastore().createQuery(ServerGroup.class).field("id").equalIgnoreCase(id).get();
}
public ServerGroup() {} // For Morphia

View File

@ -40,7 +40,7 @@ public final class User {
@Deprecated
public static User byName(String name) {
return APIv3.getDatastore().createQuery(User.class).field("lastName").equal(name).get();
return APIv3.getDatastore().createQuery(User.class).field("lastName").equalIgnoreCase(name).get();
}
public User() {} // For Morphia
@ -61,4 +61,15 @@ public final class User {
aliases.put(lastName, new Date());
}
public boolean hasPermissionAnywhere(String permission) {
return hasPermissionScoped(permission, null);
}
public boolean hasPermissionScoped(String permission, ServerGroup scope) {
// TODO: BLAH FIX THIS IF WE DONT REMOVE THEN IDK WHAT TO SAY
// Also this is 1 > 0 because 'return true;' means all usages of this
// get marked as a warning until we change it.
return 1 > 0;
}
}

View File

@ -1,9 +1,11 @@
package net.frozenorb.apiv3.routes.grants;
import net.frozenorb.apiv3.models.Grant;
import net.frozenorb.apiv3.models.Server;
import net.frozenorb.apiv3.models.ServerGroup;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.AuditLog;
import net.frozenorb.apiv3.weirdStuff.ErrorUtils;
import net.frozenorb.apiv3.weirdStuff.Permissions;
import org.bson.Document;
import spark.Request;
import spark.Response;
import spark.Route;
@ -14,10 +16,27 @@ public final class DELETEGrant implements Route {
public Object handle(Request req, Response res) {
Grant grant = Grant.byId(req.params("id"));
if (grant == null) {
return ErrorUtils.notFound("Grant", req.params("id"));
} else if (!grant.isActive()) {
return ErrorUtils.error("Cannot remove an inactive grant.");
}
User removedBy = User.byId(UUID.fromString(req.queryParams("removedBy")));
String requiredPermission = Permissions.REMOVE_GRANT + "." + grant.getRank();
if (removedBy == null) {
return ErrorUtils.notFound("User", req.queryParams("removedBy"));
} else if (!removedBy.hasPermissionAnywhere(requiredPermission)) {
return ErrorUtils.unauthorized(requiredPermission);
}
String removedByIp = req.queryParams("removedByIp");
String reason = req.queryParams("removalReason");
grant.delete(removedBy.getId(), reason);
grant.delete(removedBy, reason);
AuditLog.log(removedBy, removedByIp, "grant.remove", "Removed a " + grant.getRank() + " grant from " + grant.getTarget() + " for \" " + reason + "\"", new Document("grantId", grant.getId()));
return grant;
}

View File

@ -2,8 +2,6 @@ package net.frozenorb.apiv3.routes.grants;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.Grant;
import net.frozenorb.apiv3.models.Server;
import net.frozenorb.apiv3.models.ServerGroup;
import spark.Request;
import spark.Response;
import spark.Route;

View File

@ -18,9 +18,9 @@ public final class POSTUserGrant implements Route {
Set<String> scopes = new HashSet<>(Arrays.asList(req.queryParams("scopes").split(",")));
Rank rank = Rank.byId(req.queryParams("rank"));
Date expiresAt = new Date(Long.parseLong(req.queryParams("expiresAt")));
User createdBy = User.byId(UUID.fromString(req.queryParams("createdBy")));
User addedBy = User.byId(UUID.fromString(req.queryParams("addedBy")));
Grant grant = new Grant(target.getId(), reason, scopes, rank.getId(), expiresAt, createdBy.getId());
Grant grant = new Grant(target, reason, scopes, rank, expiresAt, addedBy);
APIv3.getDatastore().save(grant);
return grant;
}

View File

@ -2,6 +2,8 @@ package net.frozenorb.apiv3.routes.punishments;
import net.frozenorb.apiv3.models.Punishment;
import net.frozenorb.apiv3.models.User;
import net.frozenorb.apiv3.weirdStuff.AuditLog;
import org.bson.Document;
import spark.Request;
import spark.Response;
import spark.Route;
@ -13,9 +15,11 @@ public final class DELETEPunishment implements Route {
public Object handle(Request req, Response res) {
Punishment punishment = Punishment.byId(req.params("id"));
User removedBy = User.byId(UUID.fromString(req.queryParams("removedBy")));
String removedByIp = req.queryParams("removedByIp");
String reason = req.queryParams("removalReason");
punishment.delete(removedBy.getId(), reason);
punishment.delete(removedBy, reason);
AuditLog.log(removedBy, removedByIp, "punishment.remove", "Removed a " + punishment.getType().name().toLowerCase() + " from " + punishment.getTarget() + " for \" " + reason + "\"", new Document("punishmentId", punishment.getId()));
return punishment;
}

View File

@ -21,7 +21,7 @@ public final class POSTUserPunish implements Route {
User createdBy = User.byId(UUID.fromString(req.queryParams("createdBy")));
Server addedOn = Server.byId(req.queryParams("addedOn"));
Punishment punishment = new Punishment(target.getId(), reason, type, expiresAt, createdBy.getId(), addedOn.getId());
Punishment punishment = new Punishment(target, reason, type, expiresAt, createdBy, addedOn);
APIv3.getDatastore().save(punishment);
return punishment;
}

View File

@ -1,5 +1,6 @@
package net.frozenorb.apiv3.routes.servers;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.Server;
import spark.Request;
import spark.Response;

View File

@ -0,0 +1,20 @@
package net.frozenorb.apiv3.weirdStuff;
import lombok.experimental.UtilityClass;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.models.AuditLogEntry;
import net.frozenorb.apiv3.models.User;
import org.bson.Document;
@UtilityClass
public class AuditLog {
public static void log(User performedBy, String performedFrom, String actionType, String description) {
log(performedBy, performedFrom, actionType, description, new Document());
}
public static void log(User performedBy, String performedFrom, String actionType, String description, Document actionData) {
APIv3.getDatastore().save(new AuditLogEntry(performedBy, performedFrom, actionType, description, actionData));
}
}

View File

@ -0,0 +1,21 @@
package net.frozenorb.apiv3.weirdStuff;
import lombok.experimental.UtilityClass;
import org.bson.Document;
@UtilityClass
public class ErrorUtils {
public static Document notFound(String itemType, String id) {
return error(itemType + " with id " + id + " cannot be found.");
}
public static Document unauthorized(String permission) {
return error("Unauthorized access. Permission \"" + permission + "\" required.");
}
public static Document error(String reason) {
return new Document("success", false).append("reason", reason);
}
}

View File

@ -13,6 +13,9 @@ public final class ObjectIdTypeAdapter extends TypeAdapter<ObjectId> {
writer.value(write.toString());
}
// This is used with Gson, which is only used
// to serialize outgoing responses, thus we
// don't need to have a read method.
public ObjectId read(JsonReader reader) {
throw new IllegalArgumentException();
}

View File

@ -0,0 +1,10 @@
package net.frozenorb.apiv3.weirdStuff;
import lombok.experimental.UtilityClass;
@UtilityClass
public class Permissions {
public static final String REMOVE_GRANT = "minehq.grant.remove"; // minehq.grant.remove.%RANK%
}