#1141 2FA implementation fixes
- Merge TotpService into TotpAuthenticator - Add missing tests - Migrate old 2fa enabled key to new one
This commit is contained in:
@@ -33,13 +33,17 @@ public class ConfirmTotpCommand extends PlayerCommand {
|
||||
messages.send(player, MessageKey.REGISTER_MESSAGE);
|
||||
} else if (auth.getTotpKey() != null) {
|
||||
messages.send(player, MessageKey.TWO_FACTOR_ALREADY_ENABLED);
|
||||
} else {
|
||||
verifyTotpCodeConfirmation(player, arguments.get(0));
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyTotpCodeConfirmation(Player player, String inputTotpCode) {
|
||||
final TotpGenerationResult totpDetails = generateTotpService.getGeneratedTotpKey(player);
|
||||
if (totpDetails == null) {
|
||||
messages.send(player, MessageKey.TWO_FACTOR_ENABLE_ERROR_NO_CODE);
|
||||
} else {
|
||||
boolean isCodeValid = generateTotpService.isTotpCodeCorrectForGeneratedTotpKey(player, arguments.get(0));
|
||||
boolean isCodeValid = generateTotpService.isTotpCodeCorrectForGeneratedTotpKey(player, inputTotpCode);
|
||||
if (isCodeValid) {
|
||||
generateTotpService.removeGenerateTotpKey(player);
|
||||
dataSource.setTotpKey(player.getName(), totpDetails.getTotpKey());
|
||||
|
||||
@@ -5,7 +5,7 @@ import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.message.Messages;
|
||||
import fr.xephi.authme.security.totp.TotpService;
|
||||
import fr.xephi.authme.security.totp.TotpAuthenticator;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -20,7 +20,7 @@ public class RemoveTotpCommand extends PlayerCommand {
|
||||
private DataSource dataSource;
|
||||
|
||||
@Inject
|
||||
private TotpService totpService;
|
||||
private TotpAuthenticator totpAuthenticator;
|
||||
|
||||
@Inject
|
||||
private Messages messages;
|
||||
@@ -31,7 +31,7 @@ public class RemoveTotpCommand extends PlayerCommand {
|
||||
if (auth.getTotpKey() == null) {
|
||||
messages.send(player, MessageKey.TWO_FACTOR_NOT_ENABLED_ERROR);
|
||||
} else {
|
||||
if (totpService.verifyCode(auth, arguments.get(0))) {
|
||||
if (totpAuthenticator.checkCode(auth, arguments.get(0))) {
|
||||
dataSource.removeTotpKey(auth.getNickname());
|
||||
messages.send(player, MessageKey.TWO_FACTOR_REMOVED_SUCCESS);
|
||||
} else {
|
||||
|
||||
@@ -10,7 +10,7 @@ import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.message.MessageKey;
|
||||
import fr.xephi.authme.message.Messages;
|
||||
import fr.xephi.authme.process.login.AsynchronousLogin;
|
||||
import fr.xephi.authme.security.totp.TotpService;
|
||||
import fr.xephi.authme.security.totp.TotpAuthenticator;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
@@ -31,7 +31,7 @@ public class TotpCodeCommand extends PlayerCommand {
|
||||
private Messages messages;
|
||||
|
||||
@Inject
|
||||
private TotpService totpService;
|
||||
private TotpAuthenticator totpAuthenticator;
|
||||
|
||||
@Inject
|
||||
private DataSource dataSource;
|
||||
@@ -61,7 +61,7 @@ public class TotpCodeCommand extends PlayerCommand {
|
||||
}
|
||||
|
||||
private void processCode(Player player, PlayerAuth auth, String inputCode) {
|
||||
boolean isCodeValid = totpService.verifyCode(auth, inputCode);
|
||||
boolean isCodeValid = totpAuthenticator.checkCode(auth, inputCode);
|
||||
if (isCodeValid) {
|
||||
asynchronousLogin.performLogin(player, auth);
|
||||
} else {
|
||||
|
||||
@@ -5,7 +5,7 @@ import ch.jalu.configme.configurationdata.ConfigurationData;
|
||||
import ch.jalu.configme.configurationdata.PropertyListBuilder;
|
||||
import ch.jalu.configme.properties.Property;
|
||||
import ch.jalu.configme.properties.StringProperty;
|
||||
import ch.jalu.configme.resource.YamlFileResource;
|
||||
import ch.jalu.configme.resource.PropertyResource;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
@@ -57,14 +57,16 @@ public class MessageUpdater {
|
||||
*/
|
||||
private boolean migrateAndSave(File userFile, JarMessageSource jarMessageSource) {
|
||||
// YamlConfiguration escapes all special characters when saving, making the file hard to use, so use ConfigMe
|
||||
YamlFileResource userResource = new MigraterYamlFileResource(userFile);
|
||||
PropertyResource userResource = new MigraterYamlFileResource(userFile);
|
||||
|
||||
// Step 1: Migrate any old keys in the file to the new paths
|
||||
boolean movedOldKeys = migrateOldKeys(userResource);
|
||||
// Step 2: Take any missing messages from the message files shipped in the AuthMe JAR
|
||||
// Step 2: Perform newer migrations
|
||||
boolean movedNewerKeys = migrateKeys(userResource);
|
||||
// Step 3: Take any missing messages from the message files shipped in the AuthMe JAR
|
||||
boolean addedMissingKeys = addMissingKeys(jarMessageSource, userResource);
|
||||
|
||||
if (movedOldKeys || addedMissingKeys) {
|
||||
if (movedOldKeys || movedNewerKeys || addedMissingKeys) {
|
||||
backupMessagesFile(userFile);
|
||||
|
||||
SettingsManager settingsManager = new SettingsManager(userResource, null, CONFIGURATION_DATA);
|
||||
@@ -75,7 +77,19 @@ public class MessageUpdater {
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean migrateOldKeys(YamlFileResource userResource) {
|
||||
private boolean migrateKeys(PropertyResource userResource) {
|
||||
return moveIfApplicable(userResource, "misc.two_factor_create", MessageKey.TWO_FACTOR_CREATE.getKey());
|
||||
}
|
||||
|
||||
private static boolean moveIfApplicable(PropertyResource resource, String oldPath, String newPath) {
|
||||
if (resource.getString(newPath) == null && resource.getString(oldPath) != null) {
|
||||
resource.setValue(newPath, resource.getString(oldPath));
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
private boolean migrateOldKeys(PropertyResource userResource) {
|
||||
boolean hasChange = OldMessageKeysMigrater.migrateOldPaths(userResource);
|
||||
if (hasChange) {
|
||||
ConsoleLogger.info("Old keys have been moved to the new ones in your messages_xx.yml file");
|
||||
@@ -83,7 +97,7 @@ public class MessageUpdater {
|
||||
return hasChange;
|
||||
}
|
||||
|
||||
private boolean addMissingKeys(JarMessageSource jarMessageSource, YamlFileResource userResource) {
|
||||
private boolean addMissingKeys(JarMessageSource jarMessageSource, PropertyResource userResource) {
|
||||
List<String> addedKeys = new ArrayList<>();
|
||||
for (Property<?> property : CONFIGURATION_DATA.getProperties()) {
|
||||
final String key = property.getPath();
|
||||
|
||||
@@ -4,13 +4,14 @@ import com.warrenstrange.googleauth.GoogleAuthenticator;
|
||||
import com.warrenstrange.googleauth.GoogleAuthenticatorKey;
|
||||
import com.warrenstrange.googleauth.GoogleAuthenticatorQRGenerator;
|
||||
import com.warrenstrange.googleauth.IGoogleAuthenticator;
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
import fr.xephi.authme.service.BukkitService;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Provides rudimentary TOTP functions (wraps third-party TOTP implementation).
|
||||
* Provides TOTP functions (wrapping a third-party TOTP implementation).
|
||||
*/
|
||||
public class TotpAuthenticator {
|
||||
|
||||
@@ -30,6 +31,10 @@ public class TotpAuthenticator {
|
||||
return new GoogleAuthenticator();
|
||||
}
|
||||
|
||||
public boolean checkCode(PlayerAuth auth, String totpCode) {
|
||||
return checkCode(auth.getTotpKey(), totpCode);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given input code matches for the provided TOTP key.
|
||||
*
|
||||
@@ -58,7 +63,7 @@ public class TotpAuthenticator {
|
||||
private final String totpKey;
|
||||
private final String authenticatorQrCodeUrl;
|
||||
|
||||
TotpGenerationResult(String totpKey, String authenticatorQrCodeUrl) {
|
||||
public TotpGenerationResult(String totpKey, String authenticatorQrCodeUrl) {
|
||||
this.totpKey = totpKey;
|
||||
this.authenticatorQrCodeUrl = authenticatorQrCodeUrl;
|
||||
}
|
||||
|
||||
@@ -1,18 +0,0 @@
|
||||
package fr.xephi.authme.security.totp;
|
||||
|
||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||
|
||||
import javax.inject.Inject;
|
||||
|
||||
/**
|
||||
* Service for TOTP actions.
|
||||
*/
|
||||
public class TotpService {
|
||||
|
||||
@Inject
|
||||
private TotpAuthenticator totpAuthenticator;
|
||||
|
||||
public boolean verifyCode(PlayerAuth auth, String totpCode) {
|
||||
return totpAuthenticator.checkCode(auth.getTotpKey(), totpCode);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user