#1141 Move TOTP code during login as separate step: /2fa code

Rough version.
- Introduces a limbo player state on the LimboPlayer, allowing us to add further mandatory actions between successful (password) authentication and the ability to play on the server
This commit is contained in:
ljacqu
2018-03-20 23:06:08 +01:00
parent af6bee59bd
commit 495cfc69a9
18 changed files with 162 additions and 62 deletions
@@ -0,0 +1,11 @@
package fr.xephi.authme.data.limbo;
public enum LimboMessageType {
REGISTER,
LOG_IN,
TOTP_CODE
}
@@ -23,6 +23,7 @@ public class LimboPlayer {
private final float flySpeed;
private BukkitTask timeoutTask = null;
private MessageTask messageTask = null;
private LimboPlayerState state = LimboPlayerState.PASSWORD_REQUIRED;
public LimboPlayer(Location loc, boolean operator, Collection<String> groups, boolean fly, float walkSpeed,
float flySpeed) {
@@ -124,4 +125,12 @@ public class LimboPlayer {
setMessageTask(null);
setTimeoutTask(null);
}
public LimboPlayerState getState() {
return state;
}
public void setState(LimboPlayerState state) {
this.state = state;
}
}
@@ -0,0 +1,11 @@
package fr.xephi.authme.data.limbo;
public enum LimboPlayerState {
PASSWORD_REQUIRED,
TOTP_REQUIRED,
FINISHED
}
@@ -45,11 +45,11 @@ class LimboPlayerTaskManager {
*
* @param player the player
* @param limbo the associated limbo player of the player
* @param isRegistered whether the player is registered or not (needed to determine the message in the task)
* @param messageType message type
*/
void registerMessageTask(Player player, LimboPlayer limbo, boolean isRegistered) {
void registerMessageTask(Player player, LimboPlayer limbo, LimboMessageType messageType) {
int interval = settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
MessageResult result = getMessageKey(player.getName(), isRegistered);
MessageResult result = getMessageKey(player.getName(), messageType);
if (interval > 0) {
String[] joinMessage = messages.retrieveSingle(player, result.messageKey, result.args).split("\n");
MessageTask messageTask = new MessageTask(player, joinMessage);
@@ -89,12 +89,14 @@ class LimboPlayerTaskManager {
* Returns the appropriate message key according to the registration status and settings.
*
* @param name the player's name
* @param isRegistered whether or not the username is registered
* @param messageType the message to show
* @return the message key to display to the user
*/
private MessageResult getMessageKey(String name, boolean isRegistered) {
if (isRegistered) {
private MessageResult getMessageKey(String name, LimboMessageType messageType) {
if (messageType == LimboMessageType.LOG_IN) {
return new MessageResult(MessageKey.LOGIN_MESSAGE);
} else if (messageType == LimboMessageType.TOTP_CODE) {
return new MessageResult(MessageKey.TWO_FACTOR_CODE_REQUIRED);
} else if (registrationCaptchaManager.isCaptchaRequired(name)) {
final String captchaCode = registrationCaptchaManager.getCaptchaCodeOrGenerateNew(name);
return new MessageResult(MessageKey.CAPTCHA_FOR_REGISTRATION_REQUIRED, captchaCode);
@@ -69,7 +69,8 @@ public class LimboService {
LimboPlayer limboPlayer = helper.merge(existingLimbo, limboFromDisk);
limboPlayer = helper.merge(helper.createLimboPlayer(player, isRegistered, location), limboPlayer);
taskManager.registerMessageTask(player, limboPlayer, isRegistered);
taskManager.registerMessageTask(player, limboPlayer,
isRegistered ? LimboMessageType.LOG_IN : LimboMessageType.REGISTER);
taskManager.registerTimeoutTask(player, limboPlayer);
helper.revokeLimboStates(player);
authGroupHandler.setGroup(player, limboPlayer,
@@ -134,7 +135,7 @@ public class LimboService {
Optional<LimboPlayer> limboPlayer = getLimboOrLogError(player, "reset tasks");
limboPlayer.ifPresent(limbo -> {
taskManager.registerTimeoutTask(player, limbo);
taskManager.registerMessageTask(player, limbo, true);
taskManager.registerMessageTask(player, limbo, LimboMessageType.LOG_IN);
});
authGroupHandler.setGroup(player, limboPlayer.orElse(null), AuthGroupType.REGISTERED_UNAUTHENTICATED);
}
@@ -143,11 +144,11 @@ public class LimboService {
* Resets the message task associated with the player's LimboPlayer.
*
* @param player the player to set a new message task for
* @param isRegistered whether or not the player is registered
* @param messageType the message to show for the limbo player
*/
public void resetMessageTask(Player player, boolean isRegistered) {
public void resetMessageTask(Player player, LimboMessageType messageType) {
getLimboOrLogError(player, "reset message task")
.ifPresent(limbo -> taskManager.registerMessageTask(player, limbo, isRegistered));
.ifPresent(limbo -> taskManager.registerMessageTask(player, limbo, messageType));
}
/**