Add test for IP manager + create captcha manager (still unused)

This commit is contained in:
ljacqu 2016-03-03 09:32:25 +01:00
parent aeb8307a46
commit fd8db2cd51
4 changed files with 209 additions and 1 deletions

View File

@ -0,0 +1,81 @@
package fr.xephi.authme.manager;
import fr.xephi.authme.security.RandomString;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.SecuritySettings;
import java.util.concurrent.ConcurrentHashMap;
/**
* Manager for the handling of captchas.
*/
public class CaptchaManager {
private final int threshold;
private final int captchaLength;
private final ConcurrentHashMap<String, Integer> playerCounts;
private final ConcurrentHashMap<String, String> captchaCodes;
public CaptchaManager(NewSetting settings) {
this.playerCounts = new ConcurrentHashMap<>();
this.captchaCodes = new ConcurrentHashMap<>();
this.threshold = settings.getProperty(SecuritySettings.MAX_LOGIN_TRIES_BEFORE_CAPTCHA);
this.captchaLength = settings.getProperty(SecuritySettings.CAPTCHA_LENGTH);
}
public void increaseCount(String player) {
String playerLower = player.toLowerCase();
Integer currentCount = playerCounts.get(playerLower);
if (currentCount == null) {
playerCounts.put(playerLower, 1);
} else {
playerCounts.put(playerLower, currentCount + 1);
}
}
/**
* Return whether the given player is required to solve a captcha.
*
* @param player The player to verify
* @return True if the player has to solve a captcha, false otherwise
*/
public boolean isCaptchaRequired(String player) {
Integer count = playerCounts.get(player.toLowerCase());
return count != null && count >= threshold;
}
/**
* Return the captcha code for the player. Creates one if none present, so call only after
* checking with {@link #isCaptchaRequired}.
*
* @param player The player
* @return The code required for the player
*/
public String getCaptchaCode(String player) {
String code = captchaCodes.get(player.toLowerCase());
if (code == null) {
code = RandomString.generate(captchaLength);
captchaCodes.put(player.toLowerCase(), code);
}
return code;
}
/**
* Return whether the supplied code is correct for the given player.
*
* @param player The player to check
* @param code The supplied code
* @return True if the code matches or if no captcha is required for the player, false otherwise
*/
public boolean checkCode(String player, String code) {
String savedCode = captchaCodes.get(player.toLowerCase());
if (savedCode == null) {
return true;
} else if (savedCode.equalsIgnoreCase(code)) {
captchaCodes.remove(player.toLowerCase());
return true;
}
return false;
}
}

View File

@ -60,7 +60,7 @@ public class IpAddressManager {
ipCache.remove(player.toLowerCase());
}
// returns null if IP could not be looked up --> expect that it won't be cached
// returns null if IP could not be looked up
private String getVeryGamesIp(final String plainIp, final int port) {
final String sUrl = String.format("http://monitor-1.verygames.net/api/?action=ipclean-real-ip"
+ "&out=raw&ip=%s&port=%d", plainIp, port);

View File

@ -0,0 +1,63 @@
package fr.xephi.authme.manager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.SecuritySettings;
import org.junit.Test;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Test for {@link CaptchaManager}.
*/
public class CaptchaManagerTest {
@Test
public void shouldAddCounts() {
// given
NewSetting settings = mockSettings(3, 4);
CaptchaManager manager = new CaptchaManager(settings);
String player = "tester";
// when
for (int i = 0; i < 2; ++i) {
manager.increaseCount(player);
}
// then
assertThat(manager.isCaptchaRequired(player), equalTo(false));
manager.increaseCount(player);
assertThat(manager.isCaptchaRequired(player.toUpperCase()), equalTo(true));
assertThat(manager.isCaptchaRequired("otherPlayer"), equalTo(false));
}
@Test
public void shouldCreateAndCheckCaptcha() {
// given
String player = "Miner";
NewSetting settings = mockSettings(1, 4);
CaptchaManager manager = new CaptchaManager(settings);
String captchaCode = manager.getCaptchaCode(player);
// when
boolean badResult = manager.checkCode(player, "wrong_code");
boolean goodResult = manager.checkCode(player, captchaCode);
// then
assertThat(captchaCode.length(), equalTo(4));
assertThat(badResult, equalTo(false));
assertThat(goodResult, equalTo(true));
// Supplying correct code should clear the entry, and any code should be valid if no entry is present
assertThat(manager.checkCode(player, "bogus"), equalTo(true));
}
private static NewSetting mockSettings(int maxTries, int captchaLength) {
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(SecuritySettings.MAX_LOGIN_TRIES_BEFORE_CAPTCHA)).willReturn(maxTries);
given(settings.getProperty(SecuritySettings.CAPTCHA_LENGTH)).willReturn(captchaLength);
return settings;
}
}

View File

@ -0,0 +1,64 @@
package fr.xephi.authme.manager;
import fr.xephi.authme.settings.NewSetting;
import fr.xephi.authme.settings.properties.HooksSettings;
import org.bukkit.entity.Player;
import org.junit.Test;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
/**
* Test for {@link IpAddressManager}.
*/
public class IpAddressManagerTest {
@Test
public void shouldRetrieveFromCache() {
// given
IpAddressManager ipAddressManager = new IpAddressManager(mockSettings(false));
ipAddressManager.addCache("Test", "my test IP");
// when
String result = ipAddressManager.getPlayerIp(mockPlayer("test", "123.123.123.123"));
// then
assertThat(result, equalTo("my test IP"));
}
@Test
public void shouldReturnPlainIp() {
// given
IpAddressManager ipAddressManager = new IpAddressManager(mockSettings(false));
// when
String result = ipAddressManager.getPlayerIp(mockPlayer("bobby", "8.8.8.8"));
// then
assertThat(result, equalTo("8.8.8.8"));
}
private static NewSetting mockSettings(boolean useVeryGames) {
NewSetting settings = mock(NewSetting.class);
given(settings.getProperty(HooksSettings.ENABLE_VERYGAMES_IP_CHECK)).willReturn(useVeryGames);
return settings;
}
private static Player mockPlayer(String name, String ip) {
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
InetAddress inetAddress = mock(InetAddress.class);
given(inetAddress.getHostAddress()).willReturn(ip);
InetSocketAddress inetSocketAddress = new InetSocketAddress(inetAddress, 8093);
given(player.getAddress()).willReturn(inetSocketAddress);
return player;
}
}