From 3780ead45800c29efcd74412dbed1ceacf0bb276 Mon Sep 17 00:00:00 2001 From: Colin McDonald Date: Thu, 28 Apr 2016 16:57:44 -0400 Subject: [PATCH] General API work --- src/main/java/net/frozenorb/apiv3/APIv3.java | 67 ++++++------------- .../ActorAttributeFilter.java | 3 +- .../apiv3/filters/AuthorizationFilter.java | 20 ++++++ .../ContentTypeFilter.java | 2 +- .../frozenorb/apiv3/models/AuditLogEntry.java | 11 ++- .../net/frozenorb/apiv3/models/Grant.java | 13 +++- .../frozenorb/apiv3/models/IPLogEntry.java | 1 - .../apiv3/models/NotificationTemplate.java | 13 +--- .../frozenorb/apiv3/models/Punishment.java | 1 - .../java/net/frozenorb/apiv3/models/Rank.java | 2 +- .../java/net/frozenorb/apiv3/models/User.java | 26 ++++++- .../frozenorb/apiv3/models/UserMetaEntry.java | 1 - .../net/frozenorb/apiv3/routes/GETDump.java | 2 +- .../apiv3/routes/POSTConfirmRegister.java | 2 +- .../apiv3/routes/grants/DELETEGrant.java | 9 ++- .../apiv3/routes/grants/GETUserGrants.java | 2 +- .../apiv3/routes/grants/POSTUserGrant.java | 4 +- .../apiv3/routes/ipLog/GETUserIPLog.java | 2 +- .../routes/punishments/DELETEPunishment.java | 9 ++- .../routes/punishments/POSTUserPunish.java | 4 +- .../apiv3/routes/users/DELETEUserMeta.java | 2 +- .../apiv3/routes/users/GETUserDetails.java | 2 +- .../apiv3/routes/users/GETUserMeta.java | 2 +- .../apiv3/routes/users/GETUsers.java | 14 ---- .../apiv3/routes/users/POSTUserLogin.java | 27 ++++++++ .../apiv3/routes/users/POSTUserNotify.java | 4 +- .../apiv3/routes/users/POSTUserRegister.java | 4 +- .../apiv3/routes/users/PUTUserMeta.java | 2 +- .../ExcludeFromReplies.java | 2 +- .../FollowAnnotationExclusionStrategy.java | 2 +- .../ObjectIdTypeAdapter.java | 2 +- .../apiv3/{weirdStuff => unsorted}/Actor.java | 4 +- .../frozenorb/apiv3/unsorted/AuditLog.java | 22 ++++++ .../Notification.java | 5 +- .../{weirdStuff => unsorted}/Permissions.java | 2 +- .../{weirdStuff => utils}/ErrorUtils.java | 2 +- .../{weirdStuff => utils}/MandrillUtils.java | 15 +---- .../apiv3/utils/PermissionUtils.java | 22 ++++++ .../frozenorb/apiv3/weirdStuff/AuditLog.java | 20 ------ src/main/resources/apiv3.properties | 3 +- src/main/resources/mandrill.properties | 1 - 41 files changed, 196 insertions(+), 157 deletions(-) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => filters}/ActorAttributeFilter.java (88%) create mode 100644 src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java rename src/main/java/net/frozenorb/apiv3/{weirdStuff => filters}/ContentTypeFilter.java (85%) delete mode 100644 src/main/java/net/frozenorb/apiv3/routes/users/GETUsers.java create mode 100644 src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java rename src/main/java/net/frozenorb/apiv3/{weirdStuff => serialization}/ExcludeFromReplies.java (85%) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => serialization}/FollowAnnotationExclusionStrategy.java (90%) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => serialization}/ObjectIdTypeAdapter.java (93%) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => unsorted}/Actor.java (62%) create mode 100644 src/main/java/net/frozenorb/apiv3/unsorted/AuditLog.java rename src/main/java/net/frozenorb/apiv3/{weirdStuff => unsorted}/Notification.java (92%) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => unsorted}/Permissions.java (92%) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => utils}/ErrorUtils.java (94%) rename src/main/java/net/frozenorb/apiv3/{weirdStuff => utils}/MandrillUtils.java (73%) create mode 100644 src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java delete mode 100644 src/main/java/net/frozenorb/apiv3/weirdStuff/AuditLog.java delete mode 100644 src/main/resources/mandrill.properties diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index ad20ef6..8bda225 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -7,8 +7,9 @@ import com.mongodb.MongoClient; import com.mongodb.MongoCredential; import com.mongodb.ServerAddress; import lombok.Getter; -import net.frozenorb.apiv3.models.Rank; -import net.frozenorb.apiv3.models.ServerGroup; +import net.frozenorb.apiv3.filters.ActorAttributeFilter; +import net.frozenorb.apiv3.filters.AuthorizationFilter; +import net.frozenorb.apiv3.filters.ContentTypeFilter; import net.frozenorb.apiv3.routes.GETDump; import net.frozenorb.apiv3.routes.GETRoutes; import net.frozenorb.apiv3.routes.announcements.GETAnnouncements; @@ -28,27 +29,30 @@ 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.*; -import net.frozenorb.apiv3.weirdStuff.*; +import net.frozenorb.apiv3.serialization.FollowAnnotationExclusionStrategy; +import net.frozenorb.apiv3.serialization.ObjectIdTypeAdapter; import org.bson.types.ObjectId; import org.mongodb.morphia.Datastore; import org.mongodb.morphia.Morphia; -import spark.Request; -import spark.Spark; -import java.util.HashMap; -import java.util.Map; import java.util.Properties; import static spark.Spark.*; public final class APIv3 { + // TODO: Cleanup main class + @Getter private static Datastore datastore; - private final Gson gson = new GsonBuilder().registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()).setExclusionStrategies(new FollowAnnotationExclusionStrategy()).create(); - private final Properties config = new Properties(); + @Getter private static Properties config = new Properties(); + private final Gson gson = new GsonBuilder() + .registerTypeAdapter(ObjectId.class, new ObjectIdTypeAdapter()) + .setExclusionStrategies(new FollowAnnotationExclusionStrategy()) + .create(); APIv3() { try { + // TODO: Load config.load(APIv3.class.getClassLoader().getResourceAsStream("apiv3.properties")); } catch (Exception ex) { throw new RuntimeException(ex); @@ -56,40 +60,12 @@ public final class APIv3 { setupDatabase(); setupHttp(); - - ServerGroup scope = ServerGroup.byId("HCTeams"); - Map userRanks = new HashMap<>(); - - - ServerGroup global = ServerGroup.byId("Global"); - Map calculatedPermissions = global.getPermissions(userRanks.get(global)); - - // for global calculations - - for (ServerGroup serverGroup : ServerGroup.values()) { - if (serverGroup != global) { - mergePermissions(serverGroup, userRanks.get(serverGroup), calculatedPermissions); - } - } - - // for scoped calculations - - mergePermissions(scope, userRanks.get(scope), calculatedPermissions); - - } - - public void mergePermissions(ServerGroup serverGroup, Rank rank, Map current) { - Map groupPermissions = serverGroup.getPermissions(rank); - - groupPermissions.forEach((permissionNode, grant) -> { - if (!current.containsKey(permissionNode) || !current.get(permissionNode)) { - current.put(permissionNode, grant); - } - }); } private void setupDatabase() { - MongoClient mongoClient = new MongoClient(new ServerAddress((String) config.get("mongo.address"), (Integer) config.get("mongo.port")), + MongoClient mongoClient = new MongoClient(new ServerAddress( + (String) config.get("mongo.address"), + (Integer) config.get("mongo.port")), ImmutableList.of( MongoCredential.createCredential( (String) config.get("mongo.username"), @@ -109,6 +85,7 @@ public final class APIv3 { port((Integer) config.get("http.port")); before(new ContentTypeFilter()); before(new ActorAttributeFilter()); + before(new AuthorizationFilter()); get("/announcements", new GETAnnouncements(), gson::toJson); @@ -134,11 +111,12 @@ public final class APIv3 { get("/server/:id", new GETServer(), gson::toJson); get("/servers", new GETServers(), gson::toJson); + delete("/user/:id/meta", new DELETEUserMeta(), 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/login", new POSTUserLogin(), 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); @@ -147,11 +125,4 @@ public final class APIv3 { get("/routes", new GETRoutes()); } - public static void requireAuthorizedActor(Request req) { - Actor actor = req.attribute("actor"); - if (!actor.isAuthorized()) { - Spark.halt(); - } - } - } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/ActorAttributeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java similarity index 88% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/ActorAttributeFilter.java rename to src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java index 720cdd0..9460c21 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/ActorAttributeFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/ActorAttributeFilter.java @@ -1,5 +1,6 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.filters; +import net.frozenorb.apiv3.unsorted.Actor; import spark.Filter; import spark.Request; import spark.Response; diff --git a/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java new file mode 100644 index 0000000..8c7dace --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/filters/AuthorizationFilter.java @@ -0,0 +1,20 @@ +package net.frozenorb.apiv3.filters; + +import net.frozenorb.apiv3.unsorted.Actor; +import net.frozenorb.apiv3.utils.ErrorUtils; +import spark.Filter; +import spark.Request; +import spark.Response; +import spark.Spark; + +public final class AuthorizationFilter implements Filter { + + public void handle(Request req, Response res) { + Actor actor = req.attribute("actor"); + + if (!actor.isAuthorized()) { + Spark.halt(ErrorUtils.error("Unauthorized access: Please authenticate as either a server, the website, or an authorized user.").toJson()); + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/ContentTypeFilter.java b/src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/ContentTypeFilter.java rename to src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java index 140a552..629e163 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/ContentTypeFilter.java +++ b/src/main/java/net/frozenorb/apiv3/filters/ContentTypeFilter.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.filters; import spark.Filter; import spark.Request; diff --git a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java index a8f7198..4221797 100644 --- a/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/AuditLogEntry.java @@ -1,14 +1,13 @@ package net.frozenorb.apiv3.models; import lombok.Getter; -import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.unsorted.Actor; 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) @@ -17,19 +16,17 @@ public final class AuditLogEntry { @Getter @Id private ObjectId id; @Getter private UUID performedBy; @Getter private Date performedAt; - @Getter private String performedFrom; + @Getter private String actorName; @Getter private String actionType; - @Getter private String description; @Getter private Document actionData; public AuditLogEntry() {} // For Morphia - public AuditLogEntry(User performedBy, String performedFrom, String actionType, String description, Document actionData) { + public AuditLogEntry(User performedBy, Actor actor, String actionType, Document actionData) { this.performedBy = performedBy.getId(); this.performedAt = new Date(); - this.performedFrom = performedFrom; + this.actorName = actor.getName(); this.actionType = actionType; - this.description = description; this.actionData = actionData; } diff --git a/src/main/java/net/frozenorb/apiv3/models/Grant.java b/src/main/java/net/frozenorb/apiv3/models/Grant.java index ff6e27a..cada769 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Grant.java +++ b/src/main/java/net/frozenorb/apiv3/models/Grant.java @@ -7,7 +7,10 @@ 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 { @@ -66,4 +69,12 @@ public final class Grant { return removedBy != null; } + public boolean appliesOn(Server server) { + return scopes.contains(server.getId()); + } + + public boolean appliesOn(ServerGroup serverGroup) { + return scopes.contains(serverGroup.getId()); + } + } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java index 89454d6..8007a4d 100644 --- a/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/IPLogEntry.java @@ -7,7 +7,6 @@ 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) diff --git a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java index a0c3e18..8d11b1e 100644 --- a/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.java +++ b/src/main/java/net/frozenorb/apiv3/models/NotificationTemplate.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.List; import java.util.Map; -import java.util.UUID; @Entity(value = "notificationTemplates", noClassnameStored = true) public final class NotificationTemplate { @@ -16,8 +13,6 @@ public final class NotificationTemplate { @Getter @Id private String id; @Getter private String subject; @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").equalIgnoreCase(id).get(); @@ -25,18 +20,14 @@ public final class NotificationTemplate { public NotificationTemplate() {} // For Morphia - public NotificationTemplate(String subject, String body, User creator) { + public NotificationTemplate(String subject, String body) { this.subject = subject; this.body = body; - this.lastUpdatedAt = new Date(); - this.lastUpdatedBy = creator.getId(); } - public void update(String subject, String body, User updatedBy) { + public void update(String subject, String body) { this.subject = subject; this.body = body; - this.lastUpdatedAt = new Date(); - this.lastUpdatedBy = updatedBy.getId(); APIv3.getDatastore().save(this); } diff --git a/src/main/java/net/frozenorb/apiv3/models/Punishment.java b/src/main/java/net/frozenorb/apiv3/models/Punishment.java index 4c35d64..1d5a34a 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Punishment.java +++ b/src/main/java/net/frozenorb/apiv3/models/Punishment.java @@ -7,7 +7,6 @@ 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) diff --git a/src/main/java/net/frozenorb/apiv3/models/Rank.java b/src/main/java/net/frozenorb/apiv3/models/Rank.java index 49c5775..416b6a2 100644 --- a/src/main/java/net/frozenorb/apiv3/models/Rank.java +++ b/src/main/java/net/frozenorb/apiv3/models/Rank.java @@ -18,7 +18,7 @@ public final class Rank { @Getter private boolean staffRank; public static Rank byId(String id) { - return APIv3.getDatastore().createQuery(Rank.class).field("id").equalIgnoreCase(id).get(); + return APIv3.getDatastore().createQuery(Rank.class).order("weight").field("id").equalIgnoreCase(id).get(); } public static List values() { diff --git a/src/main/java/net/frozenorb/apiv3/models/User.java b/src/main/java/net/frozenorb/apiv3/models/User.java index 1d29a88..c0cb9d8 100644 --- a/src/main/java/net/frozenorb/apiv3/models/User.java +++ b/src/main/java/net/frozenorb/apiv3/models/User.java @@ -3,7 +3,7 @@ package net.frozenorb.apiv3.models; import lombok.Getter; import lombok.Setter; import net.frozenorb.apiv3.APIv3; -import net.frozenorb.apiv3.weirdStuff.ExcludeFromReplies; +import net.frozenorb.apiv3.serialization.ExcludeFromReplies; import org.bson.Document; import org.mindrot.jbcrypt.BCrypt; import org.mongodb.morphia.annotations.Entity; @@ -130,4 +130,28 @@ public final class User { return BCrypt.checkpw(new String(unencrypted), password); } + public Map calculateGlobalPermissions() { + return null; + } + + public Map calculatePermissions(ServerGroup serverGroup) { + /*ServerGroup scope = ServerGroup.byId("HCTeams"); + Map userRanks = new HashMap<>(); + + + //ServerGroup global = ServerGroup.byId("Global"); + Map calculatedPermissions = global.getPermissions(userRanks.get(global)); + + // for global calculations + + for (ServerGroup serverGroup : ServerGroup.values()) { + mergePermissions(serverGroup, userRanks.get(serverGroup), calculatedPermissions); + } + + // for scoped calculations + + mergePermissions(scope, userRanks.get(scope), calculatedPermissions);*/ + return null; + } + } \ 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 index 0eec971..2e3c23f 100644 --- a/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java +++ b/src/main/java/net/frozenorb/apiv3/models/UserMetaEntry.java @@ -8,7 +8,6 @@ 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) diff --git a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java index e3a64ec..2d8bf1a 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/GETDump.java +++ b/src/main/java/net/frozenorb/apiv3/routes/GETDump.java @@ -3,7 +3,7 @@ package net.frozenorb.apiv3.routes; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Punishment; -import net.frozenorb.apiv3.weirdStuff.ErrorUtils; +import net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/POSTConfirmRegister.java b/src/main/java/net/frozenorb/apiv3/routes/POSTConfirmRegister.java index 106fe87..9245900 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/POSTConfirmRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/POSTConfirmRegister.java @@ -3,7 +3,7 @@ package net.frozenorb.apiv3.routes; import com.google.common.collect.ImmutableList; import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.weirdStuff.ErrorUtils; +import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; import spark.Request; import spark.Response; diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java index 383e891..9cf85a2 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/DELETEGrant.java @@ -2,9 +2,9 @@ package net.frozenorb.apiv3.routes.grants; import net.frozenorb.apiv3.models.Grant; 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 net.frozenorb.apiv3.unsorted.AuditLog; +import net.frozenorb.apiv3.unsorted.Permissions; +import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; import spark.Request; import spark.Response; @@ -30,11 +30,10 @@ public final class DELETEGrant implements Route { return ErrorUtils.unauthorized(requiredPermission); } - String removedByIp = req.queryParams("removedByIp"); String reason = req.queryParams("removalReason"); 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())); + AuditLog.log(removedBy, req.attribute("actor"), "grant.remove", new Document("grantId", grant.getId())); return grant; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java index 92e7ac6..32cc452 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/GETUserGrants.java @@ -1,7 +1,7 @@ package net.frozenorb.apiv3.routes.grants; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.weirdStuff.ErrorUtils; +import net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java index c5ed15b..bcb5cbd 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java +++ b/src/main/java/net/frozenorb/apiv3/routes/grants/POSTUserGrant.java @@ -5,8 +5,8 @@ import net.frozenorb.apiv3.models.Grant; import net.frozenorb.apiv3.models.Rank; import net.frozenorb.apiv3.models.ServerGroup; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.weirdStuff.ErrorUtils; -import net.frozenorb.apiv3.weirdStuff.Permissions; +import net.frozenorb.apiv3.unsorted.Permissions; +import net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java index 96455f3..b26787d 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java +++ b/src/main/java/net/frozenorb/apiv3/routes/ipLog/GETUserIPLog.java @@ -1,7 +1,7 @@ package net.frozenorb.apiv3.routes.ipLog; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.weirdStuff.ErrorUtils; +import net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java index f9cd66a..946b814 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/DELETEPunishment.java @@ -2,9 +2,9 @@ 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 net.frozenorb.apiv3.weirdStuff.ErrorUtils; -import net.frozenorb.apiv3.weirdStuff.Permissions; +import net.frozenorb.apiv3.unsorted.AuditLog; +import net.frozenorb.apiv3.unsorted.Permissions; +import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; import spark.Request; import spark.Response; @@ -30,11 +30,10 @@ public final class DELETEPunishment implements Route { return ErrorUtils.unauthorized(requiredPermission); } - String removedByIp = req.queryParams("removedByIp"); String reason = req.queryParams("removalReason"); 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())); + AuditLog.log(removedBy, req.attribute("actor"), "punishment.remove", new Document("punishmentId", punishment.getId())); return punishment; } diff --git a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java index efa2a04..98ecdaf 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java +++ b/src/main/java/net/frozenorb/apiv3/routes/punishments/POSTUserPunish.java @@ -4,8 +4,8 @@ import net.frozenorb.apiv3.APIv3; import net.frozenorb.apiv3.models.Punishment; import net.frozenorb.apiv3.models.Server; import net.frozenorb.apiv3.models.User; -import net.frozenorb.apiv3.weirdStuff.ErrorUtils; -import net.frozenorb.apiv3.weirdStuff.Permissions; +import net.frozenorb.apiv3.unsorted.Permissions; +import net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java index c7cc54d..415bf1d 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/DELETEUserMeta.java @@ -3,7 +3,7 @@ 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 net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java index b99d239..a454914 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserDetails.java @@ -2,7 +2,7 @@ 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 net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java index 6b3014e..7d41fa6 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/GETUserMeta.java @@ -3,7 +3,7 @@ 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 net.frozenorb.apiv3.utils.ErrorUtils; import spark.Request; import spark.Response; import spark.Route; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/GETUsers.java b/src/main/java/net/frozenorb/apiv3/routes/users/GETUsers.java deleted file mode 100644 index bddf7eb..0000000 --- a/src/main/java/net/frozenorb/apiv3/routes/users/GETUsers.java +++ /dev/null @@ -1,14 +0,0 @@ -package net.frozenorb.apiv3.routes.users; - -import net.frozenorb.apiv3.models.User; -import spark.Request; -import spark.Response; -import spark.Route; - -public final class GETUsers implements Route { - - public Object handle(Request req, Response res) { - return User.values(); - } - -} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java new file mode 100644 index 0000000..a36352e --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserLogin.java @@ -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.utils.ErrorUtils; +import spark.Request; +import spark.Response; +import spark.Route; + +public final class POSTUserLogin 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, + "access", user.getGrants(), + "rank", user.getIPLog(), + "permissions", user.getPunishments() + ); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java index 58ccb1d..1bee3ca 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserNotify.java @@ -2,8 +2,8 @@ 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 net.frozenorb.apiv3.unsorted.Notification; +import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; import spark.Request; import spark.Response; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java index f172535..7864dc8 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/POSTUserRegister.java @@ -4,8 +4,8 @@ import com.google.common.collect.ImmutableMap; import net.frozenorb.apiv3.APIv3; 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 net.frozenorb.apiv3.unsorted.Notification; +import net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; import spark.Request; import spark.Response; diff --git a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java index 5774a87..f2b24ac 100644 --- a/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java +++ b/src/main/java/net/frozenorb/apiv3/routes/users/PUTUserMeta.java @@ -2,7 +2,7 @@ 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 net.frozenorb.apiv3.utils.ErrorUtils; import org.bson.Document; import spark.Request; import spark.Response; diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/ExcludeFromReplies.java b/src/main/java/net/frozenorb/apiv3/serialization/ExcludeFromReplies.java similarity index 85% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/ExcludeFromReplies.java rename to src/main/java/net/frozenorb/apiv3/serialization/ExcludeFromReplies.java index a92cdda..eb45468 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/ExcludeFromReplies.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/ExcludeFromReplies.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.serialization; import java.lang.annotation.ElementType; import java.lang.annotation.Retention; diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/FollowAnnotationExclusionStrategy.java b/src/main/java/net/frozenorb/apiv3/serialization/FollowAnnotationExclusionStrategy.java similarity index 90% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/FollowAnnotationExclusionStrategy.java rename to src/main/java/net/frozenorb/apiv3/serialization/FollowAnnotationExclusionStrategy.java index acd49b7..77d116f 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/FollowAnnotationExclusionStrategy.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/FollowAnnotationExclusionStrategy.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.serialization; import com.google.gson.ExclusionStrategy; import com.google.gson.FieldAttributes; diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/ObjectIdTypeAdapter.java b/src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java similarity index 93% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/ObjectIdTypeAdapter.java rename to src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java index ca1aec1..78337fa 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/ObjectIdTypeAdapter.java +++ b/src/main/java/net/frozenorb/apiv3/serialization/ObjectIdTypeAdapter.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.serialization; import com.google.gson.TypeAdapter; import com.google.gson.stream.JsonReader; diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/Actor.java b/src/main/java/net/frozenorb/apiv3/unsorted/Actor.java similarity index 62% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/Actor.java rename to src/main/java/net/frozenorb/apiv3/unsorted/Actor.java index c39fc89..d58e8aa 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/Actor.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Actor.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.unsorted; public interface Actor { @@ -8,7 +8,7 @@ public interface Actor { enum Type { - WEBSITE, SERVER, UNKNOWN + WEBSITE, SERVER, USER, UNKNOWN } diff --git a/src/main/java/net/frozenorb/apiv3/unsorted/AuditLog.java b/src/main/java/net/frozenorb/apiv3/unsorted/AuditLog.java new file mode 100644 index 0000000..96cd555 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/unsorted/AuditLog.java @@ -0,0 +1,22 @@ +package net.frozenorb.apiv3.unsorted; + +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 { + + // TODO: Store user IPs + + public static void log(User performedBy, Actor actor, String actionType) { + log(performedBy, actor, actionType, new Document()); + } + + public static void log(User performedBy, Actor actor, String actionType, Document actionData) { + APIv3.getDatastore().save(new AuditLogEntry(performedBy, actor, actionType, actionData)); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/Notification.java b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java similarity index 92% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/Notification.java rename to src/main/java/net/frozenorb/apiv3/unsorted/Notification.java index 209d7eb..90dbf74 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/Notification.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Notification.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.unsorted; import com.cribbstechnologies.clients.mandrill.exception.RequestFailedException; import com.cribbstechnologies.clients.mandrill.model.MandrillHtmlMessage; @@ -6,6 +6,7 @@ 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 net.frozenorb.apiv3.utils.MandrillUtils; import sun.reflect.generics.reflectiveObjects.NotImplementedException; import java.io.IOException; @@ -20,7 +21,7 @@ public final class Notification { public Notification(NotificationTemplate template, Map subjectReplacements, Map bodyReplacements) { this.subject = template.fillSubject(subjectReplacements); - this.body = template.fillSubject(bodyReplacements); + this.body = template.fillBody(bodyReplacements); } public void sendAsEmail(String email) throws IOException { diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/Permissions.java b/src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java similarity index 92% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/Permissions.java rename to src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java index 4ab99c3..143b0b8 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/Permissions.java +++ b/src/main/java/net/frozenorb/apiv3/unsorted/Permissions.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.unsorted; import lombok.experimental.UtilityClass; diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/ErrorUtils.java b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java similarity index 94% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/ErrorUtils.java rename to src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java index cc0b386..af980e7 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/ErrorUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/ErrorUtils.java @@ -1,4 +1,4 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.utils; import lombok.experimental.UtilityClass; import org.bson.Document; diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/MandrillUtils.java b/src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java similarity index 73% rename from src/main/java/net/frozenorb/apiv3/weirdStuff/MandrillUtils.java rename to src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java index 638016d..5ba1de2 100644 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/MandrillUtils.java +++ b/src/main/java/net/frozenorb/apiv3/utils/MandrillUtils.java @@ -1,29 +1,20 @@ -package net.frozenorb.apiv3.weirdStuff; +package net.frozenorb.apiv3.utils; 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 net.frozenorb.apiv3.APIv3; import org.apache.http.impl.client.HttpClientBuilder; -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.setApiKey(APIv3.getConfig().getProperty("mandrill.apiKey")); config.setApiVersion("1.0"); config.setBaseURL("https://mandrillapp.com/api"); diff --git a/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java b/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java new file mode 100644 index 0000000..00725a9 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/utils/PermissionUtils.java @@ -0,0 +1,22 @@ +package net.frozenorb.apiv3.utils; + +import lombok.experimental.UtilityClass; +import net.frozenorb.apiv3.models.Rank; +import net.frozenorb.apiv3.models.ServerGroup; + +import java.util.Map; + +@UtilityClass +public class PermissionUtils { + + public static void mergePermissions(ServerGroup serverGroup, Rank rank, Map current) { + Map groupPermissions = serverGroup.getPermissions(rank); + + groupPermissions.forEach((permissionNode, grant) -> { + if (!current.containsKey(permissionNode) || !current.get(permissionNode)) { + current.put(permissionNode, grant); + } + }); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/weirdStuff/AuditLog.java b/src/main/java/net/frozenorb/apiv3/weirdStuff/AuditLog.java deleted file mode 100644 index 88dd3f2..0000000 --- a/src/main/java/net/frozenorb/apiv3/weirdStuff/AuditLog.java +++ /dev/null @@ -1,20 +0,0 @@ -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)); - } - -} \ No newline at end of file diff --git a/src/main/resources/apiv3.properties b/src/main/resources/apiv3.properties index a110f22..1afafda 100644 --- a/src/main/resources/apiv3.properties +++ b/src/main/resources/apiv3.properties @@ -4,4 +4,5 @@ mongo.database=minehqapi mongo.username=test mongo.password=test http.address= -http.port=80 \ No newline at end of file +http.port=80 +mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ \ No newline at end of file diff --git a/src/main/resources/mandrill.properties b/src/main/resources/mandrill.properties deleted file mode 100644 index 1e9c90e..0000000 --- a/src/main/resources/mandrill.properties +++ /dev/null @@ -1 +0,0 @@ -apiKey=0OYtwymqJP6oqvszeJu0vQ \ No newline at end of file