mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-11-03 09:10:01 +01:00
* 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:
parent
1487fc0d9e
commit
22e95493de
@ -1,5 +1,5 @@
|
|||||||
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||||
<!-- File auto-generated on Mon Oct 09 10:19:07 CEST 2017. See docs/config/config.tpl.md -->
|
<!-- File auto-generated on Tue Oct 10 13:51:56 CEST 2017. See docs/config/config.tpl.md -->
|
||||||
|
|
||||||
## AuthMe Configuration
|
## AuthMe Configuration
|
||||||
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
|
The first time you run AuthMe it will create a config.yml file in the plugins/AuthMe folder,
|
||||||
@ -41,6 +41,8 @@ DataSource:
|
|||||||
mySQLColumnEmail: 'email'
|
mySQLColumnEmail: 'email'
|
||||||
# Column for storing if a player is logged in or not
|
# Column for storing if a player is logged in or not
|
||||||
mySQLColumnLogged: 'isLogged'
|
mySQLColumnLogged: 'isLogged'
|
||||||
|
# Column for storing if a player has a valid session or not
|
||||||
|
mySQLColumnHasSession: 'hasSession'
|
||||||
# Column for storing players ips
|
# Column for storing players ips
|
||||||
mySQLColumnIp: 'ip'
|
mySQLColumnIp: 'ip'
|
||||||
# Column for storing players lastlogins
|
# Column for storing players lastlogins
|
||||||
@ -545,4 +547,4 @@ To change settings on a running server, save your changes to config.yml and use
|
|||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Mon Oct 09 10:19:07 CEST 2017
|
This page was automatically generated on the [AuthMe/AuthMeReloaded repository](https://github.com/AuthMe/AuthMeReloaded/tree/master/docs/) on Tue Oct 10 13:51:56 CEST 2017
|
||||||
|
@ -30,7 +30,6 @@ import fr.xephi.authme.service.BukkitService;
|
|||||||
import fr.xephi.authme.service.MigrationService;
|
import fr.xephi.authme.service.MigrationService;
|
||||||
import fr.xephi.authme.settings.Settings;
|
import fr.xephi.authme.settings.Settings;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||||
import fr.xephi.authme.task.CleanupTask;
|
import fr.xephi.authme.task.CleanupTask;
|
||||||
@ -264,12 +263,6 @@ public class AuthMe extends JavaPlugin {
|
|||||||
ConsoleLogger.warning("WARNING!!! By disabling ForceSingleSession, your server protection is inadequate!");
|
ConsoleLogger.warning("WARNING!!! By disabling ForceSingleSession, your server protection is inadequate!");
|
||||||
}
|
}
|
||||||
|
|
||||||
// Session timeout disabled
|
|
||||||
if (settings.getProperty(PluginSettings.SESSIONS_TIMEOUT) == 0
|
|
||||||
&& settings.getProperty(PluginSettings.SESSIONS_ENABLED)) {
|
|
||||||
ConsoleLogger.warning("WARNING!!! You set session timeout to 0, this may cause security issues!");
|
|
||||||
}
|
|
||||||
|
|
||||||
// Use TLS property only affects port 25
|
// Use TLS property only affects port 25
|
||||||
if (!settings.getProperty(EmailSettings.PORT25_USE_TLS)
|
if (!settings.getProperty(EmailSettings.PORT25_USE_TLS)
|
||||||
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
|
&& settings.getProperty(EmailSettings.SMTP_PORT) != 25) {
|
||||||
|
@ -51,38 +51,29 @@ public class RegisterAdminCommand implements ExecutableCommand {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
bukkitService.runTaskOptionallyAsync(new Runnable() {
|
bukkitService.runTaskOptionallyAsync(() -> {
|
||||||
|
if (dataSource.isAuthAvailable(playerNameLowerCase)) {
|
||||||
|
commonService.send(sender, MessageKey.NAME_ALREADY_REGISTERED);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase);
|
||||||
|
PlayerAuth auth = PlayerAuth.builder()
|
||||||
|
.name(playerNameLowerCase)
|
||||||
|
.realName(playerName)
|
||||||
|
.password(hashedPassword)
|
||||||
|
.build();
|
||||||
|
|
||||||
@Override
|
if (!dataSource.saveAuth(auth)) {
|
||||||
public void run() {
|
commonService.send(sender, MessageKey.ERROR);
|
||||||
if (dataSource.isAuthAvailable(playerNameLowerCase)) {
|
return;
|
||||||
commonService.send(sender, MessageKey.NAME_ALREADY_REGISTERED);
|
}
|
||||||
return;
|
|
||||||
}
|
|
||||||
HashedPassword hashedPassword = passwordSecurity.computeHash(playerPass, playerNameLowerCase);
|
|
||||||
PlayerAuth auth = PlayerAuth.builder()
|
|
||||||
.name(playerNameLowerCase)
|
|
||||||
.realName(playerName)
|
|
||||||
.password(hashedPassword)
|
|
||||||
.build();
|
|
||||||
|
|
||||||
if (!dataSource.saveAuth(auth)) {
|
commonService.send(sender, MessageKey.REGISTER_SUCCESS);
|
||||||
commonService.send(sender, MessageKey.ERROR);
|
ConsoleLogger.info(sender.getName() + " registered " + playerName);
|
||||||
return;
|
final Player player = bukkitService.getPlayerExact(playerName);
|
||||||
}
|
if (player != null) {
|
||||||
dataSource.setUnlogged(playerNameLowerCase);
|
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(() ->
|
||||||
|
player.kickPlayer(commonService.retrieveSingleMessage(MessageKey.KICK_FOR_ADMIN_REGISTER)));
|
||||||
commonService.send(sender, MessageKey.REGISTER_SUCCESS);
|
|
||||||
ConsoleLogger.info(sender.getName() + " registered " + playerName);
|
|
||||||
final Player player = bukkitService.getPlayerExact(playerName);
|
|
||||||
if (player != null) {
|
|
||||||
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(new Runnable() {
|
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
player.kickPlayer(commonService.retrieveSingleMessage(MessageKey.KICK_FOR_ADMIN_REGISTER));
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -208,6 +208,21 @@ public class CacheDataSource implements DataSource {
|
|||||||
source.setUnlogged(user.toLowerCase());
|
source.setUnlogged(user.toLowerCase());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSession(final String user) {
|
||||||
|
return source.hasSession(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void grantSession(final String user) {
|
||||||
|
source.grantSession(user);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void revokeSession(final String user) {
|
||||||
|
source.revokeSession(user);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void purgeLogged() {
|
public void purgeLogged() {
|
||||||
source.purgeLogged();
|
source.purgeLogged();
|
||||||
|
@ -26,6 +26,7 @@ public final class Columns {
|
|||||||
public final String EMAIL;
|
public final String EMAIL;
|
||||||
public final String ID;
|
public final String ID;
|
||||||
public final String IS_LOGGED;
|
public final String IS_LOGGED;
|
||||||
|
public final String HAS_SESSION;
|
||||||
|
|
||||||
public Columns(Settings settings) {
|
public Columns(Settings settings) {
|
||||||
NAME = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME);
|
NAME = settings.getProperty(DatabaseSettings.MYSQL_COL_NAME);
|
||||||
@ -44,6 +45,7 @@ public final class Columns {
|
|||||||
EMAIL = settings.getProperty(DatabaseSettings.MYSQL_COL_EMAIL);
|
EMAIL = settings.getProperty(DatabaseSettings.MYSQL_COL_EMAIL);
|
||||||
ID = settings.getProperty(DatabaseSettings.MYSQL_COL_ID);
|
ID = settings.getProperty(DatabaseSettings.MYSQL_COL_ID);
|
||||||
IS_LOGGED = settings.getProperty(DatabaseSettings.MYSQL_COL_ISLOGGED);
|
IS_LOGGED = settings.getProperty(DatabaseSettings.MYSQL_COL_ISLOGGED);
|
||||||
|
HAS_SESSION = settings.getProperty(DatabaseSettings.MYSQL_COL_HASSESSION);
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -161,6 +161,29 @@ public interface DataSource extends Reloadable {
|
|||||||
*/
|
*/
|
||||||
void setUnlogged(String user);
|
void setUnlogged(String user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Query the datasource whether the player has an active session or not.
|
||||||
|
* Warning: this value won't expire, you have also to check the user's last login timestamp.
|
||||||
|
*
|
||||||
|
* @param user The name of the player to verify
|
||||||
|
* @return True if the user has a valid session, false otherwise
|
||||||
|
*/
|
||||||
|
boolean hasSession(String user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the user's hasSession value to true.
|
||||||
|
*
|
||||||
|
* @param user The name of the player to change
|
||||||
|
*/
|
||||||
|
void grantSession(String user);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Mark the user's hasSession value to false.
|
||||||
|
*
|
||||||
|
* @param user The name of the player to change
|
||||||
|
*/
|
||||||
|
void revokeSession(String user);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set all players who are marked as logged in as NOT logged in.
|
* Set all players who are marked as logged in as NOT logged in.
|
||||||
*/
|
*/
|
||||||
|
@ -329,6 +329,19 @@ public class FlatFile implements DataSource {
|
|||||||
public void setUnlogged(String user) {
|
public void setUnlogged(String user) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSession(String user) {
|
||||||
|
throw new UnsupportedOperationException("Flat file no longer supported");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void grantSession(String user) {
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void revokeSession(String user) {
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void purgeLogged() {
|
public void purgeLogged() {
|
||||||
}
|
}
|
||||||
|
@ -237,6 +237,11 @@ public class MySQL implements DataSource {
|
|||||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||||
+ col.IS_LOGGED + " SMALLINT NOT NULL DEFAULT '0' AFTER " + col.EMAIL);
|
+ col.IS_LOGGED + " SMALLINT NOT NULL DEFAULT '0' AFTER " + col.EMAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isColumnMissing(md, col.HAS_SESSION)) {
|
||||||
|
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||||
|
+ col.HAS_SESSION + " SMALLINT NOT NULL DEFAULT '0' AFTER " + col.IS_LOGGED);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
ConsoleLogger.info("MySQL setup finished");
|
ConsoleLogger.info("MySQL setup finished");
|
||||||
}
|
}
|
||||||
@ -565,6 +570,44 @@ public class MySQL implements DataSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSession(String user) {
|
||||||
|
String sql = "SELECT " + col.HAS_SESSION + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
|
||||||
|
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
|
pst.setString(1, user);
|
||||||
|
try (ResultSet rs = pst.executeQuery()) {
|
||||||
|
return rs.next() && (rs.getInt(col.HAS_SESSION) == 1);
|
||||||
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logSqlException(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void grantSession(String user) {
|
||||||
|
String sql = "UPDATE " + tableName + " SET " + col.HAS_SESSION + "=? WHERE " + col.NAME + "=?;";
|
||||||
|
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
|
pst.setInt(1, 1);
|
||||||
|
pst.setString(2, user.toLowerCase());
|
||||||
|
pst.executeUpdate();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logSqlException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void revokeSession(String user) {
|
||||||
|
String sql = "UPDATE " + tableName + " SET " + col.HAS_SESSION + "=? WHERE " + col.NAME + "=?;";
|
||||||
|
try (Connection con = getConnection(); PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
|
pst.setInt(1, 0);
|
||||||
|
pst.setString(2, user.toLowerCase());
|
||||||
|
pst.executeUpdate();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logSqlException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void purgeLogged() {
|
public void purgeLogged() {
|
||||||
String sql = "UPDATE " + tableName + " SET " + col.IS_LOGGED + "=? WHERE " + col.IS_LOGGED + "=?;";
|
String sql = "UPDATE " + tableName + " SET " + col.IS_LOGGED + "=? WHERE " + col.IS_LOGGED + "=?;";
|
||||||
|
@ -134,7 +134,13 @@ public class SQLite implements DataSource {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (isColumnMissing(md, col.IS_LOGGED)) {
|
if (isColumnMissing(md, col.IS_LOGGED)) {
|
||||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.IS_LOGGED + " INT DEFAULT '0';");
|
st.executeUpdate("ALTER TABLE " + tableName
|
||||||
|
+ " ADD COLUMN " + col.IS_LOGGED + " INT NOT NULL DEFAULT '0';");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isColumnMissing(md, col.HAS_SESSION)) {
|
||||||
|
st.executeUpdate("ALTER TABLE " + tableName
|
||||||
|
+ " ADD COLUMN " + col.HAS_SESSION + " INT NOT NULL DEFAULT '0';");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ConsoleLogger.info("SQLite Setup finished");
|
ConsoleLogger.info("SQLite Setup finished");
|
||||||
@ -426,7 +432,7 @@ public class SQLite implements DataSource {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public boolean isLogged(String user) {
|
public boolean isLogged(String user) {
|
||||||
String sql = "SELECT * FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=?;";
|
String sql = "SELECT " + col.IS_LOGGED + " FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=?;";
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
pst.setString(1, user);
|
pst.setString(1, user);
|
||||||
try (ResultSet rs = pst.executeQuery()) {
|
try (ResultSet rs = pst.executeQuery()) {
|
||||||
@ -455,14 +461,52 @@ public class SQLite implements DataSource {
|
|||||||
@Override
|
@Override
|
||||||
public void setUnlogged(String user) {
|
public void setUnlogged(String user) {
|
||||||
String sql = "UPDATE " + tableName + " SET " + col.IS_LOGGED + "=? WHERE LOWER(" + col.NAME + ")=?;";
|
String sql = "UPDATE " + tableName + " SET " + col.IS_LOGGED + "=? WHERE LOWER(" + col.NAME + ")=?;";
|
||||||
if (user != null) {
|
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
pst.setInt(1, 0);
|
||||||
pst.setInt(1, 0);
|
pst.setString(2, user);
|
||||||
pst.setString(2, user);
|
pst.executeUpdate();
|
||||||
pst.executeUpdate();
|
} catch (SQLException ex) {
|
||||||
} catch (SQLException ex) {
|
logSqlException(ex);
|
||||||
logSqlException(ex);
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean hasSession(String user) {
|
||||||
|
String sql = "SELECT " + col.HAS_SESSION + " FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=?;";
|
||||||
|
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
|
pst.setString(1, user);
|
||||||
|
try (ResultSet rs = pst.executeQuery()) {
|
||||||
|
if (rs.next()) {
|
||||||
|
return rs.getInt(col.HAS_SESSION) == 1;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logSqlException(ex);
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void grantSession(String user) {
|
||||||
|
String sql = "UPDATE " + tableName + " SET " + col.HAS_SESSION + "=? WHERE LOWER(" + col.NAME + ")=?;";
|
||||||
|
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
|
pst.setInt(1, 1);
|
||||||
|
pst.setString(2, user);
|
||||||
|
pst.executeUpdate();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logSqlException(ex);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void revokeSession(String user) {
|
||||||
|
String sql = "UPDATE " + tableName + " SET " + col.HAS_SESSION + "=? WHERE LOWER(" + col.NAME + ")=?;";
|
||||||
|
try (PreparedStatement pst = con.prepareStatement(sql)) {
|
||||||
|
pst.setInt(1, 0);
|
||||||
|
pst.setString(2, user);
|
||||||
|
pst.executeUpdate();
|
||||||
|
} catch (SQLException ex) {
|
||||||
|
logSqlException(ex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -574,17 +618,6 @@ public class SQLite implements DataSource {
|
|||||||
return authBuilder.build();
|
return authBuilder.build();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void close(Statement st) {
|
|
||||||
if (st != null) {
|
|
||||||
try {
|
|
||||||
st.close();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void close(Connection con) {
|
private static void close(Connection con) {
|
||||||
if (con != null) {
|
if (con != null) {
|
||||||
try {
|
try {
|
||||||
@ -594,14 +627,4 @@ public class SQLite implements DataSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void close(ResultSet rs) {
|
|
||||||
if (rs != null) {
|
|
||||||
try {
|
|
||||||
rs.close();
|
|
||||||
} catch (SQLException ex) {
|
|
||||||
logSqlException(ex);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,9 @@
|
|||||||
package fr.xephi.authme.process.join;
|
package fr.xephi.authme.process.join;
|
||||||
|
|
||||||
import fr.xephi.authme.ConsoleLogger;
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
import fr.xephi.authme.data.auth.PlayerAuth;
|
|
||||||
import fr.xephi.authme.data.auth.PlayerCache;
|
|
||||||
import fr.xephi.authme.data.limbo.LimboService;
|
import fr.xephi.authme.data.limbo.LimboService;
|
||||||
import fr.xephi.authme.datasource.DataSource;
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
import fr.xephi.authme.events.ProtectInventoryEvent;
|
import fr.xephi.authme.events.ProtectInventoryEvent;
|
||||||
import fr.xephi.authme.events.RestoreSessionEvent;
|
|
||||||
import fr.xephi.authme.message.MessageKey;
|
import fr.xephi.authme.message.MessageKey;
|
||||||
import fr.xephi.authme.permission.PlayerStatePermission;
|
import fr.xephi.authme.permission.PlayerStatePermission;
|
||||||
import fr.xephi.authme.process.AsynchronousProcess;
|
import fr.xephi.authme.process.AsynchronousProcess;
|
||||||
@ -14,11 +11,11 @@ import fr.xephi.authme.process.login.AsynchronousLogin;
|
|||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.service.CommonService;
|
import fr.xephi.authme.service.CommonService;
|
||||||
import fr.xephi.authme.service.PluginHookService;
|
import fr.xephi.authme.service.PluginHookService;
|
||||||
|
import fr.xephi.authme.service.SessionService;
|
||||||
import fr.xephi.authme.service.ValidationService;
|
import fr.xephi.authme.service.ValidationService;
|
||||||
import fr.xephi.authme.settings.WelcomeMessageConfiguration;
|
import fr.xephi.authme.settings.WelcomeMessageConfiguration;
|
||||||
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
import fr.xephi.authme.settings.commandconfig.CommandManager;
|
||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
|
||||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||||
import fr.xephi.authme.util.PlayerUtils;
|
import fr.xephi.authme.util.PlayerUtils;
|
||||||
@ -48,9 +45,6 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private CommonService service;
|
private CommonService service;
|
||||||
|
|
||||||
@Inject
|
|
||||||
private PlayerCache playerCache;
|
|
||||||
|
|
||||||
@Inject
|
@Inject
|
||||||
private LimboService limboService;
|
private LimboService limboService;
|
||||||
|
|
||||||
@ -72,6 +66,9 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private WelcomeMessageConfiguration welcomeMessageConfiguration;
|
private WelcomeMessageConfiguration welcomeMessageConfiguration;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SessionService sessionService;
|
||||||
|
|
||||||
AsynchronousJoin() {
|
AsynchronousJoin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +118,7 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Session logic
|
// Session logic
|
||||||
if (canResumeSession(player)) {
|
if (sessionService.canResumeSession(player)) {
|
||||||
service.send(player, MessageKey.SESSION_RECONNECTION);
|
service.send(player, MessageKey.SESSION_RECONNECTION);
|
||||||
// Run commands
|
// Run commands
|
||||||
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
|
bukkitService.scheduleSyncTaskFromOptionallyAsyncTask(
|
||||||
@ -177,30 +174,6 @@ public class AsynchronousJoin implements AsynchronousProcess {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean canResumeSession(Player player) {
|
|
||||||
final String name = player.getName();
|
|
||||||
if (database.isLogged(name)) {
|
|
||||||
database.setUnlogged(name);
|
|
||||||
playerCache.removePlayer(name);
|
|
||||||
if(service.getProperty(PluginSettings.SESSIONS_ENABLED)) {
|
|
||||||
PlayerAuth auth = database.getAuth(name);
|
|
||||||
if (auth != null) {
|
|
||||||
long timeSinceLastLogin = System.currentTimeMillis() - auth.getLastLogin();
|
|
||||||
if(timeSinceLastLogin < 0
|
|
||||||
|| timeSinceLastLogin > (service.getProperty(PluginSettings.SESSIONS_TIMEOUT) * 60 * 1000)
|
|
||||||
|| !auth.getIp().equals(PlayerUtils.getPlayerIp(player))) {
|
|
||||||
service.send(player, MessageKey.SESSION_EXPIRED);
|
|
||||||
} else {
|
|
||||||
RestoreSessionEvent event = bukkitService.createAndCallEvent(
|
|
||||||
isAsync -> new RestoreSessionEvent(player, isAsync));
|
|
||||||
return !event.isCancelled();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Checks whether the maximum number of accounts has been exceeded for the given IP address (according to
|
* Checks whether the maximum number of accounts has been exceeded for the given IP address (according to
|
||||||
* settings and permissions). If this is the case, the player is kicked.
|
* settings and permissions). If this is the case, the player is kicked.
|
||||||
|
@ -20,6 +20,7 @@ import fr.xephi.authme.process.SyncProcessManager;
|
|||||||
import fr.xephi.authme.security.PasswordSecurity;
|
import fr.xephi.authme.security.PasswordSecurity;
|
||||||
import fr.xephi.authme.service.BukkitService;
|
import fr.xephi.authme.service.BukkitService;
|
||||||
import fr.xephi.authme.service.CommonService;
|
import fr.xephi.authme.service.CommonService;
|
||||||
|
import fr.xephi.authme.service.SessionService;
|
||||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||||
@ -69,6 +70,9 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
|||||||
@Inject
|
@Inject
|
||||||
private EmailService emailService;
|
private EmailService emailService;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
private SessionService sessionService;
|
||||||
|
|
||||||
AsynchronousLogin() {
|
AsynchronousLogin() {
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -238,9 +242,10 @@ public class AsynchronousLogin implements AsynchronousProcess {
|
|||||||
|
|
||||||
ConsoleLogger.fine(player.getName() + " logged in!");
|
ConsoleLogger.fine(player.getName() + " logged in!");
|
||||||
|
|
||||||
// makes player isLoggedin via API
|
// makes player loggedin
|
||||||
playerCache.updatePlayer(auth);
|
playerCache.updatePlayer(auth);
|
||||||
dataSource.setLogged(name);
|
dataSource.setLogged(name);
|
||||||
|
sessionService.grantSession(name);
|
||||||
|
|
||||||
// As the scheduling executes the Task most likely after the current
|
// As the scheduling executes the Task most likely after the current
|
||||||
// task, we schedule it in the end
|
// task, we schedule it in the end
|
||||||
|
@ -53,6 +53,7 @@ public class AsynchronousLogout implements AsynchronousProcess {
|
|||||||
|
|
||||||
playerCache.removePlayer(name);
|
playerCache.removePlayer(name);
|
||||||
database.setUnlogged(name);
|
database.setUnlogged(name);
|
||||||
|
database.revokeSession(name);
|
||||||
syncProcessManager.processSyncPlayerLogout(player);
|
syncProcessManager.processSyncPlayerLogout(player);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -82,8 +82,11 @@ public class AsynchronousQuit implements AsynchronousProcess {
|
|||||||
playerCache.removePlayer(name);
|
playerCache.removePlayer(name);
|
||||||
|
|
||||||
//always update the database when the player quit the game (if sessions are disabled)
|
//always update the database when the player quit the game (if sessions are disabled)
|
||||||
if(!wasLoggedIn || !service.getProperty(PluginSettings.SESSIONS_ENABLED)) {
|
if (wasLoggedIn) {
|
||||||
database.setUnlogged(name);
|
database.setUnlogged(name);
|
||||||
|
if (!service.getProperty(PluginSettings.SESSIONS_ENABLED)) {
|
||||||
|
database.revokeSession(name);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (plugin.isEnabled()) {
|
if (plugin.isEnabled()) {
|
||||||
|
86
src/main/java/fr/xephi/authme/service/SessionService.java
Normal file
86
src/main/java/fr/xephi/authme/service/SessionService.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package fr.xephi.authme.service;
|
||||||
|
|
||||||
|
import fr.xephi.authme.ConsoleLogger;
|
||||||
|
import fr.xephi.authme.data.auth.PlayerAuth;
|
||||||
|
import fr.xephi.authme.datasource.DataSource;
|
||||||
|
import fr.xephi.authme.events.RestoreSessionEvent;
|
||||||
|
import fr.xephi.authme.initialization.Reloadable;
|
||||||
|
import fr.xephi.authme.message.MessageKey;
|
||||||
|
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||||
|
import fr.xephi.authme.util.PlayerUtils;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
|
||||||
|
import javax.inject.Inject;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the user sessions.
|
||||||
|
*/
|
||||||
|
public class SessionService implements Reloadable {
|
||||||
|
|
||||||
|
private final CommonService service;
|
||||||
|
private final BukkitService bukkitService;
|
||||||
|
private final DataSource database;
|
||||||
|
|
||||||
|
private boolean isEnabled;
|
||||||
|
|
||||||
|
@Inject
|
||||||
|
SessionService(CommonService service, BukkitService bukkitService, DataSource database) {
|
||||||
|
this.service = service;
|
||||||
|
this.bukkitService = bukkitService;
|
||||||
|
this.database = database;
|
||||||
|
reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns whether the player has a session he can resume.
|
||||||
|
*
|
||||||
|
* @param player the player to check
|
||||||
|
* @return true if there is a current session, false otherwise
|
||||||
|
*/
|
||||||
|
public boolean canResumeSession(Player player) {
|
||||||
|
final String name = player.getName();
|
||||||
|
if (isEnabled && database.hasSession(name)) {
|
||||||
|
database.setUnlogged(name);
|
||||||
|
database.revokeSession(name);
|
||||||
|
PlayerAuth auth = database.getAuth(name);
|
||||||
|
if (hasValidSessionData(auth, player)) {
|
||||||
|
RestoreSessionEvent event = bukkitService.createAndCallEvent(
|
||||||
|
isAsync -> new RestoreSessionEvent(player, isAsync));
|
||||||
|
return !event.isCancelled();
|
||||||
|
} else {
|
||||||
|
service.send(player, MessageKey.SESSION_EXPIRED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the given Player has a current session by comparing its properties
|
||||||
|
* with the given PlayerAuth's.
|
||||||
|
*
|
||||||
|
* @param auth the player auth
|
||||||
|
* @param player the associated player
|
||||||
|
* @return true if the player may resume his login session, false otherwise
|
||||||
|
*/
|
||||||
|
private boolean hasValidSessionData(PlayerAuth auth, Player player) {
|
||||||
|
if (auth == null) {
|
||||||
|
ConsoleLogger.warning("No PlayerAuth in database for '" + player.getName() + "' during session check");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
long timeSinceLastLogin = System.currentTimeMillis() - auth.getLastLogin();
|
||||||
|
return auth.getIp().equals(PlayerUtils.getPlayerIp(player))
|
||||||
|
&& timeSinceLastLogin > 0
|
||||||
|
&& timeSinceLastLogin < service.getProperty(PluginSettings.SESSIONS_TIMEOUT) * 60 * 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void grantSession(String name) {
|
||||||
|
if (isEnabled) {
|
||||||
|
database.grantSession(name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void reload() {
|
||||||
|
this.isEnabled = service.getProperty(PluginSettings.SESSIONS_ENABLED);
|
||||||
|
}
|
||||||
|
}
|
@ -75,6 +75,10 @@ public final class DatabaseSettings implements SettingsHolder {
|
|||||||
public static final Property<String> MYSQL_COL_ISLOGGED =
|
public static final Property<String> MYSQL_COL_ISLOGGED =
|
||||||
newProperty("DataSource.mySQLColumnLogged", "isLogged");
|
newProperty("DataSource.mySQLColumnLogged", "isLogged");
|
||||||
|
|
||||||
|
@Comment("Column for storing if a player has a valid session or not")
|
||||||
|
public static final Property<String> MYSQL_COL_HASSESSION =
|
||||||
|
newProperty("DataSource.mySQLColumnHasSession", "hasSession");
|
||||||
|
|
||||||
@Comment("Column for storing players ips")
|
@Comment("Column for storing players ips")
|
||||||
public static final Property<String> MYSQL_COL_IP =
|
public static final Property<String> MYSQL_COL_IP =
|
||||||
newProperty("DataSource.mySQLColumnIp", "ip");
|
newProperty("DataSource.mySQLColumnIp", "ip");
|
||||||
|
@ -144,7 +144,6 @@ public class RegisterAdminCommandTest {
|
|||||||
ArgumentCaptor<PlayerAuth> captor = ArgumentCaptor.forClass(PlayerAuth.class);
|
ArgumentCaptor<PlayerAuth> captor = ArgumentCaptor.forClass(PlayerAuth.class);
|
||||||
verify(dataSource).saveAuth(captor.capture());
|
verify(dataSource).saveAuth(captor.capture());
|
||||||
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
|
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
|
||||||
verify(dataSource).setUnlogged(user);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -174,7 +173,6 @@ public class RegisterAdminCommandTest {
|
|||||||
ArgumentCaptor<PlayerAuth> captor = ArgumentCaptor.forClass(PlayerAuth.class);
|
ArgumentCaptor<PlayerAuth> captor = ArgumentCaptor.forClass(PlayerAuth.class);
|
||||||
verify(dataSource).saveAuth(captor.capture());
|
verify(dataSource).saveAuth(captor.capture());
|
||||||
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
|
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
|
||||||
verify(dataSource).setUnlogged(user);
|
|
||||||
verify(player).kickPlayer(kickForAdminRegister);
|
verify(player).kickPlayer(kickForAdminRegister);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,4 +416,36 @@ public abstract class AbstractDataSourceIntegrationTest {
|
|||||||
// then
|
// then
|
||||||
assertThat(loggedPlayersWithEmptyMail, contains("Bobby"));
|
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));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
222
src/test/java/fr/xephi/authme/service/SessionServiceTest.java
Normal file
222
src/test/java/fr/xephi/authme/service/SessionServiceTest.java
Normal file
@ -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,
|
yaw FLOAT,
|
||||||
pitch FLOAT,
|
pitch FLOAT,
|
||||||
email VARCHAR(255) DEFAULT 'your@email.com',
|
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),
|
salt varchar(255),
|
||||||
recoverycode VARCHAR(20),
|
recoverycode VARCHAR(20),
|
||||||
recoveryexpiration BIGINT,
|
recoveryexpiration BIGINT,
|
||||||
|
hasSession INT NOT NULL DEFAULT '0',
|
||||||
CONSTRAINT table_const_prim PRIMARY KEY (id)
|
CONSTRAINT table_const_prim PRIMARY KEY (id)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user