Large commit to convert all models to be full async
This commit is contained in:
parent
e9da784953
commit
4a727f3d04
@ -85,6 +85,7 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -107,6 +108,13 @@ public final class APIv3 extends AbstractVerticle {
|
|||||||
setupDatabase();
|
setupDatabase();
|
||||||
setupHttpServer();
|
setupHttpServer();
|
||||||
|
|
||||||
|
/*try {
|
||||||
|
ObjectMapper mapper = new ObjectMapper();
|
||||||
|
log.info(gson.toJson(mapper.readValue("email=test@google.com", Map.class)));
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}*/
|
||||||
|
|
||||||
/*V2Importer converter = new V2Importer("mongodb://158.69.126.126", "minehq");
|
/*V2Importer converter = new V2Importer("mongodb://158.69.126.126", "minehq");
|
||||||
|
|
||||||
converter.startImport((ignored, error) -> {
|
converter.startImport((ignored, error) -> {
|
||||||
@ -218,12 +226,12 @@ public final class APIv3 extends AbstractVerticle {
|
|||||||
|
|
||||||
http.route().handler(LoggerHandler.create(LoggerFormat.TINY));
|
http.route().handler(LoggerHandler.create(LoggerFormat.TINY));
|
||||||
http.route().handler(TimeoutHandler.create(TimeUnit.SECONDS.toMillis(5)));
|
http.route().handler(TimeoutHandler.create(TimeUnit.SECONDS.toMillis(5)));
|
||||||
http.route().method(HttpMethod.PUT).method(HttpMethod.POST).handler(BodyHandler.create());
|
http.route().method(HttpMethod.PUT).method(HttpMethod.POST).method(HttpMethod.DELETE).handler(BodyHandler.create());
|
||||||
http.route().handler(new ActorAttributeHandler());
|
http.route().handler(new ActorAttributeHandler());
|
||||||
http.route().handler(new AuthorizationHandler());
|
http.route().handler(new AuthorizationHandler());
|
||||||
http.exceptionHandler(Throwable::printStackTrace);
|
|
||||||
|
|
||||||
// TODO: The commented out routes
|
// TODO: The commented out routes
|
||||||
|
// TODO: RENAME THESE ROUTES TO BE RIGHT
|
||||||
|
|
||||||
http.get("/auditLog").handler(new GETAuditLog());
|
http.get("/auditLog").handler(new GETAuditLog());
|
||||||
http.post("/auditLog").handler(new POSTAuditLog());
|
http.post("/auditLog").handler(new POSTAuditLog());
|
||||||
@ -281,7 +289,7 @@ public final class APIv3 extends AbstractVerticle {
|
|||||||
http.get("/staff").blockingHandler(new GETStaff(), false);
|
http.get("/staff").blockingHandler(new GETStaff(), false);
|
||||||
http.get("/users/:id").handler(new GETUser());
|
http.get("/users/:id").handler(new GETUser());
|
||||||
http.get("/users/:id/details").blockingHandler(new GETUserDetails(), false);
|
http.get("/users/:id/details").blockingHandler(new GETUserDetails(), false);
|
||||||
http.get("/users/:id/permissions").blockingHandler(new GETUserPermissions(), false);
|
http.get("/users/:id/permissions").handler(new GETUserPermissions());
|
||||||
http.get("/users/:id/requiresTotp").handler(new GETUserRequiresTotp());
|
http.get("/users/:id/requiresTotp").handler(new GETUserRequiresTotp());
|
||||||
http.get("/users/:id/verifyPassword").blockingHandler(new GETUserVerifyPassword(), false);
|
http.get("/users/:id/verifyPassword").blockingHandler(new GETUserVerifyPassword(), false);
|
||||||
http.post("/users/:id/changePassword").blockingHandler(new POSTUserChangePassword(), false);
|
http.post("/users/:id/changePassword").blockingHandler(new POSTUserChangePassword(), false);
|
||||||
@ -299,6 +307,8 @@ public final class APIv3 extends AbstractVerticle {
|
|||||||
webServer.requestHandler(http::accept).listen(port);
|
webServer.requestHandler(http::accept).listen(port);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO: TEST IF OUR MODEL CONSTRUCTORS CAN BE PRIVATE
|
||||||
|
|
||||||
public static void respondJson(RoutingContext ctx, Object response) {
|
public static void respondJson(RoutingContext ctx, Object response) {
|
||||||
respondJson(ctx, 200, response);
|
respondJson(ctx, 200, response);
|
||||||
}
|
}
|
||||||
@ -306,6 +316,11 @@ public final class APIv3 extends AbstractVerticle {
|
|||||||
public static void respondJson(RoutingContext ctx, int code, Object response) {
|
public static void respondJson(RoutingContext ctx, int code, Object response) {
|
||||||
ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString());
|
ctx.response().putHeader(HttpHeaders.CONTENT_TYPE, MediaType.JSON_UTF_8.toString());
|
||||||
ctx.response().setStatusCode(code);
|
ctx.response().setStatusCode(code);
|
||||||
|
|
||||||
|
if (!ctx.request().path().contains("dumps")) {
|
||||||
|
log.info(gson.toJson(response));
|
||||||
|
}
|
||||||
|
|
||||||
ctx.response().end(gson.toJson(response));
|
ctx.response().end(gson.toJson(response));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -10,6 +10,7 @@ import net.frozenorb.apiv3.dataImport.converters.GrantConverter;
|
|||||||
import net.frozenorb.apiv3.dataImport.converters.IpLogConverter;
|
import net.frozenorb.apiv3.dataImport.converters.IpLogConverter;
|
||||||
import net.frozenorb.apiv3.dataImport.converters.PunishmentConverter;
|
import net.frozenorb.apiv3.dataImport.converters.PunishmentConverter;
|
||||||
import net.frozenorb.apiv3.dataImport.converters.UserConverter;
|
import net.frozenorb.apiv3.dataImport.converters.UserConverter;
|
||||||
|
import net.frozenorb.apiv3.unsorted.FutureCompatibilityCallback;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -52,22 +53,4 @@ public final class V2Importer {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class FutureCompatibilityCallback<T> implements SingleResultCallback<T> {
|
|
||||||
|
|
||||||
private final Future<T> future;
|
|
||||||
|
|
||||||
private FutureCompatibilityCallback(Future<T> future) {
|
|
||||||
this.future = future;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onResult(T val, Throwable error) {
|
|
||||||
if (error != null) {
|
|
||||||
future.fail(error);
|
|
||||||
} else {
|
|
||||||
future.complete(val);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableSet;
|
|||||||
import com.mongodb.Block;
|
import com.mongodb.Block;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.frozenorb.apiv3.model.Grant;
|
import net.frozenorb.apiv3.model.Grant;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
@ -56,7 +57,9 @@ public final class GrantConverter implements Block<Document> {
|
|||||||
null
|
null
|
||||||
);
|
);
|
||||||
|
|
||||||
created.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
created.insert(callback);
|
||||||
|
callback.get();
|
||||||
log.info("Created grant " + created.getId() + " (" + created.getRank() + ")");
|
log.info("Created grant " + created.getId() + " (" + created.getRank() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package net.frozenorb.apiv3.dataImport.converters;
|
|||||||
import com.mongodb.Block;
|
import com.mongodb.Block;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.frozenorb.apiv3.model.IpLogEntry;
|
import net.frozenorb.apiv3.model.IpLogEntry;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.IpUtils;
|
import net.frozenorb.apiv3.util.IpUtils;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
@ -50,7 +51,9 @@ public final class IpLogConverter implements Block<Document> {
|
|||||||
((Number) ipLogEntry.get("uses")).intValue()
|
((Number) ipLogEntry.get("uses")).intValue()
|
||||||
);
|
);
|
||||||
|
|
||||||
created.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
created.insert(callback);
|
||||||
|
callback.get();
|
||||||
log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")");
|
log.info("Created ip log entry " + created.getId() + " (" + created.getUser() + " - " + created.getUserIp() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import com.mongodb.Block;
|
|||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.frozenorb.apiv3.actor.ActorType;
|
import net.frozenorb.apiv3.actor.ActorType;
|
||||||
import net.frozenorb.apiv3.model.Punishment;
|
import net.frozenorb.apiv3.model.Punishment;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
@ -52,7 +53,9 @@ public final class PunishmentConverter implements Block<Document> {
|
|||||||
punishment.containsKey("removedBy") ? punishment.getString("removalReason").toString() : null
|
punishment.containsKey("removedBy") ? punishment.getString("removalReason").toString() : null
|
||||||
);
|
);
|
||||||
|
|
||||||
created.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
created.insert(callback);
|
||||||
|
callback.get();
|
||||||
log.info("Created punishment " + created.getId() + " (" + created.getType() + ")");
|
log.info("Created punishment " + created.getId() + " (" + created.getType() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap;
|
|||||||
import com.mongodb.Block;
|
import com.mongodb.Block;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.UuidUtils;
|
import net.frozenorb.apiv3.util.UuidUtils;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
@ -55,7 +56,9 @@ public final class UserConverter implements Block<Document> {
|
|||||||
false
|
false
|
||||||
);
|
);
|
||||||
|
|
||||||
created.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
created.insert(callback);
|
||||||
|
callback.get();
|
||||||
log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")");
|
log.info("Created user " + created.getLastUsername() + " (" + created.getId() + ")");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,8 +48,14 @@ public final class ActorAttributeHandler implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user != null && user.checkPassword(password)) {
|
if (user != null && user.checkPassword(password)) {
|
||||||
ctx.put("actor", new UserActor(user, user.hasPermissionAnywhere(Permissions.SIGN_API_REQUEST))); // TODO: BLOCKING
|
user.hasPermissionAnywhere(Permissions.SIGN_API_REQUEST, (hasPermission, error2) -> {
|
||||||
ctx.next();
|
if (error2 != null) {
|
||||||
|
ErrorUtils.respondInternalError(ctx, error2);
|
||||||
|
} else {
|
||||||
|
ctx.put("actor", new UserActor(user, hasPermission));
|
||||||
|
ctx.next();
|
||||||
|
}
|
||||||
|
});
|
||||||
} else {
|
} else {
|
||||||
ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + username + ".");
|
ErrorUtils.respondGeneric(ctx, 401, "Failed to authorize as " + username + ".");
|
||||||
}
|
}
|
||||||
|
@ -9,8 +9,6 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
@ -42,21 +40,9 @@ public final class Grant {
|
|||||||
grantsCollection.find().sort(new Document("addedAt", -1)).into(new LinkedList<>(), callback);
|
grantsCollection.find().sort(new Document("addedAt", -1)).into(new LinkedList<>(), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static List<Grant> findByRankSync(Collection<Rank> ranks) {
|
public static void findByRank(Collection<Rank> ranks, SingleResultCallback<List<Grant>> callback) {
|
||||||
Collection<String> convertedRanks = ranks.stream().map(Rank::getId).collect(Collectors.toList());
|
Collection<String> convertedRanks = ranks.stream().map(Rank::getId).collect(Collectors.toList());
|
||||||
return SyncUtils.blockMulti(grantsCollection.find(new Document("rank", new Document("$in", convertedRanks))));
|
grantsCollection.find(new Document("rank", new Document("$in", convertedRanks))).into(new LinkedList<>(), callback);
|
||||||
}
|
|
||||||
|
|
||||||
public static Grant findByIdSync(String id) {
|
|
||||||
return SyncUtils.blockOne(grantsCollection.find(new Document("_id", id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Grant> findByUserSync(User user) {
|
|
||||||
return findByUserSync(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Grant> findByUserSync(UUID user) {
|
|
||||||
return SyncUtils.blockMulti(grantsCollection.find(new Document("user", user)));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<Grant>> callback) {
|
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<Grant>> callback) {
|
||||||
@ -128,20 +114,16 @@ public final class Grant {
|
|||||||
return scopes.isEmpty();
|
return scopes.isEmpty();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
grantsCollection.insertOne(this, callback);
|
grantsCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(User removedBy, String reason) {
|
public void delete(User removedBy, String reason, SingleResultCallback<UpdateResult> callback) {
|
||||||
this.removedBy = removedBy.getId();
|
this.removedBy = removedBy.getId();
|
||||||
this.removedAt = Instant.now();
|
this.removedAt = Instant.now();
|
||||||
this.removalReason = reason;
|
this.removalReason = reason;
|
||||||
|
|
||||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
|
||||||
grantsCollection.replaceOne(new Document("_id", id), this, callback);
|
grantsCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -10,8 +10,6 @@ import lombok.Getter;
|
|||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.actor.Actor;
|
import net.frozenorb.apiv3.actor.Actor;
|
||||||
import net.frozenorb.apiv3.actor.ActorType;
|
import net.frozenorb.apiv3.actor.ActorType;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import net.frozenorb.apiv3.util.TimeUtils;
|
import net.frozenorb.apiv3.util.TimeUtils;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
@ -39,10 +37,6 @@ public final class IpBan {
|
|||||||
@Getter private Instant removedAt;
|
@Getter private Instant removedAt;
|
||||||
@Getter private String removalReason;
|
@Getter private String removalReason;
|
||||||
|
|
||||||
public static IpBan findByIdSync(String id) {
|
|
||||||
return SyncUtils.blockOne(ipBansCollection.find(new Document("_id", id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<IpBan>> callback) {
|
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<IpBan>> callback) {
|
||||||
ipBansCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
|
ipBansCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
|
||||||
}
|
}
|
||||||
@ -111,7 +105,6 @@ public final class IpBan {
|
|||||||
return removedBy != null;
|
return removedBy != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: CLEANUP
|
|
||||||
public void getAccessDenialReason(SingleResultCallback<String> callback) {
|
public void getAccessDenialReason(SingleResultCallback<String> callback) {
|
||||||
Punishment.findByLinkedIpBanId(id, (punishment, error) -> {
|
Punishment.findByLinkedIpBanId(id, (punishment, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
@ -123,53 +116,44 @@ public final class IpBan {
|
|||||||
User.findById(punishment.getUser(), (user, error2) -> {
|
User.findById(punishment.getUser(), (user, error2) -> {
|
||||||
if (error2 != null) {
|
if (error2 != null) {
|
||||||
callback.onResult(null, error2);
|
callback.onResult(null, error2);
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
String accessDenialReason;
|
|
||||||
|
|
||||||
if (user != null) {
|
|
||||||
accessDenialReason = "Your IP address has been suspended from the MineHQ Network for a punishment related to " + user.getLastUsername() + ". \n\n";
|
|
||||||
} else {
|
} else {
|
||||||
accessDenialReason = "Your IP address has been suspended from the MineHQ Network. \n\n";
|
callback.onResult(buildDenialReason(user), null);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getExpiresAt() != null) {
|
|
||||||
accessDenialReason += "Expires in " + TimeUtils.formatIntoDetailedString(TimeUtils.getSecondsBetween(getExpiresAt(), Instant.now()));
|
|
||||||
} else {
|
|
||||||
accessDenialReason += "Appeal at MineHQ.com/appeal";
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.onResult(accessDenialReason, null);
|
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
String accessDenialReason = "Your IP address has been suspended from the MineHQ Network. \n\n";
|
callback.onResult(buildDenialReason(null), null);
|
||||||
|
|
||||||
if (getExpiresAt() != null) {
|
|
||||||
accessDenialReason += "Expires in " + TimeUtils.formatIntoDetailedString(TimeUtils.getSecondsBetween(getExpiresAt(), Instant.now()));
|
|
||||||
} else {
|
|
||||||
accessDenialReason += "Appeal at MineHQ.com/appeal";
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.onResult(accessDenialReason, null);
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert() {
|
private String buildDenialReason(User linkedIpBanUser) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
String accessDenialReason;
|
||||||
ipBansCollection.insertOne(this, callback);
|
|
||||||
callback.get();
|
if (linkedIpBanUser != null) {
|
||||||
|
accessDenialReason = "Your IP address has been suspended from the MineHQ Network for a punishment related to " + linkedIpBanUser.getLastUsername() + ". \n\n";
|
||||||
|
} else {
|
||||||
|
accessDenialReason = "Your IP address has been suspended from the MineHQ Network. \n\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getExpiresAt() != null) {
|
||||||
|
accessDenialReason += "Expires in " + TimeUtils.formatIntoDetailedString(TimeUtils.getSecondsBetween(getExpiresAt(), Instant.now()));
|
||||||
|
} else {
|
||||||
|
accessDenialReason += "Appeal at MineHQ.com/appeal";
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessDenialReason;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(User removedBy, String reason) {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
|
ipBansCollection.insertOne(this, callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void delete(User removedBy, String reason, SingleResultCallback<UpdateResult> callback) {
|
||||||
this.removedBy = removedBy.getId();
|
this.removedBy = removedBy.getId();
|
||||||
this.removedAt = Instant.now();
|
this.removedAt = Instant.now();
|
||||||
this.removalReason = reason;
|
this.removalReason = reason;
|
||||||
|
|
||||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
|
||||||
ipBansCollection.replaceOne(new Document("_id", id), this, callback);
|
ipBansCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -46,7 +46,7 @@ public final class IpIntel {
|
|||||||
} else {
|
} else {
|
||||||
IpIntel newIpIntel = new IpIntel(id, maxMindResult);
|
IpIntel newIpIntel = new IpIntel(id, maxMindResult);
|
||||||
|
|
||||||
newIpIntel.insert((ignored, error3) -> {
|
ipIntelCollection.insertOne(newIpIntel, (ignored, error3) -> {
|
||||||
if (error3 != null) {
|
if (error3 != null) {
|
||||||
callback.onResult(null, error3);
|
callback.onResult(null, error3);
|
||||||
} else {
|
} else {
|
||||||
@ -61,14 +61,10 @@ public final class IpIntel {
|
|||||||
|
|
||||||
public IpIntel() {} // For Jackson
|
public IpIntel() {} // For Jackson
|
||||||
|
|
||||||
public IpIntel(String ip, MaxMindResult result) {
|
private IpIntel(String ip, MaxMindResult result) {
|
||||||
this.id = ip;
|
this.id = ip;
|
||||||
this.lastUpdatedAt = Instant.now();
|
this.lastUpdatedAt = Instant.now();
|
||||||
this.result = result;
|
this.result = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert(SingleResultCallback<Void> callback) {
|
|
||||||
ipIntelCollection.insertOne(this, callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
@ -8,8 +8,6 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
|||||||
import lombok.AllArgsConstructor;
|
import lombok.AllArgsConstructor;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
|
|
||||||
@ -31,30 +29,6 @@ public final class IpLogEntry {
|
|||||||
@Getter private Instant lastSeenAt;
|
@Getter private Instant lastSeenAt;
|
||||||
@Getter private int uses;
|
@Getter private int uses;
|
||||||
|
|
||||||
public static List<IpLogEntry> findAllSync() {
|
|
||||||
return SyncUtils.blockMulti(ipLogCollection.find().sort(new Document("lastSeenAt", -1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IpLogEntry findByIdSync(String id) {
|
|
||||||
return SyncUtils.blockOne(ipLogCollection.find(new Document("_id", id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<IpLogEntry> findByUserSync(User user) {
|
|
||||||
return findByUserSync(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<IpLogEntry> findByUserSync(UUID user) {
|
|
||||||
return SyncUtils.blockMulti(ipLogCollection.find(new Document("user", user)).sort(new Document("lastSeenAt", -1)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IpLogEntry findByUserAndIpSync(User user, String userIp) {
|
|
||||||
return findByUserAndIpSync(user.getId(), userIp);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static IpLogEntry findByUserAndIpSync(UUID user, String userIp) {
|
|
||||||
return SyncUtils.blockOne(ipLogCollection.find(new Document("user", user).append("userIp", userIp)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void findAll(SingleResultCallback<List<IpLogEntry>> callback) {
|
public static void findAll(SingleResultCallback<List<IpLogEntry>> callback) {
|
||||||
ipLogCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), callback);
|
ipLogCollection.find().sort(new Document("lastSeenAt", -1)).into(new LinkedList<>(), callback);
|
||||||
}
|
}
|
||||||
@ -95,16 +69,12 @@ public final class IpLogEntry {
|
|||||||
this.uses++;
|
this.uses++;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
ipLogCollection.insertOne(this, callback);
|
ipLogCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save(SingleResultCallback<UpdateResult> callback) {
|
||||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
|
||||||
ipLogCollection.replaceOne(new Document("_id", id), this, callback);
|
ipLogCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -8,8 +8,6 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.util.LinkedList;
|
import java.util.LinkedList;
|
||||||
@ -25,10 +23,6 @@ public final class NotificationTemplate {
|
|||||||
@Getter @Setter private String subject;
|
@Getter @Setter private String subject;
|
||||||
@Getter @Setter private String body;
|
@Getter @Setter private String body;
|
||||||
|
|
||||||
public static NotificationTemplate findByIdSync(String id) {
|
|
||||||
return SyncUtils.blockOne(notificationTemplatesCollection.find(new Document("_id", id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void findAll(SingleResultCallback<List<NotificationTemplate>> callback) {
|
public static void findAll(SingleResultCallback<List<NotificationTemplate>> callback) {
|
||||||
notificationTemplatesCollection.find().into(new LinkedList<>(), callback);
|
notificationTemplatesCollection.find().into(new LinkedList<>(), callback);
|
||||||
}
|
}
|
||||||
@ -64,16 +58,12 @@ public final class NotificationTemplate {
|
|||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
notificationTemplatesCollection.insertOne(this, callback);
|
notificationTemplatesCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete(SingleResultCallback<DeleteResult> callback) {
|
||||||
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
|
||||||
notificationTemplatesCollection.deleteOne(new Document("_id", id), callback);
|
notificationTemplatesCollection.deleteOne(new Document("_id", id), callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -10,8 +10,6 @@ import lombok.Getter;
|
|||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.actor.Actor;
|
import net.frozenorb.apiv3.actor.Actor;
|
||||||
import net.frozenorb.apiv3.actor.ActorType;
|
import net.frozenorb.apiv3.actor.ActorType;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import net.frozenorb.apiv3.util.TimeUtils;
|
import net.frozenorb.apiv3.util.TimeUtils;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
import org.bson.types.ObjectId;
|
import org.bson.types.ObjectId;
|
||||||
@ -48,27 +46,6 @@ public final class Punishment {
|
|||||||
punishmentsCollection.find(new Document("type", new Document("$in", convertedTypes))).into(new LinkedList<>(), callback);
|
punishmentsCollection.find(new Document("type", new Document("$in", convertedTypes))).into(new LinkedList<>(), callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Punishment findByIdSync(String id) {
|
|
||||||
return SyncUtils.blockOne(punishmentsCollection.find(new Document("_id", id)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Punishment> findByUserSync(User user) {
|
|
||||||
return findByUserSync(user.getId());
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Punishment> findByUserSync(UUID user) {
|
|
||||||
return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Punishment> findByUserAndTypeSync(User user, Collection<PunishmentType> types) {
|
|
||||||
return findByUserAndTypeSync(user.getId(), types);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static List<Punishment> findByUserAndTypeSync(UUID user, Collection<PunishmentType> types) {
|
|
||||||
Collection<String> convertedTypes = types.stream().map(PunishmentType::name).collect(Collectors.toList());
|
|
||||||
return SyncUtils.blockMulti(punishmentsCollection.find(new Document("user", user).append("type", new Document("$in", convertedTypes))));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<Punishment>> callback) {
|
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<Punishment>> callback) {
|
||||||
punishmentsCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
|
punishmentsCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), callback);
|
||||||
}
|
}
|
||||||
@ -168,28 +145,38 @@ public final class Punishment {
|
|||||||
this.linkedIpBanId = ipBan.getId();
|
this.linkedIpBanId = ipBan.getId();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
punishmentsCollection.insertOne(this, callback);
|
punishmentsCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete(User removedBy, String reason) {
|
public void delete(User removedBy, String reason, SingleResultCallback<UpdateResult> callback) {
|
||||||
this.removedBy = removedBy.getId();
|
this.removedBy = removedBy.getId();
|
||||||
this.removedAt = Instant.now();
|
this.removedAt = Instant.now();
|
||||||
this.removalReason = reason;
|
this.removalReason = reason;
|
||||||
|
|
||||||
if (linkedIpBanId != null) {
|
if (linkedIpBanId == null) {
|
||||||
IpBan ipBan = IpBan.findByIdSync(linkedIpBanId);
|
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
|
return;
|
||||||
if (ipBan != null && ipBan.isActive()) {
|
|
||||||
ipBan.delete(removedBy, "Linked punishment removed: " + reason);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
IpBan.findById(linkedIpBanId, (ipBan, error) -> {
|
||||||
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
|
if (error != null) {
|
||||||
callback.get();
|
callback.onResult(null, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ipBan != null && ipBan.isActive()) {
|
||||||
|
ipBan.delete(removedBy, "Linked punishment removed: " + reason, (ignored, error2) -> {
|
||||||
|
if (error2 != null) {
|
||||||
|
callback.onResult(null, error2);
|
||||||
|
} else {
|
||||||
|
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
punishmentsCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum PunishmentType {
|
public enum PunishmentType {
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
package net.frozenorb.apiv3.model;
|
package net.frozenorb.apiv3.model;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.primitives.Ints;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.async.SingleResultCallback;
|
||||||
import com.mongodb.async.client.MongoCollection;
|
import com.mongodb.async.client.MongoCollection;
|
||||||
import com.mongodb.client.result.DeleteResult;
|
import com.mongodb.client.result.DeleteResult;
|
||||||
import fr.javatic.mongo.jacksonCodec.Entity;
|
import fr.javatic.mongo.jacksonCodec.Entity;
|
||||||
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
@ -23,9 +22,8 @@ public final class Rank {
|
|||||||
|
|
||||||
private static final MongoCollection<Rank> ranksCollection = APIv3.getDatabase().getCollection("ranks", Rank.class);
|
private static final MongoCollection<Rank> ranksCollection = APIv3.getDatabase().getCollection("ranks", Rank.class);
|
||||||
|
|
||||||
private static Map<String, Rank> rankCache = null;
|
private static Map<String, Rank> rankIdCache = null;
|
||||||
private static List<Rank> rankAltCache = null;
|
private static List<Rank> rankCache = null;
|
||||||
private static long rankCacheUpdated = 0;
|
|
||||||
|
|
||||||
@Getter @Id private String id;
|
@Getter @Id private String id;
|
||||||
@Getter private int weight;
|
@Getter private int weight;
|
||||||
@ -35,13 +33,37 @@ public final class Rank {
|
|||||||
@Getter private boolean staffRank;
|
@Getter private boolean staffRank;
|
||||||
|
|
||||||
public static List<Rank> findAll() {
|
public static List<Rank> findAll() {
|
||||||
updateCacheIfNeeded();
|
return rankCache;
|
||||||
return ImmutableList.copyOf(rankAltCache);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Rank findById(String id) {
|
public static Rank findById(String id) {
|
||||||
updateCacheIfNeeded();
|
return rankIdCache.get(id);
|
||||||
return rankCache.get(id);
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
updateCache();
|
||||||
|
|
||||||
|
APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> {
|
||||||
|
updateCache();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateCache() {
|
||||||
|
ranksCollection.find().into(new LinkedList<>(), (ranks, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
error.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Rank> working = new HashMap<>();
|
||||||
|
|
||||||
|
for (Rank rank : ranks) {
|
||||||
|
working.put(rank.getId(), rank);
|
||||||
|
}
|
||||||
|
|
||||||
|
rankIdCache = ImmutableMap.copyOf(working);
|
||||||
|
rankCache = ImmutableList.copyOf(ranks);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rank() {} // For Jackson
|
public Rank() {} // For Jackson
|
||||||
@ -55,34 +77,12 @@ public final class Rank {
|
|||||||
this.staffRank = staffRank;
|
this.staffRank = staffRank;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateCacheIfNeeded() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
if (rankCache == null || (System.currentTimeMillis() - rankCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) {
|
|
||||||
Map<String, Rank> working = new HashMap<>();
|
|
||||||
List<Rank> workingAlt = new LinkedList<>();
|
|
||||||
List<Rank> allRanks = SyncUtils.blockMulti(ranksCollection.find());
|
|
||||||
allRanks.sort((a, b) -> Ints.compare(a.getWeight(), b.getWeight()));
|
|
||||||
|
|
||||||
for (Rank rank : allRanks) {
|
|
||||||
working.put(rank.getId(), rank);
|
|
||||||
workingAlt.add(rank);
|
|
||||||
}
|
|
||||||
|
|
||||||
rankCache = working;
|
|
||||||
rankAltCache = workingAlt;
|
|
||||||
rankCacheUpdated = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert() {
|
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
ranksCollection.insertOne(this, callback);
|
ranksCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete(SingleResultCallback<DeleteResult> callback) {
|
||||||
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
|
||||||
ranksCollection.deleteOne(new Document("_id", id), callback);
|
ranksCollection.deleteOne(new Document("_id", id), callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,6 +1,9 @@
|
|||||||
package net.frozenorb.apiv3.model;
|
package net.frozenorb.apiv3.model;
|
||||||
|
|
||||||
|
import com.google.common.collect.ImmutableList;
|
||||||
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.mongodb.async.SingleResultCallback;
|
||||||
import com.mongodb.async.client.MongoCollection;
|
import com.mongodb.async.client.MongoCollection;
|
||||||
import com.mongodb.client.result.DeleteResult;
|
import com.mongodb.client.result.DeleteResult;
|
||||||
import com.mongodb.client.result.UpdateResult;
|
import com.mongodb.client.result.UpdateResult;
|
||||||
@ -9,8 +12,6 @@ import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
|||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -22,9 +23,8 @@ public final class Server {
|
|||||||
|
|
||||||
private static final MongoCollection<Server> serversCollection = APIv3.getDatabase().getCollection("servers", Server.class);
|
private static final MongoCollection<Server> serversCollection = APIv3.getDatabase().getCollection("servers", Server.class);
|
||||||
|
|
||||||
private static Map<String, Server> serverCache = null;
|
private static Map<String, Server> serverIdCache = null;
|
||||||
private static List<Server> serverCacheAlt = null;
|
private static List<Server> serverCache = null;
|
||||||
private static long serverCacheUpdated = 0;
|
|
||||||
|
|
||||||
@Getter @Id private String id;
|
@Getter @Id private String id;
|
||||||
@Getter private String displayName;
|
@Getter private String displayName;
|
||||||
@ -36,13 +36,37 @@ public final class Server {
|
|||||||
@Getter @ExcludeFromReplies private Set<UUID> players;
|
@Getter @ExcludeFromReplies private Set<UUID> players;
|
||||||
|
|
||||||
public static List<Server> findAll() {
|
public static List<Server> findAll() {
|
||||||
updateCacheIfNeeded();
|
return serverCache;
|
||||||
return serverCacheAlt;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Server findById(String id) {
|
public static Server findById(String id) {
|
||||||
updateCacheIfNeeded();
|
return serverIdCache.get(id);
|
||||||
return serverCache.get(id);
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
updateCache();
|
||||||
|
|
||||||
|
APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> {
|
||||||
|
updateCache();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateCache() {
|
||||||
|
serversCollection.find().into(new LinkedList<>(), (servers, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
error.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Server> working = new HashMap<>();
|
||||||
|
|
||||||
|
for (Server server : servers) {
|
||||||
|
working.put(server.getId(), server);
|
||||||
|
}
|
||||||
|
|
||||||
|
serverIdCache = ImmutableMap.copyOf(working);
|
||||||
|
serverCache = ImmutableList.copyOf(servers);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public Server() {} // For Jackson
|
public Server() {} // For Jackson
|
||||||
@ -58,44 +82,22 @@ public final class Server {
|
|||||||
this.players = new HashSet<>();
|
this.players = new HashSet<>();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateCacheIfNeeded() {
|
|
||||||
if (serverCache == null || (System.currentTimeMillis() - serverCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) {
|
|
||||||
Map<String, Server> working = new HashMap<>();
|
|
||||||
List<Server> workingAlt = new LinkedList<>();
|
|
||||||
|
|
||||||
for (Server server : SyncUtils.blockMulti(serversCollection.find())) {
|
|
||||||
working.put(server.getId(), server);
|
|
||||||
workingAlt.add(server);
|
|
||||||
}
|
|
||||||
|
|
||||||
serverCache = working;
|
|
||||||
serverCacheAlt = workingAlt;
|
|
||||||
serverCacheUpdated = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void receivedHeartbeat(double tps, Iterable<UUID> players) {
|
public void receivedHeartbeat(double tps, Iterable<UUID> players) {
|
||||||
this.lastUpdatedAt = Instant.now();
|
this.lastUpdatedAt = Instant.now();
|
||||||
this.lastTps = tps;
|
this.lastTps = tps;
|
||||||
this.players = ImmutableSet.copyOf(players);
|
this.players = ImmutableSet.copyOf(players);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void insert() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
serversCollection.insertOne(this, callback);
|
serversCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save() {
|
public void save(SingleResultCallback<UpdateResult> callback) {
|
||||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
|
||||||
serversCollection.replaceOne(new Document("_id", id), this, callback);
|
serversCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete(SingleResultCallback<DeleteResult> callback) {
|
||||||
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
|
||||||
serversCollection.deleteOne(new Document("_id", id), callback);
|
serversCollection.deleteOne(new Document("_id", id), callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package net.frozenorb.apiv3.model;
|
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.SingleResultCallback;
|
||||||
import com.mongodb.async.client.MongoCollection;
|
import com.mongodb.async.client.MongoCollection;
|
||||||
import com.mongodb.client.result.DeleteResult;
|
import com.mongodb.client.result.DeleteResult;
|
||||||
@ -10,9 +12,7 @@ import lombok.Getter;
|
|||||||
import lombok.Setter;
|
import lombok.Setter;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
import net.frozenorb.apiv3.util.PermissionUtils;
|
import net.frozenorb.apiv3.util.PermissionUtils;
|
||||||
import net.frozenorb.apiv3.util.SyncUtils;
|
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
@ -23,24 +23,46 @@ public final class ServerGroup {
|
|||||||
|
|
||||||
private static final MongoCollection<ServerGroup> serverGroupsCollection = APIv3.getDatabase().getCollection("serverGroups", ServerGroup.class);
|
private static final MongoCollection<ServerGroup> serverGroupsCollection = APIv3.getDatabase().getCollection("serverGroups", ServerGroup.class);
|
||||||
|
|
||||||
private static Map<String, ServerGroup> serverGroupCache = null;
|
private static Map<String, ServerGroup> serverGroupIdCache = null;
|
||||||
private static List<ServerGroup> serverGroupAltCache = null;
|
private static List<ServerGroup> serverGroupCache = null;
|
||||||
private static long serverGroupCacheUpdated = 0;
|
|
||||||
|
|
||||||
@Getter @Id private String id;
|
@Getter @Id private String id;
|
||||||
@Getter private String image;
|
@Getter private String image;
|
||||||
@Getter @Setter private Set<String> announcements;
|
@Getter @Setter private Set<String> announcements;
|
||||||
@Getter @Setter @ExcludeFromReplies private Map<String, List<String>> permissions;
|
@Getter @Setter @ExcludeFromReplies private Map<String, List<String>> permissions;
|
||||||
|
|
||||||
// make this and other stuff async
|
|
||||||
public static List<ServerGroup> findAll() {
|
public static List<ServerGroup> findAll() {
|
||||||
updateCacheIfNeeded();
|
return serverGroupCache;
|
||||||
return serverGroupAltCache;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ServerGroup findById(String id) {
|
public static ServerGroup findById(String id) {
|
||||||
updateCacheIfNeeded();
|
return serverGroupIdCache.get(id);
|
||||||
return serverGroupCache.get(id);
|
}
|
||||||
|
|
||||||
|
static {
|
||||||
|
updateCache();
|
||||||
|
|
||||||
|
APIv3.getVertxInstance().setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> {
|
||||||
|
updateCache();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void updateCache() {
|
||||||
|
serverGroupsCollection.find().into(new LinkedList<>(), (serverGroups, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
error.printStackTrace();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, ServerGroup> working = new HashMap<>();
|
||||||
|
|
||||||
|
for (ServerGroup serverGroup : serverGroups) {
|
||||||
|
working.put(serverGroup.getId(), serverGroup);
|
||||||
|
}
|
||||||
|
|
||||||
|
serverGroupIdCache = ImmutableMap.copyOf(working);
|
||||||
|
serverGroupCache = ImmutableList.copyOf(serverGroups);
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public ServerGroup() {} // For Jackson
|
public ServerGroup() {} // For Jackson
|
||||||
@ -54,36 +76,16 @@ public final class ServerGroup {
|
|||||||
return PermissionUtils.mergeUpTo(permissions, userRank);
|
return PermissionUtils.mergeUpTo(permissions, userRank);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void updateCacheIfNeeded() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
if (serverGroupCache == null || (System.currentTimeMillis() - serverGroupCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) {
|
|
||||||
Map<String, ServerGroup> working = new HashMap<>();
|
|
||||||
List<ServerGroup> workingAlt = new LinkedList<>();
|
|
||||||
|
|
||||||
for (ServerGroup serverGroup : SyncUtils.blockMulti(serverGroupsCollection.find())) {
|
|
||||||
working.put(serverGroup.getId(), serverGroup);
|
|
||||||
workingAlt.add(serverGroup);
|
|
||||||
}
|
|
||||||
|
|
||||||
serverGroupCache = working;
|
|
||||||
serverGroupAltCache = workingAlt;
|
|
||||||
serverGroupCacheUpdated = System.currentTimeMillis();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert() {
|
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
serverGroupsCollection.insertOne(this, callback);
|
serverGroupsCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(SingleResultCallback<UpdateResult> callback) {
|
public void save(SingleResultCallback<UpdateResult> callback) {
|
||||||
serverGroupsCollection.replaceOne(new Document("_id", id), this, callback);
|
serverGroupsCollection.replaceOne(new Document("_id", id), this, callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void delete() {
|
public void delete(SingleResultCallback<DeleteResult> callback) {
|
||||||
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
|
||||||
serverGroupsCollection.deleteOne(new Document("_id", id), callback);
|
serverGroupsCollection.deleteOne(new Document("_id", id), callback);
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -23,8 +23,9 @@ import net.frozenorb.apiv3.maxmind.MaxMindUserType;
|
|||||||
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
||||||
import net.frozenorb.apiv3.serialization.jackson.UuidJsonDeserializer;
|
import net.frozenorb.apiv3.serialization.jackson.UuidJsonDeserializer;
|
||||||
import net.frozenorb.apiv3.serialization.jackson.UuidJsonSerializer;
|
import net.frozenorb.apiv3.serialization.jackson.UuidJsonSerializer;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
import net.frozenorb.apiv3.unsorted.FutureCompatibilityCallback;
|
||||||
import net.frozenorb.apiv3.unsorted.Permissions;
|
import net.frozenorb.apiv3.unsorted.Permissions;
|
||||||
|
import net.frozenorb.apiv3.unsorted.RequiresTotpResult;
|
||||||
import net.frozenorb.apiv3.util.*;
|
import net.frozenorb.apiv3.util.*;
|
||||||
import org.bson.Document;
|
import org.bson.Document;
|
||||||
|
|
||||||
@ -53,44 +54,12 @@ public final class User {
|
|||||||
@Getter private Instant firstSeenAt;
|
@Getter private Instant firstSeenAt;
|
||||||
@Getter private boolean online;
|
@Getter private boolean online;
|
||||||
|
|
||||||
public static User findByIdSync(String id) {
|
|
||||||
UUID uuid;
|
|
||||||
|
|
||||||
try {
|
|
||||||
uuid = UUID.fromString(id);
|
|
||||||
} catch (NullPointerException | IllegalArgumentException ex) {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
return findByIdSync(uuid);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static User findByIdSync(UUID id) {
|
|
||||||
if (UuidUtils.isAcceptableUuid(id)) {
|
|
||||||
return SyncUtils.blockOne(usersCollection.find(new Document("_id", id)));
|
|
||||||
} else {
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public static User findByEmailSync(String email) {
|
|
||||||
return SyncUtils.blockOne(usersCollection.find(new Document("email", email)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static User findByEmailTokenSync(String emailToken) {
|
|
||||||
return SyncUtils.blockOne(usersCollection.find(new Document("emailToken", emailToken)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static User findByLastUsernameSync(String lastUsername) {
|
|
||||||
return SyncUtils.blockOne(usersCollection.find(new Document("lastUsername", lastUsername)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void findById(String id, SingleResultCallback<User> callback) {
|
public static void findById(String id, SingleResultCallback<User> callback) {
|
||||||
try {
|
try {
|
||||||
UUID uuid = UUID.fromString(id);
|
UUID uuid = UUID.fromString(id);
|
||||||
findById(uuid, callback);
|
findById(uuid, callback);
|
||||||
} catch (IllegalArgumentException ex) { // from UUID parsing
|
} catch (IllegalArgumentException ignored) { // from UUID parsing
|
||||||
callback.onResult(null, ex);
|
callback.onResult(null, null); // We don't pass in the exception, we just pretend we couldn't find them.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,6 +71,18 @@ public final class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void findByEmail(String email, SingleResultCallback<User> callback) {
|
||||||
|
usersCollection.find(new Document("email", email)).first(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void findByEmailToken(String emailToken, SingleResultCallback<User> callback) {
|
||||||
|
usersCollection.find(new Document("emailToken", emailToken)).first(callback);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void findByLastUsername(String lastUsername, SingleResultCallback<User> callback) {
|
||||||
|
usersCollection.find(new Document("lastUsername", lastUsername)).first(callback);
|
||||||
|
}
|
||||||
|
|
||||||
public static void findByIdGrouped(Iterable<UUID> search, SingleResultCallback<Map<UUID, User>> callback) {
|
public static void findByIdGrouped(Iterable<UUID> search, SingleResultCallback<Map<UUID, User>> callback) {
|
||||||
usersCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (users, error) -> {
|
usersCollection.find(new Document("_id", new Document("$in", search))).into(new LinkedList<>(), (users, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
@ -122,62 +103,211 @@ public final class User {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void findByEmailTokenSync(String emailToken, SingleResultCallback<User> callback) {
|
|
||||||
usersCollection.find(new Document("emailToken", emailToken)).first(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void findByLastUsername(String lastUsername, SingleResultCallback<User> callback) {
|
|
||||||
usersCollection.find(new Document("lastUsername", lastUsername)).first(callback);
|
|
||||||
}
|
|
||||||
|
|
||||||
public User() {} // For Jackson
|
public User() {} // For Jackson
|
||||||
|
|
||||||
// TODO: THIS IS CURRENTLY BLOCKING. MAYBE FOR THE HEARTBEAT WE CAN DO SOMETHING
|
|
||||||
// TO MAKE IT NOT SO BLOCKING
|
|
||||||
public User(UUID id, String lastUsername) {
|
public User(UUID id, String lastUsername) {
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.lastUsername = ""; // Intentional, so updateUsername actually does something.
|
this.lastUsername = lastUsername;
|
||||||
this.aliases = new HashMap<>();
|
this.aliases = new HashMap<>();
|
||||||
this.lastSeenAt = Instant.now();
|
this.lastSeenAt = Instant.now();
|
||||||
this.firstSeenAt = Instant.now();
|
this.firstSeenAt = Instant.now();
|
||||||
|
|
||||||
updateUsername(lastUsername);
|
this.aliases.put(lastUsername, Instant.now());
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean hasPermissionAnywhere(String permission) {
|
public void updateUsername(String newUsername) {
|
||||||
Map<String, Boolean> globalPermissions = getGlobalPermissions();
|
this.aliases.put(newUsername, Instant.now());
|
||||||
return globalPermissions.containsKey(permission) && globalPermissions.get(permission);
|
this.lastUsername = newUsername;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ASYNC
|
public void checkNameCollisions(SingleResultCallback<Void> callback) {
|
||||||
public Map<String, Boolean> getGlobalPermissions() {
|
User.findByLastUsername(lastUsername, (collision, error) -> {
|
||||||
Map<String, Boolean> globalPermissions = PermissionUtils.getDefaultPermissions(getHighestRankAnywhere());
|
if (error != null) {
|
||||||
|
callback.onResult(null, error);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
for (Map.Entry<ServerGroup, Rank> serverGroupEntry : getHighestRanks().entrySet()) {
|
if (collision == null) {
|
||||||
ServerGroup serverGroup = serverGroupEntry.getKey();
|
callback.onResult(null, null);
|
||||||
Rank rank = serverGroupEntry.getValue();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
globalPermissions = PermissionUtils.mergePermissions(
|
MojangUtils.getName(collision.getId(), (collisionNewUsername, error2) -> {
|
||||||
globalPermissions,
|
if (error2 != null) {
|
||||||
serverGroup.calculatePermissions(rank)
|
callback.onResult(null, error2);
|
||||||
);
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
collision.updateUsername(collisionNewUsername);
|
||||||
|
collision.checkNameCollisions((ignored, error3) -> {
|
||||||
|
if (error3 != null) {
|
||||||
|
callback.onResult(null, error3);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
collision.save((ignored2, error4) -> {
|
||||||
|
if (error4 != null) {
|
||||||
|
callback.onResult(null, error4);
|
||||||
|
} else {
|
||||||
|
callback.onResult(null, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public void getLoginInfo(Server server, String userIp, SingleResultCallback<Map<String, Object>> callback) {
|
||||||
|
Future<List<Punishment>> punishmentsFuture = Future.future();
|
||||||
|
Future<IpIntel> ipIntelFuture = Future.future();
|
||||||
|
Future<List<IpBan>> ipBansFuture = Future.future();
|
||||||
|
Future<List<Grant>> grantsFuture = Future.future();
|
||||||
|
|
||||||
|
Punishment.findByUserAndType(this, ImmutableSet.of(
|
||||||
|
Punishment.PunishmentType.BLACKLIST,
|
||||||
|
Punishment.PunishmentType.BAN,
|
||||||
|
Punishment.PunishmentType.MUTE
|
||||||
|
), new FutureCompatibilityCallback<>(punishmentsFuture));
|
||||||
|
|
||||||
|
if (userIp != null) {
|
||||||
|
IpIntel.findByIdOrInsert(userIp, new FutureCompatibilityCallback<>(ipIntelFuture));
|
||||||
|
IpBan.findByIp(userIp, new FutureCompatibilityCallback<>(ipBansFuture));
|
||||||
|
} else {
|
||||||
|
ipIntelFuture.complete(null);
|
||||||
|
ipBansFuture.complete(ImmutableList.of());
|
||||||
}
|
}
|
||||||
|
|
||||||
return ImmutableMap.copyOf(globalPermissions);
|
Grant.findByUser(this, new FutureCompatibilityCallback<>(grantsFuture));
|
||||||
|
|
||||||
|
CompositeFuture.all(punishmentsFuture, ipIntelFuture, ipBansFuture, grantsFuture).setHandler((result) -> {
|
||||||
|
if (result.succeeded()) {
|
||||||
|
Iterable<Punishment> punishments = result.result().result(0);
|
||||||
|
IpIntel ipIntel = result.result().result(1);
|
||||||
|
Iterable<IpBan> ipBans = result.result().result(2);
|
||||||
|
Iterable<Grant> grants = result.result().result(3);
|
||||||
|
|
||||||
|
getLoginInfo(server, ipIntel, punishments, ipBans, grants, (loginInfo, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
callback.onResult(null, error);
|
||||||
|
} else {
|
||||||
|
callback.onResult(loginInfo, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback.onResult(null, result.cause());
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// This is only used to help batch requests to mongo
|
||||||
|
public void getLoginInfo(Server server, IpIntel ipIntel, Iterable<Punishment> punishments, Iterable<IpBan> ipBans, Iterable<Grant> grants, SingleResultCallback<Map<String, Object>> callback) {
|
||||||
|
getAccessInfo(ipIntel, punishments, ipBans, (accessInfo, error) -> {
|
||||||
|
ServerGroup serverGroup = ServerGroup.findById(server.getServerGroup());
|
||||||
|
Punishment activeMute = null;
|
||||||
|
|
||||||
|
for (Punishment punishment : punishments) {
|
||||||
|
if (punishment.isActive() && punishment.getType() == Punishment.PunishmentType.MUTE) {
|
||||||
|
activeMute = punishment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> result = new HashMap<>();
|
||||||
|
|
||||||
|
result.put("user", this);
|
||||||
|
result.put("access", accessInfo);
|
||||||
|
result.put("rank", getHighestRankScoped(serverGroup, grants).getId());
|
||||||
|
result.put("totpSetup", getTotpSecret() != null);
|
||||||
|
|
||||||
|
if (activeMute != null) {
|
||||||
|
result.put("mute", activeMute);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.onResult(result, null);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void getAccessInfo(IpIntel ipIntel, Iterable<Punishment> punishments, Iterable<IpBan> ipBans, SingleResultCallback<Map<String, Object>> callback) {
|
||||||
|
Punishment activeBan = null;
|
||||||
|
IpBan activeIpBan = null;
|
||||||
|
|
||||||
|
for (Punishment punishment : punishments) {
|
||||||
|
if (punishment.isActive() && (punishment.getType() == Punishment.PunishmentType.BAN || punishment.getType() == Punishment.PunishmentType.BLACKLIST)) {
|
||||||
|
activeBan = punishment;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (IpBan ipBan : ipBans) {
|
||||||
|
if (ipBan.isActive()) {
|
||||||
|
activeIpBan = ipBan;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> accessAllowed = ImmutableMap.of(
|
||||||
|
"allowed", true,
|
||||||
|
"message", ""
|
||||||
|
);
|
||||||
|
|
||||||
|
if (activeBan != null) {
|
||||||
|
callback.onResult(ImmutableMap.of(
|
||||||
|
"allowed", false,
|
||||||
|
"message", activeBan.getAccessDenialReason()
|
||||||
|
), null);
|
||||||
|
} else if (activeIpBan != null) {
|
||||||
|
activeIpBan.getAccessDenialReason((denialReason, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
callback.onResult(null, error);
|
||||||
|
} else {
|
||||||
|
callback.onResult(ImmutableMap.of(
|
||||||
|
"allowed", false,
|
||||||
|
"message", denialReason
|
||||||
|
), null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (ipIntel != null) {
|
||||||
|
MaxMindResult maxMindResult = ipIntel.getResult();
|
||||||
|
MaxMindUserType userType = maxMindResult.getTraits().getUserType();
|
||||||
|
Map<String, Object> proposedAccess = null;
|
||||||
|
|
||||||
|
if (!userType.isAllowed()) {
|
||||||
|
proposedAccess = ImmutableMap.of(
|
||||||
|
"allowed", false,
|
||||||
|
"message", "You cannot join MineHQ from a VPN."
|
||||||
|
);
|
||||||
|
} else if (ImmutableList.of().contains(maxMindResult.getTraits().getAsn())) {
|
||||||
|
proposedAccess = ImmutableMap.of(
|
||||||
|
"allowed", false,
|
||||||
|
"message", "You cannot join MineHQ from this ISP."
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
Map<String, Object> finalProposedAccess = proposedAccess;
|
||||||
|
|
||||||
|
if (proposedAccess != null) {
|
||||||
|
hasPermissionAnywhere(Permissions.BYPASS_VPN_CHECK, (bypass, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
callback.onResult(null, error);
|
||||||
|
} else {
|
||||||
|
callback.onResult(bypass ? accessAllowed : finalProposedAccess, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
callback.onResult(accessAllowed, null);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
callback.onResult(accessAllowed, null);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Clean
|
|
||||||
public boolean seenOnServer(Server server) {
|
public boolean seenOnServer(Server server) {
|
||||||
if (online && server.getId().equals(this.lastSeenOn)) {
|
if (online && server.getId().equals(lastSeenOn)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
this.lastSeenOn = server.getId();
|
this.lastSeenOn = server.getId();
|
||||||
|
this.lastSeenAt = Instant.now();
|
||||||
if (!online) {
|
|
||||||
this.lastSeenAt = Instant.now();
|
|
||||||
}
|
|
||||||
|
|
||||||
this.online = true;
|
this.online = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -187,23 +317,6 @@ public final class User {
|
|||||||
this.online = false;
|
this.online = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void updateUsername(String newUsername) {
|
|
||||||
if (!newUsername.equals(lastUsername)) {
|
|
||||||
this.lastUsername = newUsername;
|
|
||||||
|
|
||||||
User withNewUsername;
|
|
||||||
|
|
||||||
while ((withNewUsername = User.findByLastUsernameSync(newUsername)) != null) {
|
|
||||||
BlockingCallback<String> callback = new BlockingCallback<>();
|
|
||||||
MojangUtils.getName(withNewUsername.getId(), callback);
|
|
||||||
withNewUsername.updateUsername(callback.get());
|
|
||||||
withNewUsername.save();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
this.aliases.put(newUsername, Instant.now());
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setPassword(String input) {
|
public void setPassword(String input) {
|
||||||
this.password = Hashing
|
this.password = Hashing
|
||||||
.sha256()
|
.sha256()
|
||||||
@ -242,15 +355,6 @@ public final class User {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: CLEAN
|
|
||||||
public enum RequiresTotpResult {
|
|
||||||
|
|
||||||
NOT_REQUIRED_NOT_SET,
|
|
||||||
NOT_REQUIRED_IP_PRE_AUTHORIZED,
|
|
||||||
REQUIRED_NO_EXEMPTIONS
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void completeRegistration(String email) {
|
public void completeRegistration(String email) {
|
||||||
this.email = email;
|
this.email = email;
|
||||||
this.registeredAt = Instant.now();
|
this.registeredAt = Instant.now();
|
||||||
@ -265,12 +369,50 @@ public final class User {
|
|||||||
this.pendingEmailTokenSetAt = Instant.now();
|
this.pendingEmailTokenSetAt = Instant.now();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Rank getHighestRankAnywhere() {
|
public void hasPermissionAnywhere(String permission, SingleResultCallback<Boolean> callback) {
|
||||||
return getHighestRankScoped(null, Grant.findByUserSync(this));
|
getGlobalPermissions((permissions, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
callback.onResult(null, error);
|
||||||
|
} else {
|
||||||
|
boolean hasPermission = permissions.containsKey(permission) && permissions.get(permission);
|
||||||
|
callback.onResult(hasPermission, null);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// This is only used to help batch requests to mongo
|
public void getGlobalPermissions(SingleResultCallback<Map<String, Boolean>> callback) {
|
||||||
public Rank getHighestRankScoped(ServerGroup serverGroup, Iterable<Grant> grants) {
|
Grant.findByUser(this, (grants, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
callback.onResult(null, error);
|
||||||
|
} else {
|
||||||
|
Map<String, Boolean> globalPermissions = PermissionUtils.getDefaultPermissions(getHighestRankScoped(null, grants));
|
||||||
|
|
||||||
|
for (Map.Entry<ServerGroup, Rank> serverGroupEntry : getHighestRanks(grants).entrySet()) {
|
||||||
|
ServerGroup serverGroup = serverGroupEntry.getKey();
|
||||||
|
Rank rank = serverGroupEntry.getValue();
|
||||||
|
|
||||||
|
globalPermissions = PermissionUtils.mergePermissions(
|
||||||
|
globalPermissions,
|
||||||
|
serverGroup.calculatePermissions(rank)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.onResult(ImmutableMap.copyOf(globalPermissions), null);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Map<ServerGroup, Rank> getHighestRanks(List<Grant> grants) {
|
||||||
|
Map<ServerGroup, Rank> highestRanks = new HashMap<>();
|
||||||
|
|
||||||
|
for (ServerGroup serverGroup : ServerGroup.findAll()) {
|
||||||
|
highestRanks.put(serverGroup, getHighestRankScoped(serverGroup, grants));
|
||||||
|
}
|
||||||
|
|
||||||
|
return highestRanks;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Rank getHighestRankScoped(ServerGroup serverGroup, Iterable<Grant> grants) {
|
||||||
Rank highest = null;
|
Rank highest = null;
|
||||||
|
|
||||||
for (Grant grant : grants) {
|
for (Grant grant : grants) {
|
||||||
@ -292,187 +434,8 @@ public final class User {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Map<ServerGroup, Rank> getHighestRanks() {
|
public void insert(SingleResultCallback<Void> callback) {
|
||||||
Map<ServerGroup, Rank> highestRanks = new HashMap<>();
|
|
||||||
Rank defaultRank = Rank.findById("default");
|
|
||||||
List<Grant> userGrants = Grant.findByUserSync(this);
|
|
||||||
|
|
||||||
for (ServerGroup serverGroup : ServerGroup.findAll()) {
|
|
||||||
Rank highest = defaultRank;
|
|
||||||
|
|
||||||
for (Grant grant : userGrants) {
|
|
||||||
if (!grant.isActive() || !grant.appliesOn(serverGroup)) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
Rank rank = Rank.findById(grant.getRank());
|
|
||||||
|
|
||||||
if (highest == null || rank.getWeight() > highest.getWeight()) {
|
|
||||||
highest = rank;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
highestRanks.put(serverGroup, highest);
|
|
||||||
}
|
|
||||||
|
|
||||||
return highestRanks;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void getLoginInfo(Server server, String userIp, SingleResultCallback<Map<String, Object>> callback) {
|
|
||||||
Future<Iterable<Punishment>> punishmentsFuture = Future.future();
|
|
||||||
Future<IpIntel> ipIntelFuture = Future.future();
|
|
||||||
Future<Iterable<IpBan>> ipBansFuture = Future.future();
|
|
||||||
Future<Iterable<Grant>> grantsFuture = Future.future();
|
|
||||||
|
|
||||||
Punishment.findByUserAndType(this, ImmutableSet.of(
|
|
||||||
Punishment.PunishmentType.BLACKLIST,
|
|
||||||
Punishment.PunishmentType.BAN,
|
|
||||||
Punishment.PunishmentType.MUTE
|
|
||||||
), (punishments, error) -> {
|
|
||||||
if (error != null) {
|
|
||||||
punishmentsFuture.fail(error);
|
|
||||||
} else {
|
|
||||||
punishmentsFuture.complete(punishments);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
if (userIp != null) {
|
|
||||||
IpIntel.findByIdOrInsert(userIp, (ipIntel, error) -> {
|
|
||||||
if (error != null) {
|
|
||||||
ipIntelFuture.fail(error);
|
|
||||||
} else {
|
|
||||||
ipIntelFuture.complete(ipIntel);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
IpBan.findByIp(userIp, (ipBans, error) -> {
|
|
||||||
if (error != null) {
|
|
||||||
ipBansFuture.fail(error);
|
|
||||||
} else {
|
|
||||||
ipBansFuture.complete(ipBans);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
ipIntelFuture.complete(null);
|
|
||||||
ipBansFuture.complete(ImmutableSet.of());
|
|
||||||
}
|
|
||||||
|
|
||||||
Grant.findByUser(this, (grants, error) -> {
|
|
||||||
if (error != null) {
|
|
||||||
grantsFuture.fail(error);
|
|
||||||
} else {
|
|
||||||
grantsFuture.complete(grants);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CompositeFuture.all(punishmentsFuture, ipIntelFuture, ipBansFuture, grantsFuture).setHandler((result) -> {
|
|
||||||
if (result.succeeded()) {
|
|
||||||
Iterable<Punishment> punishments = result.result().result(0);
|
|
||||||
IpIntel ipIntel = result.result().result(1);
|
|
||||||
Iterable<IpBan> ipBans = result.result().result(2);
|
|
||||||
Iterable<Grant> grants = result.result().result(3);
|
|
||||||
|
|
||||||
callback.onResult(createLoginInfo(server, ipIntel, punishments, ipBans, grants), null);
|
|
||||||
} else {
|
|
||||||
callback.onResult(null, result.cause());
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// This is only used to help batch requests to mongo
|
|
||||||
public Map<String, Object> createLoginInfo(Server server, IpIntel ipIntel, Iterable<Punishment> punishments, Iterable<IpBan> ipBans, Iterable<Grant> grants) {
|
|
||||||
Punishment activeMute = null;
|
|
||||||
Punishment activeBan = null;
|
|
||||||
IpBan activeIpBan = null;
|
|
||||||
|
|
||||||
for (Punishment punishment : punishments) {
|
|
||||||
if (!punishment.isActive()) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (punishment.getType() == Punishment.PunishmentType.MUTE) {
|
|
||||||
activeMute = punishment;
|
|
||||||
} else if (punishment.getType() == Punishment.PunishmentType.BAN || punishment.getType() == Punishment.PunishmentType.BLACKLIST) {
|
|
||||||
activeBan = punishment;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (IpBan ipBan : ipBans) {
|
|
||||||
if (ipBan.isActive()) {
|
|
||||||
activeIpBan = ipBan;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
Rank highestRank = getHighestRankScoped(ServerGroup.findById(server.getServerGroup()), grants);
|
|
||||||
Map<String, Object> access = ImmutableMap.of(
|
|
||||||
"allowed", true,
|
|
||||||
"message", ""
|
|
||||||
);
|
|
||||||
|
|
||||||
if (activeBan != null) {
|
|
||||||
access = ImmutableMap.of(
|
|
||||||
"allowed", false,
|
|
||||||
"message", activeBan.getAccessDenialReason(),
|
|
||||||
"activeBanId", activeBan.getId()
|
|
||||||
);
|
|
||||||
} else if (activeIpBan != null) {
|
|
||||||
// TODO: ASYNC
|
|
||||||
BlockingCallback<String> callback = new BlockingCallback<>();
|
|
||||||
activeIpBan.getAccessDenialReason(callback);
|
|
||||||
String reason = callback.get();
|
|
||||||
|
|
||||||
access = ImmutableMap.of(
|
|
||||||
"allowed", false,
|
|
||||||
"message", reason,
|
|
||||||
"activeIpBanId", activeIpBan.getId()
|
|
||||||
);
|
|
||||||
} else if (ipIntel != null) {
|
|
||||||
MaxMindResult maxMindResult = ipIntel.getResult();
|
|
||||||
MaxMindUserType userType = maxMindResult.getTraits().getUserType();
|
|
||||||
Map<String, Object> proposedAccess = null;
|
|
||||||
|
|
||||||
if (!userType.isAllowed()) {
|
|
||||||
proposedAccess = ImmutableMap.of(
|
|
||||||
"allowed", false,
|
|
||||||
"message", "You cannot join MineHQ from a VPN.",
|
|
||||||
"userType", userType.name()
|
|
||||||
);
|
|
||||||
} else if (ImmutableList.of().contains(maxMindResult.getTraits().getAsn())) {
|
|
||||||
// TODO: BANNED ASNS
|
|
||||||
}
|
|
||||||
|
|
||||||
// We do this to avoid making an expensive .hasPermissionAnywhere call unless we need to.
|
|
||||||
// TODO: THIS IS BLOCKING :(
|
|
||||||
if (proposedAccess != null && !hasPermissionAnywhere(Permissions.BYPASS_VPN_CHECK)) {
|
|
||||||
access = proposedAccess;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Generics are weird, yes we have to do this.
|
|
||||||
ImmutableMap.Builder<String, Object> result = ImmutableMap.<String, Object>builder()
|
|
||||||
.put("user", this)
|
|
||||||
.put("access", access)
|
|
||||||
.put("rank", highestRank.getId())
|
|
||||||
.put("totpSetup", getTotpSecret() != null);
|
|
||||||
|
|
||||||
if (activeMute != null) {
|
|
||||||
result.put("mute", activeMute);
|
|
||||||
}
|
|
||||||
|
|
||||||
return result.build();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void insert() {
|
|
||||||
BlockingCallback<Void> callback = new BlockingCallback<>();
|
|
||||||
usersCollection.insertOne(this, callback);
|
usersCollection.insertOne(this, callback);
|
||||||
callback.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public void save() {
|
|
||||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
|
||||||
save(callback);
|
|
||||||
callback.get();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void save(SingleResultCallback<UpdateResult> callback) {
|
public void save(SingleResultCallback<UpdateResult> callback) {
|
||||||
|
@ -13,13 +13,14 @@ import net.frozenorb.apiv3.util.IpUtils;
|
|||||||
public final class POSTAuditLog implements Handler<RoutingContext> {
|
public final class POSTAuditLog implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User.findById(ctx.request().getParam("id"), (user, error) -> {
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
|
|
||||||
|
User.findById(requestBody.getString("user"), (user, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
ErrorUtils.respondInternalError(ctx, error);
|
ErrorUtils.respondInternalError(ctx, error);
|
||||||
} else if (user == null) {
|
} else if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("user"));
|
||||||
} else {
|
} else {
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
|
||||||
String userIp = requestBody.getString("userIp");
|
String userIp = requestBody.getString("userIp");
|
||||||
|
|
||||||
if (!IpUtils.isValidIp(userIp)) {
|
if (!IpUtils.isValidIp(userIp)) {
|
||||||
|
@ -9,7 +9,7 @@ import net.frozenorb.apiv3.util.ErrorUtils;
|
|||||||
public final class GETEmailTokensOwner implements Handler<RoutingContext> {
|
public final class GETEmailTokensOwner implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User.findByEmailTokenSync(ctx.request().getParam("id"), (user, error) -> {
|
User.findByEmailToken(ctx.request().getParam("id"), (user, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
ErrorUtils.respondInternalError(ctx, error);
|
ErrorUtils.respondInternalError(ctx, error);
|
||||||
} else {
|
} else {
|
||||||
|
@ -1,11 +1,13 @@
|
|||||||
package net.frozenorb.apiv3.route.emailToken;
|
package net.frozenorb.apiv3.route.emailToken;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
@ -13,7 +15,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public final class POSTEmailTokensConfirm implements Handler<RoutingContext> {
|
public final class POSTEmailTokensConfirm implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByEmailTokenSync(ctx.request().getParam("emailToken"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findByEmailToken(ctx.request().getParam("emailToken"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "Email token", ctx.request().getParam("emailToken"));
|
ErrorUtils.respondNotFound(ctx, "Email token", ctx.request().getParam("emailToken"));
|
||||||
@ -42,7 +46,9 @@ public final class POSTEmailTokensConfirm implements Handler<RoutingContext> {
|
|||||||
|
|
||||||
user.completeRegistration(user.getPendingEmail());
|
user.completeRegistration(user.getPendingEmail());
|
||||||
user.setPassword(password);
|
user.setPassword(password);
|
||||||
user.save();
|
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||||
|
user.save(callback);
|
||||||
|
callback.get();
|
||||||
|
|
||||||
APIv3.respondJson(ctx, ImmutableMap.of(
|
APIv3.respondJson(ctx, ImmutableMap.of(
|
||||||
"success", true
|
"success", true
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.frozenorb.apiv3.route.grants;
|
package net.frozenorb.apiv3.route.grants;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
@ -16,7 +17,9 @@ import net.frozenorb.apiv3.util.ErrorUtils;
|
|||||||
public final class DELETEGrantsId implements Handler<RoutingContext> {
|
public final class DELETEGrantsId implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
Grant grant = Grant.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<Grant> grantCallback = new BlockingCallback<>();
|
||||||
|
Grant.findById(ctx.request().getParam("id"), grantCallback);
|
||||||
|
Grant grant = grantCallback.get();
|
||||||
|
|
||||||
if (grant == null) {
|
if (grant == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "Grant", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "Grant", ctx.request().getParam("id"));
|
||||||
@ -27,7 +30,9 @@ public final class DELETEGrantsId implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
User removedBy = User.findByIdSync(requestBody.getString("removedBy"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("removedBy"), userCallback);
|
||||||
|
User removedBy = userCallback.get();
|
||||||
|
|
||||||
if (removedBy == null) {
|
if (removedBy == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
||||||
@ -41,7 +46,9 @@ public final class DELETEGrantsId implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
grant.delete(removedBy, reason);
|
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||||
|
grant.delete(removedBy, reason, callback);
|
||||||
|
callback.get();
|
||||||
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
||||||
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of(), blockingCallback);
|
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of(), blockingCallback);
|
||||||
blockingCallback.get();
|
blockingCallback.get();
|
||||||
|
@ -8,6 +8,7 @@ import net.frozenorb.apiv3.model.Grant;
|
|||||||
import net.frozenorb.apiv3.model.Rank;
|
import net.frozenorb.apiv3.model.Rank;
|
||||||
import net.frozenorb.apiv3.model.ServerGroup;
|
import net.frozenorb.apiv3.model.ServerGroup;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
@ -19,7 +20,9 @@ public final class POSTGrants implements Handler<RoutingContext> {
|
|||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
User target = User.findByIdSync(requestBody.getString("user"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("user"), userCallback);
|
||||||
|
User target = userCallback.get();
|
||||||
|
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("user"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("user"));
|
||||||
@ -68,10 +71,14 @@ public final class POSTGrants implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We purposely don't do a null check, grants don't have to have a source.
|
// We purposely don't do a null check, grants don't have to have a source.
|
||||||
User addedBy = User.findByIdSync(requestBody.getString("addedBy"));
|
BlockingCallback<User> addedByCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("addedBt"), addedByCallback);
|
||||||
|
User addedBy = addedByCallback.get();
|
||||||
|
|
||||||
Grant grant = new Grant(target, reason, scopes, rank, expiresAt, addedBy);
|
Grant grant = new Grant(target, reason, scopes, rank, expiresAt, addedBy);
|
||||||
grant.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
grant.insert(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, grant);
|
APIv3.respondJson(ctx, grant);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.frozenorb.apiv3.route.ipBans;
|
package net.frozenorb.apiv3.route.ipBans;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
@ -16,7 +17,9 @@ import net.frozenorb.apiv3.util.ErrorUtils;
|
|||||||
public final class DELETEIpBan implements Handler<RoutingContext> {
|
public final class DELETEIpBan implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
IpBan ipBan = IpBan.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<IpBan> ipBanCallback = new BlockingCallback<>();
|
||||||
|
IpBan.findById(ctx.request().getParam("id"), ipBanCallback);
|
||||||
|
IpBan ipBan = ipBanCallback.get();
|
||||||
|
|
||||||
if (ipBan == null) {
|
if (ipBan == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "IpBan", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "IpBan", ctx.request().getParam("id"));
|
||||||
@ -27,7 +30,9 @@ public final class DELETEIpBan implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
User removedBy = User.findByIdSync(requestBody.getString("removedBy"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("removedBy"), userCallback);
|
||||||
|
User removedBy = userCallback.get();
|
||||||
|
|
||||||
if (removedBy == null) {
|
if (removedBy == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
||||||
@ -41,7 +46,9 @@ public final class DELETEIpBan implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ipBan.delete(removedBy, reason);
|
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||||
|
ipBan.delete(removedBy, reason, callback);
|
||||||
|
callback.get();
|
||||||
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
||||||
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback);
|
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback);
|
||||||
blockingCallback.get();
|
blockingCallback.get();
|
||||||
|
@ -6,6 +6,7 @@ import io.vertx.ext.web.RoutingContext;
|
|||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.IpBan;
|
import net.frozenorb.apiv3.model.IpBan;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
import net.frozenorb.apiv3.util.IpUtils;
|
import net.frozenorb.apiv3.util.IpUtils;
|
||||||
|
|
||||||
@ -41,10 +42,14 @@ public final class POSTIpBans implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We purposely don't do a null check, ip bans don't have to have a source.
|
// We purposely don't do a null check, ip bans don't have to have a source.
|
||||||
User addedBy = User.findByIdSync(requestBody.getString("addedBy"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("addedBy"), userCallback);
|
||||||
|
User addedBy = userCallback.get();
|
||||||
|
|
||||||
IpBan ipBan = new IpBan(userIp, reason, expiresAt, addedBy, ctx.get("actor"));
|
IpBan ipBan = new IpBan(userIp, reason, expiresAt, addedBy, ctx.get("actor"));
|
||||||
ipBan.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
ipBan.insert(callback);
|
||||||
|
callback.get();
|
||||||
|
|
||||||
APIv3.respondJson(ctx, ipBan);
|
APIv3.respondJson(ctx, ipBan);
|
||||||
}
|
}
|
||||||
|
@ -1,22 +1,28 @@
|
|||||||
package net.frozenorb.apiv3.route.notificationTemplates;
|
package net.frozenorb.apiv3.route.notificationTemplates;
|
||||||
|
|
||||||
|
import com.mongodb.client.result.DeleteResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.NotificationTemplate;
|
import net.frozenorb.apiv3.model.NotificationTemplate;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
public final class DELETENotificationTemplatesId implements Handler<RoutingContext> {
|
public final class DELETENotificationTemplatesId implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
NotificationTemplate notificationTemplate = NotificationTemplate.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<NotificationTemplate> notificationTemplateCallback = new BlockingCallback<>();
|
||||||
|
NotificationTemplate.findById(ctx.request().getParam("id"), notificationTemplateCallback);
|
||||||
|
NotificationTemplate notificationTemplate = notificationTemplateCallback.get();
|
||||||
|
|
||||||
if (notificationTemplate == null) {
|
if (notificationTemplate == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "Notification template", ctx.request().getParam("id"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
notificationTemplate.delete();
|
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
||||||
|
notificationTemplate.delete(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, notificationTemplate);
|
APIv3.respondJson(ctx, notificationTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import io.vertx.core.json.JsonObject;
|
|||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.NotificationTemplate;
|
import net.frozenorb.apiv3.model.NotificationTemplate;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
|
|
||||||
public final class POSTNotificationTemplates implements Handler<RoutingContext> {
|
public final class POSTNotificationTemplates implements Handler<RoutingContext> {
|
||||||
|
|
||||||
@ -15,7 +16,9 @@ public final class POSTNotificationTemplates implements Handler<RoutingContext>
|
|||||||
String body = requestBody.getString("body");
|
String body = requestBody.getString("body");
|
||||||
|
|
||||||
NotificationTemplate notificationTemplate = new NotificationTemplate(id, subject, body);
|
NotificationTemplate notificationTemplate = new NotificationTemplate(id, subject, body);
|
||||||
notificationTemplate.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
notificationTemplate.insert(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, notificationTemplate);
|
APIv3.respondJson(ctx, notificationTemplate);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package net.frozenorb.apiv3.route.punishments;
|
package net.frozenorb.apiv3.route.punishments;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
@ -16,7 +17,9 @@ import net.frozenorb.apiv3.util.ErrorUtils;
|
|||||||
public final class DELETEPunishments implements Handler<RoutingContext> {
|
public final class DELETEPunishments implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
Punishment punishment = Punishment.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<Punishment> punishmentCallback = new BlockingCallback<>();
|
||||||
|
Punishment.findById(ctx.request().getParam("id"), punishmentCallback);
|
||||||
|
Punishment punishment = punishmentCallback.get();
|
||||||
|
|
||||||
if (punishment == null) {
|
if (punishment == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "Punishment", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "Punishment", ctx.request().getParam("id"));
|
||||||
@ -27,7 +30,9 @@ public final class DELETEPunishments implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
User removedBy = User.findByIdSync(requestBody.getString("removedBy"));
|
BlockingCallback<User> removedByCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("removedBy"), removedByCallback);
|
||||||
|
User removedBy = removedByCallback.get();
|
||||||
|
|
||||||
if (removedBy == null) {
|
if (removedBy == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
||||||
@ -41,7 +46,9 @@ public final class DELETEPunishments implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
punishment.delete(removedBy, reason);
|
BlockingCallback<UpdateResult> removeCallback = new BlockingCallback<>();
|
||||||
|
punishment.delete(removedBy, reason, removeCallback);
|
||||||
|
removeCallback.get();
|
||||||
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
||||||
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback);
|
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback);
|
||||||
blockingCallback.get();
|
blockingCallback.get();
|
||||||
|
@ -2,6 +2,7 @@ package net.frozenorb.apiv3.route.punishments;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
import com.google.common.collect.ImmutableSet;
|
import com.google.common.collect.ImmutableSet;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
@ -14,10 +15,14 @@ import net.frozenorb.apiv3.model.User;
|
|||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
public final class DELETEUserActivePunishment implements Handler<RoutingContext> {
|
public final class DELETEUserActivePunishment implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User target = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User target = userCallback.get();
|
||||||
|
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
@ -26,7 +31,10 @@ public final class DELETEUserActivePunishment implements Handler<RoutingContext>
|
|||||||
|
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(requestBody.getString("type").toUpperCase());
|
Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(requestBody.getString("type").toUpperCase());
|
||||||
User removedBy = User.findByIdSync(requestBody.getString("removedBy"));
|
|
||||||
|
BlockingCallback<User> removedByCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("removedBy"), removedByCallback);
|
||||||
|
User removedBy = removedByCallback.get();
|
||||||
|
|
||||||
if (removedBy == null) {
|
if (removedBy == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("removedBy"));
|
||||||
@ -40,9 +48,14 @@ public final class DELETEUserActivePunishment implements Handler<RoutingContext>
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (Punishment punishment : Punishment.findByUserAndTypeSync(target, ImmutableSet.of(type))) {
|
BlockingCallback<List<Punishment>> callback = new BlockingCallback<>();
|
||||||
|
Punishment.findByUserAndType(target, ImmutableSet.of(type), callback);
|
||||||
|
|
||||||
|
for (Punishment punishment : callback.get()) {
|
||||||
if (punishment.isActive()) {
|
if (punishment.isActive()) {
|
||||||
punishment.delete(removedBy, reason);
|
BlockingCallback<UpdateResult> punishmentCallback = new BlockingCallback<>();
|
||||||
|
punishment.delete(removedBy, reason, punishmentCallback);
|
||||||
|
punishmentCallback.get();
|
||||||
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
BlockingCallback<AuditLogEntry> blockingCallback = new BlockingCallback<>();
|
||||||
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback);
|
AuditLog.log(removedBy, "", ctx.get("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of(), blockingCallback);
|
||||||
blockingCallback.get();
|
blockingCallback.get();
|
||||||
|
@ -9,17 +9,21 @@ import net.frozenorb.apiv3.APIv3;
|
|||||||
import net.frozenorb.apiv3.model.IpBan;
|
import net.frozenorb.apiv3.model.IpBan;
|
||||||
import net.frozenorb.apiv3.model.Punishment;
|
import net.frozenorb.apiv3.model.Punishment;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.unsorted.Permissions;
|
import net.frozenorb.apiv3.unsorted.Permissions;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
public final class POSTPunishments implements Handler<RoutingContext> {
|
public final class POSTPunishments implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
User target = User.findByIdSync(requestBody.getString("user"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("user"), userCallback);
|
||||||
|
User target = userCallback.get();
|
||||||
|
|
||||||
if (target == null) {
|
if (target == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("user"));
|
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("user"));
|
||||||
@ -36,9 +40,14 @@ public final class POSTPunishments implements Handler<RoutingContext> {
|
|||||||
Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(requestBody.getString("type"));
|
Punishment.PunishmentType type = Punishment.PunishmentType.valueOf(requestBody.getString("type"));
|
||||||
|
|
||||||
if (type != Punishment.PunishmentType.WARN) {
|
if (type != Punishment.PunishmentType.WARN) {
|
||||||
for (Punishment punishment : Punishment.findByUserAndTypeSync(target, ImmutableSet.of(type))) {
|
BlockingCallback<List<Punishment>> punishmentsCallback = new BlockingCallback<>();
|
||||||
|
Punishment.findByUserAndType(target, ImmutableSet.of(type), punishmentsCallback);
|
||||||
|
|
||||||
|
for (Punishment punishment : punishmentsCallback.get()) {
|
||||||
if (punishment.isActive()) {
|
if (punishment.isActive()) {
|
||||||
ErrorUtils.respondGeneric(ctx, 200, "A punishment by " + User.findByIdSync(punishment.getAddedBy()).getLastUsername() + " already covers this user.");
|
BlockingCallback<User> addedByCallback = new BlockingCallback<>();
|
||||||
|
User.findById(punishment.getAddedBy(), addedByCallback);
|
||||||
|
ErrorUtils.respondGeneric(ctx, 200, "A punishment by " + addedByCallback.get().getLastUsername() + " already covers this user.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,9 +72,14 @@ public final class POSTPunishments implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// We purposely don't do a null check, punishments don't have to have a source.
|
// We purposely don't do a null check, punishments don't have to have a source.
|
||||||
User addedBy = User.findByIdSync(requestBody.getString("addedBy"));
|
BlockingCallback<User> addedByCallback = new BlockingCallback<>();
|
||||||
|
User.findById(requestBody.getString("addedBy"), addedByCallback);
|
||||||
|
User addedBy = addedByCallback.get();
|
||||||
|
|
||||||
if (target.hasPermissionAnywhere(Permissions.PROTECTED_PUNISHMENT)) {
|
BlockingCallback<Boolean> permissionsCallback = new BlockingCallback<>();
|
||||||
|
target.hasPermissionAnywhere(Permissions.PROTECTED_PUNISHMENT, permissionsCallback);
|
||||||
|
|
||||||
|
if (permissionsCallback.get()) {
|
||||||
ErrorUtils.respondGeneric(ctx, 200, target.getLastSeenOn() + " is protected from punishments.");
|
ErrorUtils.respondGeneric(ctx, 200, target.getLastSeenOn() + " is protected from punishments.");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -76,12 +90,16 @@ public final class POSTPunishments implements Handler<RoutingContext> {
|
|||||||
|
|
||||||
if ((type == Punishment.PunishmentType.BAN || type == Punishment.PunishmentType.BLACKLIST) && userIp != null) {
|
if ((type == Punishment.PunishmentType.BAN || type == Punishment.PunishmentType.BLACKLIST) && userIp != null) {
|
||||||
IpBan ipBan = new IpBan(userIp, punishment);
|
IpBan ipBan = new IpBan(userIp, punishment);
|
||||||
ipBan.insert();
|
BlockingCallback<Void> ipBanCallback = new BlockingCallback<>();
|
||||||
|
ipBan.insert(ipBanCallback);
|
||||||
|
ipBanCallback.get();
|
||||||
|
|
||||||
punishment.linkIpBan(ipBan);
|
punishment.linkIpBan(ipBan);
|
||||||
}
|
}
|
||||||
|
|
||||||
punishment.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
punishment.insert(callback);
|
||||||
|
callback.get();
|
||||||
|
|
||||||
APIv3.respondJson(ctx, ImmutableMap.of(
|
APIv3.respondJson(ctx, ImmutableMap.of(
|
||||||
"punishment", punishment,
|
"punishment", punishment,
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package net.frozenorb.apiv3.route.ranks;
|
package net.frozenorb.apiv3.route.ranks;
|
||||||
|
|
||||||
|
import com.mongodb.client.result.DeleteResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.Rank;
|
import net.frozenorb.apiv3.model.Rank;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
public final class DELETERanksId implements Handler<RoutingContext> {
|
public final class DELETERanksId implements Handler<RoutingContext> {
|
||||||
@ -16,7 +18,9 @@ public final class DELETERanksId implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
rank.delete();
|
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
||||||
|
rank.delete(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, rank);
|
APIv3.respondJson(ctx, rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import io.vertx.core.json.JsonObject;
|
|||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.Rank;
|
import net.frozenorb.apiv3.model.Rank;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
|
|
||||||
public final class POSTRanks implements Handler<RoutingContext> {
|
public final class POSTRanks implements Handler<RoutingContext> {
|
||||||
|
|
||||||
@ -18,7 +19,9 @@ public final class POSTRanks implements Handler<RoutingContext> {
|
|||||||
boolean staffRank = requestBody.getBoolean("staffRank");
|
boolean staffRank = requestBody.getBoolean("staffRank");
|
||||||
|
|
||||||
Rank rank = new Rank(id, weight, displayName, gameColor, websiteColor, staffRank);
|
Rank rank = new Rank(id, weight, displayName, gameColor, websiteColor, staffRank);
|
||||||
rank.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
rank.insert(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, rank);
|
APIv3.respondJson(ctx, rank);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package net.frozenorb.apiv3.route.serverGroups;
|
package net.frozenorb.apiv3.route.serverGroups;
|
||||||
|
|
||||||
|
import com.mongodb.client.result.DeleteResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.ServerGroup;
|
import net.frozenorb.apiv3.model.ServerGroup;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
public final class DELETEServerGroupsId implements Handler<RoutingContext> {
|
public final class DELETEServerGroupsId implements Handler<RoutingContext> {
|
||||||
@ -16,7 +18,9 @@ public final class DELETEServerGroupsId implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
serverGroup.delete();
|
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
||||||
|
serverGroup.delete(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, serverGroup);
|
APIv3.respondJson(ctx, serverGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import io.vertx.core.json.JsonObject;
|
|||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.ServerGroup;
|
import net.frozenorb.apiv3.model.ServerGroup;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
|
|
||||||
public final class POSTServerGroups implements Handler<RoutingContext> {
|
public final class POSTServerGroups implements Handler<RoutingContext> {
|
||||||
|
|
||||||
@ -14,7 +15,9 @@ public final class POSTServerGroups implements Handler<RoutingContext> {
|
|||||||
String image = requestBody.getString("image");
|
String image = requestBody.getString("image");
|
||||||
|
|
||||||
ServerGroup serverGroup = new ServerGroup(id, image);
|
ServerGroup serverGroup = new ServerGroup(id, image);
|
||||||
serverGroup.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
serverGroup.insert(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, serverGroup);
|
APIv3.respondJson(ctx, serverGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
package net.frozenorb.apiv3.route.servers;
|
package net.frozenorb.apiv3.route.servers;
|
||||||
|
|
||||||
|
import com.mongodb.client.result.DeleteResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.Server;
|
import net.frozenorb.apiv3.model.Server;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
public final class DELETEServersId implements Handler<RoutingContext> {
|
public final class DELETEServersId implements Handler<RoutingContext> {
|
||||||
@ -16,7 +18,9 @@ public final class DELETEServersId implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
server.delete();
|
BlockingCallback<DeleteResult> callback = new BlockingCallback<>();
|
||||||
|
server.delete(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, server);
|
APIv3.respondJson(ctx, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ import io.vertx.ext.web.RoutingContext;
|
|||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.Server;
|
import net.frozenorb.apiv3.model.Server;
|
||||||
import net.frozenorb.apiv3.model.ServerGroup;
|
import net.frozenorb.apiv3.model.ServerGroup;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
import net.frozenorb.apiv3.util.IpUtils;
|
import net.frozenorb.apiv3.util.IpUtils;
|
||||||
|
|
||||||
@ -32,7 +33,9 @@ public final class POSTServers implements Handler<RoutingContext> {
|
|||||||
|
|
||||||
String generatedApiKey = UUID.randomUUID().toString();
|
String generatedApiKey = UUID.randomUUID().toString();
|
||||||
Server server = new Server(id, displayName, generatedApiKey, group, ip);
|
Server server = new Server(id, displayName, generatedApiKey, group, ip);
|
||||||
server.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
server.insert(callback);
|
||||||
|
callback.get();
|
||||||
APIv3.respondJson(ctx, server);
|
APIv3.respondJson(ctx, server);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,6 +2,7 @@ package net.frozenorb.apiv3.route.servers;
|
|||||||
|
|
||||||
import com.google.common.collect.ImmutableList;
|
import com.google.common.collect.ImmutableList;
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.CompositeFuture;
|
import io.vertx.core.CompositeFuture;
|
||||||
import io.vertx.core.Future;
|
import io.vertx.core.Future;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
@ -13,14 +14,13 @@ import net.frozenorb.apiv3.APIv3;
|
|||||||
import net.frozenorb.apiv3.actor.Actor;
|
import net.frozenorb.apiv3.actor.Actor;
|
||||||
import net.frozenorb.apiv3.actor.ActorType;
|
import net.frozenorb.apiv3.actor.ActorType;
|
||||||
import net.frozenorb.apiv3.model.*;
|
import net.frozenorb.apiv3.model.*;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
|
import net.frozenorb.apiv3.unsorted.FutureCompatibilityCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
import net.frozenorb.apiv3.util.PermissionUtils;
|
import net.frozenorb.apiv3.util.PermissionUtils;
|
||||||
import net.frozenorb.apiv3.util.UuidUtils;
|
import net.frozenorb.apiv3.util.UuidUtils;
|
||||||
|
|
||||||
import java.util.HashMap;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.Map;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Slf4j
|
@Slf4j
|
||||||
public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
||||||
@ -58,14 +58,18 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: ASYNC (MAKE ALL SAVES/INSERTS/ETC USED HERE ASYNC
|
|
||||||
private Future<Void> createInfoResponse(Server server, double tps, Map<UUID, String> playerNames) {
|
private Future<Void> createInfoResponse(Server server, double tps, Map<UUID, String> playerNames) {
|
||||||
Future<Void> callback = Future.future();
|
Future<Void> callback = Future.future();
|
||||||
|
|
||||||
server.receivedHeartbeat(tps, playerNames.keySet());
|
server.receivedHeartbeat(tps, playerNames.keySet());
|
||||||
server.save();
|
server.save((ignored, error) -> {
|
||||||
|
if (error != null) {
|
||||||
|
callback.fail(error);
|
||||||
|
} else {
|
||||||
|
callback.complete();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
callback.complete();
|
|
||||||
return callback;
|
return callback;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -76,29 +80,9 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
Future<Map<UUID, List<Grant>>> grantLookupCallback = Future.future();
|
Future<Map<UUID, List<Grant>>> grantLookupCallback = Future.future();
|
||||||
Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future();
|
Future<Map<UUID, List<Punishment>>> punishmentLookupCallback = Future.future();
|
||||||
|
|
||||||
User.findByIdGrouped(playerNames.keySet(), (users, error) -> {
|
User.findByIdGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(userLookupCallback));
|
||||||
if (error != null) {
|
Grant.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(grantLookupCallback));
|
||||||
userLookupCallback.fail(error);
|
Punishment.findByUserGrouped(playerNames.keySet(), new FutureCompatibilityCallback<>(punishmentLookupCallback));
|
||||||
} else {
|
|
||||||
userLookupCallback.complete(users);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Grant.findByUserGrouped(playerNames.keySet(), (grants, error) -> {
|
|
||||||
if (error != null) {
|
|
||||||
grantLookupCallback.fail(error);
|
|
||||||
} else {
|
|
||||||
grantLookupCallback.complete(grants);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
Punishment.findByUserGrouped(playerNames.keySet(), (punishments, error) -> {
|
|
||||||
if (error != null) {
|
|
||||||
punishmentLookupCallback.fail(error);
|
|
||||||
} else {
|
|
||||||
punishmentLookupCallback.complete(punishments);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
CompositeFuture.all(
|
CompositeFuture.all(
|
||||||
userLookupCallback,
|
userLookupCallback,
|
||||||
@ -107,38 +91,58 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
|||||||
).setHandler((result) -> {
|
).setHandler((result) -> {
|
||||||
if (result.failed()) {
|
if (result.failed()) {
|
||||||
callback.fail(result.cause());
|
callback.fail(result.cause());
|
||||||
} else {
|
return;
|
||||||
try {
|
|
||||||
Map<UUID, User> users = result.result().result(0);
|
|
||||||
Map<UUID, List<Grant>> grants = result.result().result(1);
|
|
||||||
Map<UUID, List<Punishment>> punishments = result.result().result(2);
|
|
||||||
Map<String, Object> response = new HashMap<>();
|
|
||||||
|
|
||||||
for (Map.Entry<UUID, User> userEntry : users.entrySet()) {
|
|
||||||
UUID uuid = userEntry.getKey();
|
|
||||||
User user = userEntry.getValue();
|
|
||||||
|
|
||||||
if (user == null) {
|
|
||||||
String username = playerNames.get(uuid);
|
|
||||||
user = new User(uuid, username);
|
|
||||||
user.insert();
|
|
||||||
users.put(uuid, user);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Only save if needed
|
|
||||||
if (user.seenOnServer(server)) {
|
|
||||||
user.save();
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: Provide IPs for ip ban lookup (and ip intel)
|
|
||||||
response.put(uuid.toString(), user.createLoginInfo(server,null, punishments.get(uuid), ImmutableList.of(), grants.get(uuid)));
|
|
||||||
}
|
|
||||||
|
|
||||||
callback.complete(response);
|
|
||||||
} catch (Exception ex) {
|
|
||||||
callback.fail(ex);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Map<UUID, User> users = result.result().result(0);
|
||||||
|
Map<UUID, List<Grant>> grants = result.result().result(1);
|
||||||
|
Map<UUID, List<Punishment>> punishments = result.result().result(2);
|
||||||
|
Map<String, Object> response = new HashMap<>();
|
||||||
|
|
||||||
|
List<Future> loginInfoFutures = new LinkedList<>();
|
||||||
|
|
||||||
|
for (Map.Entry<UUID, User> userEntry : users.entrySet()) {
|
||||||
|
Future<Map<String, Object>> loginInfoFuture = Future.future();
|
||||||
|
|
||||||
|
Map<String, Object> res2 = new HashMap<>();
|
||||||
|
UUID uuid = userEntry.getKey();
|
||||||
|
User user = userEntry.getValue();
|
||||||
|
|
||||||
|
if (user == null) {
|
||||||
|
String username = playerNames.get(uuid);
|
||||||
|
user = new User(uuid, username);
|
||||||
|
BlockingCallback<Void> nameCollisionCallback = new BlockingCallback<>();
|
||||||
|
user.checkNameCollisions(nameCollisionCallback);
|
||||||
|
nameCollisionCallback.get();
|
||||||
|
BlockingCallback<Void> insertCallback = new BlockingCallback<>();
|
||||||
|
user.insert(insertCallback);
|
||||||
|
insertCallback.get();
|
||||||
|
users.put(uuid, user);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only save if needed
|
||||||
|
if (user.seenOnServer(server)) {
|
||||||
|
BlockingCallback<UpdateResult> saveCallback = new BlockingCallback<>();
|
||||||
|
user.save(saveCallback);
|
||||||
|
saveCallback.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: Provide IPs for ip ban lookup (and ip intel)
|
||||||
|
BlockingCallback<Map<String, Object>> loginInfo = new BlockingCallback<>();
|
||||||
|
user.getLoginInfo(server, null, punishments.get(uuid), ImmutableList.of(), grants.get(uuid), loginInfo);
|
||||||
|
res2.put(uuid.toString(), loginInfo.get());
|
||||||
|
|
||||||
|
loginInfoFuture.complete(res2);
|
||||||
|
loginInfoFutures.add(loginInfoFuture);
|
||||||
|
}
|
||||||
|
|
||||||
|
CompositeFuture.all(loginInfoFutures).setHandler((allLoginInfo) -> {
|
||||||
|
for (int i = 0; i < allLoginInfo.result().size(); i++) {
|
||||||
|
response.putAll(allLoginInfo.result().result(i));
|
||||||
|
}
|
||||||
|
|
||||||
|
callback.complete(response);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
return callback;
|
return callback;
|
||||||
|
@ -6,6 +6,7 @@ import net.frozenorb.apiv3.APIv3;
|
|||||||
import net.frozenorb.apiv3.model.Grant;
|
import net.frozenorb.apiv3.model.Grant;
|
||||||
import net.frozenorb.apiv3.model.Rank;
|
import net.frozenorb.apiv3.model.Rank;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
@ -27,9 +28,14 @@ public final class GETStaff implements Handler<RoutingContext> {
|
|||||||
return Integer.compare(firstRank.getWeight(), secondRank.getWeight());
|
return Integer.compare(firstRank.getWeight(), secondRank.getWeight());
|
||||||
});
|
});
|
||||||
|
|
||||||
Grant.findByRankSync(staffRanks.values()).forEach(grant -> {
|
BlockingCallback<List<Grant>> grantsCallback = new BlockingCallback<>();
|
||||||
|
Grant.findByRank(staffRanks.values(), grantsCallback);
|
||||||
|
|
||||||
|
grantsCallback.get().forEach(grant -> {
|
||||||
if (grant.isActive()) {
|
if (grant.isActive()) {
|
||||||
User user = User.findByIdSync(grant.getUser());
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(grant.getUser(), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
Rank rank = staffRanks.get(grant.getRank());
|
Rank rank = staffRanks.get(grant.getRank());
|
||||||
|
|
||||||
if (!result.containsKey(rank.getId())) {
|
if (!result.containsKey(rank.getId())) {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package net.frozenorb.apiv3.route.users;
|
package net.frozenorb.apiv3.route.users;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
@ -8,28 +7,43 @@ import net.frozenorb.apiv3.model.Grant;
|
|||||||
import net.frozenorb.apiv3.model.IpLogEntry;
|
import net.frozenorb.apiv3.model.IpLogEntry;
|
||||||
import net.frozenorb.apiv3.model.Punishment;
|
import net.frozenorb.apiv3.model.Punishment;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
public final class GETUserDetails implements Handler<RoutingContext> {
|
public final class GETUserDetails implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Too many fields to use .of()
|
BlockingCallback<List<Grant>> grantsCallback = new BlockingCallback<>();
|
||||||
APIv3.respondJson(ctx, ImmutableMap.builder()
|
BlockingCallback<List<IpLogEntry>> ipLogCallback = new BlockingCallback<>();
|
||||||
.put("user", user)
|
BlockingCallback<List<Punishment>> punishmentsCallback = new BlockingCallback<>();
|
||||||
.put("grants", Grant.findByUserSync(user))
|
|
||||||
.put("ipLog", IpLogEntry.findByUserSync(user))
|
Grant.findByUser(user, grantsCallback);
|
||||||
.put("punishments", Punishment.findByUserSync(user))
|
IpLogEntry.findByUser(user, ipLogCallback);
|
||||||
.put("aliases", user.getAliases())
|
Punishment.findByUser(user, punishmentsCallback);
|
||||||
.put("totpSetup", user.getTotpSecret() != null)
|
|
||||||
.build()
|
Map<String, Object> result = new HashMap<>();
|
||||||
);
|
|
||||||
|
result.put("user", user);
|
||||||
|
result.put("grants", grantsCallback.get());
|
||||||
|
result.put("ipLog", ipLogCallback.get());
|
||||||
|
result.put("punishments", punishmentsCallback.get());
|
||||||
|
result.put("aliases", user.getAliases());
|
||||||
|
result.put("totpSetup", user.getTotpSecret() != null);
|
||||||
|
|
||||||
|
APIv3.respondJson(ctx, result);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -9,14 +9,21 @@ import net.frozenorb.apiv3.util.ErrorUtils;
|
|||||||
public final class GETUserPermissions implements Handler<RoutingContext> {
|
public final class GETUserPermissions implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User target = User.findByIdSync(ctx.request().getParam("id"));
|
User.findById(ctx.request().getParam("id"), (user, error) -> {
|
||||||
|
if (error != null) {
|
||||||
if (target == null) {
|
ErrorUtils.respondInternalError(ctx, error);
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
} else if (user == null) {
|
||||||
return;
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
}
|
} else {
|
||||||
|
user.getGlobalPermissions((permissions, error2) -> {
|
||||||
APIv3.respondJson(ctx, target.getGlobalPermissions());
|
if (error2 != null) {
|
||||||
|
ErrorUtils.respondInternalError(ctx, error2);
|
||||||
|
} else {
|
||||||
|
APIv3.respondJson(ctx, permissions);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import io.vertx.core.Handler;
|
|||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.RequiresTotpResult;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
import net.frozenorb.apiv3.util.IpUtils;
|
import net.frozenorb.apiv3.util.IpUtils;
|
||||||
|
|
||||||
@ -29,7 +30,7 @@ public final class GETUserRequiresTotp implements Handler<RoutingContext> {
|
|||||||
ErrorUtils.respondInternalError(ctx, error2);
|
ErrorUtils.respondInternalError(ctx, error2);
|
||||||
} else {
|
} else {
|
||||||
APIv3.respondJson(ctx, ImmutableMap.of(
|
APIv3.respondJson(ctx, ImmutableMap.of(
|
||||||
"required", (requiresTotpResult == User.RequiresTotpResult.REQUIRED_NO_EXEMPTIONS),
|
"required", (requiresTotpResult == RequiresTotpResult.REQUIRED_NO_EXEMPTIONS),
|
||||||
"message", requiresTotpResult.name()
|
"message", requiresTotpResult.name()
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -5,19 +5,26 @@ import io.vertx.core.Handler;
|
|||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
public final class GETUserVerifyPassword implements Handler<RoutingContext> {
|
public final class GETUserVerifyPassword implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> callback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), callback);
|
||||||
|
User user = callback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = User.findByLastUsernameSync(ctx.request().getParam("id"));
|
callback = new BlockingCallback<>();
|
||||||
|
User.findByLastUsername(ctx.request().getParam("id"), callback);
|
||||||
|
user = callback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
user = User.findByEmailSync(ctx.request().getParam("id"));
|
callback = new BlockingCallback<>();
|
||||||
|
User.findByEmail(ctx.request().getParam("id"), callback);
|
||||||
|
user = callback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
package net.frozenorb.apiv3.route.users;
|
package net.frozenorb.apiv3.route.users;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
|
import net.frozenorb.apiv3.unsorted.RequiresTotpResult;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
public final class POSTUserChangePassword implements Handler<RoutingContext> {
|
public final class POSTUserChangePassword implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
@ -33,11 +37,11 @@ public final class POSTUserChangePassword implements Handler<RoutingContext> {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockingCallback<User.RequiresTotpResult> totpRequiredCallback = new BlockingCallback<>();
|
BlockingCallback<RequiresTotpResult> totpRequiredCallback = new BlockingCallback<>();
|
||||||
user.requiresTotpAuthorization(null, totpRequiredCallback);
|
user.requiresTotpAuthorization(null, totpRequiredCallback);
|
||||||
User.RequiresTotpResult requiresTotp = totpRequiredCallback.get();
|
RequiresTotpResult requiresTotp = totpRequiredCallback.get();
|
||||||
|
|
||||||
if (requiresTotp == User.RequiresTotpResult.REQUIRED_NO_EXEMPTIONS) {
|
if (requiresTotp == RequiresTotpResult.REQUIRED_NO_EXEMPTIONS) {
|
||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,7 +53,9 @@ public final class POSTUserChangePassword implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.setPassword(newPassword);
|
user.setPassword(newPassword);
|
||||||
user.save();
|
BlockingCallback<UpdateResult> saveCallback = new BlockingCallback<>();
|
||||||
|
user.save(saveCallback);
|
||||||
|
saveCallback.get();
|
||||||
|
|
||||||
APIv3.respondJson(ctx, ImmutableMap.of(
|
APIv3.respondJson(ctx, ImmutableMap.of(
|
||||||
"success", true
|
"success", true
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package net.frozenorb.apiv3.route.users;
|
package net.frozenorb.apiv3.route.users;
|
||||||
|
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
@ -9,6 +10,7 @@ import net.frozenorb.apiv3.actor.ActorType;
|
|||||||
import net.frozenorb.apiv3.model.IpLogEntry;
|
import net.frozenorb.apiv3.model.IpLogEntry;
|
||||||
import net.frozenorb.apiv3.model.Server;
|
import net.frozenorb.apiv3.model.Server;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
import net.frozenorb.apiv3.util.IpUtils;
|
import net.frozenorb.apiv3.util.IpUtils;
|
||||||
import net.frozenorb.apiv3.util.UuidUtils;
|
import net.frozenorb.apiv3.util.UuidUtils;
|
||||||
@ -26,7 +28,9 @@ public final class POSTUserLogin implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
User user = User.findByIdSync(uuid);
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(uuid, userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
String username = requestBody.getString("username");
|
String username = requestBody.getString("username");
|
||||||
String userIp = requestBody.getString("userIp");
|
String userIp = requestBody.getString("userIp");
|
||||||
Actor actor = ctx.get("actor");
|
Actor actor = ctx.get("actor");
|
||||||
@ -44,24 +48,42 @@ public final class POSTUserLogin implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
// Will be saved in the User constructor
|
|
||||||
user = new User(uuid, username);
|
user = new User(uuid, username);
|
||||||
|
BlockingCallback<Void> nameCollisionCallback = new BlockingCallback<>();
|
||||||
|
user.checkNameCollisions(nameCollisionCallback);
|
||||||
|
nameCollisionCallback.get();
|
||||||
|
BlockingCallback<Void> insertCallback = new BlockingCallback<>();
|
||||||
|
user.checkNameCollisions(insertCallback);
|
||||||
|
insertCallback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
IpLogEntry ipLogEntry = IpLogEntry.findByUserAndIpSync(user, userIp);
|
BlockingCallback<IpLogEntry> ipLogEntryCallback = new BlockingCallback<>();
|
||||||
|
IpLogEntry.findByUserAndIp(user, userIp, ipLogEntryCallback);
|
||||||
|
IpLogEntry ipLogEntry = ipLogEntryCallback.get();
|
||||||
|
|
||||||
// We use a little bit more verbose code here to save on the
|
// We use a little bit more verbose code here to save on the
|
||||||
// overhead of a .insert() immediately followed by a .save()
|
// overhead of a .insert() immediately followed by a .save()
|
||||||
if (ipLogEntry == null) {
|
if (ipLogEntry == null) {
|
||||||
ipLogEntry = new IpLogEntry(user, userIp);
|
ipLogEntry = new IpLogEntry(user, userIp);
|
||||||
ipLogEntry.used();
|
ipLogEntry.used();
|
||||||
ipLogEntry.insert();
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
ipLogEntry.insert(callback);
|
||||||
|
callback.get();
|
||||||
} else {
|
} else {
|
||||||
ipLogEntry.used();
|
ipLogEntry.used();
|
||||||
ipLogEntry.save();
|
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||||
|
ipLogEntry.save(callback);
|
||||||
|
callback.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!username.equals(user.getLastUsername())) {
|
||||||
|
BlockingCallback<Void> callback = new BlockingCallback<>();
|
||||||
|
user.checkNameCollisions(callback);
|
||||||
|
callback.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
user.updateUsername(username);
|
user.updateUsername(username);
|
||||||
|
|
||||||
user.getLoginInfo(server, userIp, (loginInfo, error) -> {
|
user.getLoginInfo(server, userIp, (loginInfo, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
ErrorUtils.respondInternalError(ctx, error);
|
ErrorUtils.respondInternalError(ctx, error);
|
||||||
|
@ -7,6 +7,7 @@ import io.vertx.ext.web.RoutingContext;
|
|||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.NotificationTemplate;
|
import net.frozenorb.apiv3.model.NotificationTemplate;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.unsorted.Notification;
|
import net.frozenorb.apiv3.unsorted.Notification;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
@ -15,7 +16,9 @@ import java.util.Map;
|
|||||||
public final class POSTUserNotify implements Handler<RoutingContext> {
|
public final class POSTUserNotify implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
@ -28,7 +31,9 @@ public final class POSTUserNotify implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
JsonObject requestBody = ctx.getBodyAsJson();
|
JsonObject requestBody = ctx.getBodyAsJson();
|
||||||
NotificationTemplate template = NotificationTemplate.findByIdSync(requestBody.getString("template"));
|
BlockingCallback<NotificationTemplate> notificationTemplateCallback = new BlockingCallback<>();
|
||||||
|
NotificationTemplate.findById(requestBody.getString("template"), notificationTemplateCallback);
|
||||||
|
NotificationTemplate template = notificationTemplateCallback.get();
|
||||||
|
|
||||||
if (template == null) {
|
if (template == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "Notification template", requestBody.getString("template"));
|
ErrorUtils.respondNotFound(ctx, "Notification template", requestBody.getString("template"));
|
||||||
|
@ -1,12 +1,14 @@
|
|||||||
package net.frozenorb.apiv3.route.users;
|
package net.frozenorb.apiv3.route.users;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.core.json.JsonObject;
|
import io.vertx.core.json.JsonObject;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.NotificationTemplate;
|
import net.frozenorb.apiv3.model.NotificationTemplate;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.unsorted.Notification;
|
import net.frozenorb.apiv3.unsorted.Notification;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
|
|
||||||
@ -22,7 +24,9 @@ public final class POSTUserRegister implements Handler<RoutingContext> {
|
|||||||
);
|
);
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
@ -48,15 +52,19 @@ public final class POSTUserRegister implements Handler<RoutingContext> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
user.startRegistration(email);
|
user.startRegistration(email);
|
||||||
user.save();
|
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||||
|
user.save(callback);
|
||||||
|
callback.get();
|
||||||
|
|
||||||
Map<String, Object> replacements = ImmutableMap.of(
|
Map<String, Object> replacements = ImmutableMap.of(
|
||||||
"username", user.getLastUsername(),
|
"username", user.getLastUsername(),
|
||||||
"email", user.getEmail(),
|
"email", user.getPendingEmail(),
|
||||||
"emailToken", user.getPendingEmailToken()
|
"emailToken", user.getPendingEmailToken()
|
||||||
);
|
);
|
||||||
|
|
||||||
Notification notification = new Notification(NotificationTemplate.findByIdSync("email-confirmation"), replacements, replacements);
|
BlockingCallback<NotificationTemplate> notificationTemplateCallback = new BlockingCallback<>();
|
||||||
|
NotificationTemplate.findById("email-confirmation", notificationTemplateCallback);
|
||||||
|
Notification notification = new Notification(notificationTemplateCallback.get(), replacements, replacements);
|
||||||
|
|
||||||
notification.sendAsEmail(user.getEmail(), (ignored, error) -> {
|
notification.sendAsEmail(user.getEmail(), (ignored, error) -> {
|
||||||
if (error != null) {
|
if (error != null) {
|
||||||
|
@ -1,18 +1,22 @@
|
|||||||
package net.frozenorb.apiv3.route.users;
|
package net.frozenorb.apiv3.route.users;
|
||||||
|
|
||||||
import com.google.common.collect.ImmutableMap;
|
import com.google.common.collect.ImmutableMap;
|
||||||
|
import com.mongodb.client.result.UpdateResult;
|
||||||
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
|
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
|
||||||
import io.vertx.core.Handler;
|
import io.vertx.core.Handler;
|
||||||
import io.vertx.ext.web.RoutingContext;
|
import io.vertx.ext.web.RoutingContext;
|
||||||
import net.frozenorb.apiv3.APIv3;
|
import net.frozenorb.apiv3.APIv3;
|
||||||
import net.frozenorb.apiv3.model.User;
|
import net.frozenorb.apiv3.model.User;
|
||||||
|
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||||
import net.frozenorb.apiv3.util.TotpUtils;
|
import net.frozenorb.apiv3.util.TotpUtils;
|
||||||
|
|
||||||
public final class POSTUserSetupTotp implements Handler<RoutingContext> {
|
public final class POSTUserSetupTotp implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
@ -27,7 +31,9 @@ public final class POSTUserSetupTotp implements Handler<RoutingContext> {
|
|||||||
GoogleAuthenticatorKey generated = TotpUtils.generateTotpSecret();
|
GoogleAuthenticatorKey generated = TotpUtils.generateTotpSecret();
|
||||||
|
|
||||||
user.setTotpSecret(generated.getKey());
|
user.setTotpSecret(generated.getKey());
|
||||||
user.save();
|
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||||
|
user.save(callback);
|
||||||
|
callback.get();
|
||||||
|
|
||||||
APIv3.respondJson(ctx, ImmutableMap.of(
|
APIv3.respondJson(ctx, ImmutableMap.of(
|
||||||
"qrCode", TotpUtils.getQrCodeUrl(user, generated)
|
"qrCode", TotpUtils.getQrCodeUrl(user, generated)
|
||||||
|
@ -16,7 +16,9 @@ import java.util.concurrent.TimeUnit;
|
|||||||
public final class POSTUserVerifyTotp implements Handler<RoutingContext> {
|
public final class POSTUserVerifyTotp implements Handler<RoutingContext> {
|
||||||
|
|
||||||
public void handle(RoutingContext ctx) {
|
public void handle(RoutingContext ctx) {
|
||||||
User user = User.findByIdSync(ctx.request().getParam("id"));
|
BlockingCallback<User> userCallback = new BlockingCallback<>();
|
||||||
|
User.findById(ctx.request().getParam("id"), userCallback);
|
||||||
|
User user = userCallback.get();
|
||||||
|
|
||||||
if (user == null) {
|
if (user == null) {
|
||||||
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
ErrorUtils.respondNotFound(ctx, "User", ctx.request().getParam("id"));
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package net.frozenorb.apiv3.unsorted;
|
||||||
|
|
||||||
|
import com.mongodb.async.SingleResultCallback;
|
||||||
|
import io.vertx.core.Future;
|
||||||
|
|
||||||
|
public class FutureCompatibilityCallback<T> implements SingleResultCallback<T> {
|
||||||
|
|
||||||
|
private final Future<T> future;
|
||||||
|
|
||||||
|
public FutureCompatibilityCallback(Future<T> future) {
|
||||||
|
this.future = future;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onResult(T val, Throwable error) {
|
||||||
|
if (error != null) {
|
||||||
|
future.fail(error);
|
||||||
|
} else {
|
||||||
|
future.complete(val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,9 @@
|
|||||||
|
package net.frozenorb.apiv3.unsorted;
|
||||||
|
|
||||||
|
public enum RequiresTotpResult {
|
||||||
|
|
||||||
|
NOT_REQUIRED_NOT_SET,
|
||||||
|
NOT_REQUIRED_IP_PRE_AUTHORIZED,
|
||||||
|
REQUIRED_NO_EXEMPTIONS
|
||||||
|
|
||||||
|
}
|
@ -1,27 +0,0 @@
|
|||||||
package net.frozenorb.apiv3.util;
|
|
||||||
|
|
||||||
import com.mongodb.async.client.MongoIterable;
|
|
||||||
import lombok.experimental.UtilityClass;
|
|
||||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
|
||||||
|
|
||||||
import java.util.LinkedList;
|
|
||||||
import java.util.List;
|
|
||||||
|
|
||||||
@UtilityClass
|
|
||||||
public class SyncUtils {
|
|
||||||
|
|
||||||
public static <T> T blockOne(MongoIterable<T> mongoIterable) {
|
|
||||||
BlockingCallback<T> callback = new BlockingCallback<>();
|
|
||||||
|
|
||||||
mongoIterable.first(callback);
|
|
||||||
return callback.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> List<T> blockMulti(MongoIterable<T> mongoIterable) {
|
|
||||||
BlockingCallback<List<T>> callback = new BlockingCallback<>();
|
|
||||||
|
|
||||||
mongoIterable.into(new LinkedList<>(), callback);
|
|
||||||
return callback.get();
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
Loading…
Reference in New Issue
Block a user