diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 7814c04..f63281a 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -39,6 +39,10 @@ import net.frozenorb.apiv3.route.GETDumpsType; import net.frozenorb.apiv3.route.GETWhoAmI; import net.frozenorb.apiv3.route.auditLog.GETAuditLog; import net.frozenorb.apiv3.route.auditLog.POSTAuditLog; +import net.frozenorb.apiv3.route.bannedAsns.DELETEBannedAsnsId; +import net.frozenorb.apiv3.route.bannedAsns.GETBannedAsns; +import net.frozenorb.apiv3.route.bannedAsns.GETBannedAsnsId; +import net.frozenorb.apiv3.route.bannedAsns.POSTBannedAsns; import net.frozenorb.apiv3.route.chatFilterList.GETChatFilter; import net.frozenorb.apiv3.route.emailToken.GETEmailTokensIdOwner; import net.frozenorb.apiv3.route.emailToken.POSTEmailTokensIdConfirm; @@ -228,6 +232,12 @@ public final class APIv3 extends AbstractVerticle { http.get("/auditLog").handler(new GETAuditLog()); http.post("/auditLog").handler(new POSTAuditLog()); + http.get("/bannedAsns/:id").handler(new GETBannedAsnsId()); + http.get("/bannedAsns").handler(new GETBannedAsns()); + http.post("/bannedAsns").blockingHandler(new POSTBannedAsns(), false); + //http.put("/bannedAsns/:id").blockingHandler(new PUTBannedAsnsId(), false); + http.delete("/bannedAsns/:id").blockingHandler(new DELETEBannedAsnsId(), false); + http.get("/chatFilter").handler(new GETChatFilter()); http.get("/emailTokens/:id/owner").blockingHandler(new GETEmailTokensIdOwner(), false); diff --git a/src/main/java/net/frozenorb/apiv3/model/BannedAsn.java b/src/main/java/net/frozenorb/apiv3/model/BannedAsn.java new file mode 100644 index 0000000..1440070 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/model/BannedAsn.java @@ -0,0 +1,96 @@ +package net.frozenorb.apiv3.model; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.mongodb.async.SingleResultCallback; +import com.mongodb.async.client.MongoCollection; +import com.mongodb.client.result.DeleteResult; +import com.mongodb.client.result.UpdateResult; +import fr.javatic.mongo.jacksonCodec.Entity; +import fr.javatic.mongo.jacksonCodec.objectId.Id; +import lombok.Getter; +import lombok.Setter; +import net.frozenorb.apiv3.APIv3; +import org.bson.Document; + +import java.time.Instant; +import java.util.HashMap; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; + +@Entity +public final class BannedAsn { + + private static final MongoCollection bannedAsnsCollection = APIv3.getDatabase().getCollection("bannedAsns", BannedAsn.class); + + private static Map bannedAsnIdCache = null; + private static List bannedAsnCache = null; + + @Getter @Id private int id; + @Getter @Setter String note; + @Getter private Instant bannedAt; + @Getter private Instant lastUpdatedAt; + + public static List findAll() { + return bannedAsnCache; + } + + public static BannedAsn findById(int id) { + return bannedAsnIdCache.get(id); + } + + static { + updateCache(); + + APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> { + updateCache(); + }); + } + + private static void updateCache() { + bannedAsnsCollection.find().into(new LinkedList<>(), (bannedAsns, error) -> { + if (error != null) { + error.printStackTrace(); + return; + } + + Map working = new HashMap<>(); + + for (BannedAsn bannedAsn : bannedAsns) { + working.put(bannedAsn.getId(), bannedAsn); + } + + bannedAsnIdCache = ImmutableMap.copyOf(working); + bannedAsnCache = ImmutableList.copyOf(bannedAsns); + }); + } + + private BannedAsn() {} // For Jackson + + public BannedAsn(int id, String note) { + this.id = id; + this.note = note; + this.bannedAt = Instant.now(); + this.lastUpdatedAt = Instant.now(); + } + + public void updateNote(String newNote) { + this.note = newNote; + this.lastUpdatedAt = Instant.now(); + } + + public void insert(SingleResultCallback callback) { + bannedAsnsCollection.insertOne(this, callback); + } + + public void save(SingleResultCallback callback) { + bannedAsnsCollection.replaceOne(new Document("_id", id), this, callback); + } + + public void delete(SingleResultCallback callback) { + bannedAsnsCollection.deleteOne(new Document("_id", id), callback); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/model/User.java b/src/main/java/net/frozenorb/apiv3/model/User.java index 1845490..093dba3 100644 --- a/src/main/java/net/frozenorb/apiv3/model/User.java +++ b/src/main/java/net/frozenorb/apiv3/model/User.java @@ -277,7 +277,7 @@ public final class User { "allowed", false, "message", "You cannot join MineHQ from a VPN." ); - } else if (ImmutableList.of().contains(maxMindResult.getTraits().getAsn())) { + } else if (BannedAsn.findById(maxMindResult.getTraits().getAsn()) != null) { proposedAccess = ImmutableMap.of( "allowed", false, "message", "You cannot join MineHQ from this ISP." diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java new file mode 100644 index 0000000..24a5156 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/DELETEBannedAsnsId.java @@ -0,0 +1,27 @@ +package net.frozenorb.apiv3.route.bannedAsns; + +import com.mongodb.client.result.DeleteResult; +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.model.BannedAsn; +import net.frozenorb.apiv3.unsorted.BlockingCallback; +import net.frozenorb.apiv3.util.ErrorUtils; + +public final class DELETEBannedAsnsId implements Handler { + + public void handle(RoutingContext ctx) { + BannedAsn bannedAsn = BannedAsn.findById(Integer.parseInt(ctx.request().getParam("id"))); + + if (bannedAsn == null) { + ErrorUtils.respondNotFound(ctx, "Banned asn", ctx.request().getParam("id")); + return; + } + + BlockingCallback callback = new BlockingCallback<>(); + bannedAsn.delete(callback); + callback.get(); + APIv3.respondJson(ctx, bannedAsn); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/GETBannedAsns.java b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/GETBannedAsns.java new file mode 100644 index 0000000..35a521e --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/GETBannedAsns.java @@ -0,0 +1,14 @@ +package net.frozenorb.apiv3.route.bannedAsns; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.model.BannedAsn; + +public final class GETBannedAsns implements Handler { + + public void handle(RoutingContext ctx) { + APIv3.respondJson(ctx, BannedAsn.findAll()); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/GETBannedAsnsId.java b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/GETBannedAsnsId.java new file mode 100644 index 0000000..4b935e5 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/GETBannedAsnsId.java @@ -0,0 +1,14 @@ +package net.frozenorb.apiv3.route.bannedAsns; + +import io.vertx.core.Handler; +import io.vertx.ext.web.RoutingContext; +import net.frozenorb.apiv3.APIv3; +import net.frozenorb.apiv3.model.BannedAsn; + +public final class GETBannedAsnsId implements Handler { + + public void handle(RoutingContext ctx) { + APIv3.respondJson(ctx, BannedAsn.findById(Integer.parseInt(ctx.request().getParam("id")))); + } + +} \ 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 new file mode 100644 index 0000000..fad78f8 --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/POSTBannedAsns.java @@ -0,0 +1,24 @@ +package net.frozenorb.apiv3.route.bannedAsns; + +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.model.BannedAsn; +import net.frozenorb.apiv3.unsorted.BlockingCallback; + +public final class POSTBannedAsns implements Handler { + + public void handle(RoutingContext ctx) { + JsonObject requestBody = ctx.getBodyAsJson(); + int id = requestBody.getInteger("id"); + String note = requestBody.getString("note"); + + BannedAsn bannedAsn = new BannedAsn(id, note); + BlockingCallback callback = new BlockingCallback<>(); + bannedAsn.insert(callback); + callback.get(); + APIv3.respondJson(ctx, bannedAsn); + } + +} \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/bannedAsns/PUTBannedAsnsId.java b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/PUTBannedAsnsId.java new file mode 100644 index 0000000..455646c --- /dev/null +++ b/src/main/java/net/frozenorb/apiv3/route/bannedAsns/PUTBannedAsnsId.java @@ -0,0 +1,4 @@ +package net.frozenorb.apiv3.route.bannedAsns; + +public class PUTBannedAsnsId { +}