From e5bfbf6304e95e873fbafcb83f09fc1c809ebe30 Mon Sep 17 00:00:00 2001 From: ljacqu Date: Sat, 13 May 2017 09:37:36 +0200 Subject: [PATCH] #1023 LoginSecurity converter: fix last login conversion, extend test --- .../converter/LoginSecurityConverter.java | 39 ++++++++++++- .../converter/LoginSecurityConverterTest.java | 53 ++++++++++++++++++ .../datasource/converter/LoginSecurity.db | Bin 15360 -> 15360 bytes .../datasource/converter/loginsecurity.sql | 34 +++++++++++ 4 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 src/test/resources/fr/xephi/authme/datasource/converter/loginsecurity.sql diff --git a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java b/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java index b8eabbe4a..9a6f4f354 100644 --- a/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java +++ b/src/main/java/fr/xephi/authme/datasource/converter/LoginSecurityConverter.java @@ -16,8 +16,10 @@ import java.sql.DriverManager; import java.sql.ResultSet; import java.sql.SQLException; import java.sql.Statement; +import java.sql.Timestamp; import java.util.ArrayList; import java.util.List; +import java.util.Optional; import static fr.xephi.authme.util.Utils.logAndSendMessage; @@ -59,6 +61,12 @@ public class LoginSecurityConverter implements Converter { } } + /** + * Performs the conversion from LoginSecurity to AuthMe. + * + * @param sender the command sender who launched the conversion + * @param connection connection to the LoginSecurity data source + */ @VisibleForTesting void performConversion(CommandSender sender, Connection connection) throws SQLException { try (Statement statement = connection.createStatement()) { @@ -70,6 +78,12 @@ public class LoginSecurityConverter implements Converter { } } + /** + * Migrates the accounts. + * + * @param sender the command sender + * @param resultSet result set with the account data to migrate + */ private void migrateData(CommandSender sender, ResultSet resultSet) throws SQLException { List skippedPlayers = new ArrayList<>(); long successfulSaves = 0; @@ -91,13 +105,23 @@ public class LoginSecurityConverter implements Converter { } } + /** + * Creates a PlayerAuth based on data extracted from the given result set. + * + * @param name the name of the player to build + * @param resultSet the result set to extract data from + * @return the created player auth object + */ private static PlayerAuth buildAuthFromLoginSecurity(String name, ResultSet resultSet) throws SQLException { + // TODO #792: Last login should be null if not present + long lastLoginMillis = Optional.ofNullable(resultSet.getTimestamp("last_login")) + .map(Timestamp::getTime).orElse(System.currentTimeMillis()); return PlayerAuth.builder() .name(name) .realName(name) .password(resultSet.getString("password"), null) .ip(resultSet.getString("ip_address")) - .lastLogin(resultSet.getLong("last_login")) + .lastLogin(lastLoginMillis) // TODO #792: Register date .locX(resultSet.getDouble("x")) .locY(resultSet.getDouble("y")) @@ -108,6 +132,13 @@ public class LoginSecurityConverter implements Converter { .build(); } + /** + * Creates a {@link Connection} to the LoginSecurity data source based on the settings, + * or informs the sender of the error that occurred. + * + * @param sender the command sender who launched the conversion + * @return the created connection object, or null if it failed + */ private Connection createConnectionOrInformSender(CommandSender sender) { Connection connection; if (useSqlite) { @@ -133,6 +164,12 @@ public class LoginSecurityConverter implements Converter { return connection; } + /** + * Creates a connection to SQLite. + * + * @param path the path to the SQLite database + * @return the created connection + */ @VisibleForTesting Connection createSqliteConnection(String path) { try { diff --git a/src/test/java/fr/xephi/authme/datasource/converter/LoginSecurityConverterTest.java b/src/test/java/fr/xephi/authme/datasource/converter/LoginSecurityConverterTest.java index 3d19e3d2a..7e4afee39 100644 --- a/src/test/java/fr/xephi/authme/datasource/converter/LoginSecurityConverterTest.java +++ b/src/test/java/fr/xephi/authme/datasource/converter/LoginSecurityConverterTest.java @@ -3,6 +3,8 @@ package fr.xephi.authme.datasource.converter; import ch.jalu.injector.testing.BeforeInjecting; import ch.jalu.injector.testing.DelayedInjectionRunner; import ch.jalu.injector.testing.InjectDelayed; +import com.zaxxer.hikari.HikariConfig; +import com.zaxxer.hikari.HikariDataSource; import fr.xephi.authme.TestHelper; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; @@ -16,10 +18,14 @@ import org.mockito.ArgumentCaptor; import org.mockito.Mock; import java.io.File; +import java.io.IOException; +import java.nio.file.Files; import java.sql.Connection; import java.sql.SQLException; +import java.sql.Statement; import static fr.xephi.authme.AuthMeMatchers.equalToHash; +import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; @@ -74,6 +80,53 @@ public class LoginSecurityConverterTest { assertThat(captor.getAllValues().get(2).getRealName(), equalTo("Player3")); assertThat(captor.getAllValues().get(2).getPassword(), equalToHash("$2a$10$WFui8KSXMLDOVXKFpCLyPukPi4M82w1cv/rNojsAnwJjba3pp8sba")); + assertThat(captor.getAllValues().get(2), hasAuthLocation(14.24, 67.99, -12.83, "hubb", -10f, 185f)); } + @Test + public void shouldConvertFromMySql() throws IOException, SQLException { + // given + Connection connection = initializeMySqlTable(); + CommandSender sender = mock(CommandSender.class); + + // when + converter.performConversion(sender, connection); + + // then + ArgumentCaptor captor = ArgumentCaptor.forClass(PlayerAuth.class); + verify(dataSource, times(3)).saveAuth(captor.capture()); + assertThat(captor.getAllValues().get(0).getNickname(), equalTo("player1")); + assertThat(captor.getAllValues().get(0).getRealName(), equalTo("Player1")); + assertThat(captor.getAllValues().get(0).getLastLogin(), equalTo(1494242093000L)); + assertThat(captor.getAllValues().get(0).getPassword(), equalToHash("$2a$10$E1Ri7XKeIIBv4qVaiPplgepT7QH9xGFh3hbHfcmCjq7hiW.UBTiGK")); + assertThat(captor.getAllValues().get(0).getIp(), equalTo("127.0.0.1")); + + assertThat(captor.getAllValues().get(1).getNickname(), equalTo("player2")); + assertThat(captor.getAllValues().get(1).getLastLogin(), equalTo(1489317753000L)); + assertThat(captor.getAllValues().get(1).getIp(), equalTo("127.4.5.6")); + + assertThat(captor.getAllValues().get(2).getRealName(), equalTo("Player3")); + assertThat(captor.getAllValues().get(2).getPassword(), equalToHash("$2a$10$WFui8KSXMLDOVXKFpCLyPukPi4M82w1cv/rNojsAnwJjba3pp8sba")); + assertThat(captor.getAllValues().get(2), hasAuthLocation(14.24, 67.99, -12.83, "hubb", -10f, 185f)); + } + + private Connection initializeMySqlTable() throws IOException, SQLException { + File sqlInitFile = TestHelper.getJarFile(TestHelper.PROJECT_ROOT + "datasource/converter/loginsecurity.sql"); + String initStatement = new String(Files.readAllBytes(sqlInitFile.toPath())); + + HikariConfig config = new HikariConfig(); + config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource"); + config.setConnectionTestQuery("VALUES 1"); + config.addDataSourceProperty("URL", "jdbc:h2:mem:test"); + config.addDataSourceProperty("user", "sa"); + config.addDataSourceProperty("password", "sa"); + HikariDataSource ds = new HikariDataSource(config); + Connection connection = ds.getConnection(); + + try (Statement st = connection.createStatement()) { + st.execute("DROP TABLE IF EXISTS authme"); + st.execute(initStatement); + } + return connection; + } } diff --git a/src/test/resources/fr/xephi/authme/datasource/converter/LoginSecurity.db b/src/test/resources/fr/xephi/authme/datasource/converter/LoginSecurity.db index 4c10efc77af44f85433148bb5a78048de1caaa7e..7dc6336b97182828aeb2b5b0d91848fe6ceb13a0 100644 GIT binary patch delta 87 zcmZpuXsDPV&B#4b#+i|OW5NG@V>OY{l0!YSaeq-3VNI?bw*Vq~} delta 27 jcmZpuXsDPV&B!@X#+i|GW5N>Y%`7Z`nKv^k{Fep*e*Fm< diff --git a/src/test/resources/fr/xephi/authme/datasource/converter/loginsecurity.sql b/src/test/resources/fr/xephi/authme/datasource/converter/loginsecurity.sql new file mode 100644 index 000000000..361fe87a3 --- /dev/null +++ b/src/test/resources/fr/xephi/authme/datasource/converter/loginsecurity.sql @@ -0,0 +1,34 @@ +CREATE TABLE ls_players ( + id integer not null, + unique_user_id varchar(128), + last_name varchar(16), + ip_address varchar(64), + password varchar(512), + hashing_algorithm integer, + location_id integer, + inventory_id integer, + last_login datetime, + registration_date date, + optlock integer not null, + uuid_mode varchar(1) check ( uuid_mode in ('M','U','O')), + constraint uq_ls_players_unique_user_id unique (unique_user_id), + constraint uq_ls_players_location_id unique (location_id), + constraint uq_ls_players_inventory_id unique (inventory_id), + constraint pk_ls_players primary key (id) +); +CREATE TABLE ls_locations ( + id integer not null, + world varchar(255), + x double, + y double, + z double, + yaw integer, + pitch integer, + constraint pk_ls_locations primary key (id) +); + +INSERT INTO ls_players VALUES(1,'0cb1fa9b-846a-3cda-a1d9-5a9d6939ce14','Player1',NULL,'$2a$10$E1Ri7XKeIIBv4qVaiPplgepT7QH9xGFh3hbHfcmCjq7hiW.UBTiGK',7,NULL,NULL,'2017-05-08T11:14:53+00:00','2017-05-08',1,'O'); +INSERT INTO ls_players VALUES(2,'6765ad15-4e42-364e-a116-3ca7a7433d08','Player2','127.4.5.6','$2a$10$p27YkDQWrDHS/7k/l/86xeHW5NBnFEL61.2o2Y.BM5IEn/yrZC5VW',7,NULL,NULL,'2017-03-12T11:22:33+00:00','2017-01-04',1,'O'); +INSERT INTO ls_players VALUES(3,'1a1975b9-0bbd-3ced-afb8-1059d8c22c9e','Player3','127.8.9.0','$2a$10$WFui8KSXMLDOVXKFpCLyPukPi4M82w1cv/rNojsAnwJjba3pp8sba',7,NULL,NULL,'2017-04-20T15:02:19+00:00','2017-03-17',1,'O'); + +INSERT INTO ls_locations VALUES(3, 'hubb', 14.24, 67.99, -12.83, -10, 185);