Integrate user logins with MaxMind, and deny access to users on VPNs
This commit is contained in:
parent
4e00381e50
commit
ddd0e0159a
@ -3,6 +3,7 @@ package net.frozenorb.apiv3.model;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonDeserialize;
|
||||
import com.fasterxml.jackson.databind.annotation.JsonSerialize;
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.collect.ImmutableList;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.common.hash.Hashing;
|
||||
@ -17,10 +18,13 @@ import lombok.AllArgsConstructor;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import net.frozenorb.apiv3.APIv3;
|
||||
import net.frozenorb.apiv3.maxmind.MaxMindResult;
|
||||
import net.frozenorb.apiv3.maxmind.MaxMindUserType;
|
||||
import net.frozenorb.apiv3.serialization.gson.ExcludeFromReplies;
|
||||
import net.frozenorb.apiv3.serialization.jackson.UuidJsonDeserializer;
|
||||
import net.frozenorb.apiv3.serialization.jackson.UuidJsonSerializer;
|
||||
import net.frozenorb.apiv3.unsorted.BlockingCallback;
|
||||
import net.frozenorb.apiv3.unsorted.Permissions;
|
||||
import net.frozenorb.apiv3.util.*;
|
||||
import org.bson.Document;
|
||||
|
||||
@ -187,13 +191,13 @@ public final class User {
|
||||
if (!newUsername.equals(lastUsername)) {
|
||||
this.lastUsername = newUsername;
|
||||
|
||||
// TODO: FIX MOJANG API CALL
|
||||
User withNewUsername;
|
||||
|
||||
while ((withNewUsername = User.findByLastUsernameSync(newUsername)) != null) {
|
||||
BlockingCallback<String> callback = new BlockingCallback<>();
|
||||
MojangUtils.getName(withNewUsername.getId(), callback);
|
||||
withNewUsername.updateUsername(callback.get());
|
||||
withNewUsername.save();
|
||||
}
|
||||
}
|
||||
|
||||
@ -265,7 +269,6 @@ public final class User {
|
||||
return getHighestRankScoped(null, Grant.findByUserSync(this));
|
||||
}
|
||||
|
||||
// TODO: Clean
|
||||
// This is only used to help batch requests to mongo
|
||||
public Rank getHighestRankScoped(ServerGroup serverGroup, Iterable<Grant> grants) {
|
||||
Rank highest = null;
|
||||
@ -289,7 +292,6 @@ public final class User {
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: Clean
|
||||
public Map<ServerGroup, Rank> getHighestRanks() {
|
||||
Map<ServerGroup, Rank> highestRanks = new HashMap<>();
|
||||
Rank defaultRank = Rank.findById("default");
|
||||
@ -318,6 +320,7 @@ public final class User {
|
||||
|
||||
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();
|
||||
|
||||
@ -334,6 +337,14 @@ public final class User {
|
||||
});
|
||||
|
||||
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);
|
||||
@ -342,6 +353,7 @@ public final class User {
|
||||
}
|
||||
});
|
||||
} else {
|
||||
ipIntelFuture.complete(null);
|
||||
ipBansFuture.complete(ImmutableSet.of());
|
||||
}
|
||||
|
||||
@ -353,13 +365,14 @@ public final class User {
|
||||
}
|
||||
});
|
||||
|
||||
CompositeFuture.all(punishmentsFuture, ipBansFuture, grantsFuture).setHandler((result) -> {
|
||||
CompositeFuture.all(punishmentsFuture, ipIntelFuture, ipBansFuture, grantsFuture).setHandler((result) -> {
|
||||
if (result.succeeded()) {
|
||||
Iterable<Punishment> punishments = result.result().result(0);
|
||||
Iterable<IpBan> ipBans = result.result().result(1);
|
||||
Iterable<Grant> grants = result.result().result(2);
|
||||
IpIntel ipIntel = result.result().result(1);
|
||||
Iterable<IpBan> ipBans = result.result().result(2);
|
||||
Iterable<Grant> grants = result.result().result(3);
|
||||
|
||||
callback.onResult(createLoginInfo(server, punishments, ipBans, grants), null);
|
||||
callback.onResult(createLoginInfo(server, ipIntel, punishments, ipBans, grants), null);
|
||||
} else {
|
||||
callback.onResult(null, result.cause());
|
||||
}
|
||||
@ -367,7 +380,7 @@ public final class User {
|
||||
}
|
||||
|
||||
// This is only used to help batch requests to mongo
|
||||
public Map<String, Object> createLoginInfo(Server server, Iterable<Punishment> punishments, Iterable<IpBan> ipBans, Iterable<Grant> grants) {
|
||||
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;
|
||||
@ -414,6 +427,26 @@ public final class User {
|
||||
"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.
|
||||
|
@ -130,8 +130,8 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
|
||||
user.save();
|
||||
}
|
||||
|
||||
// TODO: Provide IPs for ip ban lookup
|
||||
response.put(uuid.toString(), user.createLoginInfo(server, punishments.get(uuid), ImmutableList.of(), grants.get(uuid)));
|
||||
// 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);
|
||||
|
@ -7,5 +7,6 @@ public class Permissions {
|
||||
|
||||
public static final String PROTECTED_PUNISHMENT = "minehq.punishment.protected";
|
||||
public static final String SIGN_API_REQUEST = "apiv3.signRequest";
|
||||
public static final String BYPASS_VPN_CHECK = "minehq.vpn.bypass";
|
||||
|
||||
}
|
Loading…
Reference in New Issue
Block a user