#1141 Check that user is logged in before changing TOTP key

- Use PlayerCache to check that user is logged in where appropriate
- Add log statements
This commit is contained in:
ljacqu
2018-05-13 18:49:40 +02:00
parent 6f2f7a73af
commit 729c567dd5
8 changed files with 244 additions and 35 deletions
@@ -2,7 +2,7 @@ package fr.xephi.authme.command.executable.totp;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
import fr.xephi.authme.security.totp.GenerateTotpService;
@@ -21,16 +21,16 @@ public class AddTotpCommand extends PlayerCommand {
private GenerateTotpService generateTotpService;
@Inject
private DataSource dataSource;
private PlayerCache playerCache;
@Inject
private Messages messages;
@Override
protected void runCommand(Player player, List<String> arguments) {
PlayerAuth auth = dataSource.getAuth(player.getName());
PlayerAuth auth = playerCache.getAuth(player.getName());
if (auth == null) {
messages.send(player, MessageKey.REGISTER_MESSAGE);
messages.send(player, MessageKey.NOT_LOGGED_IN);
} else if (auth.getTotpKey() == null) {
TotpGenerationResult createdTotpInfo = generateTotpService.generateTotpKey(player);
messages.send(player, MessageKey.TWO_FACTOR_CREATE,
@@ -1,7 +1,9 @@
package fr.xephi.authme.command.executable.totp;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
@@ -20,6 +22,9 @@ public class ConfirmTotpCommand extends PlayerCommand {
@Inject
private GenerateTotpService generateTotpService;
@Inject
private PlayerCache playerCache;
@Inject
private DataSource dataSource;
@@ -28,17 +33,17 @@ public class ConfirmTotpCommand extends PlayerCommand {
@Override
protected void runCommand(Player player, List<String> arguments) {
PlayerAuth auth = dataSource.getAuth(player.getName());
PlayerAuth auth = playerCache.getAuth(player.getName());
if (auth == null) {
messages.send(player, MessageKey.REGISTER_MESSAGE);
messages.send(player, MessageKey.NOT_LOGGED_IN);
} else if (auth.getTotpKey() != null) {
messages.send(player, MessageKey.TWO_FACTOR_ALREADY_ENABLED);
} else {
verifyTotpCodeConfirmation(player, arguments.get(0));
verifyTotpCodeConfirmation(player, auth, arguments.get(0));
}
}
private void verifyTotpCodeConfirmation(Player player, String inputTotpCode) {
private void verifyTotpCodeConfirmation(Player player, PlayerAuth auth, String inputTotpCode) {
final TotpGenerationResult totpDetails = generateTotpService.getGeneratedTotpKey(player);
if (totpDetails == null) {
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_ERROR_NO_CODE);
@@ -46,11 +51,21 @@ public class ConfirmTotpCommand extends PlayerCommand {
boolean isCodeValid = generateTotpService.isTotpCodeCorrectForGeneratedTotpKey(player, inputTotpCode);
if (isCodeValid) {
generateTotpService.removeGenerateTotpKey(player);
dataSource.setTotpKey(player.getName(), totpDetails.getTotpKey());
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_SUCCESS);
insertTotpKeyIntoDatabase(player, auth, totpDetails);
} else {
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_ERROR_WRONG_CODE);
}
}
}
private void insertTotpKeyIntoDatabase(Player player, PlayerAuth auth, TotpGenerationResult totpDetails) {
if (dataSource.setTotpKey(player.getName(), totpDetails.getTotpKey())) {
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_SUCCESS);
auth.setTotpKey(totpDetails.getTotpKey());
playerCache.updatePlayer(auth);
ConsoleLogger.info("Player '" + player.getName() + "' has successfully added a TOTP key to their account");
} else {
messages.send(player, MessageKey.ERROR);
}
}
}
@@ -1,7 +1,9 @@
package fr.xephi.authme.command.executable.totp;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
@@ -19,6 +21,9 @@ public class RemoveTotpCommand extends PlayerCommand {
@Inject
private DataSource dataSource;
@Inject
private PlayerCache playerCache;
@Inject
private TotpAuthenticator totpAuthenticator;
@@ -27,16 +32,28 @@ public class RemoveTotpCommand extends PlayerCommand {
@Override
protected void runCommand(Player player, List<String> arguments) {
PlayerAuth auth = dataSource.getAuth(player.getName());
if (auth.getTotpKey() == null) {
PlayerAuth auth = playerCache.getAuth(player.getName());
if (auth == null) {
messages.send(player, MessageKey.NOT_LOGGED_IN);
} else if (auth.getTotpKey() == null) {
messages.send(player, MessageKey.TWO_FACTOR_NOT_ENABLED_ERROR);
} else {
if (totpAuthenticator.checkCode(auth, arguments.get(0))) {
dataSource.removeTotpKey(auth.getNickname());
messages.send(player, MessageKey.TWO_FACTOR_REMOVED_SUCCESS);
removeTotpKeyFromDatabase(player, auth);
} else {
messages.send(player, MessageKey.TWO_FACTOR_INVALID_CODE);
}
}
}
private void removeTotpKeyFromDatabase(Player player, PlayerAuth auth) {
if (dataSource.removeTotpKey(auth.getNickname())) {
auth.setTotpKey(null);
playerCache.updatePlayer(auth);
messages.send(player, MessageKey.TWO_FACTOR_REMOVED_SUCCESS);
ConsoleLogger.info("Player '" + player.getName() + "' removed their TOTP key");
} else {
messages.send(player, MessageKey.ERROR);
}
}
}
@@ -1,5 +1,6 @@
package fr.xephi.authme.command.executable.totp;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.PlayerCommand;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.data.auth.PlayerCache;
@@ -56,6 +57,8 @@ public class TotpCodeCommand extends PlayerCommand {
if (limbo != null && limbo.getState() == LimboPlayerState.TOTP_REQUIRED) {
processCode(player, auth, arguments.get(0));
} else {
ConsoleLogger.debug(() -> "Aborting TOTP check for player '" + player.getName()
+ "'. Invalid limbo state: " + (limbo == null ? "no limbo" : limbo.getState()));
messages.send(player, MessageKey.LOGIN_MESSAGE);
}
}
@@ -63,8 +66,10 @@ public class TotpCodeCommand extends PlayerCommand {
private void processCode(Player player, PlayerAuth auth, String inputCode) {
boolean isCodeValid = totpAuthenticator.checkCode(auth, inputCode);
if (isCodeValid) {
ConsoleLogger.debug("Successfully checked TOTP code for `{0}`", player.getName());
asynchronousLogin.performLogin(player, auth);
} else {
ConsoleLogger.debug("Input TOTP code was invalid for player `{0}`", player.getName());
messages.send(player, MessageKey.TWO_FACTOR_INVALID_CODE);
}
}
@@ -165,6 +165,10 @@ public class PlayerAuth {
return totpKey;
}
public void setTotpKey(String totpKey) {
this.totpKey = totpKey;
}
@Override
public boolean equals(Object obj) {
if (!(obj instanceof PlayerAuth)) {