diff --git a/pom.xml b/pom.xml index 24f44db0c..4a5292ce8 100644 --- a/pom.xml +++ b/pom.xml @@ -37,12 +37,12 @@ - nexus-snapshots - https://nexus.authme.eu/repository/maven-snapshots/ + codemc-snapshots + https://repo.codemc.org/repository/maven-snapshots/ - nexus-releases - https://nexus.authme.eu/repository/maven-releases/ + codemc-releases + https://repo.codemc.org/repository/maven-releases/ @@ -57,7 +57,8 @@ UTF-8 - 1.8 + UTF-8 + 1.8 AuthMe @@ -104,6 +105,7 @@ + clean install ${project.outputName}-${project.version} @@ -126,17 +128,44 @@ - + + org.apache.maven.plugins + maven-clean-plugin + 3.0.0 + + + org.apache.maven.plugins + maven-resources-plugin + 3.0.2 + org.apache.maven.plugins maven-compiler-plugin 3.7.0 - ${project.jdkVersion} - ${project.jdkVersion} + ${jdk.version} + ${jdk.version} - + + org.jacoco + jacoco-maven-plugin + 0.8.0 + + + pre-unit-test + + prepare-agent + + + + post-unit-test + + report + + + + org.apache.maven.plugins maven-surefire-plugin @@ -149,13 +178,47 @@ - + + org.apache.maven.plugins + maven-jar-plugin + 3.0.2 + + + org.apache.maven.plugins + maven-javadoc-plugin + 2.10.4 + + + attach-javadocs + + aggregate + jar + + + + + public + false + + + + org.apache.maven.plugins + maven-source-plugin + 3.0.1 + + + attach-sources + + jar + + + + org.apache.maven.plugins maven-shade-plugin 3.1.0 - package @@ -165,7 +228,7 @@ false - true + - org.jacoco - jacoco-maven-plugin - 0.7.9 + org.apache.maven.plugins + maven-install-plugin + 2.5.2 - prepare-agent + default-install + none + + + install-custom + install - prepare-agent + install-file - - - - org.eluder.coveralls - coveralls-maven-plugin - 4.3.0 - false + pom.xml + target/original-${project.build.finalName}.jar + target/${project.build.finalName}-javadoc.jar + target/${project.build.finalName}-sources.jar - - - - - org.apache.maven.plugins - maven-javadoc-plugin - 2.10.4 - - public - false - - - - attach-javadocs - deploy - jar - - org.apache.maven.plugins maven-deploy-plugin 2.8.2 - - - deploy + + + default-deploy + none + + + deploy-custom deploy - deploy - - + + deploy-file + + + + + + ${project.distributionManagement.snapshotRepository.id} + ${project.distributionManagement.snapshotRepository.url} + pom.xml + target/original-${project.build.finalName}.jar + + + + + org.eluder.coveralls + coveralls-maven-plugin + 4.3.0 + + + false + @@ -360,7 +432,7 @@ com.google.guava guava - 23.5-jre + 23.6-jre compile true @@ -395,15 +467,15 @@ com.zaxxer HikariCP - 2.7.4 + 2.7.6 compile + true slf4j-api org.slf4j - true @@ -428,6 +500,8 @@ de.mkammerer argon2-jvm-nolibs 2.3 + compile + true @@ -462,6 +536,21 @@ + + + ch.jalu + configme + 0.4.1 + compile + true + + + org.yaml + snakeyaml + + + + org.bstats @@ -501,7 +590,7 @@ ru.tehkode PermissionsEx - 1.23.4 + 1.23.5 provided @@ -680,7 +769,7 @@ net.ess3 Essentials - 2.13-SNAPSHOT + 2.13.1 provided @@ -736,21 +825,6 @@ - - - ch.jalu - configme - 0.4.1 - compile - true - - - org.yaml - snakeyaml - - - - diff --git a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java index 25bdb209e..575c61ab1 100644 --- a/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java +++ b/src/main/java/fr/xephi/authme/api/v3/AuthMeApi.java @@ -167,7 +167,7 @@ public class AuthMeApi { * @param playerName The name of the player to process * * @return The date of the last login, or null if the player doesn't exist or has never logged in - * @Deprecated Use Java 8's Instant method {@link #getLastLoginTime(String)} + * @deprecated Use Java 8's Instant method {@link #getLastLoginTime(String)} */ @Deprecated public Date getLastLogin(String playerName) { diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java index 4924e0cc0..422d57b17 100644 --- a/src/main/java/fr/xephi/authme/datasource/SQLite.java +++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java @@ -41,6 +41,7 @@ public class SQLite implements DataSource { * Constructor for SQLite. * * @param settings The settings instance + * @param dataFolder The data folder * * @throws SQLException when initialization of a SQL datasource failed */ diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java index b661d2ca1..ef9d8bdde 100644 --- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java +++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java @@ -1,5 +1,6 @@ package fr.xephi.authme.permission; +import com.google.common.annotations.VisibleForTesting; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.initialization.Reloadable; import fr.xephi.authme.listener.JoiningPlayer; @@ -41,8 +42,7 @@ public class PermissionsManager implements Reloadable { private final Server server; private final PluginManager pluginManager; - - private Settings settings; + private final Settings settings; /** * The permission handler that is currently in use. @@ -50,14 +50,8 @@ public class PermissionsManager implements Reloadable { */ private PermissionHandler handler = null; - /** - * Constructor. - * - * @param server Server instance - * @param pluginManager Bukkit plugin manager - */ @Inject - public PermissionsManager(Server server, PluginManager pluginManager, Settings settings) { + PermissionsManager(Server server, PluginManager pluginManager, Settings settings) { this.server = server; this.pluginManager = pluginManager; this.settings = settings; @@ -76,7 +70,8 @@ public class PermissionsManager implements Reloadable { * Setup and hook into the permissions systems. */ @PostConstruct - private void setup() { + @VisibleForTesting + void setup() { if (settings.getProperty(PluginSettings.FORCE_VAULT_HOOK)) { try { PermissionHandler handler = createPermissionHandler(PermissionsSystemType.VAULT); diff --git a/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java b/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java index 2c30c030e..ad46a35ca 100644 --- a/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java +++ b/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java @@ -36,8 +36,7 @@ public class LuckPermsHandler implements PermissionHandler { try { luckPermsApi = LuckPerms.getApi(); } catch (IllegalStateException e) { - e.printStackTrace(); - throw new PermissionHandlerException("Could not get api of LuckPerms"); + throw new PermissionHandlerException("Could not get api of LuckPerms", e); } } diff --git a/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java b/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java index 3037c4dd1..a0de9ada1 100644 --- a/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java +++ b/src/main/java/fr/xephi/authme/permission/handlers/PermissionHandlerException.java @@ -9,4 +9,8 @@ public class PermissionHandlerException extends Exception { public PermissionHandlerException(String message) { super(message); } + + public PermissionHandlerException(String message, Throwable cause) { + super(message, cause); + } } diff --git a/src/main/resources/messages/messages_it.yml b/src/main/resources/messages/messages_it.yml index 4f8726e5a..c739bec93 100644 --- a/src/main/resources/messages/messages_it.yml +++ b/src/main/resources/messages/messages_it.yml @@ -68,7 +68,7 @@ country_banned: '&4Il tuo paese è bandito da questo server!' not_owner_error: 'Non sei il proprietario di questo account. Per favore scegli un altro nome!' kick_fullserver: '&4Il server è attualmente pieno, riprova più tardi!' same_nick: '&4Un giocatore con il tuo stesso nome utente è già connesso sul server!' -invalid_name_case: 'Dovresti entrare con questo nome utente: "%valid", al posto di: "%invalid".' +invalid_name_case: 'Dovresti entrare con questo nome utente "%valid", al posto di "%invalid".' same_ip_online: 'Un giocatore con il tuo stesso IP è già connesso sul server!' # Email @@ -94,15 +94,15 @@ email_cooldown_error: '&cUna email di recupero ti è già stata inviata recentem # Captcha usage_captcha: '&3Per poterti autenticare devi risolvere un captcha, per favore scrivi: /captcha ' -wrong_captcha: '&cCaptcha sbagliato, per favore riprova scrivendo: "/captcha THE_CAPTCHA" in chat!' +wrong_captcha: '&cCaptcha sbagliato, per favore riprova scrivendo "/captcha THE_CAPTCHA" in chat!' valid_captcha: '&2Il captcha inserito è valido!' -# TODO captcha_for_registration: 'To register you have to solve a captcha first, please use the command: /captcha ' -# TODO register_captcha_valid: '&2Valid captcha! You may now register with /register' +captcha_for_registration: 'Per poterti registrare devi prima risolvere un captcha, per favore scrivi: /captcha ' +register_captcha_valid: '&2Il captcha inserito è valido! Ora puoi eseguire la registrazione con: /register ' # Codice di verifica verification_code_required: '&3Questo comando va a modificare dati sensibili e richiede una verifica tramite email! Controlla la tua posta in arrivo e segui le istruzioni nell''email.' usage_verification_code: '&cUtilizzo: /verification ' -incorrect_verification_code: '&cCodice sbagliato, per favore riprova scrivendo: "/verification " in chat, usando il codice che hai ricevuto tramite email' +incorrect_verification_code: '&cCodice sbagliato, per favore riprova scrivendo "/verification " in chat, usando il codice che hai ricevuto tramite email' verification_code_verified: '&2La tua identità è stata verificata! Ora puoi eseguire tutti i comandi che modificano dati sensibili per questa sessione!' verification_code_already_verified: '&2Puoi già eseguire tutti i comandi che modificano dati sensibili per questa sessione!' verification_code_expired: '&3Il tuo codice è scaduto! Esegui nuovamente un comando che modifica dati sensibili per ricevere uno nuovo codice!' diff --git a/src/test/java/fr/xephi/authme/permission/PermissionsManagerInitializationTest.java b/src/test/java/fr/xephi/authme/permission/PermissionsManagerInitializationTest.java new file mode 100644 index 000000000..d2cf51453 --- /dev/null +++ b/src/test/java/fr/xephi/authme/permission/PermissionsManagerInitializationTest.java @@ -0,0 +1,191 @@ +package fr.xephi.authme.permission; + +import com.google.common.collect.ImmutableMap; +import fr.xephi.authme.ReflectionTestUtils; +import fr.xephi.authme.TestHelper; +import fr.xephi.authme.permission.handlers.BPermissionsHandler; +import fr.xephi.authme.permission.handlers.LuckPermsHandler; +import fr.xephi.authme.permission.handlers.PermissionHandler; +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.settings.Settings; +import fr.xephi.authme.settings.properties.PluginSettings; +import me.lucko.luckperms.LuckPerms; +import me.lucko.luckperms.api.LuckPermsApi; +import net.milkbowl.vault.permission.Permission; +import org.bukkit.Bukkit; +import org.bukkit.Server; +import org.bukkit.plugin.Plugin; +import org.bukkit.plugin.PluginManager; +import org.bukkit.plugin.RegisteredServiceProvider; +import org.bukkit.plugin.ServicesManager; +import org.junit.AssumptionViolatedException; +import org.junit.Before; +import org.junit.BeforeClass; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.Parameterized; +import org.tyrannyofheaven.bukkit.zPermissions.ZPermissionsService; + +import java.util.Collection; +import java.util.Map; +import java.util.stream.Collectors; + +import static com.google.common.collect.Sets.newHashSet; +import static fr.xephi.authme.permission.PermissionsSystemType.B_PERMISSIONS; +import static fr.xephi.authme.permission.PermissionsSystemType.LUCK_PERMS; +import static fr.xephi.authme.permission.PermissionsSystemType.PERMISSIONS_EX; +import static fr.xephi.authme.permission.PermissionsSystemType.VAULT; +import static fr.xephi.authme.permission.PermissionsSystemType.Z_PERMISSIONS; +import static org.hamcrest.Matchers.instanceOf; +import static org.hamcrest.Matchers.nullValue; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.only; +import static org.mockito.Mockito.verify; + +/** + * Tests the initialization of {@link PermissionHandler} in {@link PermissionsManager}. + */ +@RunWith(Parameterized.class) +public class PermissionsManagerInitializationTest { + + @Parameterized.Parameter(0) + public PermissionsSystemType permissionsSystemType; + @Parameterized.Parameter(1) + public Class expectedHandlerType; + + private Settings settings = mock(Settings.class); + private ServicesManager servicesManager = mock(ServicesManager.class); + private Server server = mock(Server.class); + private PluginManager pluginManager = mock(PluginManager.class); + private PermissionsManager permissionsManager = new PermissionsManager(server, pluginManager, settings); + + @BeforeClass + public static void setUpLogger() { + TestHelper.setRealLogger(); + } + + @Before + public void setUp() { + ReflectionTestUtils.setField(Bukkit.class, null, "server", server); + given(server.getServicesManager()).willReturn(servicesManager); + } + + @Test + public void shouldInitializeHandler() { + // given + setUpForPermissionSystemTest(); + given(settings.getProperty(PluginSettings.FORCE_VAULT_HOOK)).willReturn(false); + Plugin plugin = mock(Plugin.class); + given(plugin.isEnabled()).willReturn(true); + given(pluginManager.getPlugin(permissionsSystemType.getPluginName())).willReturn(plugin); + + // when + permissionsManager.setup(); + + // then + PermissionHandler handler = getHandlerFieldValue(); + assertThat(handler, instanceOf(expectedHandlerType)); + } + + @Test + public void shouldInitializeToVaultIfSoConfigured() { + // given + setUpForVault(); + given(settings.getProperty(PluginSettings.FORCE_VAULT_HOOK)).willReturn(true); + Plugin plugin = mock(Plugin.class); + given(plugin.isEnabled()).willReturn(true); + given(pluginManager.getPlugin(VAULT.getPluginName())).willReturn(plugin); + + // when + permissionsManager.setup(); + + // then + PermissionHandler handler = getHandlerFieldValue(); + assertThat(handler, instanceOf(VaultHandler.class)); + verify(pluginManager, only()).getPlugin(VAULT.getPluginName()); + } + + @Test + public void shouldNotHookIntoDisabledPlugin() { + // given + given(settings.getProperty(PluginSettings.FORCE_VAULT_HOOK)).willReturn(false); + Plugin plugin = mock(Plugin.class); + given(plugin.isEnabled()).willReturn(false); + given(pluginManager.getPlugin(permissionsSystemType.getPluginName())).willReturn(plugin); + + // when + permissionsManager.setup(); + + // then + assertThat(getHandlerFieldValue(), nullValue()); + } + + @Test + public void shouldCatchInitializationException() { + // given + given(settings.getProperty(PluginSettings.FORCE_VAULT_HOOK)).willReturn(false); + Plugin plugin = mock(Plugin.class); + // Typically we'd expect a PermissionHandler exception further down the line but we can test it easily like this + given(plugin.isEnabled()).willThrow(new IllegalStateException("Some exception occurred")); + given(pluginManager.getPlugin(permissionsSystemType.getPluginName())).willReturn(plugin); + + // when + permissionsManager.setup(); + + // then + assertThat(getHandlerFieldValue(), nullValue()); + } + + @Parameterized.Parameters(name = "{0}") + public static Collection createParameters() { + Map> handlersByPermissionSystemType = ImmutableMap.of( + LUCK_PERMS, LuckPermsHandler.class, + PERMISSIONS_EX, PermissionsExHandler.class, + B_PERMISSIONS, BPermissionsHandler.class, + Z_PERMISSIONS, ZPermissionsHandler.class, + VAULT, VaultHandler.class); + + // Verify that all handlers are present -> reminder to add any new entry here as well + if (!handlersByPermissionSystemType.keySet().equals(newHashSet(PermissionsSystemType.values()))) { + throw new IllegalStateException("Test is not set up with all " + + PermissionsSystemType.class.getSimpleName() + " entries"); + } + + // Wrap the above map in a Collection to satisfy JUnit + return handlersByPermissionSystemType.entrySet().stream() + .map(e -> new Object[]{ e.getKey(), e.getValue() }) + .collect(Collectors.toList()); + } + + private void setUpForPermissionSystemTest() { + if (permissionsSystemType == LUCK_PERMS) { + LuckPermsApi api = mock(LuckPermsApi.class); + ReflectionTestUtils.setField(LuckPerms.class, null, "instance", api); + } else if (permissionsSystemType == PERMISSIONS_EX) { + throw new AssumptionViolatedException( + "PermissionsEx instance cannot be mocked because of missing dependencies -- skipping"); + } else if (permissionsSystemType == Z_PERMISSIONS) { + ZPermissionsService zPermissionsService = mock(ZPermissionsService.class); + given(servicesManager.load(ZPermissionsService.class)).willReturn(zPermissionsService); + } else if (permissionsSystemType == VAULT) { + setUpForVault(); + } else if (permissionsSystemType != B_PERMISSIONS) { + throw new IllegalStateException("Unhandled permission systems type: " + permissionsSystemType); + } + } + + private void setUpForVault() { + RegisteredServiceProvider registeredServiceProvider = mock(RegisteredServiceProvider.class); + given(servicesManager.getRegistration(Permission.class)).willReturn(registeredServiceProvider); + Permission permission = mock(Permission.class); + given(registeredServiceProvider.getProvider()).willReturn(permission); + } + + private PermissionHandler getHandlerFieldValue() { + return ReflectionTestUtils.getFieldValue(PermissionsManager.class, permissionsManager, "handler"); + } +}