dumb shit
This commit is contained in:
parent
87675fad10
commit
a0459183a7
@ -3,15 +3,11 @@ package net.frozenorb.apiv3;
|
||||
import com.google.common.net.MediaType;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import net.frozenorb.apiv3.domain.*;
|
||||
import net.frozenorb.apiv3.web.filter.AuthenticationFilter;
|
||||
import net.frozenorb.apiv3.web.filter.AuthorizationFilter;
|
||||
import net.frozenorb.apiv3.web.filter.MetricsFilter;
|
||||
import net.frozenorb.apiv3.web.filter.WebsiteUserSessionFilter;
|
||||
import net.frozenorb.apiv3.domain.BannedAsn;
|
||||
import net.frozenorb.apiv3.domain.BannedCellCarrier;
|
||||
import net.frozenorb.apiv3.domain.Rank;
|
||||
import net.frozenorb.apiv3.domain.Server;
|
||||
import net.frozenorb.apiv3.domain.ServerGroup;
|
||||
import net.frozenorb.apiv3.web.route.GETDumpsType;
|
||||
import net.frozenorb.apiv3.web.route.GETSearch;
|
||||
import net.frozenorb.apiv3.web.route.GETWhoAmI;
|
||||
@ -56,6 +52,14 @@ import net.frozenorb.apiv3.web.route.notificationTemplates.GETNotificationTempla
|
||||
import net.frozenorb.apiv3.web.route.notificationTemplates.GETNotificationTemplatesId;
|
||||
import net.frozenorb.apiv3.web.route.notificationTemplates.POSTNotificationTemplates;
|
||||
import net.frozenorb.apiv3.web.route.phoneIntel.GETPhoneInteld;
|
||||
import net.frozenorb.apiv3.web.route.prefix.DELETEPrefixesId;
|
||||
import net.frozenorb.apiv3.web.route.prefix.GETPrefixes;
|
||||
import net.frozenorb.apiv3.web.route.prefix.GETPrefixesId;
|
||||
import net.frozenorb.apiv3.web.route.prefix.POSTPrefixes;
|
||||
import net.frozenorb.apiv3.web.route.prefixGrants.DELETEPrefixGrantsId;
|
||||
import net.frozenorb.apiv3.web.route.prefixGrants.GETPrefixGrants;
|
||||
import net.frozenorb.apiv3.web.route.prefixGrants.GETPrefixGrantsId;
|
||||
import net.frozenorb.apiv3.web.route.prefixGrants.POSTPrefixGrants;
|
||||
import net.frozenorb.apiv3.web.route.punishments.DELETEPunishmentsId;
|
||||
import net.frozenorb.apiv3.web.route.punishments.DELETEUsersIdActivePunishment;
|
||||
import net.frozenorb.apiv3.web.route.punishments.GETPunishments;
|
||||
@ -123,6 +127,7 @@ public final class APIv3 {
|
||||
BannedAsn.updateCache();
|
||||
BannedCellCarrier.updateCache();
|
||||
Rank.updateCache();
|
||||
Prefix.updateCache();
|
||||
Server.updateCache();
|
||||
ServerGroup.updateCache();
|
||||
}
|
||||
@ -232,6 +237,19 @@ public final class APIv3 {
|
||||
//httpPut(router, "/servers/:serverId", PUTServersId.class);
|
||||
httpDelete(router, "/servers/:serverId", DELETEServersId.class);
|
||||
|
||||
|
||||
httpGet(router, "/prefixes/:prefixId", GETPrefixesId.class);
|
||||
httpGet(router, "/prefixes", GETPrefixes.class);
|
||||
httpPost(router, "/prefixes", POSTPrefixes.class);
|
||||
//httpPut(router, "/prefixes/:prefixId", PUTPrefixesId.class);
|
||||
httpDelete(router, "/prefixes/:prefixId", DELETEPrefixesId.class);
|
||||
|
||||
httpGet(router, "/prefixes/grants/:grantId", GETPrefixGrantsId.class);
|
||||
httpGet(router, "/prefixes/grants", GETPrefixGrants.class);
|
||||
httpPost(router, "/prefixes/grants", POSTPrefixGrants.class);
|
||||
//httpPut(router, "/grants/:grantId", PUTPrefixGrantsId.class);
|
||||
httpDelete(router, "/prefixes/grants/:grantId", DELETEPrefixGrantsId.class);
|
||||
|
||||
httpGet(router, "/staff", GETStaff.class);
|
||||
httpGet(router, "/users/:userId", GETUsersId.class);
|
||||
httpGet(router, "/users/:userId/compoundedPermissions", GETUsersIdCompoundedPermissions.class);
|
||||
|
84
src/main/java/net/frozenorb/apiv3/domain/Prefix.java
Normal file
84
src/main/java/net/frozenorb/apiv3/domain/Prefix.java
Normal file
@ -0,0 +1,84 @@
|
||||
package net.frozenorb.apiv3.domain;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.mongodb.async.SingleResultCallback;
|
||||
import com.mongodb.async.client.MongoCollection;
|
||||
import com.mongodb.async.client.MongoDatabase;
|
||||
import fr.javatic.mongo.jacksonCodec.Entity;
|
||||
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
||||
import io.vertx.core.Vertx;
|
||||
import lombok.Getter;
|
||||
import net.frozenorb.apiv3.unsorted.MongoToVoidMongoCallback;
|
||||
import net.frozenorb.apiv3.util.SpringUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedList;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Entity
|
||||
public final class Prefix {
|
||||
|
||||
private static final MongoCollection<Prefix> prefixesCollection = SpringUtils.getBean(MongoDatabase.class).getCollection("prefixes", Prefix.class);
|
||||
|
||||
private static Map<String, Prefix> prefixIdCache = null;
|
||||
private static List<Prefix> prefixCache = null;
|
||||
|
||||
@Getter @Id private String id;
|
||||
@Getter private String displayName;
|
||||
@Getter private String prefix;
|
||||
@Getter private boolean purchaseable;
|
||||
@Getter private String buttonName;
|
||||
@Getter private String buttonDescription;
|
||||
|
||||
public static List<Prefix> findAll() {
|
||||
return ImmutableList.copyOf(prefixCache);
|
||||
}
|
||||
|
||||
public static Prefix findById(String id) {
|
||||
return id == null ? null : prefixIdCache.get(id.toLowerCase());
|
||||
}
|
||||
|
||||
static {
|
||||
SpringUtils.getBean(Vertx.class).setPeriodic(TimeUnit.MINUTES.toMillis(1), (id) -> updateCache());
|
||||
}
|
||||
|
||||
public static void updateCache() {
|
||||
List<Prefix> prefixes = SyncUtils.runBlocking(v -> prefixesCollection.find().into(new LinkedList<>(), v));
|
||||
Map<String, Prefix> working = new HashMap<>();
|
||||
|
||||
for (Prefix prefix : prefixes) {
|
||||
working.put(prefix.getId().toLowerCase(), prefix);
|
||||
}
|
||||
|
||||
prefixIdCache = working;
|
||||
prefixCache = prefixes;
|
||||
}
|
||||
|
||||
private Prefix() {} // For Jackson
|
||||
|
||||
public Prefix(String id, String displayName, String prefix, boolean purchaseable, String buttonName, String buttonDescription) {
|
||||
this.id = id;
|
||||
this.displayName = displayName;
|
||||
this.prefix = prefix;
|
||||
this.purchaseable = purchaseable;
|
||||
this.buttonName = buttonName;
|
||||
this.buttonDescription = buttonDescription;
|
||||
}
|
||||
|
||||
public void insert(SingleResultCallback<Void> callback) {
|
||||
prefixCache.add(this);
|
||||
prefixIdCache.put(id.toLowerCase(), this);
|
||||
prefixesCollection.insertOne(this, SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public void delete(SingleResultCallback<Void> callback) {
|
||||
prefixCache.remove(this);
|
||||
prefixIdCache.remove(id.toLowerCase());
|
||||
prefixesCollection.deleteOne(new Document("_id", id), SyncUtils.vertxWrap(new MongoToVoidMongoCallback<>(callback)));
|
||||
}
|
||||
|
||||
}
|
140
src/main/java/net/frozenorb/apiv3/domain/PrefixGrant.java
Normal file
140
src/main/java/net/frozenorb/apiv3/domain/PrefixGrant.java
Normal file
@ -0,0 +1,140 @@
|
||||
package net.frozenorb.apiv3.domain;
|
||||
|
||||
import com.google.common.collect.Collections2;
|
||||
import com.mongodb.async.SingleResultCallback;
|
||||
import com.mongodb.async.client.MongoCollection;
|
||||
import com.mongodb.async.client.MongoDatabase;
|
||||
import fr.javatic.mongo.jacksonCodec.Entity;
|
||||
import fr.javatic.mongo.jacksonCodec.objectId.Id;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import net.frozenorb.apiv3.unsorted.MongoToVoidMongoCallback;
|
||||
import net.frozenorb.apiv3.util.SpringUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.*;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@Entity
|
||||
@AllArgsConstructor
|
||||
public final class PrefixGrant {
|
||||
|
||||
private static final MongoCollection<PrefixGrant> grantsCollection = SpringUtils.getBean(MongoDatabase.class).getCollection("prefixGrants", PrefixGrant.class);
|
||||
|
||||
@Getter @Id private String id;
|
||||
@Getter private UUID user;
|
||||
@Getter private String reason;
|
||||
@Getter private Set<String> scopes;
|
||||
@Getter private String prefix;
|
||||
@Getter private Instant expiresAt;
|
||||
|
||||
@Getter private UUID addedBy;
|
||||
@Getter private Instant addedAt;
|
||||
|
||||
@Getter private UUID removedBy;
|
||||
@Getter private Instant removedAt;
|
||||
@Getter private String removalReason;
|
||||
|
||||
@Getter private int storeItemId;
|
||||
@Getter private int storeOrderId;
|
||||
|
||||
public static void findAll(SingleResultCallback<List<PrefixGrant>> callback) {
|
||||
grantsCollection.find().sort(new Document("addedAt", -1)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public static void findByPrefix(Collection<Prefix> prefixes, SingleResultCallback<List<PrefixGrant>> callback) {
|
||||
Collection<String> convertedPrefixes = prefixes.stream().map(Prefix::getId).collect(Collectors.toList());
|
||||
grantsCollection.find(new Document("prefix", new Document("$in", convertedPrefixes))).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public static void findPaginated(Document query, int skip, int pageSize, SingleResultCallback<List<PrefixGrant>> callback) {
|
||||
grantsCollection.find(query).sort(new Document("addedAt", -1)).skip(skip).limit(pageSize).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public static void findById(String id, SingleResultCallback<PrefixGrant> callback) {
|
||||
grantsCollection.find(new Document("_id", id)).first(SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public static void findByUser(User user, SingleResultCallback<List<PrefixGrant>> callback) {
|
||||
findByUser(user.getId(), callback);
|
||||
}
|
||||
|
||||
public static void findByUser(UUID user, SingleResultCallback<List<PrefixGrant>> callback) {
|
||||
grantsCollection.find(new Document("user", user)).into(new LinkedList<>(), SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public static void findByUserGrouped(Iterable<UUID> users, SingleResultCallback<Map<UUID, List<PrefixGrant>>> callback) {
|
||||
grantsCollection.find(new Document("user", new Document("$in", users))).into(new LinkedList<>(), SyncUtils.vertxWrap((grants, error) -> {
|
||||
if (error != null) {
|
||||
callback.onResult(null, error);
|
||||
} else {
|
||||
Map<UUID, List<PrefixGrant>> result = new HashMap<>();
|
||||
|
||||
for (UUID user : users) {
|
||||
result.put(user, new LinkedList<>());
|
||||
}
|
||||
|
||||
for (PrefixGrant grant : grants) {
|
||||
result.get(grant.getUser()).add(grant);
|
||||
}
|
||||
|
||||
callback.onResult(result, null);
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private PrefixGrant() {} // For Jackson
|
||||
|
||||
public PrefixGrant(User user, String reason, Set<ServerGroup> scopes, Prefix prefix, Instant expiresAt, User addedBy) {
|
||||
this(user, reason, scopes, prefix, expiresAt, addedBy, -1, -1);
|
||||
}
|
||||
|
||||
public PrefixGrant(User user, String reason, Set<ServerGroup> scopes, Prefix prefix, Instant expiresAt, User addedBy, int storeItemId, int storeOrderId) {
|
||||
this.id = new ObjectId().toString();
|
||||
this.user = user.getId();
|
||||
this.reason = reason;
|
||||
this.scopes = new HashSet<>(Collections2.transform(scopes, ServerGroup::getId));
|
||||
this.prefix = prefix.getId();
|
||||
this.expiresAt = expiresAt;
|
||||
this.addedBy = addedBy == null ? null : addedBy.getId();
|
||||
this.addedAt = Instant.now();
|
||||
this.storeItemId = storeItemId;
|
||||
this.storeOrderId = storeOrderId;
|
||||
}
|
||||
|
||||
public boolean isActive() {
|
||||
return !(isExpired() || isRemoved());
|
||||
}
|
||||
|
||||
public boolean isExpired() {
|
||||
return expiresAt != null && expiresAt.isBefore(Instant.now());
|
||||
}
|
||||
|
||||
public boolean isRemoved() {
|
||||
return removedAt != null;
|
||||
}
|
||||
|
||||
public boolean appliesOn(ServerGroup serverGroup) {
|
||||
return isGlobal() || scopes.contains(serverGroup.getId());
|
||||
}
|
||||
|
||||
public boolean isGlobal() {
|
||||
return scopes.isEmpty();
|
||||
}
|
||||
|
||||
public void insert(SingleResultCallback<Void> callback) {
|
||||
grantsCollection.insertOne(this, SyncUtils.vertxWrap(callback));
|
||||
}
|
||||
|
||||
public void delete(User removedBy, String reason, SingleResultCallback<Void> callback) {
|
||||
this.removedBy = removedBy == null ? null : removedBy.getId();
|
||||
this.removedAt = Instant.now();
|
||||
this.removalReason = reason;
|
||||
|
||||
grantsCollection.replaceOne(new Document("_id", id), this, SyncUtils.vertxWrap(new MongoToVoidMongoCallback<>(callback)));
|
||||
}
|
||||
|
||||
}
|
@ -690,14 +690,16 @@ public final class User {
|
||||
}
|
||||
|
||||
Rank parent = otherRank;
|
||||
if(parent != null) {
|
||||
|
||||
// Iterate up the inheritance tree to detect rank redundancies.
|
||||
while (parent.getInheritsFromId() != null) {
|
||||
if (parent == grantedRank) {
|
||||
grantedRanks.remove(grantedRank);
|
||||
// Iterate up the inheritance tree to detect rank redundancies.
|
||||
while (parent.getInheritsFromId() != null) {
|
||||
if (parent == grantedRank) {
|
||||
grantedRanks.remove(grantedRank);
|
||||
}
|
||||
|
||||
parent = Rank.findById(parent.getInheritsFromId());
|
||||
}
|
||||
|
||||
parent = Rank.findById(parent.getInheritsFromId());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -27,6 +27,10 @@ public enum AuditLogActionType {
|
||||
GRANT_CREATE(false),
|
||||
GRANT_UPDATE(false),
|
||||
GRANT_DELETE(false),
|
||||
PREFIXGRANT_CREATE(false),
|
||||
PREFIXGRANT_UPDATE(false),
|
||||
PREFIXGRANT_DELETE(false),
|
||||
|
||||
IP_BAN_CREATE(false),
|
||||
IP_BAN_UPDATE(false),
|
||||
IP_BAN_DELETE(false),
|
||||
@ -62,6 +66,11 @@ public enum AuditLogActionType {
|
||||
RANK_CREATE(false),
|
||||
RANK_UPDATE(false),
|
||||
RANK_DELETE(false),
|
||||
PREFIX_CREATE(false),
|
||||
PREFIX_UPDATE(false),
|
||||
PREFIX_DELETE(false),
|
||||
|
||||
|
||||
SERVER_GROUP_CREATE(false),
|
||||
SERVER_GROUP_UPDATE(false),
|
||||
SERVER_GROUP_DELETE(false),
|
||||
|
@ -17,4 +17,6 @@ public class Permissions {
|
||||
public static final String CREATE_GRANT = rootPermission + ".grant.create";
|
||||
public static final String REMOVE_GRANT = rootPermission + ".grant.remove";
|
||||
|
||||
public static final String CREATE_PREFIXGRANT = rootPermission + ".prefixgrant.create";
|
||||
public static final String REMOVE_PREFIXGRANT = rootPermission + ".prefixgrant.remove";
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package net.frozenorb.apiv3.unsorted.actor;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
|
||||
public interface Actor {
|
||||
|
||||
boolean isAuthorized();
|
||||
@ -8,4 +10,5 @@ public interface Actor {
|
||||
|
||||
ActorType getType();
|
||||
|
||||
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package net.frozenorb.apiv3.unsorted.actor;
|
||||
|
||||
import com.google.common.base.MoreObjects;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
|
||||
@ -9,5 +10,12 @@ public final class SimpleActor implements Actor {
|
||||
@Getter private String name;
|
||||
@Getter private ActorType type;
|
||||
@Getter private boolean authorized;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return MoreObjects.toStringHelper(getClass())
|
||||
.add("authorized", isAuthorized())
|
||||
.add("name",getName())
|
||||
.add("type",getType().name())
|
||||
.toString();
|
||||
}
|
||||
}
|
@ -35,7 +35,6 @@ public class PermissionUtils {
|
||||
|
||||
for (Rank rank : mergeQueue) {
|
||||
Map<String, Boolean> rankPermissions = convertFromList(raw.get(rank.getId()));
|
||||
|
||||
// If there's no permissions defined for this rank just skip it.
|
||||
if (!rankPermissions.isEmpty()) {
|
||||
result = mergePermissions(result, rankPermissions);
|
||||
|
@ -18,11 +18,11 @@ public final class AuthorizationFilter implements Handler<RoutingContext> {
|
||||
Actor actor = ctx.get("actor");
|
||||
|
||||
ctx.next();
|
||||
/*if (actor.isAuthorized()) {
|
||||
if (actor.isAuthorized()) {
|
||||
|
||||
} else {
|
||||
ErrorUtils.respondOther(ctx, 403, "Failed to authorize as an approved actor.", "failedToAuthorizeNotApprovedActor", ImmutableMap.of());
|
||||
}*/
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package net.frozenorb.apiv3.web.route.prefix;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.Prefix;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLog;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLogActionType;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import net.frozenorb.apiv3.util.UuidUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class DELETEPrefixesId implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
Prefix prefix = Prefix.findById(ctx.request().getParam("prefixId"));
|
||||
|
||||
if (prefix == null) {
|
||||
ErrorUtils.respondNotFound(ctx, "Prefix", ctx.request().getParam("prefixId"));
|
||||
return;
|
||||
}
|
||||
|
||||
SyncUtils.<Void>runBlocking(v -> prefix.delete(v));
|
||||
|
||||
JsonObject requestBody = ctx.getBodyAsJson();
|
||||
|
||||
if (requestBody.containsKey("removedBy")) {
|
||||
AuditLog.log(UuidUtils.parseUuid(requestBody.getString("removedBy")), requestBody.getString("removedByIp"), ctx, AuditLogActionType.RANK_DELETE, ImmutableMap.of("prefixId", prefix.getId()), (ignored, error) -> {
|
||||
if (error != null) {
|
||||
ErrorUtils.respondInternalError(ctx, error);
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, prefix);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, prefix);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package net.frozenorb.apiv3.web.route.prefix;
|
||||
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.Prefix;
|
||||
import net.frozenorb.apiv3.domain.Rank;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@Component
|
||||
public final class GETPrefixes implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
APIv3.respondJson(ctx, 200, Prefix.findAll());
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package net.frozenorb.apiv3.web.route.prefix;
|
||||
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.Prefix;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class GETPrefixesId implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
APIv3.respondJson(ctx, 200, Prefix.findById(ctx.request().getParam("prefixId")));
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,44 @@
|
||||
package net.frozenorb.apiv3.web.route.prefix;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.Prefix;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLog;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLogActionType;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import net.frozenorb.apiv3.util.UuidUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class POSTPrefixes implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
JsonObject requestBody = ctx.getBodyAsJson();
|
||||
String id = requestBody.getString("id");
|
||||
String displayName = requestBody.getString("displayName");
|
||||
String prefix = requestBody.getString("prefix");
|
||||
boolean purchaseable = requestBody.getBoolean("purchaseable");
|
||||
String buttonName = requestBody.getString("buttonName");
|
||||
String buttonDescription = requestBody.getString("buttonDescription");
|
||||
|
||||
Prefix pref = new Prefix(id, displayName, prefix, purchaseable, buttonName, buttonDescription);
|
||||
SyncUtils.<Void>runBlocking(pref::insert);
|
||||
|
||||
if (requestBody.containsKey("addedBy")) {
|
||||
AuditLog.log(UuidUtils.parseUuid(requestBody.getString("addedBy")), requestBody.getString("addedByIp"), ctx, AuditLogActionType.PREFIX_CREATE, ImmutableMap.of("prefixId", id), (ignored, error) -> {
|
||||
if (error != null) {
|
||||
ErrorUtils.respondInternalError(ctx, error);
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, pref);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, pref);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,7 @@
|
||||
package net.frozenorb.apiv3.web.route.prefix;
|
||||
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public class PUTPrefixesId {
|
||||
}
|
@ -0,0 +1,65 @@
|
||||
package net.frozenorb.apiv3.web.route.prefixGrants;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.Grant;
|
||||
import net.frozenorb.apiv3.domain.User;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLog;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLogActionType;
|
||||
import net.frozenorb.apiv3.unsorted.Permissions;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class DELETEPrefixGrantsId implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
Grant grant = SyncUtils.runBlocking(v -> Grant.findById(ctx.request().getParam("grantId"), v));
|
||||
|
||||
if (grant == null) {
|
||||
ErrorUtils.respondNotFound(ctx, "Grant", ctx.request().getParam("grantId"));
|
||||
return;
|
||||
} else if (!grant.isActive()) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "Cannot remove an inactive grant.");
|
||||
return;
|
||||
}
|
||||
|
||||
JsonObject requestBody = ctx.getBodyAsJson();
|
||||
// We purposely don't do a null check, grant removals don't have to have a user/ip.
|
||||
User removedBy = SyncUtils.runBlocking(v -> User.findById(requestBody.getString("removedBy"), v));
|
||||
String reason = requestBody.getString("reason");
|
||||
|
||||
if (reason == null || reason.trim().isEmpty()) {
|
||||
ErrorUtils.respondRequiredInput(ctx, "reason");
|
||||
return;
|
||||
}
|
||||
|
||||
if (removedBy != null) {
|
||||
boolean allowed = SyncUtils.runBlocking(v -> removedBy.hasPermissionAnywhere(Permissions.REMOVE_PREFIXGRANT + "." + grant.getRank(), v));
|
||||
|
||||
if (!allowed) {
|
||||
ErrorUtils.respondOther(ctx, 409, "User given does not have permission to remove this grant.", "userDoesNotHavePermission", ImmutableMap.of());
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
SyncUtils.<Void>runBlocking(v -> grant.delete(removedBy, reason, v));
|
||||
|
||||
if (removedBy != null) {
|
||||
AuditLog.log(removedBy.getId(), requestBody.getString("removedByIp"), ctx, AuditLogActionType.PREFIXGRANT_DELETE, ImmutableMap.of("grantId", grant.getId()), (ignored, error) -> {
|
||||
if (error != null) {
|
||||
ErrorUtils.respondInternalError(ctx, error);
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, grant);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, grant);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,37 @@
|
||||
package net.frozenorb.apiv3.web.route.prefixGrants;
|
||||
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.PrefixGrant;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import net.frozenorb.apiv3.util.UuidUtils;
|
||||
|
||||
import org.bson.Document;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
|
||||
@Component
|
||||
public final class GETPrefixGrants implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
try {
|
||||
int skip = ctx.request().getParam("skip") == null ? 0 : Integer.parseInt(ctx.request().getParam("skip"));
|
||||
int pageSize = ctx.request().getParam("pageSize") == null ? 100 : Integer.parseInt(ctx.request().getParam("pageSize"));
|
||||
|
||||
PrefixGrant.findPaginated(ctx.request().getParam("user") == null ? new Document() : new Document("user", UuidUtils.parseUuid(ctx.request().getParam("user"))), skip, pageSize, (grants, error) -> {
|
||||
if (ctx.request().getParam("active") != null) {
|
||||
boolean requireActive = Boolean.parseBoolean(ctx.request().getParam("active"));
|
||||
APIv3.respondJson(ctx, 200, grants.stream().filter(grant -> grant.isActive() == requireActive).collect(Collectors.toList()));
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, grants);
|
||||
}
|
||||
});
|
||||
} catch (NumberFormatException ignored) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "skip and pageSize must be numerical inputs.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,24 @@
|
||||
package net.frozenorb.apiv3.web.route.prefixGrants;
|
||||
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.Grant;
|
||||
import net.frozenorb.apiv3.domain.PrefixGrant;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
@Component
|
||||
public final class GETPrefixGrantsId implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
PrefixGrant.findById(ctx.request().getParam("grantId"), (grant, error) -> {
|
||||
if (error != null) {
|
||||
ErrorUtils.respondInternalError(ctx, error);
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, grant);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,125 @@
|
||||
package net.frozenorb.apiv3.web.route.prefixGrants;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.vertx.core.Handler;
|
||||
import io.vertx.core.json.JsonObject;
|
||||
import io.vertx.ext.web.RoutingContext;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.domain.*;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLog;
|
||||
import net.frozenorb.apiv3.service.auditlog.AuditLogActionType;
|
||||
import net.frozenorb.apiv3.service.totp.TotpAuthorizationResult;
|
||||
import net.frozenorb.apiv3.unsorted.Permissions;
|
||||
import net.frozenorb.apiv3.util.ErrorUtils;
|
||||
import net.frozenorb.apiv3.util.SyncUtils;
|
||||
import org.springframework.stereotype.Component;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
@Component
|
||||
public final class POSTPrefixGrants implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
JsonObject requestBody = ctx.getBodyAsJson();
|
||||
User target = SyncUtils.runBlocking(v -> User.findById(requestBody.getString("user"), v));
|
||||
|
||||
if (target == null) {
|
||||
ErrorUtils.respondNotFound(ctx, "User", requestBody.getString("user"));
|
||||
return;
|
||||
}
|
||||
|
||||
String reason = requestBody.getString("reason");
|
||||
|
||||
if (reason == null || reason.trim().isEmpty()) {
|
||||
ErrorUtils.respondRequiredInput(ctx, "reason");
|
||||
return;
|
||||
}
|
||||
|
||||
Set<ServerGroup> scopes = new HashSet<>();
|
||||
List<String> scopeIds = (List<String>) requestBody.getJsonArray("scopes").getList();
|
||||
|
||||
if (!scopeIds.isEmpty()) {
|
||||
for (String serverGroupId : scopeIds) {
|
||||
ServerGroup serverGroup = ServerGroup.findById(serverGroupId);
|
||||
|
||||
if (serverGroup == null) {
|
||||
ErrorUtils.respondNotFound(ctx, "Server group", serverGroupId);
|
||||
return;
|
||||
}
|
||||
|
||||
scopes.add(serverGroup);
|
||||
}
|
||||
}
|
||||
|
||||
Prefix prefix = Prefix.findById(requestBody.getString("prefix"));
|
||||
|
||||
if (prefix == null) {
|
||||
ErrorUtils.respondNotFound(ctx, "Prefix", requestBody.getString("prefix"));
|
||||
return;
|
||||
}
|
||||
|
||||
Instant expiresAt = null;
|
||||
|
||||
if (requestBody.containsKey("expiresIn") && requestBody.getLong("expiresIn") != -1) {
|
||||
long expiresInMillis = requestBody.getLong("expiresIn") * 1000;
|
||||
expiresAt = Instant.ofEpochMilli(System.currentTimeMillis() + expiresInMillis);
|
||||
}
|
||||
|
||||
if (expiresAt != null && expiresAt.isBefore(Instant.now())) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "Expiration time cannot be in the past.");
|
||||
return;
|
||||
}
|
||||
|
||||
// We purposely don't fail on a null check, grants don't have to have a source.
|
||||
User addedBy = SyncUtils.runBlocking(v -> User.findById(requestBody.getString("addedBy"), v));
|
||||
|
||||
if (addedBy != null) {
|
||||
boolean allowed = SyncUtils.runBlocking(v -> addedBy.hasPermissionAnywhere(Permissions.CREATE_PREFIXGRANT + "." + prefix.getId(), v));
|
||||
|
||||
if (!allowed) {
|
||||
ErrorUtils.respondOther(ctx, 409, "User given does not have permission to create this grant.", "userDoesNotHavePermission", ImmutableMap.of());
|
||||
return;
|
||||
}
|
||||
|
||||
if (false) {
|
||||
if (!requestBody.containsKey("totpCode")) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "prefix must be granted through API or website.");
|
||||
return;
|
||||
}
|
||||
|
||||
int code = requestBody.getInteger("totpCode", -1);
|
||||
TotpAuthorizationResult totpAuthorizationResult = SyncUtils.runBlocking(v -> addedBy.checkTotpAuthorization(code, null, v));
|
||||
|
||||
if (!totpAuthorizationResult.isAuthorized()) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "Totp authorization failed: " + totpAuthorizationResult.name());
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else if (false) {
|
||||
ErrorUtils.respondInvalidInput(ctx, "Prefix must be granted through API or website.");
|
||||
return;
|
||||
}
|
||||
|
||||
int storeItemId = requestBody.getInteger("storeItemId", -1);
|
||||
int storeOrderId = requestBody.getInteger("storeOrderId", -1);
|
||||
|
||||
PrefixGrant grant = new PrefixGrant(target, reason, scopes, prefix, expiresAt, addedBy, storeItemId, storeOrderId);
|
||||
SyncUtils.<Void>runBlocking(v -> grant.insert(v));
|
||||
|
||||
if (addedBy != null) {
|
||||
AuditLog.log(addedBy.getId(), requestBody.getString("addedByIp"), ctx, AuditLogActionType.PREFIXGRANT_CREATE, ImmutableMap.of("grantId", grant.getId()), (ignored, error) -> {
|
||||
if (error != null) {
|
||||
ErrorUtils.respondInternalError(ctx, error);
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, grant);
|
||||
}
|
||||
});
|
||||
} else {
|
||||
APIv3.respondJson(ctx, 200, grant);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -40,15 +40,16 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
||||
|
||||
public void handle(RoutingContext ctx) {
|
||||
Actor actor = ctx.get("actor");
|
||||
|
||||
if (actor.getType() != ActorType.SERVER) {
|
||||
ErrorUtils.respondOther(ctx, 403, "This action can only be performed when requested by a server.", "serverOnly", ImmutableMap.of());
|
||||
ErrorUtils.respondOther(ctx, 403,
|
||||
"This action can only be performed when requested by a server.", "serverOnly", ImmutableMap.of());
|
||||
return;
|
||||
}
|
||||
|
||||
Server actorServer = Server.findById(actor.getName());
|
||||
|
||||
JsonObject requestBody = ctx.getBodyAsJson();
|
||||
System.out.println("body: " + requestBody);
|
||||
|
||||
JsonObject players = requestBody.getJsonObject("players");
|
||||
Map<UUID, String> playerNames = extractPlayerNames(players);
|
||||
Map<UUID, String> playerIps = extractPlayerIps(players);
|
||||
@ -75,6 +76,7 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
||||
}
|
||||
|
||||
private Future<Void> createInfoResponse(Server server, double tps, Map<UUID, String> playerNames) {
|
||||
|
||||
Future<Void> callback = Future.future();
|
||||
|
||||
if (server != null && playerNames != null) {
|
||||
@ -92,6 +94,7 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
||||
}
|
||||
|
||||
private Future<Map<String, Object>> createPlayerResponse(Server server, Map<UUID, String> playerNames, Map<UUID, String> playerIps) {
|
||||
|
||||
Future<Map<String, Object>> callback = Future.future();
|
||||
|
||||
Future<Map<UUID, User>> userLookupCallback = Future.future();
|
||||
@ -139,18 +142,19 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
||||
}
|
||||
|
||||
private Future<Map<String, Object>> createPermissionsResponse(ServerGroup serverGroup) {
|
||||
|
||||
Future<Map<String, Object>> callback = Future.future();
|
||||
Map<String, Object> permissionsResponse = new HashMap<>();
|
||||
|
||||
for (Rank rank : Rank.findAll()) {
|
||||
Map<String, Boolean> defaultCalculatedPermissions = ServerGroup.findDefault().calculatePermissions(rank);
|
||||
Map<String, Boolean> calculatedPermissions = serverGroup.calculatePermissions(rank);
|
||||
Map<String, Boolean> scopedPermissions = PermissionUtils.mergePermissions(
|
||||
ServerGroup.findDefault().calculatePermissions(rank),
|
||||
serverGroup.calculatePermissions(rank)
|
||||
defaultCalculatedPermissions,
|
||||
calculatedPermissions
|
||||
);
|
||||
|
||||
permissionsResponse.put(rank.getId(), PermissionUtils.convertToList(scopedPermissions));
|
||||
}
|
||||
|
||||
callback.complete(permissionsResponse);
|
||||
return callback;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user