More stuff
This commit is contained in:
parent
4b49c5bafe
commit
d062ab5718
@ -1,15 +1,15 @@
|
||||
general.releaseStage=production
|
||||
logging.level=info
|
||||
mongo.address=ds055505.mongolab.com
|
||||
mongo.port=55505
|
||||
mongo.address=209.222.96.50
|
||||
mongo.port=27017
|
||||
mongo.database=minehqapi
|
||||
mongo.username=test
|
||||
mongo.password=test
|
||||
mongo.username=
|
||||
mongo.password=
|
||||
redis.address=localhost
|
||||
redis.port=6379
|
||||
http.address=0.0.0.0
|
||||
http.port=80
|
||||
http.workerThreads=6
|
||||
http.workerThreads=
|
||||
twillio.accountSID=AC9e2f88c5690134d29a56f698de3cd740
|
||||
twillio.authToken=982592505a171d3be6b0722f5ecacc0e
|
||||
mandrill.apiKey=0OYtwymqJP6oqvszeJu0vQ
|
||||
|
10
pom.xml
10
pom.xml
@ -133,6 +133,16 @@
|
||||
<artifactId>googleauth</artifactId>
|
||||
<version>0.5.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okhttp3</groupId>
|
||||
<artifactId>okhttp</artifactId>
|
||||
<version>3.2.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.squareup.okio</groupId>
|
||||
<artifactId>okio</artifactId>
|
||||
<version>1.8.0</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
|
@ -1,9 +1,11 @@
|
||||
package net.frozenorb.apiv3;
|
||||
|
||||
import com.bugsnag.Client;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import com.mongodb.MongoClient;
|
||||
import com.mongodb.MongoCredential;
|
||||
import com.mongodb.ServerAddress;
|
||||
import com.timgroup.statsd.NonBlockingStatsDClient;
|
||||
import com.timgroup.statsd.StatsDClient;
|
||||
@ -37,6 +39,7 @@ import net.frozenorb.apiv3.routes.users.*;
|
||||
import net.frozenorb.apiv3.serialization.DateTypeAdapter;
|
||||
import net.frozenorb.apiv3.serialization.FollowAnnotationExclusionStrategy;
|
||||
import net.frozenorb.apiv3.serialization.ObjectIdTypeAdapter;
|
||||
import net.frozenorb.apiv3.unsorted.BugsnagSLF4jLogger;
|
||||
import net.frozenorb.apiv3.unsorted.LoggingExceptionHandler;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.mongodb.morphia.Datastore;
|
||||
@ -77,6 +80,8 @@ public final class APIv3 {
|
||||
setupMetrics();
|
||||
setupBugsnag();
|
||||
setupHttp();
|
||||
|
||||
LoggingFilter.setDebug(true);
|
||||
}
|
||||
|
||||
private void setupConfig() {
|
||||
@ -88,17 +93,21 @@ public final class APIv3 {
|
||||
}
|
||||
|
||||
private void setupDatabase() {
|
||||
MongoClient mongoClient = new MongoClient(new ServerAddress(
|
||||
config.getProperty("mongo.address"),
|
||||
Integer.parseInt(config.getProperty("mongo.port")))/*,
|
||||
ImmutableList.of(
|
||||
MongoCredential.createCredential(
|
||||
ImmutableList<MongoCredential> credentials = ImmutableList.of();
|
||||
|
||||
if (!config.getProperty("mongo.username").isEmpty()) {
|
||||
credentials = ImmutableList.of(MongoCredential.createCredential(
|
||||
config.getProperty("mongo.username"),
|
||||
config.getProperty("mongo.database"),
|
||||
config.getProperty("mongo.password").toCharArray())
|
||||
)*/);
|
||||
config.getProperty("mongo.password").toCharArray()
|
||||
));
|
||||
}
|
||||
|
||||
// TODO: DISABLE CREDS IF NOT NEEDED
|
||||
MongoClient mongoClient = new MongoClient(new ServerAddress(
|
||||
config.getProperty("mongo.address"),
|
||||
Integer.parseInt(config.getProperty("mongo.port"))),
|
||||
credentials
|
||||
);
|
||||
|
||||
MorphiaLoggerFactory.reset();
|
||||
MorphiaLoggerFactory.registerLogger(SLF4JLoggerImplFactory.class);
|
||||
@ -120,7 +129,7 @@ public final class APIv3 {
|
||||
private void setupMetrics() {
|
||||
statsD = new NonBlockingStatsDClient(null, "localhost", 8125);
|
||||
|
||||
new Timer("Librato Post Task").scheduleAtFixedRate(new TimerTask() {
|
||||
new Timer("Metrics Task").scheduleAtFixedRate(new TimerTask() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
@ -135,15 +144,18 @@ public final class APIv3 {
|
||||
Client bugsnag = new Client(config.getProperty("bugsnag.apiKey"));
|
||||
bugsnag.setReleaseStage(config.getProperty("general.releaseStage"));
|
||||
bugsnag.setProjectPackages("net.frozenorb.apiv3");
|
||||
|
||||
// TODO: Use .setLogger to use slf4j with this
|
||||
bugsnag.setLogger(new BugsnagSLF4jLogger());
|
||||
}
|
||||
|
||||
private void setupHttp() {
|
||||
ipAddress(config.getProperty("http.address"));
|
||||
port(Integer.parseInt(config.getProperty("http.port")));
|
||||
// TODO: if threadPool == null use default value
|
||||
threadPool(Integer.parseInt(config.getProperty("http.workerThreads")));
|
||||
String workerThreads = config.getProperty("http.workerThreads");
|
||||
|
||||
if (!workerThreads.isEmpty()) {
|
||||
threadPool(Integer.parseInt(workerThreads));
|
||||
}
|
||||
|
||||
before(new ContentTypeFilter());
|
||||
before(new ActorAttributeFilter());
|
||||
before(new AuthorizationFilter());
|
||||
|
@ -1,10 +1,11 @@
|
||||
package net.frozenorb.apiv3.actors;
|
||||
|
||||
import lombok.Getter;
|
||||
import net.frozenorb.apiv3.models.Server;
|
||||
|
||||
public final class ServerActor implements Actor {
|
||||
|
||||
private final Server server;
|
||||
@Getter private final Server server;
|
||||
|
||||
public ServerActor(Server server) {
|
||||
this.server = server;
|
||||
|
@ -1,6 +1,7 @@
|
||||
package net.frozenorb.apiv3.actors;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import lombok.Getter;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.models.User;
|
||||
|
||||
@ -10,7 +11,7 @@ public final class UserActor implements Actor {
|
||||
|
||||
private static final Set<String> authorizedUserGrants = ImmutableSet.copyOf(APIv3.getConfig().getProperty("auth.permittedUserRanks").split(","));
|
||||
|
||||
private final User user;
|
||||
@Getter private final User user;
|
||||
// We use Boolean here so we can have null = not calculated;
|
||||
private Boolean cachedAuthorized = null;
|
||||
|
||||
|
@ -7,7 +7,7 @@ import spark.Response;
|
||||
public final class ContentTypeFilter implements Filter {
|
||||
|
||||
public void handle(Request req, Response res) {
|
||||
res.header("content-type", "application/json");
|
||||
res.header("Content-Type", "application/json");
|
||||
}
|
||||
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package net.frozenorb.apiv3.filters;
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import spark.Filter;
|
||||
import spark.Request;
|
||||
@ -8,12 +10,14 @@ import spark.Response;
|
||||
@Slf4j
|
||||
public final class LoggingFilter implements Filter {
|
||||
|
||||
public void handle(Request req, Response res) {
|
||||
if (req.url().toLowerCase().contains("password=")) {
|
||||
return;
|
||||
}
|
||||
@Getter @Setter private static boolean debug = false;
|
||||
|
||||
public void handle(Request req, Response res) {
|
||||
if (debug) {
|
||||
log.info(req.requestMethod().toUpperCase() + " " + req.url() + "\n" + res.body());
|
||||
} else {
|
||||
log.info(req.requestMethod().toUpperCase() + " " + req.url());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -11,6 +11,7 @@ import org.mongodb.morphia.annotations.Id;
|
||||
import org.mongodb.morphia.annotations.Indexed;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
import java.util.UUID;
|
||||
|
||||
@Entity(value = "punishments", noClassnameStored = true)
|
||||
@ -21,6 +22,7 @@ public final class Punishment {
|
||||
@Getter private String reason;
|
||||
@Getter @Indexed private PunishmentType type; // Type is indexed for the rank dump
|
||||
@Getter private Date expiresAt;
|
||||
@Getter private Map<String, Object> meta;
|
||||
|
||||
@Getter private UUID addedBy;
|
||||
@Getter @Indexed private Date addedAt;
|
||||
@ -37,7 +39,7 @@ public final class Punishment {
|
||||
|
||||
public Punishment() {} // For Morphia
|
||||
|
||||
public Punishment(User target, String reason, PunishmentType type, Date expiresAt, User addedBy, Actor actor) {
|
||||
public Punishment(User target, String reason, PunishmentType type, Date expiresAt, User addedBy, Actor actor, Map<String, Object> meta) {
|
||||
this.id = new ObjectId().toString();
|
||||
this.target = target.getId();
|
||||
this.reason = reason;
|
||||
@ -47,6 +49,7 @@ public final class Punishment {
|
||||
this.addedAt = new Date();
|
||||
this.actorName = actor.getName();
|
||||
this.actorType = actor.getType();
|
||||
this.meta = meta;
|
||||
}
|
||||
|
||||
public void delete(User removedBy, String reason) {
|
||||
|
@ -1,16 +1,23 @@
|
||||
package net.frozenorb.apiv3.models;
|
||||
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import lombok.Getter;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import org.mongodb.morphia.annotations.Entity;
|
||||
import org.mongodb.morphia.annotations.Id;
|
||||
import org.mongodb.morphia.annotations.Indexed;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
@Entity(value = "ranks", noClassnameStored = true)
|
||||
public final class Rank {
|
||||
|
||||
private static Map<String, Rank> rankCache = null;
|
||||
private static long rankCacheUpdated = 0;
|
||||
|
||||
@Getter @Id private String id;
|
||||
@Getter private int weight;
|
||||
@Getter private String displayName;
|
||||
@ -19,11 +26,12 @@ public final class Rank {
|
||||
@Getter @Indexed private boolean staffRank;
|
||||
|
||||
public static Rank byId(String id) {
|
||||
return APIv3.getDatastore().createQuery(Rank.class).field("id").equal(id).get();
|
||||
updateCacheIfNeeded();
|
||||
return rankCache.get(id);
|
||||
}
|
||||
|
||||
public static List<Rank> values() {
|
||||
return APIv3.getDatastore().createQuery(Rank.class).order("weight").asList();
|
||||
return ImmutableList.copyOf(rankCache.values());
|
||||
}
|
||||
|
||||
public Rank() {} // For Morphia
|
||||
@ -41,4 +49,17 @@ public final class Rank {
|
||||
APIv3.getDatastore().delete(this);
|
||||
}
|
||||
|
||||
private static void updateCacheIfNeeded() {
|
||||
if (rankCache == null || (System.currentTimeMillis() - rankCacheUpdated) > TimeUnit.MINUTES.toMillis(1)) {
|
||||
Map<String, Rank> working = new HashMap<>();
|
||||
|
||||
for (Rank rank : APIv3.getDatastore().createQuery(Rank.class).order("weight").asList()) {
|
||||
working.put(rank.getId(), rank);
|
||||
}
|
||||
|
||||
rankCache = working;
|
||||
rankCacheUpdated = System.currentTimeMillis();
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -7,6 +7,7 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.serialization.ExcludeFromReplies;
|
||||
import net.frozenorb.apiv3.utils.MojangUtils;
|
||||
import net.frozenorb.apiv3.utils.PermissionUtils;
|
||||
import org.bson.Document;
|
||||
import org.mindrot.jbcrypt.BCrypt;
|
||||
@ -57,7 +58,7 @@ public final class User {
|
||||
|
||||
public User(UUID id, String lastUsername) {
|
||||
this.id = id;
|
||||
this.lastUsername = lastUsername;
|
||||
this.lastUsername = ""; // Intentional, so updateUsername actually does something.
|
||||
this.aliases = new HashMap<>();
|
||||
this.totpSecret = null;
|
||||
this.password = null;
|
||||
@ -67,7 +68,7 @@ public final class User {
|
||||
this.lastSeenAt = new Date();
|
||||
this.firstSeenAt = new Date();
|
||||
|
||||
aliases.put(lastUsername, new Date());
|
||||
updateUsername(lastUsername);
|
||||
}
|
||||
|
||||
public boolean hasPermissionScoped(String permission, ServerGroup scope) {
|
||||
@ -138,9 +139,23 @@ public final class User {
|
||||
}
|
||||
}
|
||||
|
||||
public void seenOnServer(String username, Server server) {
|
||||
public void seenOnServer(Server server) {
|
||||
this.lastSeenOn = server.getId();
|
||||
this.lastSeenAt = new Date();
|
||||
}
|
||||
|
||||
public void updateUsername(String username) {
|
||||
if (!username.equals(lastUsername)) {
|
||||
this.lastUsername = username;
|
||||
|
||||
User withNewUsername;
|
||||
|
||||
while ((withNewUsername = User.byLastUsername(username)) != null) {
|
||||
String newUsername = MojangUtils.getName(withNewUsername.getId());
|
||||
withNewUsername.updateUsername(newUsername);
|
||||
}
|
||||
}
|
||||
|
||||
this.aliases.put(username, new Date());
|
||||
}
|
||||
|
||||
@ -157,7 +172,7 @@ public final class User {
|
||||
}
|
||||
|
||||
public Rank getHighestRank(ServerGroup serverGroup) {
|
||||
Rank highest = null;;
|
||||
Rank highest = null;
|
||||
|
||||
for (Grant grant : getGrants()) {
|
||||
if (!grant.isActive() || (serverGroup != null && !grant.appliesOn(serverGroup))) {
|
||||
@ -205,51 +220,43 @@ public final class User {
|
||||
}
|
||||
|
||||
public Map<String, Object> getLoginInfo(Server server) {
|
||||
Punishment activeMute = null;
|
||||
String accessDenialReason = null;
|
||||
|
||||
for (Punishment punishment : getPunishments(ImmutableSet.of(
|
||||
Punishment.PunishmentType.BLACKLIST,
|
||||
Punishment.PunishmentType.BAN
|
||||
Punishment.PunishmentType.BAN,
|
||||
Punishment.PunishmentType.MUTE
|
||||
))) {
|
||||
if (!punishment.isActive()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (punishment.getType() == Punishment.PunishmentType.MUTE) {
|
||||
activeMute = punishment;
|
||||
} else {
|
||||
accessDenialReason = punishment.getAccessDenialReason();
|
||||
}
|
||||
|
||||
Punishment mute = null;
|
||||
for (Punishment punishment : getPunishments(ImmutableSet.of(Punishment.PunishmentType.MUTE))) {
|
||||
if (!punishment.isActive()) {
|
||||
continue;
|
||||
}
|
||||
|
||||
mute = punishment;
|
||||
}
|
||||
|
||||
ServerGroup actorGroup = ServerGroup.byId(server.getGroup());
|
||||
Rank highestRank = getHighestRank(actorGroup);
|
||||
|
||||
Map<String, Boolean> scopedPermissions = PermissionUtils.mergePermissions(
|
||||
PermissionUtils.getDefaultPermissions(highestRank),
|
||||
actorGroup.calculatePermissions(highestRank)
|
||||
);
|
||||
|
||||
Map<String, Object> loginInfo = Maps.newHashMap();
|
||||
|
||||
loginInfo.put("user", this);
|
||||
loginInfo.put("access", ImmutableMap.of(
|
||||
// Generics are weird, yes we have to do this.
|
||||
ImmutableMap.Builder<String, Object> result = ImmutableMap.<String, Object>builder()
|
||||
.put("user", this)
|
||||
.put("access", ImmutableMap.of(
|
||||
"allowed", accessDenialReason == null,
|
||||
"message", accessDenialReason == null ? "Public server" : accessDenialReason
|
||||
));
|
||||
loginInfo.put("rank", highestRank.getId());
|
||||
loginInfo.put("permissions", scopedPermissions);
|
||||
loginInfo.put("totpSetup", getTotpSecret() != null);
|
||||
if (mute != null) {
|
||||
loginInfo.put("mute", mute);
|
||||
))
|
||||
.put("rank", highestRank.getId())
|
||||
.put("totpSetup", getTotpSecret() != null);
|
||||
|
||||
if (activeMute != null) {
|
||||
result.put("mute", activeMute);
|
||||
}
|
||||
|
||||
return loginInfo;
|
||||
return result.build();
|
||||
}
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package net.frozenorb.apiv3.routes.announcements;
|
||||
|
||||
import net.frozenorb.apiv3.actors.Actor;
|
||||
import net.frozenorb.apiv3.actors.ActorType;
|
||||
import net.frozenorb.apiv3.actors.ServerActor;
|
||||
import net.frozenorb.apiv3.models.Server;
|
||||
import net.frozenorb.apiv3.models.ServerGroup;
|
||||
import net.frozenorb.apiv3.utils.ErrorUtils;
|
||||
@ -18,7 +19,7 @@ public final class GETAnnouncements implements Route {
|
||||
return ErrorUtils.serverOnly();
|
||||
}
|
||||
|
||||
Server sender = Server.byId(actor.getName());
|
||||
Server sender = ((ServerActor) req.attribute("actor")).getServer();
|
||||
ServerGroup senderGroup = ServerGroup.byId(sender.getGroup());
|
||||
|
||||
return senderGroup.getAnnouncements();
|
||||
|
@ -16,7 +16,7 @@ public final class GETAuditLog implements Route {
|
||||
|
||||
return APIv3.getDatastore().createQuery(AuditLogEntry.class).order("performedAt").limit(limit).offset(offset).asList();
|
||||
} catch (NumberFormatException ex) {
|
||||
return ErrorUtils.invalidInput(";imit and offset must be numerical inputs.");
|
||||
return ErrorUtils.invalidInput("limit and offset must be numerical inputs.");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -34,7 +34,6 @@ public final class DELETEGrant implements Route {
|
||||
}
|
||||
|
||||
grant.delete(removedBy, reason);
|
||||
// TODO: Fix IP
|
||||
AuditLog.log(removedBy, "", req.attribute("actor"), AuditLogActionType.DELETE_GRANT, ImmutableMap.of());
|
||||
return grant;
|
||||
}
|
||||
|
@ -34,7 +34,6 @@ public final class DELETEPunishment implements Route {
|
||||
}
|
||||
|
||||
punishment.delete(removedBy, reason);
|
||||
// TODO: Fix IP
|
||||
AuditLog.log(removedBy, "", req.attribute("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of());
|
||||
return punishment;
|
||||
}
|
||||
|
@ -7,11 +7,13 @@ import net.frozenorb.apiv3.models.Punishment;
|
||||
import net.frozenorb.apiv3.models.User;
|
||||
import net.frozenorb.apiv3.unsorted.Permissions;
|
||||
import net.frozenorb.apiv3.utils.ErrorUtils;
|
||||
import org.bson.Document;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
import spark.Route;
|
||||
|
||||
import java.util.Date;
|
||||
import java.util.Map;
|
||||
|
||||
public final class POSTUserPunish implements Route {
|
||||
|
||||
@ -50,6 +52,12 @@ public final class POSTUserPunish implements Route {
|
||||
return ErrorUtils.invalidInput("Expiration date cannot be in the past.");
|
||||
}
|
||||
|
||||
Map<String, Object> meta = Document.parse(req.body());
|
||||
|
||||
if (meta == null) {
|
||||
return ErrorUtils.requiredInput("request body meta");
|
||||
}
|
||||
|
||||
// We purposely don't do a null check, grants don't have to have a source.
|
||||
User addedBy = User.byId(req.queryParams("addedBy"));
|
||||
|
||||
@ -57,12 +65,13 @@ public final class POSTUserPunish implements Route {
|
||||
return ErrorUtils.error(target.getLastSeenOn() + " is protected from punishments.");
|
||||
}
|
||||
|
||||
Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, req.attribute("actor"));
|
||||
Punishment punishment = new Punishment(target, reason, type, expiresAt, addedBy, req.attribute("actor"), meta);
|
||||
String accessDenialReason = punishment.getAccessDenialReason();
|
||||
APIv3.getDatastore().save(punishment);
|
||||
|
||||
return ImmutableMap.of(
|
||||
"punishment", punishment,
|
||||
"accessDenialReason", punishment.getAccessDenialReason() == null ? "" : punishment.getAccessDenialReason()
|
||||
"accessDenialReason", accessDenialReason == null ? "" : accessDenialReason
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,16 @@
|
||||
package net.frozenorb.apiv3.routes.servers;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.actors.Actor;
|
||||
import net.frozenorb.apiv3.actors.ActorType;
|
||||
import net.frozenorb.apiv3.models.Rank;
|
||||
import net.frozenorb.apiv3.models.Server;
|
||||
import net.frozenorb.apiv3.models.ServerGroup;
|
||||
import net.frozenorb.apiv3.models.User;
|
||||
import net.frozenorb.apiv3.utils.ErrorUtils;
|
||||
import net.frozenorb.apiv3.utils.PermissionUtils;
|
||||
import org.bson.Document;
|
||||
import spark.Request;
|
||||
import spark.Response;
|
||||
@ -14,6 +18,7 @@ import spark.Route;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
@Slf4j
|
||||
public final class POSTServerHeartbeat implements Route {
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
@ -25,6 +30,7 @@ public final class POSTServerHeartbeat implements Route {
|
||||
}
|
||||
|
||||
Server actorServer = Server.byId(actor.getName());
|
||||
ServerGroup actorServerGroup = ServerGroup.byId(actorServer.getGroup());
|
||||
Document reqJson = Document.parse(req.body());
|
||||
Set<UUID> onlinePlayers = new HashSet<>();
|
||||
Map<String, Object> playersResponse = new HashMap<>();
|
||||
@ -39,7 +45,7 @@ public final class POSTServerHeartbeat implements Route {
|
||||
user = new User(UUID.fromString(playerJson.getString("uuid")), username);
|
||||
}
|
||||
|
||||
user.seenOnServer(username, actorServer);
|
||||
user.seenOnServer(actorServer);
|
||||
APIv3.getDatastore().save(user);
|
||||
|
||||
onlinePlayers.add(user.getId());
|
||||
@ -58,17 +64,29 @@ public final class POSTServerHeartbeat implements Route {
|
||||
case "metrics":
|
||||
break;
|
||||
default:
|
||||
System.err.println("Recieved event with unknown type " + type + ".");
|
||||
log.warn("Recieved event with unknown type " + type + ".");
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Map<String, Boolean>> permissions = new HashMap<>();
|
||||
|
||||
for (Rank rank : Rank.values()) {
|
||||
Map<String, Boolean> scopedPermissions = PermissionUtils.mergePermissions(
|
||||
PermissionUtils.getDefaultPermissions(rank),
|
||||
actorServerGroup.calculatePermissions(rank)
|
||||
);
|
||||
|
||||
permissions.put(rank.getId(), scopedPermissions);
|
||||
}
|
||||
|
||||
actorServer.setPlayers(onlinePlayers);
|
||||
actorServer.setLastTps(reqJson.getDouble("lastTps"));
|
||||
actorServer.setLastUpdate(new Date());
|
||||
APIv3.getDatastore().save(actorServer);
|
||||
|
||||
return ImmutableMap.of(
|
||||
"players", playersResponse
|
||||
"players", playersResponse,
|
||||
"permissions", permissions
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -36,7 +36,6 @@ public final class DELETEUserPunishment implements Route {
|
||||
for (Punishment punishment : target.getPunishments(ImmutableSet.of(type))) {
|
||||
if (punishment.isActive()) {
|
||||
punishment.delete(removedBy, reason);
|
||||
// TODO: Fix IP
|
||||
AuditLog.log(removedBy, "", req.attribute("actor"), AuditLogActionType.DELETE_PUNISHMENT, ImmutableMap.of());
|
||||
return punishment;
|
||||
}
|
||||
|
@ -37,6 +37,8 @@ public final class POSTUserLogin implements Route {
|
||||
Server actorServer = Server.byId(actor.getName());
|
||||
|
||||
user.getIPLogEntry(userIp).used();
|
||||
user.updateUsername(username);
|
||||
APIv3.getDatastore().save(user);
|
||||
return user.getLoginInfo(actorServer);
|
||||
}
|
||||
|
||||
|
@ -10,7 +10,11 @@ import java.util.Date;
|
||||
public final class DateTypeAdapter extends TypeAdapter<Date> {
|
||||
|
||||
public void write(JsonWriter writer, Date write) throws IOException {
|
||||
writer.value(write == null ? -1 : write.getTime());
|
||||
if (write == null) {
|
||||
writer.value(-1);
|
||||
} else {
|
||||
writer.value(write.getTime());
|
||||
}
|
||||
}
|
||||
|
||||
// This is used with Gson, which is only used
|
||||
|
@ -0,0 +1,29 @@
|
||||
package net.frozenorb.apiv3.unsorted;
|
||||
|
||||
import com.bugsnag.Logger;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
@Slf4j
|
||||
public class BugsnagSLF4jLogger extends Logger {
|
||||
|
||||
public void debug(String message) {
|
||||
log.debug(message);
|
||||
}
|
||||
|
||||
public void info(String message) {
|
||||
log.info(message);
|
||||
}
|
||||
|
||||
public void warn(String message) {
|
||||
log.warn(message);
|
||||
}
|
||||
|
||||
public void warn(String message, Throwable ex) {
|
||||
log.warn(message, ex);
|
||||
}
|
||||
|
||||
public void warn(Throwable ex) {
|
||||
log.warn("error in bugsnag", ex);
|
||||
}
|
||||
|
||||
}
|
39
src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java
Normal file
39
src/main/java/net/frozenorb/apiv3/utils/MojangUtils.java
Normal file
@ -0,0 +1,39 @@
|
||||
package net.frozenorb.apiv3.utils;
|
||||
|
||||
import lombok.experimental.UtilityClass;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.bson.Document;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.UUID;
|
||||
|
||||
@UtilityClass
|
||||
public class MojangUtils {
|
||||
|
||||
private static OkHttpClient okHttpClient = new OkHttpClient();
|
||||
|
||||
public static String getName(UUID id) {
|
||||
Request.Builder builder = new Request.Builder();
|
||||
|
||||
builder.get();
|
||||
builder.url("https://sessionserver.mojang.com/session/minecraft/profile/" + id.toString().replace("-", ""));
|
||||
|
||||
try {
|
||||
Response response = okHttpClient.newCall(builder.build()).execute();
|
||||
Document resJson = Document.parse(response.body().string());
|
||||
|
||||
String name = resJson.getString("name");
|
||||
|
||||
if (name == null) {
|
||||
throw new RuntimeException("Hit Mojang API rate limit");
|
||||
}
|
||||
|
||||
return name;
|
||||
} catch (Exception ex) {
|
||||
throw new RuntimeException(ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user