- Overloaded method with (String, String...) as args was problematic as it could be confusing on its own and also confusing with the (CommandSender, String...) flavor
266 lines
9.9 KiB
Java
266 lines
9.9 KiB
Java
package fr.xephi.authme.data;
|
|
|
|
import fr.xephi.authme.ReflectionTestUtils;
|
|
import fr.xephi.authme.TestHelper;
|
|
import fr.xephi.authme.message.MessageKey;
|
|
import fr.xephi.authme.message.Messages;
|
|
import fr.xephi.authme.service.BukkitService;
|
|
import fr.xephi.authme.settings.Settings;
|
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
|
import fr.xephi.authme.util.expiring.TimedCounter;
|
|
import org.bukkit.entity.Player;
|
|
import org.junit.Test;
|
|
import org.junit.runner.RunWith;
|
|
import org.mockito.ArgumentCaptor;
|
|
import org.mockito.Mock;
|
|
import org.mockito.junit.MockitoJUnitRunner;
|
|
|
|
import java.util.Calendar;
|
|
import java.util.Date;
|
|
import java.util.HashMap;
|
|
import java.util.Map;
|
|
|
|
import static fr.xephi.authme.service.BukkitServiceTestHelper.setBukkitServiceToScheduleSyncDelayedTask;
|
|
import static org.hamcrest.Matchers.contains;
|
|
import static org.hamcrest.Matchers.equalTo;
|
|
import static org.hamcrest.Matchers.lessThan;
|
|
import static org.junit.Assert.assertThat;
|
|
import static org.mockito.ArgumentMatchers.eq;
|
|
import static org.mockito.BDDMockito.given;
|
|
import static org.mockito.Mockito.mock;
|
|
import static org.mockito.Mockito.verify;
|
|
import static org.mockito.Mockito.verifyZeroInteractions;
|
|
|
|
/**
|
|
* Test for {@link TempbanManager}.
|
|
*/
|
|
@RunWith(MockitoJUnitRunner.class)
|
|
public class TempbanManagerTest {
|
|
|
|
private static final long DATE_TOLERANCE_MILLISECONDS = 200L;
|
|
private static final long TEST_EXPIRATION_THRESHOLD = 120_000L;
|
|
|
|
@Mock
|
|
private BukkitService bukkitService;
|
|
|
|
@Mock
|
|
private Messages messages;
|
|
|
|
@Test
|
|
public void shouldAddCounts() {
|
|
// given
|
|
Settings settings = mockSettings(3, 60, "");
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
String address = "192.168.1.1";
|
|
|
|
// when
|
|
manager.increaseCount(address, "Bob");
|
|
manager.increaseCount(address, "Todd");
|
|
|
|
// then
|
|
assertThat(manager.shouldTempban(address), equalTo(false));
|
|
assertHasCount(manager, address, "Bob", 1);
|
|
assertHasCount(manager, address, "Todd", 1);
|
|
manager.increaseCount(address, "Bob");
|
|
assertThat(manager.shouldTempban(address), equalTo(true));
|
|
assertThat(manager.shouldTempban("10.0.0.1"), equalTo(false));
|
|
}
|
|
|
|
@Test
|
|
public void shouldIncreaseAndResetCount() {
|
|
// given
|
|
String address = "192.168.1.2";
|
|
Settings settings = mockSettings(3, 60, "");
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
|
|
// when
|
|
manager.increaseCount(address, "test");
|
|
manager.increaseCount(address, "test");
|
|
manager.increaseCount(address, "test");
|
|
|
|
// then
|
|
assertThat(manager.shouldTempban(address), equalTo(true));
|
|
assertHasCount(manager, address, "test", 3);
|
|
|
|
// when 2
|
|
manager.resetCount(address, "test");
|
|
|
|
// then 2
|
|
assertThat(manager.shouldTempban(address), equalTo(false));
|
|
assertHasNoEntries(manager, address);
|
|
}
|
|
|
|
@Test
|
|
public void shouldNotIncreaseCountForDisabledTempban() {
|
|
// given
|
|
String address = "192.168.1.3";
|
|
Settings settings = mockSettings(1, 5, "");
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_ON_MAX_LOGINS)).willReturn(false);
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
|
|
// when
|
|
manager.increaseCount(address, "username");
|
|
|
|
// then
|
|
assertThat(manager.shouldTempban(address), equalTo(false));
|
|
assertHasNoEntries(manager, address);
|
|
}
|
|
|
|
@Test
|
|
public void shouldNotCheckCountIfTempbanIsDisabled() {
|
|
// given
|
|
String address = "192.168.1.4";
|
|
Settings settings = mockSettings(1, 5, "");
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_ON_MAX_LOGINS)).willReturn(false);
|
|
|
|
// when
|
|
manager.increaseCount(address, "username");
|
|
// assumptions
|
|
assertThat(manager.shouldTempban(address), equalTo(true));
|
|
assertHasCount(manager, address, "username", 1);
|
|
// end assumptions
|
|
manager.reload(settings);
|
|
boolean result = manager.shouldTempban(address);
|
|
|
|
// then
|
|
assertThat(result, equalTo(false));
|
|
}
|
|
|
|
@Test
|
|
public void shouldNotIssueBanIfDisabled() {
|
|
// given
|
|
Settings settings = mockSettings(0, 0, "");
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_ON_MAX_LOGINS)).willReturn(false);
|
|
Player player = mock(Player.class);
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
|
|
// when
|
|
manager.tempbanPlayer(player);
|
|
|
|
// then
|
|
verifyZeroInteractions(player, bukkitService);
|
|
}
|
|
|
|
@Test
|
|
public void shouldBanPlayerIp() {
|
|
// given
|
|
Player player = mock(Player.class);
|
|
String ip = "123.45.67.89";
|
|
TestHelper.mockPlayerIp(player, ip);
|
|
String banReason = "IP ban too many logins";
|
|
given(messages.retrieveSingle(player, MessageKey.TEMPBAN_MAX_LOGINS)).willReturn(banReason);
|
|
Settings settings = mockSettings(2, 100, "");
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
setBukkitServiceToScheduleSyncDelayedTask(bukkitService);
|
|
|
|
// when
|
|
manager.tempbanPlayer(player);
|
|
|
|
// then
|
|
verify(player).kickPlayer(banReason);
|
|
ArgumentCaptor<Date> captor = ArgumentCaptor.forClass(Date.class);
|
|
verify(bukkitService).banIp(eq(ip), eq(banReason), captor.capture(), eq("AuthMe"));
|
|
|
|
// Compute the expected expiration date and check that the actual date is within the difference tolerance
|
|
Calendar cal = Calendar.getInstance();
|
|
cal.add(Calendar.MINUTE, 100);
|
|
long expectedExpiration = cal.getTime().getTime();
|
|
assertThat(Math.abs(captor.getValue().getTime() - expectedExpiration), lessThan(DATE_TOLERANCE_MILLISECONDS));
|
|
}
|
|
|
|
@Test
|
|
public void shouldBanPlayerIpCustom() {
|
|
// given
|
|
Player player = mock(Player.class);
|
|
given(player.getName()).willReturn("Bob");
|
|
String ip = "143.45.77.89";
|
|
TestHelper.mockPlayerIp(player, ip);
|
|
String banCommand = "banip %ip% 15d IP ban too many logins";
|
|
Settings settings = mockSettings(2, 100, banCommand);
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
setBukkitServiceToScheduleSyncDelayedTask(bukkitService);
|
|
|
|
// when
|
|
manager.tempbanPlayer(player);
|
|
|
|
// then
|
|
verify(bukkitService).dispatchConsoleCommand(banCommand.replace("%ip%", ip));
|
|
}
|
|
|
|
@Test
|
|
public void shouldResetCountAfterBan() {
|
|
// given
|
|
Player player = mock(Player.class);
|
|
String ip = "22.44.66.88";
|
|
TestHelper.mockPlayerIp(player, ip);
|
|
String banReason = "kick msg";
|
|
given(messages.retrieveSingle(player, MessageKey.TEMPBAN_MAX_LOGINS)).willReturn(banReason);
|
|
Settings settings = mockSettings(10, 60, "");
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, settings);
|
|
manager.increaseCount(ip, "user");
|
|
manager.increaseCount(ip, "name2");
|
|
manager.increaseCount(ip, "user");
|
|
setBukkitServiceToScheduleSyncDelayedTask(bukkitService);
|
|
|
|
// when
|
|
manager.tempbanPlayer(player);
|
|
|
|
// then
|
|
verify(player).kickPlayer(banReason);
|
|
assertHasNoEntries(manager, ip);
|
|
}
|
|
|
|
@Test
|
|
public void shouldPerformCleanup() {
|
|
// given
|
|
Map<String, TimedCounter<String>> counts = new HashMap<>();
|
|
TimedCounter<String> counter1 = mockCounter();
|
|
given(counter1.isEmpty()).willReturn(true);
|
|
counts.put("11.11.11.11", counter1);
|
|
TimedCounter<String> counter2 = mockCounter();
|
|
given(counter2.isEmpty()).willReturn(false);
|
|
counts.put("33.33.33.33", counter2);
|
|
|
|
TempbanManager manager = new TempbanManager(bukkitService, messages, mockSettings(3, 10, ""));
|
|
ReflectionTestUtils.setField(TempbanManager.class, manager, "ipLoginFailureCounts", counts);
|
|
|
|
// when
|
|
manager.performCleanup();
|
|
|
|
// then
|
|
verify(counter1).removeExpiredEntries();
|
|
verify(counter2).removeExpiredEntries();
|
|
assertThat(counts.keySet(), contains("33.33.33.33"));
|
|
}
|
|
|
|
private static Settings mockSettings(int maxTries, int tempbanLength, String customCommand) {
|
|
Settings settings = mock(Settings.class);
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_ON_MAX_LOGINS)).willReturn(true);
|
|
given(settings.getProperty(SecuritySettings.MAX_LOGIN_TEMPBAN)).willReturn(maxTries);
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_LENGTH)).willReturn(tempbanLength);
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_MINUTES_BEFORE_RESET))
|
|
.willReturn((int) TEST_EXPIRATION_THRESHOLD / 60_000);
|
|
given(settings.getProperty(SecuritySettings.TEMPBAN_CUSTOM_COMMAND)).willReturn(customCommand);
|
|
return settings;
|
|
}
|
|
|
|
private static void assertHasNoEntries(TempbanManager manager, String address) {
|
|
Map<String, TimedCounter<String>> playerCounts = ReflectionTestUtils
|
|
.getFieldValue(TempbanManager.class, manager, "ipLoginFailureCounts");
|
|
TimedCounter<String> counter = playerCounts.get(address);
|
|
assertThat(counter == null || counter.isEmpty(), equalTo(true));
|
|
}
|
|
|
|
private static void assertHasCount(TempbanManager manager, String address, String name, int count) {
|
|
Map<String, TimedCounter<String>> playerCounts = ReflectionTestUtils
|
|
.getFieldValue(TempbanManager.class, manager, "ipLoginFailureCounts");
|
|
assertThat(playerCounts.get(address).get(name), equalTo(count));
|
|
}
|
|
|
|
@SuppressWarnings("unchecked")
|
|
private static <T> TimedCounter<T> mockCounter() {
|
|
return mock(TimedCounter.class);
|
|
}
|
|
}
|