Push a bunch of changes
This commit is contained in:
parent
922357fc7f
commit
fb12a13528
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
|
|
@ -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%
|
||||
|
||||
}
|
Loading…
Reference in New Issue