Modify POST /user/:id/setupTotp to work with adjusted requirements
This commit is contained in:
parent
aa527fa567
commit
aaba9cb369
2
pom.xml
2
pom.xml
@ -109,7 +109,7 @@
|
||||
<version>2.7.0</version>
|
||||
</dependency>
|
||||
|
||||
<!-- TOTP -->
|
||||
<!-- Totp -->
|
||||
<dependency>
|
||||
<groupId>com.warrenstrange</groupId>
|
||||
<artifactId>googleauth</artifactId>
|
||||
|
@ -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)
|
||||
);
|
||||
|
||||
|
@ -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<RoutingContext> {
|
||||
}
|
||||
|
||||
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());
|
||||
if (TotpUtils.authorizeUser(secret, code)) {
|
||||
user.setTotpSecret(secret);
|
||||
BlockingCallback<UpdateResult> callback = new BlockingCallback<>();
|
||||
user.save(callback);
|
||||
callback.get();
|
||||
|
||||
APIv3.respondJson(ctx, ImmutableMap.of(
|
||||
"qrCode", TotpUtils.getQrCodeUrl(user, generated)
|
||||
"success", true,
|
||||
"message", "Totp code set."
|
||||
));
|
||||
} else {
|
||||
ErrorUtils.respondInvalidInput(ctx, "Confirmation code provided did not match.");
|
||||
}
|
||||
}
|
||||
|
||||
}
|
@ -26,7 +26,7 @@ public final class POSTUserVerifyTotp implements Handler<RoutingContext> {
|
||||
}
|
||||
|
||||
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<RoutingContext> {
|
||||
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<RoutingContext> {
|
||||
|
||||
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."
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -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<Boolean> callback) {
|
||||
@ -68,7 +54,7 @@ public class TotpUtils {
|
||||
}
|
||||
|
||||
public static void wasRecentlyUsed(User user, int code, SingleResultCallback<Boolean> 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<Void> callback) {
|
||||
String key = user.getId() + ":recentTOTPCodes:" + code;
|
||||
String key = user.getId() + ":recentTotpCodes:" + code;
|
||||
|
||||
redisClient.set(key, "", (result) -> {
|
||||
if (result.succeeded()) {
|
||||
|
Loading…
Reference in New Issue
Block a user