From c0e1b8082f0c00257e60ff83708fc209e417b4b1 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Sun, 4 Mar 2018 17:32:16 +0100 Subject: [PATCH 01/12] #642 - Quick Command Protection manager --- .../data/QuickCommandsProtectionManager.java | 51 +++++++++++++++++++ .../authme/permission/PlayerPermission.java | 7 ++- .../properties/ProtectionSettings.java | 4 ++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java diff --git a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java new file mode 100644 index 000000000..38a007f32 --- /dev/null +++ b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java @@ -0,0 +1,51 @@ +package fr.xephi.authme.data; + +import fr.xephi.authme.initialization.HasCleanup; +import fr.xephi.authme.initialization.SettingsDependent; +import fr.xephi.authme.permission.PermissionsManager; +import fr.xephi.authme.permission.PlayerPermission; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.ProtectionSettings; +import fr.xephi.authme.util.expiring.ExpiringSet; +import org.bukkit.entity.Player; + +import javax.inject.Inject; +import java.util.concurrent.TimeUnit; + +public class QuickCommandsProtectionManager implements SettingsDependent, HasCleanup { + + private PermissionsManager permissionsManager; + + private final ExpiringSet latestLogin; + + @Inject + public QuickCommandsProtectionManager(Settings settings, PermissionsManager permissionsManager) { + this.permissionsManager = permissionsManager; + long countTimeout = settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS); + latestLogin = new ExpiringSet<>(countTimeout, TimeUnit.MILLISECONDS); + reload(settings); + } + + public void setLogin(String name) { + latestLogin.add(name); + } + + public boolean shouldSaveLogin(Player player) { + return permissionsManager.hasPermission(player, PlayerPermission.QUICK_COMMANDS_PROTECTION); + } + + public boolean isAllowed(String name) { + return !latestLogin.contains(name); + } + + @Override + public void reload(Settings settings) { + long countTimeout = settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS); + latestLogin.setExpiration(countTimeout, TimeUnit.MILLISECONDS); + } + + @Override + public void performCleanup() { + latestLogin.removeExpiredEntries(); + } +} diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java index 1a89490f2..71ee84b4d 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -68,7 +68,12 @@ public enum PlayerPermission implements PermissionNode { /** * Permission to use the email verification codes feature. */ - VERIFICATION_CODE("authme.player.security.verificationcode"); + VERIFICATION_CODE("authme.player.security.verificationcode"), + + /** + * Permission to use the email verification codes feature. + */ + QUICK_COMMANDS_PROTECTION("authme.player.protection.quickcommandsprotection"); /** * The permission node. diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java index f0a6c2f74..bb665c0f7 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java @@ -55,6 +55,10 @@ public final class ProtectionSettings implements SettingsHolder { public static final Property ANTIBOT_DELAY = newProperty("Protection.antiBotDelay", 60); + @Comment("Kicks the player that issued a command before the defined time after the login process") + public static final Property QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS = + newProperty("Protection.quickCommands.denyCommandsBeforeSeconds", 1000); + private ProtectionSettings() { } From 844bd2422167104b7e09d8b02230affea9f1f6a5 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Mon, 5 Mar 2018 21:00:24 +0100 Subject: [PATCH 02/12] Fixed minor code issues --- .../fr/xephi/authme/data/QuickCommandsProtectionManager.java | 2 +- .../java/fr/xephi/authme/permission/PlayerPermission.java | 2 +- .../xephi/authme/settings/properties/ProtectionSettings.java | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java index 38a007f32..692c1dbc5 100644 --- a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java +++ b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java @@ -14,7 +14,7 @@ import java.util.concurrent.TimeUnit; public class QuickCommandsProtectionManager implements SettingsDependent, HasCleanup { - private PermissionsManager permissionsManager; + private final PermissionsManager permissionsManager; private final ExpiringSet latestLogin; diff --git a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java index 71ee84b4d..f95fd09ba 100644 --- a/src/main/java/fr/xephi/authme/permission/PlayerPermission.java +++ b/src/main/java/fr/xephi/authme/permission/PlayerPermission.java @@ -71,7 +71,7 @@ public enum PlayerPermission implements PermissionNode { VERIFICATION_CODE("authme.player.security.verificationcode"), /** - * Permission to use the email verification codes feature. + * Permission that enables on join quick commands checks for the player. */ QUICK_COMMANDS_PROTECTION("authme.player.protection.quickcommandsprotection"); diff --git a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java index bb665c0f7..c7d0f4a82 100644 --- a/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java +++ b/src/main/java/fr/xephi/authme/settings/properties/ProtectionSettings.java @@ -55,9 +55,9 @@ public final class ProtectionSettings implements SettingsHolder { public static final Property ANTIBOT_DELAY = newProperty("Protection.antiBotDelay", 60); - @Comment("Kicks the player that issued a command before the defined time after the login process") + @Comment("Kicks the player that issued a command before the defined time after the join process") public static final Property QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS = - newProperty("Protection.quickCommands.denyCommandsBeforeSeconds", 1000); + newProperty("Protection.quickCommands.denyCommandsBeforeMilliseconds", 1000); private ProtectionSettings() { } From fe4d5e7c0df6864c7f060149bb04c0481f49221d Mon Sep 17 00:00:00 2001 From: HexelDev Date: Sat, 10 Mar 2018 19:13:23 +0100 Subject: [PATCH 03/12] Saving user join and check on command --- .../fr/xephi/authme/listener/PlayerListener.java | 13 +++++++++++++ .../java/fr/xephi/authme/message/MessageKey.java | 3 +++ 2 files changed, 16 insertions(+) diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index b4709a564..517b12ed0 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -1,5 +1,6 @@ package fr.xephi.authme.listener; +import fr.xephi.authme.data.QuickCommandsProtectionManager; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; @@ -86,6 +87,8 @@ public class PlayerListener implements Listener { @Inject private PermissionsManager permissionsManager; @Inject + private QuickCommandsProtectionManager quickCommandsProtectionManager; + @Inject private BungeeSender bungeeSender; private boolean isAsyncPlayerPreLoginEventCalled = false; @@ -100,6 +103,11 @@ public class PlayerListener implements Listener { return; } final Player player = event.getPlayer(); + if (!quickCommandsProtectionManager.isAllowed(player.getName())) { + event.setCancelled(true); + player.kickPlayer(m.retrieveSingle(MessageKey.QUICK_COMMAND_PROTECTION_KICK)); + return; + } if (listenerService.shouldCancelEvent(player)) { event.setCancelled(true); m.send(player, MessageKey.DENIED_COMMAND); @@ -207,6 +215,11 @@ public class PlayerListener implements Listener { if (!PlayerListener19Spigot.isPlayerSpawnLocationEventCalled()) { teleportationService.teleportOnJoin(player); } + + if (quickCommandsProtectionManager.shouldSaveLogin(player)) { + quickCommandsProtectionManager.setLogin(player.getName()); + } + management.performJoin(player); teleportationService.teleportNewPlayerToFirstSpawn(player); diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java index b6367c5b1..8c40fcea8 100644 --- a/src/main/java/fr/xephi/authme/message/MessageKey.java +++ b/src/main/java/fr/xephi/authme/message/MessageKey.java @@ -275,6 +275,9 @@ public enum MessageKey { /** To verify your identity you need to link an email address with your account! */ VERIFICATION_CODE_EMAIL_NEEDED("verification.email_needed"), + /** You used a command too fast! Please, join the server again and wait more before using any command. */ + QUICK_COMMAND_PROTECTION_KICK("quick_command.kick"), + /** second */ SECOND("time.second"), From 55b6f675505eb05508e026dff338c1d7439e15a9 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Thu, 15 Mar 2018 20:20:40 +0100 Subject: [PATCH 04/12] JavaDocs --- .../data/QuickCommandsProtectionManager.java | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java index 692c1dbc5..6e697db16 100644 --- a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java +++ b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java @@ -26,14 +26,28 @@ public class QuickCommandsProtectionManager implements SettingsDependent, HasCle reload(settings); } + /** + * Save the player in the set + * @param name the player's name + */ public void setLogin(String name) { latestLogin.add(name); } + /** + * Returns whether the given player has the permission and should be saved in the set + * @param player the player to check + * @return true if the player has the permission, false otherwise + */ public boolean shouldSaveLogin(Player player) { return permissionsManager.hasPermission(player, PlayerPermission.QUICK_COMMANDS_PROTECTION); } + /** + * Returns whether the given player is able to perform the command + * @param name the name of the player to check + * @return true if the player is not in the set (so it's allowed to perform the command), false otherwise + */ public boolean isAllowed(String name) { return !latestLogin.contains(name); } From 048a47ce6e05b496c298a6a4b704252a3308f186 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Thu, 15 Mar 2018 21:43:36 +0100 Subject: [PATCH 05/12] Fixing PLayerListener kick message/tests --- .../xephi/authme/listener/PlayerListener.java | 2 +- .../authme/listener/PlayerListenerTest.java | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index 4b42628fb..6ceeb835c 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -105,7 +105,7 @@ public class PlayerListener implements Listener { final Player player = event.getPlayer(); if (!quickCommandsProtectionManager.isAllowed(player.getName())) { event.setCancelled(true); - player.kickPlayer(m.retrieveSingle(MessageKey.QUICK_COMMAND_PROTECTION_KICK)); + player.kickPlayer(m.retrieveSingle(player, MessageKey.QUICK_COMMAND_PROTECTION_KICK)); return; } if (listenerService.shouldCancelEvent(player)) { diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index 3d75e2c52..35c33a145 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -1,6 +1,7 @@ package fr.xephi.authme.listener; import fr.xephi.authme.TestHelper; +import fr.xephi.authme.data.QuickCommandsProtectionManager; import fr.xephi.authme.data.auth.PlayerAuth; import fr.xephi.authme.datasource.DataSource; import fr.xephi.authme.message.MessageKey; @@ -110,6 +111,8 @@ public class PlayerListenerTest { private ValidationService validationService; @Mock private JoinMessageService joinMessageService; + @Mock + private QuickCommandsProtectionManager quickCommandsProtectionManager; /** * #831: If a player is kicked because of "logged in from another location", the kick @@ -219,6 +222,7 @@ public class PlayerListenerTest { // PlayerCommandPreprocessEvent#getPlayer is final, so create a spy instead of a mock PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); given(listenerService.shouldCancelEvent(player)).willReturn(false); + given(quickCommandsProtectionManager.isAllowed(player.getName())).willReturn(true); // when listener.onPlayerCommandPreprocess(event); @@ -238,6 +242,7 @@ public class PlayerListenerTest { Player player = playerWithMockedServer(); PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); given(listenerService.shouldCancelEvent(player)).willReturn(true); + given(quickCommandsProtectionManager.isAllowed(player.getName())).willReturn(true); // when listener.onPlayerCommandPreprocess(event); @@ -248,6 +253,23 @@ public class PlayerListenerTest { verify(messages).send(player, MessageKey.DENIED_COMMAND); } + @Test + public void shouldCancelCommandFastCommandEvent() { + // given + given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(false); + given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Arrays.asList("/spawn", "/help")); + Player player = playerWithMockedServer(); + PlayerCommandPreprocessEvent event = spy(new PlayerCommandPreprocessEvent(player, "/hub")); + given(quickCommandsProtectionManager.isAllowed(player.getName())).willReturn(false); + + // when + listener.onPlayerCommandPreprocess(event); + + // then + verify(event).setCancelled(true); + verify(player).kickPlayer(messages.retrieveSingle(player, MessageKey.QUICK_COMMAND_PROTECTION_KICK)); + } + @Test public void shouldAllowChat() { // given From 900e8f24151eeb987d99250321ddecc96542f7b3 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Thu, 15 Mar 2018 21:44:49 +0100 Subject: [PATCH 06/12] Updated messages --- .../fr/xephi/authme/message/MessageKey.java | 2 +- src/main/resources/messages/messages_bg.yml | 1 + src/main/resources/messages/messages_br.yml | 1 + src/main/resources/messages/messages_cz.yml | 1 + src/main/resources/messages/messages_de.yml | 1 + src/main/resources/messages/messages_en.yml | 1 + src/main/resources/messages/messages_eo.yml | 1 + src/main/resources/messages/messages_es.yml | 1 + src/main/resources/messages/messages_et.yml | 1 + src/main/resources/messages/messages_eu.yml | 1 + src/main/resources/messages/messages_fi.yml | 1 + src/main/resources/messages/messages_fr.yml | 1 + src/main/resources/messages/messages_gl.yml | 1 + src/main/resources/messages/messages_hu.yml | 1 + src/main/resources/messages/messages_id.yml | 1 + src/main/resources/messages/messages_it.yml | 23 +++++++++++-------- src/main/resources/messages/messages_ko.yml | 1 + src/main/resources/messages/messages_lt.yml | 1 + src/main/resources/messages/messages_nl.yml | 1 + src/main/resources/messages/messages_pl.yml | 1 + src/main/resources/messages/messages_pt.yml | 1 + src/main/resources/messages/messages_ro.yml | 1 + src/main/resources/messages/messages_ru.yml | 1 + src/main/resources/messages/messages_sk.yml | 1 + src/main/resources/messages/messages_tr.yml | 1 + src/main/resources/messages/messages_uk.yml | 1 + src/main/resources/messages/messages_vn.yml | 1 + src/main/resources/messages/messages_zhcn.yml | 1 + src/main/resources/messages/messages_zhhk.yml | 1 + src/main/resources/messages/messages_zhmc.yml | 1 + src/main/resources/messages/messages_zhtw.yml | 1 + 31 files changed, 43 insertions(+), 11 deletions(-) diff --git a/src/main/java/fr/xephi/authme/message/MessageKey.java b/src/main/java/fr/xephi/authme/message/MessageKey.java index 8c40fcea8..355f14a9a 100644 --- a/src/main/java/fr/xephi/authme/message/MessageKey.java +++ b/src/main/java/fr/xephi/authme/message/MessageKey.java @@ -276,7 +276,7 @@ public enum MessageKey { VERIFICATION_CODE_EMAIL_NEEDED("verification.email_needed"), /** You used a command too fast! Please, join the server again and wait more before using any command. */ - QUICK_COMMAND_PROTECTION_KICK("quick_command.kick"), + QUICK_COMMAND_PROTECTION_KICK("on_join_validation.quick_command"), /** second */ SECOND("time.second"), diff --git a/src/main/resources/messages/messages_bg.yml b/src/main/resources/messages/messages_bg.yml index c49e2cb00..8b073bd96 100644 --- a/src/main/resources/messages/messages_bg.yml +++ b/src/main/resources/messages/messages_bg.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Твоята държава е забранена в този сървър!' not_owner_error: 'Ти не си собственика на този акаунт. Моля избери друго потребителско име!' invalid_name_case: 'Трябва да влезеш с %valid, а не с %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_br.yml b/src/main/resources/messages/messages_br.yml index 3000840bb..69f5e3954 100644 --- a/src/main/resources/messages/messages_br.yml +++ b/src/main/resources/messages/messages_br.yml @@ -82,6 +82,7 @@ on_join_validation: country_banned: '&4O seu país está banido neste servidor!' not_owner_error: 'Você não é o proprietário da conta. Por favor, escolha outro nome!' invalid_name_case: 'Você deve se juntar usando nome de usuário %valid, não %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_cz.yml b/src/main/resources/messages/messages_cz.yml index 3b97a5aec..5ed2ceb41 100644 --- a/src/main/resources/messages/messages_cz.yml +++ b/src/main/resources/messages/messages_cz.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: 'Vaše země je na tomto serveru zakázána' not_owner_error: 'Nejsi majitelem tohoto účtu, prosím zvol si jiné jméno!' invalid_name_case: 'Měl by jsi použít jméno %valid, ne jméno %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_de.yml b/src/main/resources/messages/messages_de.yml index 108d7dad8..84679c486 100644 --- a/src/main/resources/messages/messages_de.yml +++ b/src/main/resources/messages/messages_de.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Dein Land ist gesperrt!' not_owner_error: 'Du bist nicht der Besitzer dieses Accounts. Bitte wähle einen anderen Namen!' invalid_name_case: 'Dein registrierter Benutzername ist &2%valid&f - nicht &4%invalid&f.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_en.yml b/src/main/resources/messages/messages_en.yml index e5e20055a..6d9d28798 100644 --- a/src/main/resources/messages/messages_en.yml +++ b/src/main/resources/messages/messages_en.yml @@ -78,6 +78,7 @@ on_join_validation: same_nick_online: '&4The same username is already playing on the server!' invalid_name_case: 'You should join using username %valid, not %invalid.' same_ip_online: 'A player with the same IP is already in game!' + quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_eo.yml b/src/main/resources/messages/messages_eo.yml index dd1657728..c5783c831 100644 --- a/src/main/resources/messages/messages_eo.yml +++ b/src/main/resources/messages/messages_eo.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Via lando estas malpermesitaj de tiu servilo!' not_owner_error: 'Vi ne estas la posedanto de tiu konto. Bonvolu elekti alian nomon!' invalid_name_case: 'Vi devus aliĝi uzante uzantnomon %valid, ne %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_es.yml b/src/main/resources/messages/messages_es.yml index ce0d8a369..50363ead1 100644 --- a/src/main/resources/messages/messages_es.yml +++ b/src/main/resources/messages/messages_es.yml @@ -80,6 +80,7 @@ on_join_validation: country_banned: '¡Tu país ha sido baneado de este servidor!' not_owner_error: 'No eres el propietario de esta cuenta. ¡Por favor, elije otro nombre!' invalid_name_case: 'Solo puedes unirte mediante el nombre de usuario %valid, no %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_et.yml b/src/main/resources/messages/messages_et.yml index df6bd053c..68ce520f5 100644 --- a/src/main/resources/messages/messages_et.yml +++ b/src/main/resources/messages/messages_et.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Su riik on siin serveris keelatud!' not_owner_error: 'Sa ei ole selle konto omanik. Vali teine nimi.' invalid_name_case: 'Logi sisse kasutajanimega %valid, mitte kasutajanimega %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_eu.yml b/src/main/resources/messages/messages_eu.yml index 4eec94c34..0507d1042 100644 --- a/src/main/resources/messages/messages_eu.yml +++ b/src/main/resources/messages/messages_eu.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '[AuthMe] Zure herrialdea blokeatuta dago zerbitzari honetan' # TODO not_owner_error: 'You are not the owner of this account. Please choose another name!' # TODO invalid_name_case: 'You should join using username %valid, not %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_fi.yml b/src/main/resources/messages/messages_fi.yml index 9a6578bdd..b0b4f3032 100644 --- a/src/main/resources/messages/messages_fi.yml +++ b/src/main/resources/messages/messages_fi.yml @@ -79,6 +79,7 @@ on_join_validation: # TODO country_banned: '&4Your country is banned from this server!' # TODO not_owner_error: 'You are not the owner of this account. Please choose another name!' # TODO invalid_name_case: 'You should join using username %valid, not %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_fr.yml b/src/main/resources/messages/messages_fr.yml index 93358b2e8..52fd4c882 100644 --- a/src/main/resources/messages/messages_fr.yml +++ b/src/main/resources/messages/messages_fr.yml @@ -82,6 +82,7 @@ on_join_validation: country_banned: 'Votre pays est banni de ce serveur.' not_owner_error: 'Vous n''êtes pas le propriétaire de ce compte. Veuillez utiliser un autre pseudo !' invalid_name_case: 'Veuillez vous connecter avec "%valid" et non pas avec "%invalid".' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_gl.yml b/src/main/resources/messages/messages_gl.yml index 9c47a222d..d22caa7cb 100644 --- a/src/main/resources/messages/messages_gl.yml +++ b/src/main/resources/messages/messages_gl.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: 'O teu país está bloqueado neste servidor' # TODO not_owner_error: 'You are not the owner of this account. Please choose another name!' # TODO invalid_name_case: 'You should join using username %valid, not %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_hu.yml b/src/main/resources/messages/messages_hu.yml index 609545976..1d420b746 100644 --- a/src/main/resources/messages/messages_hu.yml +++ b/src/main/resources/messages/messages_hu.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Az országod a tiltólistán van ezen a szerveren!' not_owner_error: 'Ez nem a te felhasználód. Kérlek, válassz másik nevet!' invalid_name_case: '%valid a felhasználó neved nem? Akkor ne %invalid névvel próbálj feljönni.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_id.yml b/src/main/resources/messages/messages_id.yml index 9fda2668d..65e84cd9c 100644 --- a/src/main/resources/messages/messages_id.yml +++ b/src/main/resources/messages/messages_id.yml @@ -79,6 +79,7 @@ on_join_validation: # TODO country_banned: '&4Your country is banned from this server!' # TODO not_owner_error: 'You are not the owner of this account. Please choose another name!' # TODO invalid_name_case: 'You should join using username %valid, not %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_it.yml b/src/main/resources/messages/messages_it.yml index 40b0059ec..22354cda8 100644 --- a/src/main/resources/messages/messages_it.yml +++ b/src/main/resources/messages/messages_it.yml @@ -5,6 +5,8 @@ # %displayname% - Sostituisce il nickname (e i colori) dell'utente che riceve il messaggio. # Registrazione + +# Registration registration: disabled: '&cLa registrazione tramite i comandi di gioco è disabilitata.' name_taken: '&cHai già eseguito la registrazione, non puoi eseguirla nuovamente.' @@ -14,7 +16,7 @@ registration: success: '&2Registrato correttamente!' kicked_admin_registered: 'Un amministratore ti ha appena registrato, per favore rientra nel server' -# Errori della password durante la registrazione +# Password errors on registration password: match_error: '&cLe password non corrispondono!' name_in_password: '&cNon puoi usare il tuo nome utente come password, per favore scegline un''altra...' @@ -22,7 +24,7 @@ password: forbidden_characters: '&4La tua password contiene caratteri non consentiti. I caratteri consentiti sono: %valid_chars' wrong_length: '&cLa password che hai inserito è troppo corta o troppo lunga, per favore scegline un''altra...' -# Autenticazione +# Login login: command_usage: '&cUtilizzo: /login ' wrong_password: '&cPassword non corretta!' @@ -30,7 +32,7 @@ login: login_request: '&cPer favore, esegui l''autenticazione con il comando: /login ' timeout_error: '&4Tempo scaduto per eseguire l''autenticazione, sei stato espulso dal server, per favore riprova!' -# Errori +# Errors error: denied_command: '&cPer poter usare questo comando devi essere autenticato!' denied_chat: '&cPer poter scrivere messaggi in chat devi essere autenticato!' @@ -49,12 +51,12 @@ antibot: auto_enabled: '&4Il servizio di AntiBot è stato automaticamente abilitato a seguito delle numerose connessioni!' auto_disabled: '&2Il servizio di AntiBot è stato automaticamente disabilitato dopo %m minuti!' -# Rimozione dal Database +# Unregister unregister: success: '&2Sei stato correttamente rimosso dal database!' command_usage: '&cUtilizzo: /unregister ' -# Altri messaggi +# Other messages misc: account_not_activated: '&cIl tuo account non è stato ancora verificato, controlla fra le tue email per scoprire come attivarlo!' password_changed: '&2Password cambiata correttamente!' @@ -65,12 +67,12 @@ misc: accounts_owned_self: 'Possiedi %count account:' accounts_owned_other: 'Il giocatore %name possiede %count account:' -# Messaggi della sessione +# Session messages session: valid_session: '&2Autenticato automaticamente attraverso la precedente sessione!' invalid_session: '&cIl tuo indirizzo IP è cambiato e la tua sessione è stata terminata!' -# Messaggi di errore durante l'accesso +# Error messages when joining on_join_validation: same_ip_online: 'Un giocatore con il tuo stesso IP è già connesso sul server!' same_nick_online: '&4Un giocatore con il tuo stesso nome utente è già connesso sul server!' @@ -80,6 +82,7 @@ on_join_validation: 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!' invalid_name_case: 'Dovresti entrare con questo nome utente "%valid", al posto di "%invalid".' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: @@ -100,7 +103,7 @@ email: change_password_expired: 'Non puoi più cambiare la tua password con questo comando.' email_cooldown_error: '&cUna email di recupero ti è già stata inviata recentemente. Devi attendere %time prima di poterne richiedere una nuova.' -# Recupero password via Email +# Password recovery by email recovery: forgot_password_hint: '&3Hai dimenticato la tua password? Puoi recuperarla eseguendo il comando: /email recovery ' command_usage: '&cUtilizzo: /email recovery ' @@ -120,7 +123,7 @@ captcha: captcha_for_registration: 'Per poterti registrare devi prima risolvere un captcha, per favore scrivi: /captcha %captcha_code' register_captcha_valid: '&2Il captcha inserito è valido! Ora puoi eseguire la registrazione con: /register ' -# Codice di verifica +# Verification code 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.' command_usage: '&cUtilizzo: /verification ' @@ -130,7 +133,7 @@ verification: code_expired: '&3Il tuo codice è scaduto! Esegui nuovamente un comando che modifica dati sensibili per ricevere uno nuovo codice!' email_needed: '&3Per verificare la tua identità devi collegare un indirizzo email al tuo account!' -# Unità di tempo +# Time units time: second: 'secondo' seconds: 'secondi' diff --git a/src/main/resources/messages/messages_ko.yml b/src/main/resources/messages/messages_ko.yml index f934f4ccb..41049b884 100644 --- a/src/main/resources/messages/messages_ko.yml +++ b/src/main/resources/messages/messages_ko.yml @@ -81,6 +81,7 @@ on_join_validation: country_banned: '&4당신의 국가에서는 이 서버를 이용하실 수 없습니다!' not_owner_error: '이 계정의 소유자가 아닙니다. 다른 닉네임을 선택하세요!' invalid_name_case: '%invalid가 아닌, %valid 사용하여 접속해야 합니다.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_lt.yml b/src/main/resources/messages/messages_lt.yml index 2952d4497..15eea3048 100644 --- a/src/main/resources/messages/messages_lt.yml +++ b/src/main/resources/messages/messages_lt.yml @@ -79,6 +79,7 @@ on_join_validation: # TODO country_banned: '&4Your country is banned from this server!' # TODO not_owner_error: 'You are not the owner of this account. Please choose another name!' # TODO invalid_name_case: 'You should join using username %valid, not %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_nl.yml b/src/main/resources/messages/messages_nl.yml index 00b290de9..b8fc40950 100644 --- a/src/main/resources/messages/messages_nl.yml +++ b/src/main/resources/messages/messages_nl.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Jouw land is gebanned op deze server!' not_owner_error: 'Jij bent niet de eigenaar van dit account. Kies alsjeblieft een andere naam!' invalid_name_case: 'Verbind je alsjeblieft als %valid, niet als %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_pl.yml b/src/main/resources/messages/messages_pl.yml index 427ad302b..4d9061dfd 100644 --- a/src/main/resources/messages/messages_pl.yml +++ b/src/main/resources/messages/messages_pl.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Ten kraj jest zbanowany na tym serwerze' not_owner_error: '&cNie jesteś właścicielem tego konta, wybierz inny nick!' invalid_name_case: '&cPowinieneś dołączyć do serwera z nicku %valid, a nie %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_pt.yml b/src/main/resources/messages/messages_pt.yml index fe41dd553..2fb0ad2c4 100644 --- a/src/main/resources/messages/messages_pt.yml +++ b/src/main/resources/messages/messages_pt.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: 'O seu país está banido deste servidor' not_owner_error: 'Não é o proprietário da conta. Por favor, escolha outro nome!' invalid_name_case: 'Deve se juntar usando nome de usuário %valid, não %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_ro.yml b/src/main/resources/messages/messages_ro.yml index 16b144497..6fcacb052 100644 --- a/src/main/resources/messages/messages_ro.yml +++ b/src/main/resources/messages/messages_ro.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Tara ta este interzisa pe acest server!' not_owner_error: 'Tu nu esti detinatorul acestui cont. Te rugam alege alt nume!' invalid_name_case: 'Ar trebui sa intri cu numele %valid, nu %invalid' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_ru.yml b/src/main/resources/messages/messages_ru.yml index 82d9d48e0..25a8ca032 100644 --- a/src/main/resources/messages/messages_ru.yml +++ b/src/main/resources/messages/messages_ru.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Вход с IP-адресов вашей страны запрещён на этом сервере.' not_owner_error: 'Вы не являетесь владельцем данной уч. записи. Выберите себе другое имя!' invalid_name_case: 'Неверное имя! Зайдите под именем %valid, а не %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_sk.yml b/src/main/resources/messages/messages_sk.yml index 030e721d7..5af6e5030 100644 --- a/src/main/resources/messages/messages_sk.yml +++ b/src/main/resources/messages/messages_sk.yml @@ -85,6 +85,7 @@ on_join_validation: country_banned: '&4Tvoja krajina je zabanovaná na tomto serveri!' not_owner_error: 'Niesi majiteľ tohto účtu. Prosím zvoľ si iné meno!' invalid_name_case: 'Mal by si sa pripojiť s nickom %valid, nie %invalid -pozor na veľké a malé písmená.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_tr.yml b/src/main/resources/messages/messages_tr.yml index 119f037e3..b9aff0ae9 100644 --- a/src/main/resources/messages/messages_tr.yml +++ b/src/main/resources/messages/messages_tr.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Senin bolgen sunucudan yasaklandi!' not_owner_error: 'Bu hesabin sahibi degilsin. Lutfen farkli bir isim sec!' invalid_name_case: 'Oyuna %valid isminde katilmalisin. %invalid ismini kullanarak katilamazsin.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_uk.yml b/src/main/resources/messages/messages_uk.yml index a1579c303..3ecf52905 100644 --- a/src/main/resources/messages/messages_uk.yml +++ b/src/main/resources/messages/messages_uk.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Your country is banned from this server!' not_owner_error: 'Цей акаунт вам не належить! Будь ласка, оберіть інакший нікнейм!' invalid_name_case: 'Регістр у вашому нікнеймі відрізняється від регістру при реєстрації.%nl%Поточний регістр: &c%invalid&f. Валідний регістр: &a%valid&f.%nl%Будь ласка, перезайдіть з валідним регістром!' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_vn.yml b/src/main/resources/messages/messages_vn.yml index 61bbda945..5e138f4f6 100644 --- a/src/main/resources/messages/messages_vn.yml +++ b/src/main/resources/messages/messages_vn.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4Quốc gia của bạn bị cấm tham gia máy chủ này!' not_owner_error: 'Bạn không phải là chủ sở hữu tài khoản này, hãy chọn tên khác!' invalid_name_case: 'Bạn nên vào máy chủ với tên đăng nhập là %valid, không phải là %invalid.' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_zhcn.yml b/src/main/resources/messages/messages_zhcn.yml index d53a44486..78c3c89b6 100644 --- a/src/main/resources/messages/messages_zhcn.yml +++ b/src/main/resources/messages/messages_zhcn.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '这个服务器禁止该国家登陆' not_owner_error: '&8[&6玩家系统&8] &4警告! &c你并不是此帐户持有人,请立即登出。 ' invalid_name_case: '&8[&6玩家系统&8] &c你应该使用「%valid」而并非「%invalid」登入游戏。 ' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_zhhk.yml b/src/main/resources/messages/messages_zhhk.yml index ae29c65b1..9d080748b 100644 --- a/src/main/resources/messages/messages_zhhk.yml +++ b/src/main/resources/messages/messages_zhhk.yml @@ -82,6 +82,7 @@ on_join_validation: country_banned: '&8[&6用戶系統&8] &4本伺服器已停止對你的國家提供遊戲服務。' not_owner_error: '&8[&6用戶系統&8] &4警告!&c你並不是此帳戶持有人,請立即登出。' invalid_name_case: '&8[&6用戶系統&8] &4警告!&c你應該使用「%valid」而並非「%invalid」登入遊戲。' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_zhmc.yml b/src/main/resources/messages/messages_zhmc.yml index 76fa6ccc4..a151a8cf8 100644 --- a/src/main/resources/messages/messages_zhmc.yml +++ b/src/main/resources/messages/messages_zhmc.yml @@ -79,6 +79,7 @@ on_join_validation: country_banned: '&4您的國家/地區已被禁止使用此伺服器!' not_owner_error: '您不是此帳戶的所有者。 請選擇其他名稱!' invalid_name_case: '您應該使用用戶名 %valid 而不是 %invalid 來加入。' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: diff --git a/src/main/resources/messages/messages_zhtw.yml b/src/main/resources/messages/messages_zhtw.yml index 91696b5d8..43a7b5338 100644 --- a/src/main/resources/messages/messages_zhtw.yml +++ b/src/main/resources/messages/messages_zhtw.yml @@ -81,6 +81,7 @@ on_join_validation: country_banned: '&b【AuthMe】&6您所在的地區無法進入此伺服器' not_owner_error: '&b【AuthMe】&4警告!&c您並不是此帳戶持有人,請立即登出。' invalid_name_case: '&b【AuthMe】&4警告!&c您應該使用「%valid」而並非「%invalid」登入遊戲。' + # TODO quick_command: 'You used a command too fast! Please, join the server again and wait more before using any command.' # Email email: From 66d1ee92c3273dacf2dcc15a2c8c462ef92949e2 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Thu, 15 Mar 2018 21:45:11 +0100 Subject: [PATCH 07/12] QuickCommandsProtectionManager Test class --- .../QuickCommandsProtectionManagerTest.java | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) create mode 100644 src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java diff --git a/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java b/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java new file mode 100644 index 000000000..10ef88eb8 --- /dev/null +++ b/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java @@ -0,0 +1,65 @@ +package fr.xephi.authme.data; + +import fr.xephi.authme.permission.PermissionsManager; +import fr.xephi.authme.settings.Settings; +import fr.xephi.authme.settings.properties.ProtectionSettings; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import org.mockito.junit.MockitoJUnitRunner; + +import static org.hamcrest.Matchers.equalTo; +import static org.junit.Assert.assertThat; +import static org.mockito.BDDMockito.given; + +/** + * Test for {@link QuickCommandsProtectionManager}. + */ +@RunWith(MockitoJUnitRunner.class) +public class QuickCommandsProtectionManagerTest { + + @Mock + private Settings settings; + + @Mock + private PermissionsManager permissionsManager; + + @Test + public void shouldAllowCommand() { + // given + String name1 = "TestName1"; + String name2 = "TestName2"; + given(settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS)).willReturn(0); + + QuickCommandsProtectionManager qcpm = createQuickCommandsProtectioneManager(); + qcpm.setLogin(name2); + + // when + boolean test1 = qcpm.isAllowed(name1); + boolean test2 = qcpm.isAllowed(name2); + + // then + assertThat(test1, equalTo(true)); + assertThat(test2, equalTo(true)); + } + + @Test + public void shouldDenyCommand() { + // given + String name = "TestName1"; + given(settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS)).willReturn(5000); + + QuickCommandsProtectionManager qcpm = createQuickCommandsProtectioneManager(); + qcpm.setLogin(name); + + // when + boolean test = qcpm.isAllowed(name); + + // then + assertThat(test, equalTo(false)); + } + + private QuickCommandsProtectionManager createQuickCommandsProtectioneManager() { + return new QuickCommandsProtectionManager(settings, permissionsManager); + } +} From f5efd4bf23543093937bb42042a96404a4d24d42 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Thu, 15 Mar 2018 21:45:23 +0100 Subject: [PATCH 08/12] Updating plugin.yml --- src/main/resources/plugin.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 2bae573d7..7ddb4b7e0 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -230,6 +230,7 @@ permissions: authme.player.email.see: true authme.player.login: true authme.player.logout: true + authme.player.protection.quickcommandsprotection: true authme.player.register: true authme.player.security.verificationcode: true authme.player.seeownaccounts: true @@ -268,6 +269,9 @@ permissions: authme.player.logout: description: Command permission to logout. default: true + authme.player.protection.quickcommandsprotection: + description: Permission that enables on join quick commands checks for the player. + default: true authme.player.register: description: Command permission to register. default: true From 7790fa5796e812dd80217e22ab97b8b665e7706a Mon Sep 17 00:00:00 2001 From: HexelDev Date: Thu, 15 Mar 2018 21:53:27 +0100 Subject: [PATCH 09/12] typo --- src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java index 35c33a145..42d14e463 100644 --- a/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java +++ b/src/test/java/fr/xephi/authme/listener/PlayerListenerTest.java @@ -254,7 +254,7 @@ public class PlayerListenerTest { } @Test - public void shouldCancelCommandFastCommandEvent() { + public void shouldCancelFastCommandEvent() { // given given(settings.getProperty(HooksSettings.USE_ESSENTIALS_MOTD)).willReturn(false); given(settings.getProperty(RestrictionSettings.ALLOW_COMMANDS)).willReturn(Arrays.asList("/spawn", "/help")); From 84f97ea1c2211d6025019b964409885f3e1c0d92 Mon Sep 17 00:00:00 2001 From: HexelDev Date: Mon, 19 Mar 2018 22:33:53 +0100 Subject: [PATCH 10/12] Add QuickCommandsProtectionManager#processJoin(player) --- .../data/QuickCommandsProtectionManager.java | 26 ++++++++++++------ .../xephi/authme/listener/PlayerListener.java | 4 +-- .../QuickCommandsProtectionManagerTest.java | 27 ++++++++++++++----- 3 files changed, 40 insertions(+), 17 deletions(-) diff --git a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java index 6e697db16..335944c82 100644 --- a/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java +++ b/src/main/java/fr/xephi/authme/data/QuickCommandsProtectionManager.java @@ -16,13 +16,13 @@ public class QuickCommandsProtectionManager implements SettingsDependent, HasCle private final PermissionsManager permissionsManager; - private final ExpiringSet latestLogin; + private final ExpiringSet latestJoin; @Inject public QuickCommandsProtectionManager(Settings settings, PermissionsManager permissionsManager) { this.permissionsManager = permissionsManager; long countTimeout = settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS); - latestLogin = new ExpiringSet<>(countTimeout, TimeUnit.MILLISECONDS); + latestJoin = new ExpiringSet<>(countTimeout, TimeUnit.MILLISECONDS); reload(settings); } @@ -30,8 +30,8 @@ public class QuickCommandsProtectionManager implements SettingsDependent, HasCle * Save the player in the set * @param name the player's name */ - public void setLogin(String name) { - latestLogin.add(name); + private void setJoin(String name) { + latestJoin.add(name); } /** @@ -39,27 +39,37 @@ public class QuickCommandsProtectionManager implements SettingsDependent, HasCle * @param player the player to check * @return true if the player has the permission, false otherwise */ - public boolean shouldSaveLogin(Player player) { + private boolean shouldSavePlayer(Player player) { return permissionsManager.hasPermission(player, PlayerPermission.QUICK_COMMANDS_PROTECTION); } + /** + * Process the player join + * @param player the player to process + */ + public void processJoin(Player player) { + if(shouldSavePlayer(player)) { + setJoin(player.getName()); + } + } + /** * Returns whether the given player is able to perform the command * @param name the name of the player to check * @return true if the player is not in the set (so it's allowed to perform the command), false otherwise */ public boolean isAllowed(String name) { - return !latestLogin.contains(name); + return !latestJoin.contains(name); } @Override public void reload(Settings settings) { long countTimeout = settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS); - latestLogin.setExpiration(countTimeout, TimeUnit.MILLISECONDS); + latestJoin.setExpiration(countTimeout, TimeUnit.MILLISECONDS); } @Override public void performCleanup() { - latestLogin.removeExpiredEntries(); + latestJoin.removeExpiredEntries(); } } diff --git a/src/main/java/fr/xephi/authme/listener/PlayerListener.java b/src/main/java/fr/xephi/authme/listener/PlayerListener.java index 6ceeb835c..7857114e3 100644 --- a/src/main/java/fr/xephi/authme/listener/PlayerListener.java +++ b/src/main/java/fr/xephi/authme/listener/PlayerListener.java @@ -216,9 +216,7 @@ public class PlayerListener implements Listener { teleportationService.teleportOnJoin(player); } - if (quickCommandsProtectionManager.shouldSaveLogin(player)) { - quickCommandsProtectionManager.setLogin(player.getName()); - } + quickCommandsProtectionManager.processJoin(player); management.performJoin(player); diff --git a/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java b/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java index 10ef88eb8..704075674 100644 --- a/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java +++ b/src/test/java/fr/xephi/authme/data/QuickCommandsProtectionManagerTest.java @@ -1,8 +1,10 @@ package fr.xephi.authme.data; import fr.xephi.authme.permission.PermissionsManager; +import fr.xephi.authme.permission.PlayerPermission; import fr.xephi.authme.settings.Settings; import fr.xephi.authme.settings.properties.ProtectionSettings; +import org.bukkit.entity.Player; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; @@ -11,6 +13,7 @@ import org.mockito.junit.MockitoJUnitRunner; import static org.hamcrest.Matchers.equalTo; import static org.junit.Assert.assertThat; import static org.mockito.BDDMockito.given; +import static org.mockito.Mockito.mock; /** * Test for {@link QuickCommandsProtectionManager}. @@ -27,16 +30,19 @@ public class QuickCommandsProtectionManagerTest { @Test public void shouldAllowCommand() { // given - String name1 = "TestName1"; - String name2 = "TestName2"; + String playername = "PlayerName"; + Player player = mockPlayerWithName(playername); given(settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS)).willReturn(0); + given(permissionsManager.hasPermission(player, PlayerPermission.QUICK_COMMANDS_PROTECTION)).willReturn(true); + + String name = "TestName"; QuickCommandsProtectionManager qcpm = createQuickCommandsProtectioneManager(); - qcpm.setLogin(name2); + qcpm.processJoin(player); // when - boolean test1 = qcpm.isAllowed(name1); - boolean test2 = qcpm.isAllowed(name2); + boolean test1 = qcpm.isAllowed(name); + boolean test2 = qcpm.isAllowed(playername); // then assertThat(test1, equalTo(true)); @@ -47,10 +53,12 @@ public class QuickCommandsProtectionManagerTest { public void shouldDenyCommand() { // given String name = "TestName1"; + Player player = mockPlayerWithName(name); given(settings.getProperty(ProtectionSettings.QUICK_COMMANDS_DENIED_BEFORE_MILLISECONDS)).willReturn(5000); QuickCommandsProtectionManager qcpm = createQuickCommandsProtectioneManager(); - qcpm.setLogin(name); + given(permissionsManager.hasPermission(player, PlayerPermission.QUICK_COMMANDS_PROTECTION)).willReturn(true); + qcpm.processJoin(player); // when boolean test = qcpm.isAllowed(name); @@ -62,4 +70,11 @@ public class QuickCommandsProtectionManagerTest { private QuickCommandsProtectionManager createQuickCommandsProtectioneManager() { return new QuickCommandsProtectionManager(settings, permissionsManager); } + + private static Player mockPlayerWithName(String name) { + Player player = mock(Player.class); + given(player.getName()).willReturn(name); + return player; + } + } From a1a909c01d0b8739b209b388d50ca338da468bae Mon Sep 17 00:00:00 2001 From: ljacqu Date: Mon, 19 Mar 2018 23:08:48 +0100 Subject: [PATCH 11/12] #1531 Move spigot detection to BukkitService (#1534) --- .../xephi/authme/service/BukkitService.java | 17 ++++++++++++ .../xephi/authme/settings/SettingsWarner.java | 13 ++++++--- src/main/java/fr/xephi/authme/util/Utils.java | 15 ----------- .../authme/settings/SettingsWarnerTest.java | 27 +++++++++++-------- 4 files changed, 43 insertions(+), 29 deletions(-) diff --git a/src/main/java/fr/xephi/authme/service/BukkitService.java b/src/main/java/fr/xephi/authme/service/BukkitService.java index 6c9cd0cb8..09b4869fb 100644 --- a/src/main/java/fr/xephi/authme/service/BukkitService.java +++ b/src/main/java/fr/xephi/authme/service/BukkitService.java @@ -12,6 +12,7 @@ import org.bukkit.Bukkit; import org.bukkit.OfflinePlayer; import org.bukkit.World; import org.bukkit.command.CommandSender; +import org.bukkit.configuration.file.YamlConfiguration; import org.bukkit.entity.Player; import org.bukkit.event.Event; import org.bukkit.scheduler.BukkitRunnable; @@ -25,6 +26,7 @@ import java.util.Arrays; import java.util.Collection; import java.util.Collections; import java.util.Date; +import java.util.Optional; import java.util.Set; import java.util.function.Function; @@ -376,4 +378,19 @@ public class BukkitService implements SettingsDependent { public BanEntry banIp(String ip, String reason, Date expires, String source) { return Bukkit.getServer().getBanList(BanList.Type.IP).addBan(ip, reason, expires, source); } + + /** + * Returns an optional with a boolean indicating whether bungeecord is enabled or not if the + * server implementation is Spigot. Otherwise returns an empty optional. + * + * @return Optional with configuration value for Spigot, empty optional otherwise + */ + public Optional isBungeeCordConfiguredForSpigot() { + try { + YamlConfiguration spigotConfig = Bukkit.spigot().getConfig(); + return Optional.of(spigotConfig.getBoolean("settings.bungeecord")); + } catch (NoSuchMethodError e) { + return Optional.empty(); + } + } } diff --git a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java b/src/main/java/fr/xephi/authme/settings/SettingsWarner.java index c94b0455c..d055dd0fd 100644 --- a/src/main/java/fr/xephi/authme/settings/SettingsWarner.java +++ b/src/main/java/fr/xephi/authme/settings/SettingsWarner.java @@ -4,15 +4,15 @@ import fr.xephi.authme.AuthMe; import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.security.HashAlgorithm; import fr.xephi.authme.security.crypts.Argon2; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.properties.EmailSettings; import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.SecuritySettings; -import fr.xephi.authme.util.Utils; -import org.bukkit.Bukkit; import javax.inject.Inject; +import java.util.Optional; /** * Logs warning messages in cases where the configured values suggest a misconfiguration. @@ -29,6 +29,9 @@ public class SettingsWarner { @Inject private AuthMe authMe; + @Inject + private BukkitService bukkitService; + SettingsWarner() { } @@ -54,7 +57,7 @@ public class SettingsWarner { } // Warn if spigot.yml has settings.bungeecord set to true but config.yml has Hooks.bungeecord set to false - if (Utils.isSpigot() && Bukkit.spigot().getConfig().getBoolean("settings.bungeecord") + if (isTrue(bukkitService.isBungeeCordConfiguredForSpigot()) && !settings.getProperty(HooksSettings.BUNGEECORD)) { ConsoleLogger.warning("Note: Hooks.bungeecord is set to false but your server appears to be running in" + " bungeecord mode (see your spigot.yml). In order to allow the datasource caching and the" @@ -69,4 +72,8 @@ public class SettingsWarner { authMe.stopOrUnload(); } } + + private static boolean isTrue(Optional value) { + return value.isPresent() && value.get(); + } } diff --git a/src/main/java/fr/xephi/authme/util/Utils.java b/src/main/java/fr/xephi/authme/util/Utils.java index 5a2443199..4db7f61bc 100644 --- a/src/main/java/fr/xephi/authme/util/Utils.java +++ b/src/main/java/fr/xephi/authme/util/Utils.java @@ -1,7 +1,6 @@ package fr.xephi.authme.util; import fr.xephi.authme.ConsoleLogger; -import org.bukkit.Bukkit; import org.bukkit.ChatColor; import org.bukkit.command.CommandSender; import org.bukkit.command.ConsoleCommandSender; @@ -23,20 +22,6 @@ public final class Utils { private Utils() { } - /** - * Returns if the running server instance is craftbukkit or spigot based. - * - * @return true if the running server instance is spigot-based. - */ - public static boolean isSpigot() { - try { - Bukkit.spigot(); - return true; - } catch (NoSuchMethodError e) { - return false; - } - } - /** * Compile Pattern sneaky without throwing Exception. * diff --git a/src/test/java/fr/xephi/authme/settings/SettingsWarnerTest.java b/src/test/java/fr/xephi/authme/settings/SettingsWarnerTest.java index d237268cc..16271bd94 100644 --- a/src/test/java/fr/xephi/authme/settings/SettingsWarnerTest.java +++ b/src/test/java/fr/xephi/authme/settings/SettingsWarnerTest.java @@ -1,18 +1,21 @@ package fr.xephi.authme.settings; import fr.xephi.authme.AuthMe; -import fr.xephi.authme.ReflectionTestUtils; import fr.xephi.authme.TestHelper; import fr.xephi.authme.security.HashAlgorithm; +import fr.xephi.authme.service.BukkitService; import fr.xephi.authme.settings.properties.EmailSettings; +import fr.xephi.authme.settings.properties.HooksSettings; import fr.xephi.authme.settings.properties.PluginSettings; import fr.xephi.authme.settings.properties.RestrictionSettings; import fr.xephi.authme.settings.properties.SecuritySettings; import org.junit.Test; import org.junit.runner.RunWith; +import org.mockito.InjectMocks; import org.mockito.Mock; import org.mockito.junit.MockitoJUnitRunner; +import java.util.Optional; import java.util.logging.Logger; import static org.mockito.ArgumentMatchers.anyString; @@ -27,12 +30,18 @@ import static org.mockito.internal.verification.VerificationModeFactory.times; @RunWith(MockitoJUnitRunner.class) public class SettingsWarnerTest { + @InjectMocks + private SettingsWarner settingsWarner; + @Mock private Settings settings; @Mock private AuthMe authMe; + @Mock + private BukkitService bukkitService; + @Test public void shouldLogWarnings() { // given @@ -43,12 +52,14 @@ public class SettingsWarnerTest { given(settings.getProperty(PluginSettings.SESSIONS_ENABLED)).willReturn(true); given(settings.getProperty(PluginSettings.SESSIONS_TIMEOUT)).willReturn(-5); given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.BCRYPT); + given(settings.getProperty(HooksSettings.BUNGEECORD)).willReturn(false); + given(bukkitService.isBungeeCordConfiguredForSpigot()).willReturn(Optional.of(true)); // when - createSettingsWarner().logWarningsForMisconfigurations(); + settingsWarner.logWarningsForMisconfigurations(); // then - verify(logger, times(3)).warning(anyString()); + verify(logger, times(4)).warning(anyString()); } @Test @@ -59,18 +70,12 @@ public class SettingsWarnerTest { given(settings.getProperty(EmailSettings.PORT25_USE_TLS)).willReturn(false); given(settings.getProperty(PluginSettings.SESSIONS_ENABLED)).willReturn(false); given(settings.getProperty(SecuritySettings.PASSWORD_HASH)).willReturn(HashAlgorithm.MD5); + given(bukkitService.isBungeeCordConfiguredForSpigot()).willReturn(Optional.empty()); // when - createSettingsWarner().logWarningsForMisconfigurations(); + settingsWarner.logWarningsForMisconfigurations(); // then verifyZeroInteractions(logger); } - - private SettingsWarner createSettingsWarner() { - SettingsWarner warner = new SettingsWarner(); - ReflectionTestUtils.setField(warner, "settings", settings); - ReflectionTestUtils.setField(warner, "authMe", authMe); - return warner; - } } From 6251a69d3eda3bb62842965256519075e68ad367 Mon Sep 17 00:00:00 2001 From: Gabriele C Date: Tue, 20 Mar 2018 10:42:17 +0100 Subject: [PATCH 12/12] Use the latest LuckPerms api methods --- .../permission/handlers/LuckPermsHandler.java | 28 +++++++++++-------- 1 file changed, 17 insertions(+), 11 deletions(-) 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 9e52746fc..f01f14c34 100644 --- a/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java +++ b/src/main/java/fr/xephi/authme/permission/handlers/LuckPermsHandler.java @@ -1,5 +1,6 @@ package fr.xephi.authme.permission.handlers; +import fr.xephi.authme.ConsoleLogger; import fr.xephi.authme.permission.PermissionNode; import fr.xephi.authme.permission.PermissionsSystemType; import me.lucko.luckperms.LuckPerms; @@ -41,13 +42,8 @@ public class LuckPermsHandler implements PermissionHandler { } private void saveUser(User user) { - luckPermsApi.getStorage().saveUser(user) - .thenAcceptAsync(wasSuccessful -> { - if (!wasSuccessful) { - return; - } - user.refreshPermissions(); - }, luckPermsApi.getStorage().getAsyncExecutor()); + luckPermsApi.getUserManager().saveUser(user) + .thenAcceptAsync(wasSuccessful -> user.refreshCachedData()); } @Override @@ -62,7 +58,7 @@ public class LuckPermsHandler implements PermissionHandler { return false; } - DataMutateResult result = user.setPermissionUnchecked( + DataMutateResult result = user.setPermission( luckPermsApi.getNodeFactory().makeGroupNode(newGroup).build()); if (result == DataMutateResult.FAIL) { return false; @@ -83,6 +79,8 @@ public class LuckPermsHandler implements PermissionHandler { public boolean hasPermissionOffline(String name, PermissionNode node) { User user = luckPermsApi.getUser(name); if (user == null) { + ConsoleLogger.warning("LuckPermsHandler: tried to check permission for offline user " + + name + " but it isn't loaded!"); return false; } @@ -98,6 +96,8 @@ public class LuckPermsHandler implements PermissionHandler { public boolean isInGroup(OfflinePlayer player, String group) { User user = luckPermsApi.getUser(player.getName()); if (user == null) { + ConsoleLogger.warning("LuckPermsHandler: tried to check group for offline user " + + player.getName() + " but it isn't loaded!"); return false; } @@ -112,6 +112,8 @@ public class LuckPermsHandler implements PermissionHandler { public boolean removeFromGroup(OfflinePlayer player, String group) { User user = luckPermsApi.getUser(player.getName()); if (user == null) { + ConsoleLogger.warning("LuckPermsHandler: tried to remove group for offline user " + + player.getName() + " but it isn't loaded!"); return false; } @@ -121,7 +123,7 @@ public class LuckPermsHandler implements PermissionHandler { } Node groupNode = luckPermsApi.getNodeFactory().makeGroupNode(permissionGroup).build(); - boolean result = user.unsetPermissionUnchecked(groupNode) != DataMutateResult.FAIL; + boolean result = user.unsetPermission(groupNode) != DataMutateResult.FAIL; luckPermsApi.cleanupUser(user); return result; @@ -131,6 +133,8 @@ public class LuckPermsHandler implements PermissionHandler { public boolean setGroup(OfflinePlayer player, String group) { User user = luckPermsApi.getUser(player.getName()); if (user == null) { + ConsoleLogger.warning("LuckPermsHandler: tried to set group for offline user " + + player.getName() + " but it isn't loaded!"); return false; } Group permissionGroup = luckPermsApi.getGroup(group); @@ -138,7 +142,7 @@ public class LuckPermsHandler implements PermissionHandler { return false; } Node groupNode = luckPermsApi.getNodeFactory().makeGroupNode(permissionGroup).build(); - DataMutateResult result = user.setPermissionUnchecked(groupNode); + DataMutateResult result = user.setPermission(groupNode); if (result == DataMutateResult.FAIL) { return false; } @@ -153,6 +157,8 @@ public class LuckPermsHandler implements PermissionHandler { public List getGroups(OfflinePlayer player) { User user = luckPermsApi.getUser(player.getName()); if (user == null) { + ConsoleLogger.warning("LuckPermsHandler: tried to get groups for offline user " + + player.getName() + " but it isn't loaded!"); return Collections.emptyList(); } @@ -185,7 +191,7 @@ public class LuckPermsHandler implements PermissionHandler { @Override public void loadUserData(UUID uuid) { try { - luckPermsApi.getStorage().loadUser(uuid).get(5, TimeUnit.SECONDS); + luckPermsApi.getUserManager().loadUser(uuid).get(5, TimeUnit.SECONDS); } catch (InterruptedException | ExecutionException | TimeoutException e) { e.printStackTrace(); }