#930 Registration captcha: update message shown to player on failed captcha

- Show message with new captcha code when a captcha has failed
- Requires implementation of circular dependency handler (initial draft)
This commit is contained in:
ljacqu
2018-01-05 00:17:22 +01:00
parent c8d82a23e0
commit 7cf3f6d77b
9 changed files with 201 additions and 11 deletions
@@ -72,6 +72,8 @@ public abstract class AbstractCaptchaManager implements SettingsDependent, HasCl
captchaCodes.remove(nameLowerCase);
processSuccessfulCode(nameLowerCase);
return true;
} else {
processUnsuccessfulCode(nameLowerCase);
}
return false;
}
@@ -106,6 +108,14 @@ public abstract class AbstractCaptchaManager implements SettingsDependent, HasCl
*/
protected abstract void processSuccessfulCode(String nameLower);
/**
* Called when a player has failed the captcha code.
*
* @param nameLower the player's name (all lowercase)
*/
protected void processUnsuccessfulCode(String nameLower) {
}
/**
* Returns the number of minutes a generated captcha code should live for before it may expire.
*
@@ -1,8 +1,13 @@
package fr.xephi.authme.data;
import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.initialization.circulardependency.HasCircularDependency;
import fr.xephi.authme.initialization.circulardependency.InjectAfterInitialization;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.SecuritySettings;
import fr.xephi.authme.util.expiring.ExpiringSet;
import org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import javax.inject.Inject;
import java.util.concurrent.TimeUnit;
@@ -10,10 +15,12 @@ import java.util.concurrent.TimeUnit;
/**
* Captcha manager for registration.
*/
public class RegistrationCaptchaManager extends AbstractCaptchaManager {
public class RegistrationCaptchaManager extends AbstractCaptchaManager implements HasCircularDependency {
private static final int MINUTES_VALID_FOR_REGISTRATION = 30;
private LimboService limboService;
private final ExpiringSet<String> verifiedNamesForRegistration =
new ExpiringSet<>(MINUTES_VALID_FOR_REGISTRATION, TimeUnit.MINUTES);
private boolean isEnabled;
@@ -46,8 +53,19 @@ public class RegistrationCaptchaManager extends AbstractCaptchaManager {
verifiedNamesForRegistration.add(nameLower);
}
@Override
protected void processUnsuccessfulCode(String nameLower) {
final Player player = Bukkit.getPlayerExact(nameLower); // TODO #930: Pass in player!
limboService.resetMessageTask(player, false);
}
@Override
protected int minutesBeforeCodeExpires(Settings settings) {
return MINUTES_VALID_FOR_REGISTRATION;
}
@InjectAfterInitialization
public void setLimboService(LimboService limboService) {
this.limboService = limboService;
}
}
@@ -1,5 +1,6 @@
package fr.xephi.authme.data.limbo;
import fr.xephi.authme.data.RegistrationCaptchaManager;
import fr.xephi.authme.data.auth.PlayerCache;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.message.Messages;
@@ -33,6 +34,9 @@ class LimboPlayerTaskManager {
@Inject
private PlayerCache playerCache;
@Inject
private RegistrationCaptchaManager registrationCaptchaManager;
LimboPlayerTaskManager() {
}
@@ -41,14 +45,14 @@ class LimboPlayerTaskManager {
*
* @param player the player
* @param limbo the associated limbo player of the player
* @param isRegistered whether the player is registered or not
* (false shows "please register", true shows "please log in")
* @param isRegistered whether the player is registered or not (needed to determine the message in the task)
*/
void registerMessageTask(Player player, LimboPlayer limbo, boolean isRegistered) {
int interval = settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL);
MessageKey key = getMessageKey(isRegistered);
MessageResult messageResult = getMessageKey(player.getName(), isRegistered);
if (interval > 0) {
MessageTask messageTask = new MessageTask(player, messages.retrieve(key));
String[] joinMessage = messages.retrieveSingle(messageResult.messageKey, messageResult.args).split("\n");
MessageTask messageTask = new MessageTask(player, joinMessage);
bukkitService.runTaskTimer(messageTask, 2 * TICKS_PER_SECOND, interval * TICKS_PER_SECOND);
limbo.setMessageTask(messageTask);
}
@@ -84,14 +88,28 @@ 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
* @return the message key to display to the user
*/
private static MessageKey getMessageKey(boolean isRegistered) {
private MessageResult getMessageKey(String name, boolean isRegistered) {
if (isRegistered) {
return MessageKey.LOGIN_MESSAGE;
return new MessageResult(MessageKey.LOGIN_MESSAGE);
} else if (registrationCaptchaManager.isCaptchaRequired(name)) {
final String captchaCode = registrationCaptchaManager.getCaptchaCodeOrGenerateNew(name);
return new MessageResult(MessageKey.CAPTCHA_FOR_REGISTRATION_REQUIRED, captchaCode);
} else {
return MessageKey.REGISTER_MESSAGE;
return new MessageResult(MessageKey.REGISTER_MESSAGE);
}
}
private static final class MessageResult {
private final MessageKey messageKey;
private final String[] args;
MessageResult(MessageKey messageKey, String... args) {
this.messageKey = messageKey;
this.args = args;
}
}
}