diff --git a/.travis.yml b/.travis.yml
index 06d6183c0..bca4843fd 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,7 +1,7 @@
sudo: false
language: java
-jdk: oraclejdk7
+jdk: oraclejdk8
script: mvn clean verify -B
diff --git a/README.md b/README.md
index d270887da..e3e4b937e 100644
--- a/README.md
+++ b/README.md
@@ -45,7 +45,7 @@ Outdated!
#####Compiling Requirements:
->- JDK 1.7
+>- JDK 1.8
>- Maven
>- Git/Github (Optional)
@@ -54,7 +54,7 @@ Outdated!
>- Execute command "mvn clean install"
#####Running Requirements:
->- Java 1.7 or 1.8
+>- Java 1.8
>- PaperSpigot, Spigot or CraftBukkit (1.7.10, 1.8.X, 1.9.X, 1.10.X)
>- ProtocolLib (optional, required by the protectInventory feature)
diff --git a/circle.yml b/circle.yml
index dea5e80c1..80201e5e8 100644
--- a/circle.yml
+++ b/circle.yml
@@ -1,6 +1,6 @@
machine:
java:
- version: oraclejdk7
+ version: oraclejdk8
general:
artifacts:
- "target/AuthMe-*.jar"
diff --git a/pom.xml b/pom.xml
index 01ac56157..4dd41e51b 100644
--- a/pom.xml
+++ b/pom.xml
@@ -46,7 +46,7 @@
UTF-8
- 1.7
+ 1.8
AuthMe
@@ -98,38 +98,38 @@
true
-
- org.spigotmc
- spigot-api
- ${bukkit.version}
- provided
-
-
- junit
- junit
-
-
- json-simple
- com.googlecode.json-simple
-
-
- persistence-api
- javax.persistence
-
-
- guava
- com.google.guava
-
-
- bungeecord-chat
- net.md-5
-
-
- gson
- com.google.code.gson
-
-
-
+
+ org.spigotmc
+ spigot-api
+ ${bukkit.version}
+ provided
+
+
+ junit
+ junit
+
+
+ json-simple
+ com.googlecode.json-simple
+
+
+ persistence-api
+ javax.persistence
+
+
+ guava
+ com.google.guava
+
+
+ bungeecord-chat
+ net.md-5
+
+
+ gson
+ com.google.code.gson
+
+
+
@@ -244,31 +244,35 @@
-
- com.zaxxer.hikari
- fr.xephi.authme.libs.zaxxer.hikari
-
-
- org.slf4j
- fr.xephi.authme.libs.slf4j.slf4j
-
-
- com.maxmind.geoip
- fr.xephi.authme.libs.maxmind.geoip
-
-
- net.ricecode.similarity
- fr.xephi.authme.libs.ricecode.similarity
-
-
- javax.inject
- fr.xephi.authme.libs.javax.inject
-
-
-
- org.mcstats
- fr.xephi.authme
-
+
+ ch.jalu.injector
+ fr.xephi.authme.libs.jalu.injector
+
+
+ com.zaxxer.hikari
+ fr.xephi.authme.libs.zaxxer.hikari
+
+
+ org.slf4j
+ fr.xephi.authme.libs.slf4j.slf4j
+
+
+ com.maxmind.geoip
+ fr.xephi.authme.libs.maxmind.geoip
+
+
+ net.ricecode.similarity
+ fr.xephi.authme.libs.ricecode.similarity
+
+
+ javax.inject
+ fr.xephi.authme.libs.javax.inject
+
+
+
+ org.mcstats
+ fr.xephi.authme
+
target/${project.finalName}-spigot.jar
@@ -287,6 +291,10 @@
com.google
fr.xephi.authme.libs.google
+
+ ch.jalu.injector
+ fr.xephi.authme.libs.jalu.injector
+
com.zaxxer.hikari
fr.xephi.authme.libs.zaxxer.hikari
@@ -421,42 +429,22 @@
-
+
+
+
- com.zaxxer
- HikariCP
- 2.4.7
- compile
-
-
- slf4j-api
- org.slf4j
-
-
- true
-
-
-
- org.slf4j
- slf4j-simple
- 1.7.21
+ ch.jalu
+ injector
+ 0.3
compile
true
-
+
- org.apache.logging.log4j
- log4j-core
- 2.5
- provided
-
-
-
-
- org.apache.commons
- commons-email
- 1.4
+ net.ricecode
+ string-similarity
+ 1.0.0
compile
true
@@ -479,15 +467,6 @@
true
-
-
- javax.inject
- javax.inject
- 1
- compile
- true
-
-
com.maxmind.geoip
@@ -497,6 +476,51 @@
true
+
+
+ org.apache.commons
+ commons-email
+ 1.4
+ compile
+ true
+
+
+
+
+ org.apache.logging.log4j
+ log4j-core
+ 2.5
+ provided
+
+
+
+
+ com.zaxxer
+ HikariCP
+ 2.5.0-SNAPSHOT
+ compile
+
+
+ slf4j-api
+ org.slf4j
+
+
+ true
+
+
+
+ org.slf4j
+ slf4j-simple
+ 1.7.21
+ compile
+ true
+
+
+
+
+
+
+
org.mcstats.bukkit
@@ -512,14 +536,11 @@
true
-
-
-
-
+
com.comphenix.protocol
- ProtocolLib
- 3.6.5-SNAPSHOT
+ ProtocolLib-API
+ 4.1.0-SNAPSHOT
provided
@@ -537,7 +558,7 @@
ru.tehkode
PermissionsEx
- 1.23.1
+ 1.23.4
provided
@@ -559,20 +580,6 @@
-
-
- org.anjocaido
- groupmanagerx
- 2.2-SNAPSHOT
- provided
-
-
- org.bukkit
- bukkit
-
-
-
-
de.bananaco
@@ -591,7 +598,7 @@
org.tyrannyofheaven.bukkit
zPermissions
- 1.3-SNAPSHOT
+ 1.3.1-SNAPSHOT
provided
@@ -625,7 +632,7 @@
net.milkbowl.vault
VaultAPI
- 1.5
+ 1.6
provided
@@ -692,12 +699,12 @@
junit
- spigot-api
- org.spigotmc
+ spigot-api
+ org.spigotmc
- jettison
- org.codehaus.jettison
+ jettison
+ org.codehaus.jettison
@@ -724,7 +731,7 @@
net.minelink
CombatTagPlus
- 1.2.2-SNAPSHOT
+ 1.3.0-SNAPSHOT
provided
@@ -791,6 +798,24 @@
metrics-lite
org.mcstats.bukkit
+
+ net.minelink
+ CombatTagPlusCompat-v1_9_R1
+
+
+ net.minelink
+ CombatTagPlusCompat-v1_9_R2
+
+
+ net.minelink
+
+ CombatTagPlusCompat-v1_10_R1
+
+
+
+ com.google.code.findbugs
+ jsr305
+
@@ -836,22 +861,6 @@
-
-
- ch.jalu
- injector
- 0.3
-
-
-
-
- net.ricecode
- string-similarity
- 1.0.0
- compile
- true
-
-
com.github.authme
@@ -860,18 +869,21 @@
+
junit
junit
test
4.12
+
org.hamcrest
java-hamcrest
test
2.0.0.0
+
org.mockito
mockito-core
@@ -884,6 +896,7 @@
+
org.xerial
@@ -897,5 +910,6 @@
1.4.192
test
+
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index 8d01e4131..42b3bc33d 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -151,7 +151,7 @@ public class AuthMe extends JavaPlugin {
ConsoleLogger.info("Do you want a good game server? Look at our sponsor GameHosting.it leader in Italy as Game Server Provider!");
// Successful message
- ConsoleLogger.info("AuthMe " + getPluginVersion() + " build n°" + getPluginBuildNumber() + " correctly enabled!");
+ ConsoleLogger.info("AuthMe " + getPluginVersion() + " build n." + getPluginBuildNumber() + " correctly enabled!");
// Purge on start if enabled
PurgeService purgeService = injector.getSingleton(PurgeService.class);
diff --git a/src/main/java/fr/xephi/authme/command/CommandInitializer.java b/src/main/java/fr/xephi/authme/command/CommandInitializer.java
index ce02b9a8d..0d5c6da07 100644
--- a/src/main/java/fr/xephi/authme/command/CommandInitializer.java
+++ b/src/main/java/fr/xephi/authme/command/CommandInitializer.java
@@ -282,7 +282,7 @@ public class CommandInitializer {
.description("Converter command")
.detailedDescription("Converter command for AuthMeReloaded.")
.withArgument("job", "Conversion job: xauth / crazylogin / rakamak / " +
- "royalauth / vauth / sqlitetosql", false)
+ "royalauth / vauth / sqliteToSql / mysqlToSqlite", false)
.permission(AdminPermission.CONVERTER)
.executableCommand(ConverterCommand.class)
.build();
diff --git a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java
index a4a064869..a615f3ec9 100644
--- a/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java
+++ b/src/main/java/fr/xephi/authme/command/executable/authme/ConverterCommand.java
@@ -2,11 +2,13 @@ package fr.xephi.authme.command.executable.authme;
import ch.jalu.injector.Injector;
import com.google.common.annotations.VisibleForTesting;
+import com.google.common.collect.ImmutableMap;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.command.CommandService;
import fr.xephi.authme.command.ExecutableCommand;
import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.converter.CrazyLoginConverter;
+import fr.xephi.authme.converter.MySqlToSqlite;
import fr.xephi.authme.converter.RakamakConverter;
import fr.xephi.authme.converter.RoyalAuthConverter;
import fr.xephi.authme.converter.SqliteToSql;
@@ -18,12 +20,16 @@ import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
+import java.util.Map;
/**
* Converter command: launches conversion based on its parameters.
*/
public class ConverterCommand implements ExecutableCommand {
+ @VisibleForTesting
+ static final Map> CONVERTERS = getConverters();
+
@Inject
private CommandService commandService;
@@ -39,14 +45,14 @@ public class ConverterCommand implements ExecutableCommand {
String job = arguments.get(0);
// Determine the job type
- ConvertType jobType = ConvertType.fromName(job);
- if (jobType == null) {
- commandService.send(sender, MessageKey.ERROR);
+ Class extends Converter> converterClass = CONVERTERS.get(job.toLowerCase());
+ if (converterClass == null) {
+ sender.sendMessage("[AuthMe] Converter does not exist!");
return;
}
// Get the proper converter instance
- final Converter converter = injector.newInstance(jobType.getConverterClass());
+ final Converter converter = injector.newInstance(converterClass);
// Run the convert job
bukkitService.runTaskAsynchronously(new Runnable() {
@@ -55,47 +61,31 @@ public class ConverterCommand implements ExecutableCommand {
try {
converter.execute(sender);
} catch (Exception e) {
+ commandService.send(sender, MessageKey.ERROR);
ConsoleLogger.logException("Error during conversion:", e);
}
}
});
// Show a status message
- sender.sendMessage("[AuthMe] Successfully converted from " + jobType.getName());
+ sender.sendMessage("[AuthMe] Successfully started " + job);
}
- @VisibleForTesting
- enum ConvertType {
- XAUTH("xauth", xAuthConverter.class),
- CRAZYLOGIN("crazylogin", CrazyLoginConverter.class),
- RAKAMAK("rakamak", RakamakConverter.class),
- ROYALAUTH("royalauth", RoyalAuthConverter.class),
- VAUTH("vauth", vAuthConverter.class),
- SQLITETOSQL("sqlitetosql", SqliteToSql.class);
-
- private final String name;
- private final Class extends Converter> converterClass;
-
- ConvertType(String name, Class extends Converter> converterClass) {
- this.name = name;
- this.converterClass = converterClass;
- }
-
- public static ConvertType fromName(String name) {
- for (ConvertType type : ConvertType.values()) {
- if (type.getName().equalsIgnoreCase(name)) {
- return type;
- }
- }
- return null;
- }
-
- public String getName() {
- return this.name;
- }
-
- public Class extends Converter> getConverterClass() {
- return converterClass;
- }
+ /**
+ * Initializes a map with all available converters.
+ *
+ * @return map with all available converters
+ */
+ private static Map> getConverters() {
+ return ImmutableMap.>builder()
+ .put("xauth", xAuthConverter.class)
+ .put("crazylogin", CrazyLoginConverter.class)
+ .put("rakamak", RakamakConverter.class)
+ .put("royalauth", RoyalAuthConverter.class)
+ .put("vauth", vAuthConverter.class)
+ .put("sqlitetosql", SqliteToSql.class)
+ .put("mysqltosqlite", MySqlToSqlite.class)
+ .build();
}
+
}
diff --git a/src/main/java/fr/xephi/authme/converter/AbstractDataSourceConverter.java b/src/main/java/fr/xephi/authme/converter/AbstractDataSourceConverter.java
new file mode 100644
index 000000000..19be41c33
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/converter/AbstractDataSourceConverter.java
@@ -0,0 +1,90 @@
+package fr.xephi.authme.converter;
+
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.cache.auth.PlayerAuth;
+import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.datasource.DataSourceType;
+import fr.xephi.authme.util.StringUtils;
+import org.bukkit.command.CommandSender;
+import org.bukkit.command.ConsoleCommandSender;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Converts from one AuthMe data source type to another.
+ *
+ * @param the source type to convert from
+ */
+public abstract class AbstractDataSourceConverter implements Converter {
+
+ private DataSource destination;
+ private DataSourceType destinationType;
+
+ /**
+ * Constructor.
+ *
+ * @param destination the data source to convert to
+ * @param destinationType the data source type of the destination. The given data source is checked that its
+ * type corresponds to this type before the conversion is started, enabling us to just pass
+ * the current data source and letting this class check that the types correspond.
+ */
+ public AbstractDataSourceConverter(DataSource destination, DataSourceType destinationType) {
+ this.destination = destination;
+ this.destinationType = destinationType;
+ }
+
+ // Implementation note: Because of ForceFlatToSqlite it is possible that the CommandSender is null,
+ // which is never the case when a converter is launched from the /authme converter command.
+ @Override
+ public void execute(CommandSender sender) {
+ if (!destinationType.equals(destination.getType())) {
+ if (sender != null) {
+ sender.sendMessage("Please configure your connection to "
+ + destinationType + " and re-run this command");
+ }
+ return;
+ }
+
+ S source;
+ try {
+ source = getSource();
+ } catch (Exception e) {
+ logAndSendMessage(sender, "The data source to convert from could not be initialized");
+ ConsoleLogger.logException("Could not initialize source:", e);
+ return;
+ }
+
+ List skippedPlayers = new ArrayList<>();
+ for (PlayerAuth auth : source.getAllAuths()) {
+ if (destination.isAuthAvailable(auth.getNickname())) {
+ skippedPlayers.add(auth.getNickname());
+ } else {
+ destination.saveAuth(auth);
+ destination.updateQuitLoc(auth);
+ }
+ }
+
+ if (!skippedPlayers.isEmpty()) {
+ logAndSendMessage(sender, "Skipped conversion for players which were already in "
+ + destinationType + ": " + StringUtils.join(", ", skippedPlayers));
+ }
+ logAndSendMessage(sender, "Database successfully converted from " + source.getType()
+ + " to " + destinationType);
+ }
+
+ /**
+ * @return the data source to convert from
+ * @throws Exception during initialization of source
+ */
+ protected abstract S getSource() throws Exception;
+
+ private static void logAndSendMessage(CommandSender sender, String message) {
+ ConsoleLogger.info(message);
+ // Make sure sender is not console user, which will see the message from ConsoleLogger already
+ if (sender != null && !(sender instanceof ConsoleCommandSender)) {
+ sender.sendMessage(message);
+ }
+ }
+
+}
diff --git a/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java b/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java
index 64f89b7e5..321ef2463 100644
--- a/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java
+++ b/src/main/java/fr/xephi/authme/converter/ForceFlatToSqlite.java
@@ -1,21 +1,14 @@
package fr.xephi.authme.converter;
-import fr.xephi.authme.ConsoleLogger;
-import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.FlatFile;
-import fr.xephi.authme.util.StringUtils;
-
-import java.util.ArrayList;
-import java.util.List;
/**
* Mandatory migration from the deprecated flat file datasource to SQLite.
*/
-public class ForceFlatToSqlite {
+public class ForceFlatToSqlite extends AbstractDataSourceConverter {
- private final DataSource source;
- private final DataSource destination;
+ private final FlatFile source;
/**
* Constructor.
@@ -24,29 +17,12 @@ public class ForceFlatToSqlite {
* @param destination The datasource to copy the data to (sqlite)
*/
public ForceFlatToSqlite(FlatFile source, DataSource destination) {
+ super(destination, destination.getType());
this.source = source;
- this.destination = destination;
}
- /**
- * Perform the conversion.
- */
- public void run() {
- List skippedPlayers = new ArrayList<>();
- for (PlayerAuth auth : source.getAllAuths()) {
- if (destination.isAuthAvailable(auth.getNickname())) {
- skippedPlayers.add(auth.getNickname());
- } else {
- destination.saveAuth(auth);
- destination.updateQuitLoc(auth);
- }
- }
-
- if (!skippedPlayers.isEmpty()) {
- ConsoleLogger.warning("Warning: skipped conversion for players which were already in SQLite: "
- + StringUtils.join(", ", skippedPlayers));
- }
- ConsoleLogger.info("Database successfully converted from " + source.getClass().getSimpleName()
- + " to " + destination.getClass().getSimpleName());
+ @Override
+ public FlatFile getSource() {
+ return source;
}
}
diff --git a/src/main/java/fr/xephi/authme/converter/MySqlToSqlite.java b/src/main/java/fr/xephi/authme/converter/MySqlToSqlite.java
new file mode 100644
index 000000000..76e58f960
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/converter/MySqlToSqlite.java
@@ -0,0 +1,28 @@
+package fr.xephi.authme.converter;
+
+import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.datasource.DataSourceType;
+import fr.xephi.authme.datasource.MySQL;
+import fr.xephi.authme.settings.Settings;
+
+import javax.inject.Inject;
+import java.sql.SQLException;
+
+/**
+ * Converts from MySQL to SQLite.
+ */
+public class MySqlToSqlite extends AbstractDataSourceConverter {
+
+ private final Settings settings;
+
+ @Inject
+ MySqlToSqlite(DataSource dataSource, Settings settings) {
+ super(dataSource, DataSourceType.SQLITE);
+ this.settings = settings;
+ }
+
+ @Override
+ protected MySQL getSource() throws SQLException, ClassNotFoundException {
+ return new MySQL(settings);
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/converter/SqliteToSql.java b/src/main/java/fr/xephi/authme/converter/SqliteToSql.java
index dbb127f5e..fafa7e27d 100644
--- a/src/main/java/fr/xephi/authme/converter/SqliteToSql.java
+++ b/src/main/java/fr/xephi/authme/converter/SqliteToSql.java
@@ -1,45 +1,28 @@
package fr.xephi.authme.converter;
-import fr.xephi.authme.ConsoleLogger;
-import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.datasource.SQLite;
-import fr.xephi.authme.output.MessageKey;
-import fr.xephi.authme.output.Messages;
import fr.xephi.authme.settings.Settings;
-import org.bukkit.command.CommandSender;
import javax.inject.Inject;
+import java.sql.SQLException;
-public class SqliteToSql implements Converter {
+/**
+ * Converts from SQLite to MySQL.
+ */
+public class SqliteToSql extends AbstractDataSourceConverter {
private final Settings settings;
- private final DataSource dataSource;
- private final Messages messages;
@Inject
- SqliteToSql(Settings settings, DataSource dataSource, Messages messages) {
+ SqliteToSql(Settings settings, DataSource dataSource) {
+ super(dataSource, DataSourceType.MYSQL);
this.settings = settings;
- this.dataSource = dataSource;
- this.messages = messages;
}
@Override
- public void execute(CommandSender sender) {
- if (dataSource.getType() != DataSourceType.MYSQL) {
- sender.sendMessage("Please configure your mySQL connection and re-run this command");
- return;
- }
- try {
- SQLite data = new SQLite(settings);
- for (PlayerAuth auth : data.getAllAuths()) {
- dataSource.saveAuth(auth);
- }
- } catch (Exception e) {
- messages.send(sender, MessageKey.ERROR);
- ConsoleLogger.logException("Problem during SQLite to SQL conversion:", e);
- }
+ protected SQLite getSource() throws SQLException, ClassNotFoundException {
+ return new SQLite(settings);
}
-
}
diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
index 1db9fbfd6..c0c6981aa 100644
--- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
+++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
@@ -3,7 +3,6 @@ package fr.xephi.authme.permission;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.permission.handlers.BPermissionsHandler;
-import fr.xephi.authme.permission.handlers.GroupManagerHandler;
import fr.xephi.authme.permission.handlers.PermissionHandler;
import fr.xephi.authme.permission.handlers.PermissionHandlerException;
import fr.xephi.authme.permission.handlers.PermissionsBukkitHandler;
@@ -11,7 +10,6 @@ import fr.xephi.authme.permission.handlers.PermissionsExHandler;
import fr.xephi.authme.permission.handlers.VaultHandler;
import fr.xephi.authme.permission.handlers.ZPermissionsHandler;
import fr.xephi.authme.util.StringUtils;
-import org.anjocaido.groupmanager.GroupManager;
import org.bukkit.OfflinePlayer;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
@@ -110,8 +108,6 @@ public class PermissionsManager implements Reloadable {
switch (type) {
case PERMISSIONS_EX:
return new PermissionsExHandler();
- case ESSENTIALS_GROUP_MANAGER:
- return new GroupManagerHandler((GroupManager) plugin);
case Z_PERMISSIONS:
return new ZPermissionsHandler();
case VAULT:
diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java b/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java
index 88b09d193..1410bc668 100644
--- a/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java
+++ b/src/main/java/fr/xephi/authme/permission/PermissionsSystemType.java
@@ -20,11 +20,6 @@ public enum PermissionsSystemType {
*/
B_PERMISSIONS("bPermissions", "bPermissions"),
- /**
- * Essentials Group Manager.
- */
- ESSENTIALS_GROUP_MANAGER("Essentials Group Manager", "GroupManager"),
-
/**
* zPermissions.
*/
diff --git a/src/main/java/fr/xephi/authme/permission/handlers/GroupManagerHandler.java b/src/main/java/fr/xephi/authme/permission/handlers/GroupManagerHandler.java
deleted file mode 100644
index a952c124d..000000000
--- a/src/main/java/fr/xephi/authme/permission/handlers/GroupManagerHandler.java
+++ /dev/null
@@ -1,84 +0,0 @@
-package fr.xephi.authme.permission.handlers;
-
-import fr.xephi.authme.permission.PermissionNode;
-import fr.xephi.authme.permission.PermissionsSystemType;
-import org.anjocaido.groupmanager.GroupManager;
-import org.anjocaido.groupmanager.permissions.AnjoPermissionsHandler;
-import org.bukkit.Bukkit;
-import org.bukkit.entity.Player;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-
-public class GroupManagerHandler implements PermissionHandler {
-
- private GroupManager groupManager;
-
- public GroupManagerHandler(GroupManager groupManager) {
- this.groupManager = groupManager;
- }
-
- @Override
- public boolean addToGroup(Player player, String group) {
- return Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "manuaddsub " + player.getName() + " " + group);
- }
-
- @Override
- public boolean hasGroupSupport() {
- return true;
- }
-
- @Override
- public boolean hasPermissionOffline(String name, PermissionNode node) {
- final AnjoPermissionsHandler handler = groupManager.getWorldsHolder().getWorldPermissionsByPlayerName(name);
- if(handler == null) {
- return false;
- }
-
- List perms = handler.getAllPlayersPermissions(name);
- return perms.contains(node.getNode());
- }
-
- @Override
- public boolean isInGroup(Player player, String group) {
- final AnjoPermissionsHandler handler = groupManager.getWorldsHolder().getWorldPermissions(player);
- return handler != null && handler.inGroup(player.getName(), group);
- }
-
- @Override
- public boolean removeFromGroup(Player player, String group) {
- return Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "manudelsub " + player.getName() + " " + group);
- }
-
- @Override
- public boolean setGroup(Player player, String group) {
- final AnjoPermissionsHandler handler = groupManager.getWorldsHolder().getWorldPermissions(player);
- for (String groupName : handler.getGroups(player.getName())) {
- removeFromGroup(player, groupName);
- }
-
- return Bukkit.dispatchCommand(Bukkit.getConsoleSender(), "manuadd " + player.getName() + " " + group);
- }
-
- @Override
- public List getGroups(Player player) {
- final AnjoPermissionsHandler handler = groupManager.getWorldsHolder().getWorldPermissions(player);
- if (handler == null)
- return new ArrayList<>();
- return Arrays.asList(handler.getGroups(player.getName()));
- }
-
- @Override
- public String getPrimaryGroup(Player player) {
- final AnjoPermissionsHandler handler = groupManager.getWorldsHolder().getWorldPermissions(player);
- if (handler == null)
- return null;
- return handler.getGroup(player.getName());
- }
-
- @Override
- public PermissionsSystemType getPermissionSystem() {
- return PermissionsSystemType.ESSENTIALS_GROUP_MANAGER;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
index ac5b90a6e..aa3f3783d 100644
--- a/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
+++ b/src/main/java/fr/xephi/authme/settings/properties/SecuritySettings.java
@@ -89,7 +89,7 @@ public class SecuritySettings implements SettingsHolder {
"- '123456'",
"- 'password'"})
public static final Property> UNSAFE_PASSWORDS =
- newLowercaseListProperty("settings.security.unsafePasswords", "123456", "password", "qwerty", "12345", "54321");
+ newLowercaseListProperty("settings.security.unsafePasswords", "123456", "password", "qwerty", "12345", "54321", "123456789");
@Comment("Tempban a user's IP address if they enter the wrong password too many times")
public static final Property TEMPBAN_ON_MAX_LOGINS =
diff --git a/src/main/java/fr/xephi/authme/util/MigrationService.java b/src/main/java/fr/xephi/authme/util/MigrationService.java
index cc0ef72a4..7b0a32d0a 100644
--- a/src/main/java/fr/xephi/authme/util/MigrationService.java
+++ b/src/main/java/fr/xephi/authme/util/MigrationService.java
@@ -69,7 +69,7 @@ public final class MigrationService {
try {
SQLite sqlite = new SQLite(settings);
ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, sqlite);
- converter.run();
+ converter.execute(null);
settings.setProperty(DatabaseSettings.BACKEND, DataSourceType.SQLITE);
settings.save();
return sqlite;
diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml
index bfa09d74e..07f3c3c7e 100644
--- a/src/main/resources/config.yml
+++ b/src/main/resources/config.yml
@@ -206,6 +206,7 @@ settings:
- 'qwerty'
- '12345'
- '54321'
+ - '123456789'
registration:
# enable registration on the server?
enabled: true
diff --git a/src/main/resources/messages/messages_pt.yml b/src/main/resources/messages/messages_pt.yml
index c6a714c75..4b2cb410a 100644
--- a/src/main/resources/messages/messages_pt.yml
+++ b/src/main/resources/messages/messages_pt.yml
@@ -7,12 +7,11 @@ wrong_pwd: '&cPassword errada!'
unregistered: '&cRegisto eliminado com sucesso!'
reg_disabled: '&cRegito de novos utilizadores desactivado'
valid_session: '&cSessão válida'
-login: '&cAutenticado com sucesso!'
+login: '&bAutenticado com sucesso!'
vb_nonActiv: '&fA sua conta não foi ainda activada, verifique o seu email onde irá receber indicações para activação de conta. '
user_regged: '&cUtilizador já registado'
usage_reg: '&cUse: /register seu@email.com seu@email.com'
-# TODO max_reg: Missing tags %reg_count, %reg_names, %max_acc
-max_reg: '&cAtingiu o numero máximo de registos permitidos'
+max_reg: '&cAtingiu o numero máximo de %reg_count contas registas, maximo de contas %max_acc'
no_perm: '&cSem Permissões'
error: '&fOcorreu um erro; Por favor contacte um admin'
login_msg: '&cIdentifique-se com "/login password"'
@@ -36,7 +35,7 @@ name_len: '&cO seu nick é demasiado curto ou muito longo.'
regex: '&cO seu nickname contém caracteres não permitidos. Permitido: REG_EX'
add_email: '&cPor favor adicione o seu email com : /email add seuEmail confirmarSeuEmail'
recovery_email: '&cPerdeu a sua password? Para a recuperar escreva /email recovery '
-usage_captcha: '&cVocê precisa digitar um captcha, escreva: /captcha '
+usage_captcha: '&cPrecisa digitar um captcha, escreva: /captcha '
wrong_captcha: '&cCaptcha errado, por favor escreva: /captcha THE_CAPTCHA'
valid_captcha: '&cO seu captcha é válido!'
kick_forvip: '&cUm jogador VIP entrou no servidor cheio!'
@@ -55,20 +54,20 @@ email_send: 'Nova palavra-passe enviada para o seu email!'
country_banned: 'O seu país está banido deste servidor'
antibot_auto_enabled: '[AuthMe] AntiBotMod activado automaticamente devido a um aumento anormal de tentativas de ligação!'
antibot_auto_disabled: '[AuthMe] AntiBotMod desactivado automaticamente após %m minutos, esperamos que a invasão tenha parado'
-# TODO password_error_nick: '&cYou can''t use your name as password, please choose another one...'
-# TODO email_already_used: '&4The email address is already being used'
-# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
-# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
-# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
+password_error_nick: '&cNão pode o usar seu nome como senha, por favor, escolha outra ...'
+not_owner_error: 'Não é o proprietário da conta. Por favor, escolha outro nome!'
+two_factor_create: '&2O seu código secreto é o %code. Você pode verificá-lo a partir daqui %url'
+email_already_used: '&4O endereço de e-mail já está sendo usado'
+denied_command: '&cPara utilizar este comando é necessário estar logado!'
+same_ip_online: 'Um jogador com o mesmo IP já está em jogo!'
+password_error_chars: '&4Sua senha contém caracteres ilegais. caracteres permitidos: REG_EX'
+denied_chat: '&cPara usar o chat deve estar logado!'
+password_error_unsafe: '&cA senha escolhida não é segura, por favor, escolha outra ...'
+kick_antibot: 'Modo de protecção anti-Bot está habilitado! Tem que espere alguns minutos antes de entrar no servidor.'
+email_exists: '&cUm e-mail de recuperação já foi enviado! Pode descartá-lo e enviar um novo usando o comando abaixo:'
+invalid_name_case: 'Deve se juntar usando nome de usuário %valid, não %invalid.'
# TODO accounts_owned_other: 'The player %name has %count accounts:'
# TODO kicked_admin_registered: 'An admin just registered you; please log in again'
# TODO tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.'
-# TODO password_error_chars: '&4Your password contains illegal characters. Allowed chars: REG_EX'
# TODO incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
-# TODO denied_chat: '&cIn order to chat you must be authenticated!'
-# TODO denied_command: '&cIn order to use this command you must be authenticated!'
-# TODO same_ip_online: 'A player with the same IP is already in game!'
-# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
# TODO accounts_owned_self: 'You own %count accounts:'
-# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
-# TODO not_owner_error: 'You are not the owner of this account. Please choose another name!'
\ No newline at end of file
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index 769f9fffc..f6af6d4c7 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -8,7 +8,8 @@ softdepend:
- Vault
- PermissionsBukkit
- PermissionsEX
- - EssentialsGroupManager
+ - bPermissions
+ - zPermissions
- Multiverse-Core
- Essentials
- EssentialsSpawn
diff --git a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
index 2f4eaa944..a978833a4 100644
--- a/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
+++ b/src/test/java/fr/xephi/authme/command/executable/authme/ConverterCommandTest.java
@@ -3,25 +3,30 @@ package fr.xephi.authme.command.executable.authme;
import ch.jalu.injector.Injector;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.command.CommandService;
-import fr.xephi.authme.converter.RakamakConverter;
+import fr.xephi.authme.converter.Converter;
import fr.xephi.authme.output.MessageKey;
import fr.xephi.authme.util.BukkitService;
+import fr.xephi.authme.util.StringUtils;
import org.bukkit.command.CommandSender;
+import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;
-import java.util.ArrayList;
import java.util.Collections;
-import java.util.List;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
-import static org.hamcrest.Matchers.hasItem;
-import static org.hamcrest.Matchers.not;
-import static org.hamcrest.Matchers.nullValue;
+import static org.hamcrest.Matchers.containsString;
+import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.BDDMockito.given;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.doThrow;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyNoMoreInteractions;
@@ -45,6 +50,11 @@ public class ConverterCommandTest {
@Mock
private Injector injector;
+ @BeforeClass
+ public static void initLogger() {
+ TestHelper.setupLogger();
+ }
+
@Test
public void shouldHandleUnknownConversionType() {
// given
@@ -54,51 +64,71 @@ public class ConverterCommandTest {
command.executeCommand(sender, Collections.singletonList("invalid"));
// then
- verify(commandService).send(sender, MessageKey.ERROR);
+ verify(sender).sendMessage(argThat(containsString("Converter does not exist")));
verifyNoMoreInteractions(commandService);
verifyZeroInteractions(injector);
verifyZeroInteractions(bukkitService);
}
@Test
- public void shouldHaveUniqueNameAndClassForEachType() {
+ public void shouldHaveUniqueClassForEachConverter() {
// given
- ConverterCommand.ConvertType[] types = ConverterCommand.ConvertType.values();
- List names = new ArrayList<>(types.length);
- List> classes = new ArrayList<>(types.length);
+ Set> classes = new HashSet<>();
// when / then
- for (ConverterCommand.ConvertType type : types) {
- assertThat("Name for '" + type + "' is not null",
- type.getName(), not(nullValue()));
- assertThat("Class for '" + type + "' is not null",
- type.getConverterClass(), not(nullValue()));
- assertThat("Name '" + type.getName() + "' is unique",
- names, not(hasItem(type.getName())));
- assertThat("Class '" + type.getConverterClass() + "' is unique",
- classes, not(hasItem(type.getConverterClass())));
- names.add(type.getName());
- classes.add(type.getConverterClass());
+ for (Map.Entry> entry : ConverterCommand.CONVERTERS.entrySet()) {
+ assertThat("Name is not null or empty",
+ StringUtils.isEmpty(entry.getKey()), equalTo(false));
+
+ assertThat("Converter class is unique for each entry",
+ classes.add(entry.getValue()), equalTo(true));
}
}
@Test
public void shouldLaunchConverterForAllTypes() {
// given
- ConverterCommand.ConvertType type = ConverterCommand.ConvertType.RAKAMAK;
- RakamakConverter converter = mock(RakamakConverter.class);
- given(injector.newInstance(RakamakConverter.class)).willReturn(converter);
+ String converterName = "rakamak";
+ Class extends Converter> converterClass = ConverterCommand.CONVERTERS.get(converterName);
+ Converter converter = createMockReturnedByInjector(converterClass);
CommandSender sender = mock(CommandSender.class);
// when
- command.executeCommand(sender, Collections.singletonList(type.getName()));
+ command.executeCommand(sender, Collections.singletonList(converterName));
TestHelper.runInnerRunnable(bukkitService);
// then
verify(converter).execute(sender);
verifyNoMoreInteractions(converter);
- verify(injector).newInstance(type.getConverterClass());
+ verify(injector).newInstance(converterClass);
verifyNoMoreInteractions(injector);
}
+ @Test
+ public void shouldCatchExceptionInConverterAndInformSender() {
+ // given
+ String converterName = "vauth";
+ Class extends Converter> converterClass = ConverterCommand.CONVERTERS.get(converterName);
+ Converter converter = createMockReturnedByInjector(converterClass);
+ doThrow(IllegalStateException.class).when(converter).execute(any(CommandSender.class));
+ CommandSender sender = mock(CommandSender.class);
+
+ // when
+ command.executeCommand(sender, Collections.singletonList(converterName.toUpperCase()));
+ TestHelper.runInnerRunnable(bukkitService);
+
+ // then
+ verify(converter).execute(sender);
+ verifyNoMoreInteractions(converter);
+ verify(injector).newInstance(converterClass);
+ verifyNoMoreInteractions(injector);
+ verify(commandService).send(sender, MessageKey.ERROR);
+ }
+
+ private T createMockReturnedByInjector(Class clazz) {
+ T converter = mock(clazz);
+ given(injector.newInstance(clazz)).willReturn(converter);
+ return converter;
+ }
+
}
diff --git a/src/test/java/fr/xephi/authme/converter/AbstractDataSourceConverterTest.java b/src/test/java/fr/xephi/authme/converter/AbstractDataSourceConverterTest.java
new file mode 100644
index 000000000..a14923f3a
--- /dev/null
+++ b/src/test/java/fr/xephi/authme/converter/AbstractDataSourceConverterTest.java
@@ -0,0 +1,126 @@
+package fr.xephi.authme.converter;
+
+import fr.xephi.authme.TestHelper;
+import fr.xephi.authme.cache.auth.PlayerAuth;
+import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.datasource.DataSourceType;
+import org.bukkit.command.CommandSender;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.mockito.Mockito;
+
+import java.util.Arrays;
+import java.util.List;
+
+import static org.hamcrest.Matchers.containsString;
+import static org.mockito.BDDMockito.given;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.argThat;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.only;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.verifyNoMoreInteractions;
+import static org.mockito.Mockito.verifyZeroInteractions;
+
+/**
+ * Test for {@link AbstractDataSourceConverter}.
+ */
+public class AbstractDataSourceConverterTest {
+
+ @BeforeClass
+ public static void initLogger() {
+ TestHelper.setupLogger();
+ }
+
+ @Test
+ public void shouldThrowForDestinationTypeMismatch() {
+ // given
+ DataSource destination = mock(DataSource.class);
+ given(destination.getType()).willReturn(DataSourceType.MYSQL);
+ DataSourceType destinationType = DataSourceType.SQLITE;
+ DataSource source = mock(DataSource.class);
+ Converter converter = new DataSourceConverterTestImpl<>(source, destination, destinationType);
+ CommandSender sender = mock(CommandSender.class);
+
+ // when
+ converter.execute(sender);
+
+ // then
+ verify(sender).sendMessage(argThat(containsString("Please configure your connection to SQLITE")));
+ verify(destination, only()).getType();
+ verifyZeroInteractions(source);
+ }
+
+ @Test
+ public void shouldHandleSourceThrowingException() {
+ // given
+ DataSource source = mock(DataSource.class);
+ DataSource destination = mock(DataSource.class);
+ DataSourceType destinationType = DataSourceType.SQLITE;
+ given(destination.getType()).willReturn(destinationType);
+ DataSourceConverterTestImpl converter =
+ Mockito.spy(new DataSourceConverterTestImpl<>(source, destination, destinationType));
+ doThrow(IllegalStateException.class).when(converter).getSource();
+ CommandSender sender = mock(CommandSender.class);
+
+ // when
+ converter.execute(sender);
+
+ // then
+ verify(sender).sendMessage("The data source to convert from could not be initialized");
+ verify(destination, only()).getType();
+ verifyZeroInteractions(source);
+ }
+
+ @Test
+ public void shouldConvertAndSkipExistingPlayers() {
+ // given
+ DataSource source = mock(DataSource.class);
+ DataSource destination = mock(DataSource.class);
+ DataSourceType destinationType = DataSourceType.MYSQL;
+ given(destination.getType()).willReturn(destinationType);
+
+ List auths =
+ Arrays.asList(mockAuthWithName("Steven"), mockAuthWithName("bobby"), mockAuthWithName("Jack"));
+ given(source.getAllAuths()).willReturn(auths);
+ given(destination.isAuthAvailable(auths.get(0).getNickname())).willReturn(true);
+
+ Converter converter = new DataSourceConverterTestImpl<>(source, destination, destinationType);
+ CommandSender sender = mock(CommandSender.class);
+
+ // when
+ converter.execute(sender);
+
+ // then
+ verify(destination).getType();
+ verify(destination, times(3)).isAuthAvailable(anyString());
+ verify(destination, times(2)).saveAuth(any(PlayerAuth.class));
+ verify(destination, times(2)).updateQuitLoc(any(PlayerAuth.class));
+ verifyNoMoreInteractions(destination);
+ verify(sender).sendMessage(argThat(containsString(auths.get(0).getNickname())));
+ verify(sender).sendMessage(argThat(containsString("successfully converted")));
+ }
+
+ private static PlayerAuth mockAuthWithName(String name) {
+ PlayerAuth auth = mock(PlayerAuth.class);
+ given(auth.getNickname()).willReturn(name);
+ return auth;
+ }
+
+ private static class DataSourceConverterTestImpl extends AbstractDataSourceConverter {
+ private final S source;
+
+ DataSourceConverterTestImpl(S source, DataSource destination, DataSourceType destinationType) {
+ super(destination, destinationType);
+ this.source = source;
+ }
+
+ @Override
+ protected S getSource() {
+ return source;
+ }
+ }
+}
diff --git a/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java b/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java
index 903c58ff3..273d5530f 100644
--- a/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java
+++ b/src/test/java/fr/xephi/authme/converter/ForceFlatToSqliteTest.java
@@ -4,6 +4,7 @@ import com.google.common.io.Files;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.datasource.DataSourceType;
import fr.xephi.authme.datasource.FlatFile;
import org.junit.Before;
import org.junit.BeforeClass;
@@ -20,6 +21,7 @@ import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData;
import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation;
import static org.hamcrest.Matchers.hasItem;
import static org.junit.Assert.assertThat;
+import static org.mockito.BDDMockito.given;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.times;
import static org.mockito.Mockito.verify;
@@ -51,10 +53,11 @@ public class ForceFlatToSqliteTest {
public void shouldConvertToSqlite() {
// given
DataSource dataSource = mock(DataSource.class);
+ given(dataSource.getType()).willReturn(DataSourceType.MYSQL);
ForceFlatToSqlite converter = new ForceFlatToSqlite(flatFile, dataSource);
// when
- converter.run();
+ converter.execute(null);
// then
ArgumentCaptor authCaptor = ArgumentCaptor.forClass(PlayerAuth.class);