diff --git a/pom.xml b/pom.xml index 3d12dbf..ebdc559 100644 --- a/pom.xml +++ b/pom.xml @@ -109,7 +109,7 @@ 2.7.0 - + com.warrenstrange googleauth diff --git a/src/main/java/net/frozenorb/apiv3/APIv3.java b/src/main/java/net/frozenorb/apiv3/APIv3.java index 80d4b90..039085e 100644 --- a/src/main/java/net/frozenorb/apiv3/APIv3.java +++ b/src/main/java/net/frozenorb/apiv3/APIv3.java @@ -25,6 +25,7 @@ import io.vertx.core.http.HttpHeaders; import io.vertx.core.http.HttpMethod; import io.vertx.core.http.HttpServer; import io.vertx.core.http.HttpServerOptions; +import io.vertx.core.net.JksOptions; import io.vertx.ext.web.Router; import io.vertx.ext.web.RoutingContext; import io.vertx.ext.web.handler.BodyHandler; @@ -218,7 +219,8 @@ public final class APIv3 extends AbstractVerticle { private void setupHttpServer() { HttpServer webServer = vertx.createHttpServer( new HttpServerOptions() - //.setSsl(true) // TODO + //.setSsl(true) + //.setKeyStoreOptions(new JksOptions().setPath("c:\\Users\\cmcdonald\\Desktop\\apiv3.jks").setPassword("password")) .setCompressionSupported(true) ); diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java index 27bb487..3078e28 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserSetupTOTP.java @@ -4,6 +4,7 @@ import com.google.common.collect.ImmutableMap; import com.mongodb.client.result.UpdateResult; import com.warrenstrange.googleauth.GoogleAuthenticatorKey; 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.model.User; @@ -24,20 +25,27 @@ public final class POSTUserSetupTotp implements Handler { } if (user.getTotpSecret() != null) { - ErrorUtils.respondInvalidInput(ctx, "User provided already has TOTP code set."); + ErrorUtils.respondInvalidInput(ctx, "User provided already has totp setup."); return; } - GoogleAuthenticatorKey generated = TotpUtils.generateTotpSecret(); + JsonObject requestBody = ctx.getBodyAsJson(); + String secret = requestBody.getString("secret"); + int code = requestBody.getInteger("code"); - user.setTotpSecret(generated.getKey()); - BlockingCallback callback = new BlockingCallback<>(); - user.save(callback); - callback.get(); + if (TotpUtils.authorizeUser(secret, code)) { + user.setTotpSecret(secret); + BlockingCallback callback = new BlockingCallback<>(); + user.save(callback); + callback.get(); - APIv3.respondJson(ctx, ImmutableMap.of( - "qrCode", TotpUtils.getQrCodeUrl(user, generated) - )); + APIv3.respondJson(ctx, ImmutableMap.of( + "success", true, + "message", "Totp code set." + )); + } else { + ErrorUtils.respondInvalidInput(ctx, "Confirmation code provided did not match."); + } } } \ No newline at end of file diff --git a/src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java index 313525a..9023183 100644 --- a/src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java +++ b/src/main/java/net/frozenorb/apiv3/route/users/POSTUserVerifyTOTP.java @@ -26,7 +26,7 @@ public final class POSTUserVerifyTotp implements Handler { } if (user.getTotpSecret() == null) { - ErrorUtils.respondInvalidInput(ctx, "User provided does not have TOTP code set."); + ErrorUtils.respondInvalidInput(ctx, "User provided does not have totp code set."); return; } @@ -45,7 +45,7 @@ public final class POSTUserVerifyTotp implements Handler { if (recentlyUsedCallback.get()) { APIv3.respondJson(ctx, ImmutableMap.of( "authorized", false, - "message", "TOTP code was recently used." + "message", "Totp code was recently used." )); return; } @@ -63,12 +63,12 @@ public final class POSTUserVerifyTotp implements Handler { APIv3.respondJson(ctx, ImmutableMap.of( "authorized", true, - "message", "Valid TOTP code provided." + "message", "Valid totp code provided." )); } else { APIv3.respondJson(ctx, ImmutableMap.of( "authorized", false, - "message", "TOTP code was not valid." + "message", "Totp code was not valid." )); } } diff --git a/src/main/java/net/frozenorb/apiv3/util/TotpUtils.java b/src/main/java/net/frozenorb/apiv3/util/TotpUtils.java index b6f3062..f2f8ec8 100644 --- a/src/main/java/net/frozenorb/apiv3/util/TotpUtils.java +++ b/src/main/java/net/frozenorb/apiv3/util/TotpUtils.java @@ -3,8 +3,6 @@ package net.frozenorb.apiv3.util; import com.mongodb.async.SingleResultCallback; import com.warrenstrange.googleauth.GoogleAuthenticator; import com.warrenstrange.googleauth.GoogleAuthenticatorConfig; -import com.warrenstrange.googleauth.GoogleAuthenticatorKey; -import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator; import io.vertx.redis.RedisClient; import io.vertx.redis.RedisOptions; import lombok.experimental.UtilityClass; @@ -23,20 +21,8 @@ public class TotpUtils { .setPort(Integer.parseInt(APIv3.getConfig().getProperty("redis.port"))) ); - public static GoogleAuthenticatorKey generateTotpSecret() { - return googleAuthenticator.createCredentials(); - } - - public static boolean authorizeUser(User user, int code) { - return googleAuthenticator.authorize(user.getTotpSecret(), code); - } - - public static String getQrCodeUrl(User user, GoogleAuthenticatorKey secret) { - return GoogleAuthenticatorQRGenerator.getOtpAuthURL( - "MineHQ Network", - user.getLastUsername(), - secret - ); + public static boolean authorizeUser(String secret, int code) { + return googleAuthenticator.authorize(secret, code); } public static void isPreAuthorized(User user, String ip, SingleResultCallback callback) { @@ -68,7 +54,7 @@ public class TotpUtils { } public static void wasRecentlyUsed(User user, int code, SingleResultCallback callback) { - redisClient.exists(user.getId() + ":recentTOTPCodes:" + code, (result) -> { + redisClient.exists(user.getId() + ":recentTotpCodes:" + code, (result) -> { if (result.succeeded()) { callback.onResult(result.result() == 1 , null); } else { @@ -78,7 +64,7 @@ public class TotpUtils { } public static void markRecentlyUsed(User user, int code, SingleResultCallback callback) { - String key = user.getId() + ":recentTOTPCodes:" + code; + String key = user.getId() + ":recentTotpCodes:" + code; redisClient.set(key, "", (result) -> { if (result.succeeded()) {