#1031 Introduce hasSession field in datasource (#1351)

* Introduce hasSession field in datasource

That makes isLogged more consistent as it will be '1' only when the player is online.

* Fixes

* Fix unit testing

* Update config doc

* Create SessionService

* Create test for SessionService, avoid DB operations if sessions are disabled

* Cleanup: remove outdated warning for session timeout = 0
- Remove outdated warning
- Encapsulate session enabled check in SessionService

* Fix failing SessionServiceTest, add data source integration tests for session methods
This commit is contained in:
Gabriele C
2017-10-15 18:32:51 +02:00
committed by ljacqu
parent 1487fc0d9e
commit 22e95493de
19 changed files with 537 additions and 106 deletions
@@ -144,7 +144,6 @@ public class RegisterAdminCommandTest {
ArgumentCaptor<PlayerAuth> captor = ArgumentCaptor.forClass(PlayerAuth.class);
verify(dataSource).saveAuth(captor.capture());
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
verify(dataSource).setUnlogged(user);
}
@Test
@@ -174,7 +173,6 @@ public class RegisterAdminCommandTest {
ArgumentCaptor<PlayerAuth> captor = ArgumentCaptor.forClass(PlayerAuth.class);
verify(dataSource).saveAuth(captor.capture());
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
verify(dataSource).setUnlogged(user);
verify(player).kickPlayer(kickForAdminRegister);
}
@@ -416,4 +416,36 @@ public abstract class AbstractDataSourceIntegrationTest {
// then
assertThat(loggedPlayersWithEmptyMail, contains("Bobby"));
}
@Test
public void shouldGrantAndRetrieveSessionFlag() {
// given
DataSource dataSource = getDataSource();
// when
dataSource.grantSession("bobby");
dataSource.grantSession("doesNotExist");
// then
assertThat(dataSource.hasSession("bobby"), equalTo(true));
assertThat(dataSource.hasSession("user"), equalTo(false));
assertThat(dataSource.hasSession("bogus"), equalTo(false));
}
@Test
public void shouldRevokeSession() {
// given
DataSource dataSource = getDataSource();
dataSource.grantSession("bobby");
dataSource.grantSession("user");
// when
dataSource.revokeSession("bobby");
dataSource.revokeSession("userNotInDatabase");
// then
assertThat(dataSource.hasSession("bobby"), equalTo(false));
assertThat(dataSource.hasSession("user"), equalTo(true));
assertThat(dataSource.hasSession("nonExistentName"), equalTo(false));
}
}
@@ -0,0 +1,222 @@
package fr.xephi.authme.service;
import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.RestoreSessionEvent;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.bukkit.entity.Player;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import java.util.function.Function;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.only;
import static org.mockito.Mockito.spy;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Test for {@link SessionService}.
*/
@RunWith(DelayedInjectionRunner.class)
public class SessionServiceTest {
@InjectDelayed
private SessionService sessionService;
@Mock
private DataSource dataSource;
@Mock
private CommonService commonService;
@Mock
private BukkitService bukkitService;
@BeforeClass
public static void initLogger() {
TestHelper.setupLogger();
}
@BeforeInjecting
public void setUpEnabledProperty() {
given(commonService.getProperty(PluginSettings.SESSIONS_ENABLED)).willReturn(true);
}
@Test
public void shouldCheckSessionsEnabledSetting() {
// given
Player player = mock(Player.class);
given(commonService.getProperty(PluginSettings.SESSIONS_ENABLED)).willReturn(false);
sessionService.reload();
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(false));
verifyZeroInteractions(dataSource);
}
@Test
public void shouldCheckIfUserHasSession() {
// given
String name = "Bobby";
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
given(dataSource.hasSession(name)).willReturn(false);
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(false));
verify(commonService, only()).getProperty(PluginSettings.SESSIONS_ENABLED);
verify(dataSource, only()).hasSession(name);
}
@Test
public void shouldCheckLastLoginDate() {
// given
String name = "Bobby";
String ip = "127.3.12.15";
Player player = mockPlayerWithNameAndIp(name, ip);
given(commonService.getProperty(PluginSettings.SESSIONS_TIMEOUT)).willReturn(8);
given(dataSource.hasSession(name)).willReturn(true);
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.lastLogin(System.currentTimeMillis() - 10 * 60 * 1000)
.ip(ip).build();
given(dataSource.getAuth(name)).willReturn(auth);
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(false));
verify(commonService).getProperty(PluginSettings.SESSIONS_ENABLED);
verify(commonService).send(player, MessageKey.SESSION_EXPIRED);
verify(dataSource).hasSession(name);
verify(dataSource).setUnlogged(name);
verify(dataSource).revokeSession(name);
}
@Test
public void shouldRefuseSessionForAuthWithZeroLastLoginTimestamp() {
// given
String name = "Bobby";
String ip = "127.3.12.15";
Player player = mockPlayerWithNameAndIp(name, ip);
given(commonService.getProperty(PluginSettings.SESSIONS_TIMEOUT)).willReturn(8);
given(dataSource.hasSession(name)).willReturn(true);
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.lastLogin(0)
.ip(ip).build();
given(dataSource.getAuth(name)).willReturn(auth);
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(false));
verify(commonService).getProperty(PluginSettings.SESSIONS_ENABLED);
verify(commonService).send(player, MessageKey.SESSION_EXPIRED);
verify(dataSource).hasSession(name);
verify(dataSource).setUnlogged(name);
verify(dataSource).revokeSession(name);
}
@Test
public void shouldCheckLastLoginIp() {
// given
String name = "Bobby";
String ip = "127.3.12.15";
Player player = mockPlayerWithNameAndIp(name, ip);
given(dataSource.hasSession(name)).willReturn(true);
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.lastLogin(System.currentTimeMillis())
.ip("8.8.8.8").build();
given(dataSource.getAuth(name)).willReturn(auth);
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(false));
verify(commonService).getProperty(PluginSettings.SESSIONS_ENABLED);
verify(commonService).send(player, MessageKey.SESSION_EXPIRED);
verify(dataSource).hasSession(name);
verify(dataSource).setUnlogged(name);
verify(dataSource).revokeSession(name);
}
@Test
public void shouldEmitEventForValidSession() {
// given
String name = "Bobby";
String ip = "127.3.12.15";
Player player = mockPlayerWithNameAndIp(name, ip);
given(commonService.getProperty(PluginSettings.SESSIONS_TIMEOUT)).willReturn(8);
given(dataSource.hasSession(name)).willReturn(true);
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.lastLogin(System.currentTimeMillis() - 7 * 60 * 1000)
.ip(ip).build();
given(dataSource.getAuth(name)).willReturn(auth);
RestoreSessionEvent event = spy(new RestoreSessionEvent(player, false));
given(bukkitService.createAndCallEvent(any(Function.class))).willReturn(event);
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(true));
verify(commonService).getProperty(PluginSettings.SESSIONS_ENABLED);
verify(commonService).getProperty(PluginSettings.SESSIONS_TIMEOUT);
verifyNoMoreInteractions(commonService);
verify(dataSource).hasSession(name);
verify(dataSource).setUnlogged(name);
verify(dataSource).revokeSession(name);
verify(event).isCancelled();
}
@Test
public void shouldHandleNullPlayerAuth() {
// given
String name = "Bobby";
Player player = mockPlayerWithNameAndIp(name, "127.3.12.15");
given(dataSource.hasSession(name)).willReturn(true);
given(dataSource.getAuth(name)).willReturn(null);
// when
boolean result = sessionService.canResumeSession(player);
// then
assertThat(result, equalTo(false));
verify(commonService).getProperty(PluginSettings.SESSIONS_ENABLED);
verify(dataSource).hasSession(name);
verify(dataSource).setUnlogged(name);
verify(dataSource).revokeSession(name);
verify(dataSource).getAuth(name);
}
private static Player mockPlayerWithNameAndIp(String name, String ip) {
Player player = mock(Player.class);
given(player.getName()).willReturn(name);
TestHelper.mockPlayerIp(player, ip);
return player;
}
}
@@ -13,10 +13,12 @@ CREATE TABLE authme (
yaw FLOAT,
pitch FLOAT,
email VARCHAR(255) DEFAULT 'your@email.com',
isLogged INT DEFAULT '0', realname VARCHAR(255) NOT NULL DEFAULT 'Player',
isLogged INT DEFAULT '0',
realname VARCHAR(255) NOT NULL DEFAULT 'Player',
salt varchar(255),
recoverycode VARCHAR(20),
recoveryexpiration BIGINT,
hasSession INT NOT NULL DEFAULT '0',
CONSTRAINT table_const_prim PRIMARY KEY (id)
);