diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index b53458c..8cb70c3 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -39,6 +39,7 @@ import net.frozenorb.apiv3.handler.MetricsHandler; import net.frozenorb.apiv3.model.*; import net.frozenorb.apiv3.route.GETDumpsType; import net.frozenorb.apiv3.route.GETWhoAmI; +import net.frozenorb.apiv3.route.auditLog.DELETEAuditLogId; import net.frozenorb.apiv3.route.auditLog.GETAuditLog; import net.frozenorb.apiv3.route.auditLog.POSTAuditLog; import net.frozenorb.apiv3.route.bannedAsns.DELETEBannedAsnsId; @@ -244,6 +245,7 @@ public final class APIv3 extends AbstractVerticle { http.get("/auditLog").handler(new GETAuditLog()); http.post("/auditLog").handler(new POSTAuditLog()); + http.delete("/auditLog/:id").blockingHandler(new DELETEAuditLogId()); http.get("/bannedAsns/:id").handler(new GETBannedAsnsId()); http.get("/bannedAsns").handler(new GETBannedAsns()); @@ -265,11 +267,13 @@ public final class APIv3 extends AbstractVerticle { http.get("/grants/:id").handler(new GETGrantsId()); http.get("/grants").handler(new GETGrants()); http.post("/grants").blockingHandler(new POSTGrants(), false); + //http.put("/grants/:id").blockingHandler(new PUTGrantsId(), false); http.delete("/grants/:id").blockingHandler(new DELETEGrantsId(), false); http.get("/ipBans/:id").handler(new GETIpBansId()); http.get("/ipBans").handler(new GETIpBans()); http.post("/ipBans").blockingHandler(new POSTIpBans(), false); + //http.put("/ipBans/:id").blockingHandler(new PUTIpBansId(), false); http.delete("/ipBans/:id").blockingHandler(new DELETEIpBansId(), false); http.get("/ipIntel/:id").handler(new GETIpInteld()); @@ -285,6 +289,7 @@ public final class APIv3 extends AbstractVerticle { http.get("/punishments/:id").handler(new GETPunishmentsId()); http.get("/punishments").handler(new GETPunishments()); http.post("/punishments").blockingHandler(new POSTPunishments(), false); + //http.put("/punishments/:id").blockingHandler(new PUTPunishmentsId(), false); http.delete("/punishments/:id").blockingHandler(new DELETEPunishmentsId(), false); http.delete("/users/:id/activePunishment").blockingHandler(new DELETEUsersIdActivePunishment(), false); diff --git a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java index 60cddc7..0b8e1bd 100644 --- a/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java +++ b/src/main/java/net/frozenorb/apiv3/auditLog/AuditLogActionType.java @@ -6,6 +6,7 @@ import net.frozenorb.apiv3.model.AuditLogEntry; public enum AuditLogActionType { + AUDIT_LOG_REVERT(false), BANNED_ASN_CREATE(false), BANNED_ASN_UPDATE(false), BANNED_ASN_DELETE(false), @@ -36,6 +37,7 @@ public enum AuditLogActionType { USER_CHANGE_PASSWORD(false), USER_PASSWORD_RESET(false), USER_REGISTER(false), + USER_CONFIRM_EMAIL(false), USER_SETUP_TOTP(false), USER_VERIFY_TOTP(false); @@ -45,7 +47,7 @@ public enum AuditLogActionType { this.reversible = reversible; } - public void revert(AuditLogEntry entry, SingleResultCallback callback) { + public void reverse(AuditLogEntry entry, SingleResultCallback callback) { callback.onResult(null, new UnsupportedOperationException()); } diff --git a/src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java b/src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java index ad5806d..daa9b50 100644 --- a/src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java +++ b/src/main/java/net/frozenorb/apiv3/model/AuditLogEntry.java @@ -41,6 +41,10 @@ public final class AuditLogEntry { auditLogCollection.find(query).sort(new Document("performedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback); } + public static void findById(String id, SingleResultCallback callback) { + auditLogCollection.find(new Document("_id", id)).first(callback); + } + public static void find(Document query, SingleResultCallback> callback) { auditLogCollection.find(query).into(new LinkedList<>(), callback); } diff --git a/src/main/java/net/frozenorb/apiv3/route/auditLog/DELETEAuditLogId.java b/src/main/java/net/frozenorb/apiv3/route/auditLog/DELETEAuditLogId.java new file mode 100644 index 0000000..bca7fc5 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/auditLog/DELETEAuditLogId.java @@ -0,0 +1,52 @@ +package net.frozenorb.apiv3.route.auditLog; + +import com.google.common.collect.ImmutableMap; +import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; +import net.frozenorb.apiv3.model.*; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.UUID; + +public final class DELETEAuditLogId implements Handler { + + public void handle(RoutingContext ctx) { + BlockingCallback auditLogEntryCallback = new BlockingCallback<>(); + AuditLogEntry.findById(ctx.request().getParam("id"), auditLogEntryCallback); + AuditLogEntry auditLogEntry = auditLogEntryCallback.get(); + + if (auditLogEntry == null) { + ErrorUtils.respondNotFound(ctx, "Audit log entry", ctx.request().getParam("id")); + return; + } + + if (!auditLogEntry.isReversible()) { + ErrorUtils.respondInvalidInput(ctx, "Audit log entry referenced is not reversible."); + return; + } + + BlockingCallback callback = new BlockingCallback<>(); + auditLogEntry.getType().reverse(auditLogEntry, callback); + callback.get(); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("user")) { + AuditLog.log(UUID.fromString(requestBody.getString("user")), requestBody.getString("userIp"), ctx, AuditLogActionType.AUDIT_LOG_REVERT, ImmutableMap.of("auditLogEntryId", auditLogEntry.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, auditLogEntry); + } + }); + } else { + APIv3.respondJson(ctx, auditLogEntry); + } + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java index 24a5156..731bb56 100644 --- a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java @@ -1,13 +1,19 @@ package net.frozenorb.apiv3.route.bannedAsns; +import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.DeleteResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.BannedAsn; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; +import java.util.UUID; + public final class DELETEBannedAsnsId implements Handler { public void handle(RoutingContext ctx) { @@ -21,7 +27,20 @@ public final class DELETEBannedAsnsId implements Handler { BlockingCallback callback = new BlockingCallback<>(); bannedAsn.delete(callback); callback.get(); - APIv3.respondJson(ctx, bannedAsn); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.BANNED_ASN_DELETE, ImmutableMap.of("bannedAsnId", bannedAsn.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, bannedAsn); + } + }); + } else { + APIv3.respondJson(ctx, bannedAsn); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/POSTBannedAsns.java b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/POSTBannedAsns.java index fad78f8..0d57f14 100644 --- a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/POSTBannedAsns.java +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/POSTBannedAsns.java @@ -1,11 +1,17 @@ package net.frozenorb.apiv3.route.bannedAsns; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.BannedAsn; import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.UUID; public final class POSTBannedAsns implements Handler { @@ -18,7 +24,18 @@ public final class POSTBannedAsns implements Handler { BlockingCallback callback = new BlockingCallback<>(); bannedAsn.insert(callback); callback.get(); - APIv3.respondJson(ctx, bannedAsn); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.BANNED_ASN_CREATE, ImmutableMap.of("bannedAsnId", id), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, bannedAsn); + } + }); + } else { + APIv3.respondJson(ctx, bannedAsn); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/DELETEBannedCellCarriersId.java b/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/DELETEBannedCellCarriersId.java index 24428c6..adaa843 100644 --- a/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/DELETEBannedCellCarriersId.java +++ b/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/DELETEBannedCellCarriersId.java @@ -1,13 +1,19 @@ package net.frozenorb.apiv3.route.bannedCellCarriers; +import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.DeleteResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.BannedCellCarrier; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; +import java.util.UUID; + public final class DELETEBannedCellCarriersId implements Handler { public void handle(RoutingContext ctx) { @@ -21,7 +27,20 @@ public final class DELETEBannedCellCarriersId implements Handler BlockingCallback callback = new BlockingCallback<>(); bannedCellCarrier.delete(callback); callback.get(); - APIv3.respondJson(ctx, bannedCellCarrier); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.BANNED_CALL_CARRIER_DELETE, ImmutableMap.of("bannedCellCarrierId", bannedCellCarrier.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, bannedCellCarrier); + } + }); + } else { + APIv3.respondJson(ctx, bannedCellCarrier); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/POSTBannedCellCarriers.java b/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/POSTBannedCellCarriers.java index 85ad9de..0ea3c60 100644 --- a/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/POSTBannedCellCarriers.java +++ b/src/main/java/net/frozenorb/apiv3/route/bannedCellCarriers/POSTBannedCellCarriers.java @@ -1,11 +1,17 @@ package net.frozenorb.apiv3.route.bannedCellCarriers; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.BannedCellCarrier; import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.UUID; public final class POSTBannedCellCarriers implements Handler { @@ -18,7 +24,18 @@ public final class POSTBannedCellCarriers implements Handler { BlockingCallback callback = new BlockingCallback<>(); bannedCellCarrier.insert(callback); callback.get(); - APIv3.respondJson(ctx, bannedCellCarrier); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.BANNED_CALL_CARRIER_CREATE, ImmutableMap.of("bannedCellCarrierId", id), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, bannedCellCarrier); + } + }); + } else { + APIv3.respondJson(ctx, bannedCellCarrier); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/emailToken/POSTEmailTokensIdConfirm.java b/src/main/java/net/frozenorb/apiv3/route/emailToken/POSTEmailTokensIdConfirm.java index e33d4a5..8bb525e 100644 --- a/src/main/java/net/frozenorb/apiv3/route/emailToken/POSTEmailTokensIdConfirm.java +++ b/src/main/java/net/frozenorb/apiv3/route/emailToken/POSTEmailTokensIdConfirm.java @@ -6,6 +6,8 @@ import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; @@ -50,9 +52,15 @@ public final class POSTEmailTokensIdConfirm implements Handler { user.save(callback); callback.get(); - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true - )); + AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_CONFIRM_EMAIL, (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true + )); + } + }); } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpBans.java b/src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpBans.java index f38daac..6a9c603 100644 --- a/src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpBans.java +++ b/src/main/java/net/frozenorb/apiv3/route/ipBans/POSTIpBans.java @@ -1,9 +1,12 @@ package net.frozenorb.apiv3.route.ipBans; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.IpBan; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; @@ -51,7 +54,17 @@ public final class POSTIpBans implements Handler { ipBan.insert(callback); callback.get(); - APIv3.respondJson(ctx, ipBan); + if (addedBy != null) { + AuditLog.log(addedBy.getId(), requestBody.getString("addedByIp"), ctx, AuditLogActionType.IP_BAN_CREATE, ImmutableMap.of("ipBanId", ipBan.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ipBan); + } + }); + } else { + APIv3.respondJson(ctx, ipBan); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplatesId.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplatesId.java index 301a376..104cbee 100644 --- a/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplatesId.java +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/DELETENotificationTemplatesId.java @@ -1,13 +1,19 @@ package net.frozenorb.apiv3.route.notificationTemplates; +import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.DeleteResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.NotificationTemplate; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; +import java.util.UUID; + public final class DELETENotificationTemplatesId implements Handler { public void handle(RoutingContext ctx) { @@ -23,7 +29,20 @@ public final class DELETENotificationTemplatesId implements Handler callback = new BlockingCallback<>(); notificationTemplate.delete(callback); callback.get(); - APIv3.respondJson(ctx, notificationTemplate); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.NOTIFICATION_TEMPLATE_DELETE, ImmutableMap.of("notificationTemplateId", notificationTemplate.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, notificationTemplate); + } + }); + } else { + APIv3.respondJson(ctx, notificationTemplate); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplates.java b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplates.java index 5cdfe89..1c4ce96 100644 --- a/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplates.java +++ b/src/main/java/net/frozenorb/apiv3/route/notificationTemplates/POSTNotificationTemplates.java @@ -1,11 +1,17 @@ package net.frozenorb.apiv3.route.notificationTemplates; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.NotificationTemplate; import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.UUID; public final class POSTNotificationTemplates implements Handler { @@ -19,7 +25,18 @@ public final class POSTNotificationTemplates implements Handler BlockingCallback callback = new BlockingCallback<>(); notificationTemplate.insert(callback); callback.get(); - APIv3.respondJson(ctx, notificationTemplate); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.NOTIFICATION_TEMPLATE_CREATE, ImmutableMap.of("notificationTemplateId", id), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, notificationTemplate); + } + }); + } else { + APIv3.respondJson(ctx, notificationTemplate); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/punishments/POSTPunishments.java b/src/main/java/net/frozenorb/apiv3/route/punishments/POSTPunishments.java index dfd7f9a..2572271 100644 --- a/src/main/java/net/frozenorb/apiv3/route/punishments/POSTPunishments.java +++ b/src/main/java/net/frozenorb/apiv3/route/punishments/POSTPunishments.java @@ -6,6 +6,8 @@ import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.IpBan; import net.frozenorb.apiv3.model.Punishment; import net.frozenorb.apiv3.model.User; @@ -101,10 +103,23 @@ public final class POSTPunishments implements Handler { punishment.insert(callback); callback.get(); - APIv3.respondJson(ctx, ImmutableMap.of( - "punishment", punishment, - "accessDenialReason", accessDenialReason == null ? "" : accessDenialReason - )); + if (addedBy != null) { + AuditLog.log(addedBy.getId(), requestBody.getString("addedByIp"), ctx, AuditLogActionType.PUNISHMENT_CREATE, ImmutableMap.of("punishmentId", punishment.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "punishment", punishment, + "accessDenialReason", accessDenialReason == null ? "" : accessDenialReason + )); + } + }); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "punishment", punishment, + "accessDenialReason", accessDenialReason == null ? "" : accessDenialReason + )); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/ranks/DELETERanksId.java b/src/main/java/net/frozenorb/apiv3/route/ranks/DELETERanksId.java index f9b25ca..5df8d37 100644 --- a/src/main/java/net/frozenorb/apiv3/route/ranks/DELETERanksId.java +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/DELETERanksId.java @@ -1,13 +1,19 @@ package net.frozenorb.apiv3.route.ranks; +import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.DeleteResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.Rank; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; +import java.util.UUID; + public final class DELETERanksId implements Handler { public void handle(RoutingContext ctx) { @@ -21,7 +27,20 @@ public final class DELETERanksId implements Handler { BlockingCallback callback = new BlockingCallback<>(); rank.delete(callback); callback.get(); - APIv3.respondJson(ctx, rank); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.RANK_DELETE, ImmutableMap.of("rankId", rank.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, rank); + } + }); + } else { + APIv3.respondJson(ctx, rank); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/ranks/POSTRanks.java b/src/main/java/net/frozenorb/apiv3/route/ranks/POSTRanks.java index dfa53fb..32a7e50 100644 --- a/src/main/java/net/frozenorb/apiv3/route/ranks/POSTRanks.java +++ b/src/main/java/net/frozenorb/apiv3/route/ranks/POSTRanks.java @@ -1,11 +1,17 @@ package net.frozenorb.apiv3.route.ranks; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.Rank; import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.UUID; public final class POSTRanks implements Handler { @@ -23,7 +29,18 @@ public final class POSTRanks implements Handler { BlockingCallback callback = new BlockingCallback<>(); rank.insert(callback); callback.get(); - APIv3.respondJson(ctx, rank); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.RANK_CREATE, ImmutableMap.of("rankId", id), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, rank); + } + }); + } else { + APIv3.respondJson(ctx, rank); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroupsId.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroupsId.java index 7e5614d..a3fd527 100644 --- a/src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroupsId.java +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/DELETEServerGroupsId.java @@ -1,13 +1,19 @@ package net.frozenorb.apiv3.route.serverGroups; +import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.DeleteResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.ServerGroup; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; +import java.util.UUID; + public final class DELETEServerGroupsId implements Handler { public void handle(RoutingContext ctx) { @@ -21,7 +27,20 @@ public final class DELETEServerGroupsId implements Handler { BlockingCallback callback = new BlockingCallback<>(); serverGroup.delete(callback); callback.get(); - APIv3.respondJson(ctx, serverGroup); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.SERVER_GROUP_DELETE, ImmutableMap.of("serverGroupId", serverGroup.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, serverGroup); + } + }); + } else { + APIv3.respondJson(ctx, serverGroup); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroups.java b/src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroups.java index 59cde37..5d5b59b 100644 --- a/src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroups.java +++ b/src/main/java/net/frozenorb/apiv3/route/serverGroups/POSTServerGroups.java @@ -1,11 +1,17 @@ package net.frozenorb.apiv3.route.serverGroups; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.ServerGroup; import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +import java.util.UUID; public final class POSTServerGroups implements Handler { @@ -18,7 +24,18 @@ public final class POSTServerGroups implements Handler { BlockingCallback callback = new BlockingCallback<>(); serverGroup.insert(callback); callback.get(); - APIv3.respondJson(ctx, serverGroup); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.SERVER_GROUP_CREATE, ImmutableMap.of("serverGroupId", id), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, serverGroup); + } + }); + } else { + APIv3.respondJson(ctx, serverGroup); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/servers/DELETEServersId.java b/src/main/java/net/frozenorb/apiv3/route/servers/DELETEServersId.java index df8b254..2fc3bc6 100644 --- a/src/main/java/net/frozenorb/apiv3/route/servers/DELETEServersId.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/DELETEServersId.java @@ -1,13 +1,19 @@ package net.frozenorb.apiv3.route.servers; +import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.DeleteResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.Server; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; +import java.util.UUID; + public final class DELETEServersId implements Handler { public void handle(RoutingContext ctx) { @@ -21,7 +27,20 @@ public final class DELETEServersId implements Handler { BlockingCallback callback = new BlockingCallback<>(); server.delete(callback); callback.get(); - APIv3.respondJson(ctx, server); + + JsonObject requestBody = ctx.getBodyAsJson(); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.SERVER_DELETE, ImmutableMap.of("serverId", server.getId()), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, server); + } + }); + } else { + APIv3.respondJson(ctx, server); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/servers/POSTServers.java b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServers.java index 0702383..97a29e4 100644 --- a/src/main/java/net/frozenorb/apiv3/route/servers/POSTServers.java +++ b/src/main/java/net/frozenorb/apiv3/route/servers/POSTServers.java @@ -1,9 +1,12 @@ package net.frozenorb.apiv3.route.servers; +import com.google.common.collect.ImmutableMap; import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.Server; import net.frozenorb.apiv3.model.ServerGroup; import net.frozenorb.apiv3.unsorted.BlockingCallback; @@ -36,7 +39,18 @@ public final class POSTServers implements Handler { BlockingCallback callback = new BlockingCallback<>(); server.insert(callback); callback.get(); - APIv3.respondJson(ctx, server); + + if (requestBody.containsKey("addedBy")) { + AuditLog.log(UUID.fromString(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.SERVER_CREATE, ImmutableMap.of("serverId", id), (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, server); + } + }); + } else { + APIv3.respondJson(ctx, server); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdChangePassword.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdChangePassword.java index 7ea5833..d036660 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdChangePassword.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdChangePassword.java @@ -6,6 +6,8 @@ import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.unsorted.RequiresTotpResult; @@ -79,9 +81,15 @@ public final class POSTUsersIdChangePassword implements Handler user.save(saveCallback); saveCallback.get(); - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true - )); + AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_CHANGE_PASSWORD, (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true + )); + } + }); } } diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdPasswordReset.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdPasswordReset.java index c6c988f..f3a08ec 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdPasswordReset.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdPasswordReset.java @@ -3,8 +3,11 @@ package net.frozenorb.apiv3.route.users; import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.UpdateResult; import io.vertx.core.Handler; +import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.NotificationTemplate; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; @@ -49,9 +52,17 @@ public final class POSTUsersIdPasswordReset implements Handler { if (error != null) { ErrorUtils.respondInternalError(ctx, error); } else { - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true - )); + JsonObject requestBody = ctx.getBodyAsJson(); + + AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_PASSWORD_RESET, (ignored2, error2) -> { + if (error2 != null) { + ErrorUtils.respondInternalError(ctx, error2); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true + )); + } + }); } }); } diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdRegister.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdRegister.java index 7a5ffd0..7a6cfcb 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdRegister.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdRegister.java @@ -6,6 +6,8 @@ import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.NotificationTemplate; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; @@ -18,8 +20,6 @@ import java.util.concurrent.TimeUnit; public final class POSTUsersIdRegister implements Handler { - - public void handle(RoutingContext ctx) { BlockingCallback userCallback = new BlockingCallback<>(); User.findById(ctx.request().getParam("id"), userCallback); @@ -72,9 +72,15 @@ public final class POSTUsersIdRegister implements Handler { if (error != null) { ErrorUtils.respondInternalError(ctx, error); } else { - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true - )); + AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_REGISTER, (ignored2, error2) -> { + if (error2 != null) { + ErrorUtils.respondInternalError(ctx, error2); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true + )); + } + }); } }); } diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdSetupTotp.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdSetupTotp.java index 94ecd13..47480b9 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdSetupTotp.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdSetupTotp.java @@ -6,6 +6,8 @@ import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.unsorted.BlockingCallback; import net.frozenorb.apiv3.util.ErrorUtils; @@ -38,10 +40,16 @@ public final class POSTUsersIdSetupTotp implements Handler { user.save(callback); callback.get(); - APIv3.respondJson(ctx, ImmutableMap.of( - "success", true, - "message", "Totp code set." - )); + AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_SETUP_TOTP, (ignored, error) -> { + if (error != null) { + ErrorUtils.respondInternalError(ctx, error); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true, + "message", "Totp code set." + )); + } + }); } else { ErrorUtils.respondInvalidInput(ctx, "Confirmation code provided did not match."); } diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdVerifyTotp.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdVerifyTotp.java index c1ec891..b27af90 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdVerifyTotp.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUsersIdVerifyTotp.java @@ -5,6 +5,8 @@ import io.vertx.core.Handler; import io.vertx.core.json.JsonObject; import io.vertx.ext.web.RoutingContext; import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.auditLog.AuditLog; +import net.frozenorb.apiv3.auditLog.AuditLogActionType; import net.frozenorb.apiv3.model.User; import net.frozenorb.apiv3.util.ErrorUtils; import net.frozenorb.apiv3.util.IpUtils; @@ -42,10 +44,16 @@ public final class POSTUsersIdVerifyTotp implements Handler { return; } - APIv3.respondJson(ctx, ImmutableMap.of( - "authorized", totpAuthorizationResult.isAuthorized(), - "message", totpAuthorizationResult.name() - )); + AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_VERIFY_TOTP, (ignored, error3) -> { + if (error3 != null) { + ErrorUtils.respondInternalError(ctx, error3); + } else { + APIv3.respondJson(ctx, ImmutableMap.of( + "authorized", totpAuthorizationResult.isAuthorized(), + "message", totpAuthorizationResult.name() + )); + } + }); }); }); }