Add ip validations where needed

This commit is contained in:
Colin McDonald 2016-07-25 20:58:52 -04:00
parent e827a30131
commit 4b0d66985e
14 changed files with 115 additions and 19 deletions

10
pom.xml
View File

@ -67,27 +67,27 @@
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-core</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-web</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-redis-client</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-circuit-breaker</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
</dependency>
<dependency>
<groupId>io.vertx</groupId>
<artifactId>vertx-dropwizard-metrics</artifactId>
<version>3.3.1</version>
<version>3.3.2</version>
</dependency>
<!-- Google Libs -->

View File

@ -105,6 +105,7 @@ import net.frozenorb.apiv3.serialization.mongodb.UuidCodecProvider;
import net.frozenorb.apiv3.util.EmailUtils;
import net.frozenorb.apiv3.util.MojangUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.UserSessionUtils;
import org.bson.Document;
import org.bson.codecs.BsonValueCodecProvider;
import org.bson.codecs.DocumentCodecProvider;
@ -139,6 +140,29 @@ public final class APIv3 extends AbstractVerticle {
setupMetrics();
setupHttpServer();
UserSessionUtils.setupRedis();
try {
Thread.sleep(2000L);
} catch (Exception ex) {
ex.printStackTrace();
}
UserSessionUtils.createSession(UUID.randomUUID(), "192.168.1.1", (v, i) -> {
if (i == null) {
System.out.println("a: " + v);
} else {
i.printStackTrace();
}
});
UserSessionUtils.createSession(UUID.randomUUID(), "::1", (v, i) -> {
if (i == null) {
System.out.println("b: " + v);
} else {
i.printStackTrace();
}
});
/*User.findAll((users, error) -> {
if (error != null) {
error.printStackTrace();

View File

@ -8,6 +8,7 @@ import lombok.extern.slf4j.Slf4j;
import net.frozenorb.apiv3.actor.Actor;
import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.UserSessionUtils;
@Slf4j
@ -30,6 +31,11 @@ public final class WebsiteUserSessionHandler implements Handler<RoutingContext>
String userSession = ctx.request().getHeader("MHQ-UserSession");
String userIp = ctx.request().getHeader("MHQ-UserIp");
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid.");
return;
}
UserSessionUtils.sessionExists(userIp, userSession, (exists, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);

View File

@ -9,6 +9,7 @@ import net.frozenorb.apiv3.auditLog.AuditLog;
import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.PasswordUtils;
import net.frozenorb.apiv3.util.SyncUtils;
@ -57,8 +58,14 @@ public final class POSTEmailTokensIdConfirm implements Handler<RoutingContext> {
user.completeEmailRegistration(user.getPendingEmail());
user.updatePassword(password);
SyncUtils.<Void>runBlocking(v -> user.save(v));
String userIp = requestBody.getString("userIp");
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_CONFIRM_EMAIL, (ignored, error) -> {
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_CONFIRM_EMAIL, (ignored, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {

View File

@ -5,6 +5,7 @@ import io.vertx.ext.web.RoutingContext;
import net.frozenorb.apiv3.APIv3;
import net.frozenorb.apiv3.model.IpBan;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.UuidUtils;
import org.bson.Document;
@ -14,8 +15,14 @@ public final class GETIpBans implements Handler<RoutingContext> {
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"));
String userIp = ctx.request().getParam("userIp");
IpBan.findPaginated(ctx.request().getParam("userIp") == null ? new Document() : new Document("userIp", UuidUtils.parseUuid(ctx.request().getParam("user"))), skip, pageSize, (grants, error) -> {
if (userIp != null && !IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
IpBan.findPaginated(userIp == null ? new Document() : new Document("userIp", userIp), skip, pageSize, (grants, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {

View File

@ -14,6 +14,7 @@ import net.frozenorb.apiv3.model.Punishment;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.Permissions;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import java.time.Instant;
@ -96,6 +97,9 @@ public final class POSTPunishments implements Handler<RoutingContext> {
if (latestIpLogEntry != null) {
userIp = latestIpLogEntry.getUserIp();
}
} else if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid.");
return;
}
if (addedBy != null) {

View File

@ -15,6 +15,7 @@ import net.frozenorb.apiv3.actor.ActorType;
import net.frozenorb.apiv3.model.*;
import net.frozenorb.apiv3.unsorted.MongoToVertxCallback;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.PermissionUtils;
import net.frozenorb.apiv3.util.UuidUtils;
@ -216,9 +217,10 @@ public final class POSTServersHeartbeat implements Handler<RoutingContext> {
players.forEach((entry) -> {
UUID uuid = UuidUtils.parseUuid(entry.getKey());
JsonObject data = (JsonObject) entry.getValue();
String userIp = data.getString("userIp");
if (UuidUtils.isAcceptableUuid(uuid)) {
result.put(uuid, data.getString("userIp"));
if (UuidUtils.isAcceptableUuid(uuid) && IpUtils.isValidIp(userIp)) {
result.put(uuid, userIp);
}
});

View File

@ -7,6 +7,7 @@ import net.frozenorb.apiv3.auditLog.AuditLog;
import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.UserSessionUtils;
@ -41,6 +42,11 @@ public final class GETUsersIdVerifyPassword implements Handler<RoutingContext> {
boolean authorized = user.checkPassword(ctx.request().getParam("password"));
String userIp = ctx.request().getParam("userIp");
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "IP address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, authorized ? AuditLogActionType.USER_LOGIN_SUCCESS : AuditLogActionType.USER_LOGIN_FAIL, (ignored, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);

View File

@ -10,10 +10,7 @@ import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.RequiresTotpResult;
import net.frozenorb.apiv3.unsorted.TotpAuthorizationResult;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.PasswordUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.UserSessionUtils;
import net.frozenorb.apiv3.util.*;
import java.util.concurrent.TimeUnit;
@ -86,8 +83,14 @@ public final class POSTUsersIdChangePassword implements Handler<RoutingContext>
user.updatePassword(newPassword);
SyncUtils.<Void>runBlocking(v -> user.save(v));
SyncUtils.<Void>runBlocking(v -> UserSessionUtils.invalidateAllSessions(user.getId(), v));
String userIp = requestBody.getString("userIp");
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_CHANGE_PASSWORD, (ignored, error) -> {
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_CHANGE_PASSWORD, (ignored, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {

View File

@ -9,6 +9,7 @@ import net.frozenorb.apiv3.auditLog.AuditLog;
import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import java.util.concurrent.TimeUnit;
@ -61,8 +62,14 @@ public final class POSTUsersIdConfirmPhone implements Handler<RoutingContext> {
user.completePhoneRegistration(user.getPendingPhone());
SyncUtils.<Void>runBlocking(v -> user.save(v));
String userIp = requestBody.getString("userIp");
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_CONFIRM_PHONE, (ignored, error) -> {
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_CONFIRM_PHONE, (ignored, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {

View File

@ -11,6 +11,7 @@ import net.frozenorb.apiv3.model.NotificationTemplate;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.Notification;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import java.util.Map;
@ -47,8 +48,14 @@ public final class POSTUsersIdPasswordReset implements Handler<RoutingContext> {
ErrorUtils.respondInternalError(ctx, error);
} else {
JsonObject requestBody = ctx.getBodyAsJson();
String userIp = requestBody.getString("userIp");
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_PASSWORD_RESET, (ignored2, error2) -> {
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_PASSWORD_RESET, (ignored2, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {

View File

@ -12,6 +12,7 @@ import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.Notification;
import net.frozenorb.apiv3.util.EmailUtils;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import java.util.Map;
@ -73,7 +74,14 @@ public final class POSTUsersIdRegisterEmail implements Handler<RoutingContext> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_REGISTER_EMAIL, (ignored2, error2) -> {
String userIp = requestBody.getString("userIp");
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_REGISTER_EMAIL, (ignored2, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {

View File

@ -13,6 +13,7 @@ import net.frozenorb.apiv3.model.PhoneIntel;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.unsorted.Notification;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.PhoneUtils;
import net.frozenorb.apiv3.util.SyncUtils;
@ -77,7 +78,14 @@ public final class POSTUsersIdRegisterPhone implements Handler<RoutingContext> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_REGISTER_PHONE, (ignored2, error2) -> {
String userIp = requestBody.getString("userIp");
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_REGISTER_PHONE, (ignored2, error2) -> {
if (error2 != null) {
ErrorUtils.respondInternalError(ctx, error2);
} else {

View File

@ -9,6 +9,7 @@ import net.frozenorb.apiv3.auditLog.AuditLog;
import net.frozenorb.apiv3.auditLog.AuditLogActionType;
import net.frozenorb.apiv3.model.User;
import net.frozenorb.apiv3.util.ErrorUtils;
import net.frozenorb.apiv3.util.IpUtils;
import net.frozenorb.apiv3.util.SyncUtils;
import net.frozenorb.apiv3.util.TotpUtils;
@ -34,8 +35,14 @@ public final class POSTUsersIdSetupTotp implements Handler<RoutingContext> {
if (TotpUtils.authorizeUser(secret, totpCode)) {
user.setTotpSecret(secret);
SyncUtils.<Void>runBlocking(v -> user.save(v));
String userIp = requestBody.getString("userIp");
AuditLog.log(user.getId(), requestBody.getString("userIp"), ctx, AuditLogActionType.USER_SETUP_TOTP, (ignored, error) -> {
if (!IpUtils.isValidIp(userIp)) {
ErrorUtils.respondInvalidInput(ctx, "Ip address \"" + userIp + "\" is not valid.");
return;
}
AuditLog.log(user.getId(), userIp, ctx, AuditLogActionType.USER_SETUP_TOTP, (ignored, error) -> {
if (error != null) {
ErrorUtils.respondInternalError(ctx, error);
} else {