Merge branch 'master' of https://github.com/AuthMe/AuthMeReloaded into limbo

# Conflicts:
#	src/main/java/fr/xephi/authme/command/executable/authme/debug/DebugCommand.java
This commit is contained in:
ljacqu 2017-03-12 14:54:25 +01:00
commit 689e5eeccc
21 changed files with 450 additions and 159 deletions

View File

@ -11,10 +11,10 @@ import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.service.CommonService;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.DatabaseSettings;
import fr.xephi.authme.util.Utils;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.Collection;
import java.util.List;
/**
@ -44,8 +44,7 @@ public class ReloadCommand implements ExecutableCommand {
ConsoleLogger.setLoggingOptions(settings);
// We do not change database type for consistency issues, but we'll output a note in the logs
if (!settings.getProperty(DatabaseSettings.BACKEND).equals(dataSource.getType())) {
ConsoleLogger.info("Note: cannot change database type during /authme reload");
sender.sendMessage("Note: cannot change database type during /authme reload");
Utils.logAndSendMessage(sender, "Note: cannot change database type during /authme reload");
}
performReloadOnServices();
commonService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
@ -57,14 +56,10 @@ public class ReloadCommand implements ExecutableCommand {
}
private void performReloadOnServices() {
Collection<Reloadable> reloadables = injector.retrieveAllOfType(Reloadable.class);
for (Reloadable reloadable : reloadables) {
reloadable.reload();
}
injector.retrieveAllOfType(Reloadable.class)
.forEach(r -> r.reload());
Collection<SettingsDependent> settingsDependents = injector.retrieveAllOfType(SettingsDependent.class);
for (SettingsDependent dependent : settingsDependents) {
dependent.reload(settings);
}
injector.retrieveAllOfType(SettingsDependent.class)
.forEach(s -> s.reload(settings));
}
}

View File

@ -0,0 +1,77 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.data.auth.PlayerAuth;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.service.GeoIpService;
import fr.xephi.authme.service.ValidationService;
import fr.xephi.authme.settings.properties.ProtectionSettings;
import org.bukkit.ChatColor;
import org.bukkit.command.CommandSender;
import javax.inject.Inject;
import java.util.List;
import java.util.regex.Pattern;
/**
* Shows the GeoIP information as returned by the geoIpService.
*/
class CountryLookup implements DebugSection {
private static final Pattern IS_IP_ADDR = Pattern.compile("(\\d{1,3}\\.){3}\\d{1,3}");
@Inject
private GeoIpService geoIpService;
@Inject
private DataSource dataSource;
@Inject
private ValidationService validationService;
@Override
public String getName() {
return "cty";
}
@Override
public String getDescription() {
return "Check country protection / country data";
}
@Override
public void execute(CommandSender sender, List<String> arguments) {
if (arguments.isEmpty()) {
sender.sendMessage("Check player: /authme debug cty Bobby");
sender.sendMessage("Check IP address: /authme debug cty 127.123.45.67");
return;
}
String argument = arguments.get(0);
if (IS_IP_ADDR.matcher(argument).matches()) {
outputInfoForIpAddr(sender, argument);
} else {
outputInfoForPlayer(sender, argument);
}
}
private void outputInfoForIpAddr(CommandSender sender, String ipAddr) {
sender.sendMessage("IP '" + ipAddr + "' maps to country '" + geoIpService.getCountryCode(ipAddr)
+ "' (" + geoIpService.getCountryName(ipAddr) + ")");
if (validationService.isCountryAdmitted(ipAddr)) {
sender.sendMessage(ChatColor.DARK_GREEN + "This IP address' country is not blocked");
} else {
sender.sendMessage(ChatColor.DARK_RED + "This IP address' country is blocked from the server");
}
sender.sendMessage("Note: if " + ProtectionSettings.ENABLE_PROTECTION + " is false no country is blocked");
}
private void outputInfoForPlayer(CommandSender sender, String name) {
PlayerAuth auth = dataSource.getAuth(name);
if (auth == null) {
sender.sendMessage("No player with name '" + name + "'");
} else {
sender.sendMessage("Player '" + name + "' has IP address " + auth.getIp());
outputInfoForIpAddr(sender, auth.getIp());
}
}
}

View File

@ -19,8 +19,9 @@ public class DebugCommand implements ExecutableCommand {
@Inject
private Factory<DebugSection> debugSectionFactory;
private Set<Class<? extends DebugSection>> sectionClasses =
ImmutableSet.of(PermissionGroups.class, TestEmailSender.class, PlayerAuthViewer.class, LimboPlayerViewer.class);
private Set<Class<? extends DebugSection>> sectionClasses = ImmutableSet.of(
PermissionGroups.class, TestEmailSender.class, PlayerAuthViewer.class, LimboPlayerViewer.class,
CountryLookup.class);
private Map<String, DebugSection> sections;

View File

@ -45,7 +45,10 @@ public class MySQL implements DataSource {
private HikariDataSource ds;
private String phpBbPrefix;
private String IPBPrefix;
private int phpBbGroup;
private int IPBGroup;
private int XFGroup;
private String wordpressPrefix;
public MySQL(Settings settings) throws ClassNotFoundException, SQLException {
@ -96,6 +99,9 @@ public class MySQL implements DataSource {
this.hashAlgorithm = settings.getProperty(SecuritySettings.PASSWORD_HASH);
this.phpBbPrefix = settings.getProperty(HooksSettings.PHPBB_TABLE_PREFIX);
this.phpBbGroup = settings.getProperty(HooksSettings.PHPBB_ACTIVATED_GROUP_ID);
this.IPBPrefix = settings.getProperty(HooksSettings.IPB_TABLE_PREFIX);
this.IPBGroup = settings.getProperty(HooksSettings.IPB_ACTIVATED_GROUP_ID);
this.XFGroup = settings.getProperty(HooksSettings.XF_ACTIVATED_GROUP_ID);
this.wordpressPrefix = settings.getProperty(HooksSettings.WORDPRESS_TABLE_PREFIX);
this.poolSize = settings.getProperty(DatabaseSettings.MYSQL_POOL_SIZE);
if (poolSize == -1) {
@ -334,8 +340,39 @@ public class MySQL implements DataSource {
pst.close();
}
}
if (hashAlgorithm == HashAlgorithm.PHPBB) {
if (hashAlgorithm == HashAlgorithm.IPB4){
sql = "SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
pst = con.prepareStatement(sql);
pst.setString(1, auth.getNickname());
rs = pst.executeQuery();
if (rs.next()){
// Update player group in core_members
sql = "UPDATE " + IPBPrefix + tableName + " SET "+ tableName + ".member_group_id=? WHERE " + col.NAME + "=?;";
pst2 = con.prepareStatement(sql);
pst2.setInt(1, IPBGroup);
pst2.setString(2, auth.getNickname());
pst2.executeUpdate();
pst2.close();
// Get current time without ms
long time = System.currentTimeMillis() / 1000;
// update joined date
sql = "UPDATE " + IPBPrefix + tableName + " SET "+ tableName + ".joined=? WHERE " + col.NAME + "=?;";
pst2 = con.prepareStatement(sql);
pst2.setLong(1, time);
pst2.setString(2, auth.getNickname());
pst2.executeUpdate();
pst2.close();
// Update last_visit
sql = "UPDATE " + IPBPrefix + tableName + " SET " + tableName + ".last_visit=? WHERE " + col.NAME + "=?;";
pst2 = con.prepareStatement(sql);
pst2.setLong(1, time);
pst2.setString(2, auth.getNickname());
pst2.executeUpdate();
pst2.close();
}
rs.close();
pst.close();
} else if (hashAlgorithm == HashAlgorithm.PHPBB) {
sql = "SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;";
pst = con.prepareStatement(sql);
pst.setString(1, auth.getNickname());
@ -477,8 +514,9 @@ public class MySQL implements DataSource {
pst = con.prepareStatement("SELECT " + col.ID + " FROM " + tableName + " WHERE " + col.NAME + "=?;");
pst.setString(1, auth.getNickname());
rs = pst.executeQuery();
if (rs.next()) {
if (rs.next()) {
int id = rs.getInt(col.ID);
// Insert player password, salt in xf_user_authenticate
sql = "INSERT INTO xf_user_authenticate (user_id, scheme_class, data) VALUES (?,?,?)";
pst2 = con.prepareStatement(sql);
pst2.setInt(1, id);
@ -490,6 +528,39 @@ public class MySQL implements DataSource {
pst2.setBlob(3, blob);
pst2.executeUpdate();
pst2.close();
// Update player group in xf_users
sql = "UPDATE " + tableName + " SET "+ tableName + ".user_group_id=? WHERE " + col.NAME + "=?;";
pst2 = con.prepareStatement(sql);
pst2.setInt(1, XFGroup);
pst2.setString(2, auth.getNickname());
pst2.executeUpdate();
pst2.close();
// Update player permission combination in xf_users
sql = "UPDATE " + tableName + " SET "+ tableName + ".permission_combination_id=? WHERE " + col.NAME + "=?;";
pst2 = con.prepareStatement(sql);
pst2.setInt(1, XFGroup);
pst2.setString(2, auth.getNickname());
pst2.executeUpdate();
pst2.close();
// Insert player privacy combination in xf_user_privacy
sql = "INSERT INTO xf_user_privacy (user_id, allow_view_profile, allow_post_profile, allow_send_personal_conversation, allow_view_identities, allow_receive_news_feed) VALUES (?,?,?,?,?,?)";
pst2 = con.prepareStatement(sql);
pst2.setInt(1, id);
pst2.setString(2, "everyone");
pst2.setString(3, "members");
pst2.setString(4, "members");
pst2.setString(5, "everyone");
pst2.setString(6, "everyone");
pst2.executeUpdate();
pst2.close();
// Insert player group relation in xf_user_group_relation
sql = "INSERT INTO xf_user_group_relation (user_id, user_group_id, is_primary) VALUES (?,?,?)";
pst2 = con.prepareStatement(sql);
pst2.setInt(1, id);
pst2.setInt(2, XFGroup);
pst2.setString(3, "1");
pst2.executeUpdate();
pst2.close();
}
rs.close();
pst.close();

View File

@ -1,8 +1,10 @@
package fr.xephi.authme.mail;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
import fr.xephi.authme.util.StringUtils;
import org.apache.commons.mail.EmailConstants;
import org.apache.commons.mail.EmailException;
@ -56,6 +58,9 @@ public class SendMailSSL {
email.setFrom(senderMail, senderName);
email.setSubject(settings.getProperty(EmailSettings.RECOVERY_MAIL_SUBJECT));
email.setAuthentication(settings.getProperty(EmailSettings.MAIL_ACCOUNT), mailPassword);
if (settings.getProperty(PluginSettings.LOG_LEVEL).includes(LogLevel.DEBUG)) {
email.setDebug(true);
}
setPropertiesForPort(email, port);
return email;

View File

@ -11,7 +11,6 @@ import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.AdminPermission;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerPermission;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.process.AsynchronousProcess;
@ -44,9 +43,6 @@ public class AsynchronousLogin implements AsynchronousProcess {
@Inject
private CommonService service;
@Inject
private PermissionsManager permissionsManager;
@Inject
private PlayerCache playerCache;
@ -290,10 +286,10 @@ public class AsynchronousLogin implements AsynchronousProcess {
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
if (onlinePlayer.getName().equalsIgnoreCase(player.getName())
&& permissionsManager.hasPermission(onlinePlayer, PlayerPermission.SEE_OWN_ACCOUNTS)) {
&& service.hasPermission(onlinePlayer, PlayerPermission.SEE_OWN_ACCOUNTS)) {
service.send(onlinePlayer, MessageKey.ACCOUNTS_OWNED_SELF, Integer.toString(auths.size()));
onlinePlayer.sendMessage(message);
} else if (permissionsManager.hasPermission(onlinePlayer, AdminPermission.SEE_OTHER_ACCOUNTS)) {
} else if (service.hasPermission(onlinePlayer, AdminPermission.SEE_OTHER_ACCOUNTS)) {
service.send(onlinePlayer, MessageKey.ACCOUNTS_OWNED_OTHER,
player.getName(), Integer.toString(auths.size()));
onlinePlayer.sendMessage(message);
@ -313,7 +309,7 @@ public class AsynchronousLogin implements AsynchronousProcess {
boolean hasReachedMaxLoggedInPlayersForIp(Player player, String ip) {
// Do not perform the check if player has multiple accounts permission or if IP is localhost
if (service.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP) <= 0
|| permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|| service.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)
|| "127.0.0.1".equalsIgnoreCase(ip)
|| "localhost".equalsIgnoreCase(ip)) {
return false;

View File

@ -65,16 +65,6 @@ public class CommonService {
messages.send(sender, key, replacements);
}
/**
* Retrieves a message.
*
* @param key the key of the message
* @return the message, split by line
*/
public String[] retrieveMessage(MessageKey key) {
return messages.retrieve(key);
}
/**
* Retrieves a message in one piece.
*
@ -102,6 +92,7 @@ public class CommonService {
* @param player the player to process
* @param group the group to add the player to
*/
// TODO ljacqu 20170304: Move this out of CommonService
public void setGroup(Player player, AuthGroupType group) {
authGroupHandler.setGroup(player, group);
}

View File

@ -1,6 +1,7 @@
package fr.xephi.authme.service;
import ch.jalu.configme.properties.Property;
import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.initialization.Reloadable;
import fr.xephi.authme.message.MessageKey;
@ -115,9 +116,10 @@ public class ValidationService implements Reloadable {
}
String countryCode = geoIpService.getCountryCode(hostAddress);
return validateWhitelistAndBlacklist(countryCode,
ProtectionSettings.COUNTRIES_WHITELIST,
ProtectionSettings.COUNTRIES_BLACKLIST);
boolean isCountryAllowed = validateWhitelistAndBlacklist(countryCode,
ProtectionSettings.COUNTRIES_WHITELIST, ProtectionSettings.COUNTRIES_BLACKLIST);
ConsoleLogger.debug("Country code `{0}` for `{1}` is allowed: {2}", countryCode, hostAddress, isCountryAllowed);
return isCountryAllowed;
}
/**
@ -194,6 +196,7 @@ public class ValidationService implements Reloadable {
public MessageKey getMessageKey() {
return messageKey;
}
public String[] getArgs() {
return args;
}

View File

@ -74,7 +74,7 @@ public class CommandManager implements Reloadable {
private void executeCommands(Player player, List<Command> commands) {
for (Command command : commands) {
final String execution = command.getCommand().replace("%p", player.getName());
final String execution = command.getCommand();
if (Executor.CONSOLE.equals(command.getExecutor())) {
bukkitService.dispatchConsoleCommand(execution);
} else {

View File

@ -54,6 +54,18 @@ public final class HooksSettings implements SettingsHolder {
public static final Property<Integer> PHPBB_ACTIVATED_GROUP_ID =
newProperty("ExternalBoardOptions.phpbbActivatedGroupId", 2);
@Comment("IP Board table prefix defined during the IP Board installation process")
public static final Property<String> IPB_TABLE_PREFIX =
newProperty("ExternalBoardOptions.IPBTablePrefix", "ipb_");
@Comment("IP Board default group ID; 3 is the default registered group defined by IP Board")
public static final Property<Integer> IPB_ACTIVATED_GROUP_ID =
newProperty("ExternalBoardOptions.IPBActivatedGroupId", 3);
@Comment("XenForo default group ID; 2 is the default registered group defined by Xenforo")
public static final Property<Integer> XF_ACTIVATED_GROUP_ID =
newProperty("ExternalBoardOptions.XFActivatedGroupId", 2);
@Comment("Wordpress prefix defined during WordPress installation")
public static final Property<String> WORDPRESS_TABLE_PREFIX =
newProperty("ExternalBoardOptions.wordpressTablePrefix", "wp_");

View File

@ -9,14 +9,13 @@ import fr.xephi.authme.settings.properties.PurgeSettings;
import fr.xephi.authme.util.Utils;
import org.bukkit.OfflinePlayer;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import javax.inject.Inject;
import java.util.Calendar;
import java.util.Collection;
import java.util.Set;
// TODO: move into services. -sgdc3
import static fr.xephi.authme.util.Utils.logAndSendMessage;
/**
* Initiates purge tasks.
@ -119,12 +118,4 @@ public class PurgeService {
void executePurge(Collection<OfflinePlayer> players, Collection<String> names) {
purgeExecutor.executePurge(players, names);
}
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);
}
}
}

View File

@ -1,6 +1,8 @@
package fr.xephi.authme.util;
import fr.xephi.authme.ConsoleLogger;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import java.util.Collection;
import java.util.regex.Pattern;
@ -51,6 +53,22 @@ public final class Utils {
}
}
/**
* Sends a message to the given sender (null safe), and logs the message to the console.
* This method is aware that the command sender might be the console sender and avoids
* displaying the message twice in this case.
*
* @param sender the sender to inform
* @param message the message to log and send
*/
public 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);
}
}
/**
* Null-safe way to check whether a collection is empty or not.
*

View File

@ -0,0 +1,45 @@
# Translation config for the AuthMe help, e.g. when /authme help or /authme help register is called
# -------------------------------------------------------
# List of texts used in the help section
common:
header: '==========[ AJUDA DO AuthMeReloaded ]=========='
optional: 'Opcional'
hasPermission: 'Tu tens permissão'
noPermission: 'Não tens permissão'
default: 'Padrão'
result: 'Resultado'
defaultPermissions:
notAllowed: 'Sem permissão'
opOnly: 'Só OP'
allowed: 'Toda gente é permitida'
# -------------------------------------------------------
# Titles of the individual help sections
# Set the translation text to empty text to disable the section, e.g. to hide alternatives:
# alternatives: ''
section:
command: 'Comando'
description: 'Breve descrição'
detailedDescription: 'Descrição detalhada'
arguments: 'Argumentos'
permissions: 'Permissões'
alternatives: 'Alternativas'
children: 'Comandos'
# -------------------------------------------------------
# You can translate the data for all commands using the below pattern.
# For example to translate /authme reload, create a section "authme.reload", or "login" for /login
# If the command has arguments, you can use arg1 as below to translate the first argument, and so forth
# Translations don't need to be complete; any missing section will be taken from the default silently
# Important: Put main commands like "authme" before their children (e.g. "authme.reload")
commands:
authme.register:
description: 'Registar um jogador'
detailedDescription: 'Registar um jogador com uma senha especifica.'
arg1:
label: 'jogador'
description: 'Nome de jogador'
arg2:
label: 'senha'
description: 'Senha'

View File

@ -1,105 +1,104 @@
# Registration
reg_msg: '&cМоля регистрирай се с "/register <парола> <парола>"'
reg_msg: '&3Моля регистрирайте се с: /register парола парола'
usage_reg: '&cКоманда: /register парола парола'
reg_only: '&fСамо за регистрирани! Моля посети http://example.com за регистрация'
# TODO kicked_admin_registered: 'An admin just registered you; please log in again'
registered: '&cУспешно премахната регистрация!'
reg_only: '&4Само регистрирани потребители могат да влизат в сървъра! Моля посетете http://example.com, за да се регистрирате!'
kicked_admin_registered: 'Ти беше регистриран от администратора, моля влезте отново'
registered: '&2Успешна регистрация!'
reg_disabled: '&cРегистрациите са изключени!'
user_regged: '&cПотребителското име е заето!'
user_regged: '&cПотребителското име е заетo!'
# Password errors on registration
password_error: '&аролата не съвпада'
# TODO password_error_nick: '&cYou can''t use your name as password, please choose another one...'
# TODO password_error_unsafe: '&cThe chosen password isn''t safe, please choose another one...'
# TODO password_error_chars: '&4Your password contains illegal characters. Allowed chars: REG_EX'
pass_len: '&cВашета парола не е достатъчно дълга или къса.'
password_error: '&аролите не съвпадат, провете ги отново!'
password_error_nick: '&cНе можеш да използваш потребителското си име за парола, моля изберете друга парола.'
password_error_unsafe: '&cИзбраната парола не е безопасна, моля изберете друга парола.'
password_error_chars: '&4Паролата съдържа непозволени символи. Позволени символи: REG_EX'
pass_len: '&cПаролата е твърде къса или прекалено дълга! Моля опитайте с друга парола.'
# Login
usage_log: '&cКоманда: /login парола'
wrong_pwd: '&cГрешна парола!'
login: '&cВход успешен!'
login_msg: '&cМоля влез с "/login парола"'
timeout: '&fВремето изтече, опитай отново!'
login: '&2Успешен вход!'
login_msg: '&cМоля влезте с: /login парола'
timeout: '&4Времето за вход изтече, беше кикнат от сървъра. Моля опитайте отново!'
# Errors
unknown_user: '&cПотребителя не е регистриран'
# TODO denied_command: '&cIn order to use this command you must be authenticated!'
# TODO denied_chat: '&cIn order to chat you must be authenticated!'
unknown_user: '&cПотребителското име не е регистрирано!'
denied_command: '&cЗа да използваш тази команда трябва да си си влезнал в акаунта!'
denied_chat: '&cЗа да пишеш в чата трябва даи сиси влезнал в акаунта!'
not_logged_in: '&cНе си влязъл!'
# TODO tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.'
# TODO: Missing tags %reg_count, %max_acc, %reg_names
max_reg: '&fТи достигна максималния брой регистрации!'
no_perm: '&cНямаш Достъп!'
error: '&fПолучи се грешка; Моля свържете се с админ'
unsafe_spawn: '&fТвоята локация когато излезе не беше безопасна, телепортиран си на Spawn!'
kick_forvip: '&cVIP влезе докато сървъра е пълен, ти беше изгонен!'
tempban_max_logins: '&cТи беше баннат временно, понеже си сгрешил паролата прекалено много пъти.'
max_reg: '&cТи си достигнал максималният брой регистрации (%reg_count/%max_acc %reg_names)!'
no_perm: '&4Нямаш нужните права за това действие!'
error: '&4Получи се неочаквана грешка, моля свържете се с администратора!'
unsafe_spawn: '&cКогато излезе твоето местоположение не беше безопастно, телепортиран си на Spawn.'
kick_forvip: '&3VIP потребител влезе докато сървъра беше пълен, ти беше изгонен!'
# AntiBot
# TODO kick_antibot: 'AntiBot protection mode is enabled! You have to wait some minutes before joining the server.'
antibot_auto_enabled: '[AuthMe] AntiBotMod автоматично включен, открита е потенциална атака!'
antibot_auto_disabled: '[AuthMe] AntiBotMod автоматично изключване след %m Минути.'
kick_antibot: 'Защитата от ботове е включена! Трябва да изчакаш няколко минути преди да влезеш в сървъра.'
antibot_auto_enabled: '&4Защитата за ботове е включена заради потенциална атака!'
antibot_auto_disabled: '&2Защитата за ботове ще се изключи след %m минута/и!'
# Other messages
unregistered: '&cУспешно от-регистриран!'
# TODO accounts_owned_self: 'You own %count accounts:'
# TODO accounts_owned_other: 'The player %name has %count accounts:'
# TODO two_factor_create: '&2Your secret code is %code. You can scan it from here %url'
# TODO recovery_code_sent: 'A recovery code to reset your password has been sent to your email.'
# TODO recovery_code_incorrect: 'The recovery code is not correct! Use "/email recovery [email]" to generate a new one'
vb_nonActiv: '&fТвоята регистрация не е активирана, моля провери своя Имейл!'
unregistered: '&cРегистрацията е премахната успешно!'
accounts_owned_self: 'Претежаваш %count акаунт/а:'
accounts_owned_other: 'Потребителят %name има %count акаунт/а:'
two_factor_create: '&2Кода е %code. Можеш да го провериш оттука: %url'
recovery_code_sent: 'Възстановяващият код беше изпратен на твоят email адрес.'
recovery_code_incorrect: 'Възстановяващият код е неправилен! Използвайте: /email recovery имейл, за да генерирате нов'
vb_nonActiv: '&cТвоят акаунт все още не е актириван, моля провете своят email адрес!'
usage_unreg: '&cКоманда: /unregister парола'
pwd_changed: '&аролата е променена!'
logged_in: '&cВече сте влязъл!'
logout: '&cУспешен изход от регистрацията!'
reload: '&fКонфигурацията презаредена!'
usage_changepassword: '&fКоманда: /changepassword СтараПарола НоваПарола'
pwd_changed: '&аротала е променена успешно!'
logged_in: '&cВече си вписан!'
logout: '&2Излязохте успешно!'
reload: '&2Конфигурацията и база данните бяха презаредени правилно!'
usage_changepassword: '&cКоманда: /changepassword Стара-Парола Нова-Парола'
# Session messages
# TODO invalid_session: '&cYour IP has been changed and your session data has expired!'
valid_session: '&aСесията продължена!'
invalid_session: '&cТвоят IP се е променил и сесията беше прекратена.'
valid_session: '&2Сесията е продължена.'
# Error messages when joining
name_len: '&cТвоя никнейм е твърде малък или голям'
regex: '&cТвоя никнейм съдържа забранени знацхи. Позволените са: REG_EX'
country_banned: 'Твоята държава е забранена в този сървър!'
# TODO not_owner_error: 'You are not the owner of this account. Please choose another name!'
kick_fullserver: '&cСървъра е пълен, Съжеляваме!'
same_nick: '&отребител с този никнейм е в игра'
# TODO invalid_name_case: 'You should join using username %valid, not %invalid.'
# TODO same_ip_online: 'A player with the same IP is already in game!'
name_len: '&отребителското име е прекалено късо или дълга. Моля опитайте с друго потребителско име!'
regex: '&отребителското име съдържа забранени знаци. Позволени знаци: REG_EX'
country_banned: '&4Твоята държава е забранена в този сървър!'
not_owner_error: 'Ти не си собственика на този акаунт. Моля избери друго потребителско име!'
kick_fullserver: '&4Сървъра е пълен, моля опитайте отново!'
same_nick: '&4Вече има потребител, който играете в сървъра със същото потребителско име!'
invalid_name_case: 'Трябва да влезеш с %valid, а не с %invalid.'
same_ip_online: 'Вече има потребител със същото IP в сървъра!'
# Email
usage_email_add: '&fКоманда: /email add <email> <confirmEmail> '
usage_email_change: '&fКоманда: /email change <СтарИмейл> <НовИмейл> '
usage_email_recovery: '&fКоманда: /email recovery <имейл>'
new_email_invalid: '[AuthMe] Новия имейл е грешен!'
old_email_invalid: '[AuthMe] Стария имейл е грешен!'
email_invalid: '[AuthMe] Грешен имейл'
email_added: '[AuthMe] Имейла добавен !'
email_confirm: '[AuthMe] Потвърди своя имейл !'
email_changed: '[AuthMe] Имейла е сменен !'
email_send: '[AuthMe] Изпраен е имейл !'
# TODO email_exists: '&cA recovery email was already sent! You can discard it and send a new one using the command below:'
# TODO email_show: '&2Your current email address is: &f%email'
# TODO incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
# TODO email_already_used: '&4The email address is already being used'
# TODO email_send_failure: 'The email could not be sent. Please contact an administrator.'
# TODO show_no_email: '&2You currently don''t have email address associated with this account.'
add_email: '&cМоля добави своя имейл с : /email add имейл имейл'
recovery_email: '&cЗабравихте своята парола? Моля използвай /email recovery <имейл>'
# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.'
usage_email_add: '&cКоманда: /email add имейл имейл'
usage_email_change: '&cКоманда: /email change Стар-Имейл Нов-Имейл'
usage_email_recovery: '&cКоманда: /email recovery имейл'
new_email_invalid: '&cНовият имейл е грешен, опитайте отново!'
old_email_invalid: '&cСтарият имейл е грешен, опитайте отново!'
email_invalid: '&cИмейла е невалиден, опитайте с друг!'
email_added: '&2Имейл адреса е добавен!'
email_confirm: '&cМоля потвърди своя имейл адрес!'
email_changed: '&2Имейл адреса е сменен!'
email_send: '&2Възстановяващият имейл е изпратен успешно. Моля провете пощата си!'
email_exists: '&cВъзстановяващият имейл е бил изпратен. Може да го откажеш или изпратиш отново с тази команда:'
email_show: '&2Твоят имейл адрес е: &f%email'
incomplete_email_settings: 'Грешка: Не всички настройки са написани за изпращане на имейл адрес. Моля свържете се с администратора!'
email_already_used: '&4Имейл адреса вече се използва, опитайте с друг.'
email_send_failure: 'Съобщението не беше изпратено. Моля свържете се с администратора.'
show_no_email: '&2Няма добавен имейл адрес към акаунта.'
add_email: '&3Моля добавете имейл адрес към своят акаунт: /email add имейл имейл'
recovery_email: '&3Забравена парола? Използвайте: /email recovery имейл'
email_cooldown_error: '&cВече е бил изпратен имейл адрес. Трябва а изчакаш %time преди да пратиш нов.'
# Captcha
usage_captcha: '&cYou need to type a captcha, please type: /captcha <theCaptcha>'
wrong_captcha: '&cГрешен код, използвай : /captcha THE_CAPTCHA'
valid_captcha: '&cТвоя код е валиден!'
usage_captcha: '&3Моля въведе цифрите/буквите от капчата: /captcha <theCaptcha>'
wrong_captcha: '&cКода е грешен, използвайте: "/captcha THE_CAPTCHA" в чата!'
valid_captcha: '&2Кода е валиден!'
# Time units
# TODO second: 'second'
# TODO seconds: 'seconds'
# TODO minute: 'minute'
# TODO minutes: 'minutes'
# TODO hour: 'hour'
# TODO hours: 'hours'
# TODO day: 'day'
# TODO days: 'days'
second: 'секунда'
seconds: 'секунди'
minute: 'минута'
minutes: 'минути'
hour: 'час'
hours: 'часа'
day: 'ден'
days: 'дена'

View File

@ -89,7 +89,7 @@ email_send_failure: 'No se ha podido enviar el correo electrónico. Por favor, c
show_no_email: '&2No tienes ningun E-Mail asociado en esta cuenta.'
add_email: '&cPor favor agrega tu e-mail con: /email add tuEmail confirmarEmail'
recovery_email: '&c¿Olvidaste tu contraseña? Por favor usa /email recovery <tuEmail>'
# TODO email_cooldown_error: '&cAn email was already sent recently. You must wait %time before you can send a new one.'
email_cooldown_error: '&cEl correo ha sido enviado recientemente. Debes esperar %time antes de volver a enviar uno nuevo.'
# Captcha
usage_captcha: '&cUso: /captcha <theCaptcha>'
@ -97,11 +97,11 @@ wrong_captcha: '&cCaptcha incorrecto, por favor usa: /captcha THE_CAPTCHA'
valid_captcha: '&c¡ Captcha ingresado correctamente !'
# Time units
# TODO second: 'second'
# TODO seconds: 'seconds'
# TODO minute: 'minute'
# TODO minutes: 'minutes'
# TODO hour: 'hour'
# TODO hours: 'hours'
# TODO day: 'day'
# TODO days: 'days'
second: 'segundo'
seconds: 'segundos'
minute: 'minuto'
minutes: 'minutos'
hour: 'hora'
hours: 'horas'
day: 'día'
days: 'días'

View File

@ -0,0 +1,51 @@
package fr.xephi.authme.command.executable.authme.debug;
import fr.xephi.authme.ClassCollector;
import org.junit.BeforeClass;
import org.junit.Test;
import java.lang.reflect.Modifier;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.junit.Assert.fail;
/**
* Consistency tests for {@link DebugSection} implementors.
*/
public class DebugSectionConsistencyTest {
private static List<Class<?>> debugClasses;
@BeforeClass
public static void collectClasses() {
debugClasses = new ClassCollector("src/main/java", "fr/xephi/authme/command/executable/authme/debug")
.collectClasses();
}
@Test
public void shouldAllBePackagePrivate() {
for (Class<?> clazz : debugClasses) {
if (clazz != DebugCommand.class) {
assertThat(clazz + " should be package-private",
Modifier.isPublic(clazz.getModifiers()), equalTo(false));
}
}
}
@Test
public void shouldHaveDifferentSubcommandName() throws IllegalAccessException, InstantiationException {
Set<String> names = new HashSet<>();
for (Class<?> clazz : debugClasses) {
if (DebugSection.class.isAssignableFrom(clazz) && !clazz.isInterface()) {
DebugSection debugSection = (DebugSection) clazz.newInstance();
if (!names.add(debugSection.getName())) {
fail("Encountered name '" + debugSection.getName() + "' a second time in " + clazz);
}
}
}
}
}

View File

@ -4,8 +4,10 @@ import ch.jalu.injector.testing.BeforeInjecting;
import ch.jalu.injector.testing.DelayedInjectionRunner;
import ch.jalu.injector.testing.InjectDelayed;
import fr.xephi.authme.TestHelper;
import fr.xephi.authme.output.LogLevel;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.properties.EmailSettings;
import fr.xephi.authme.settings.properties.PluginSettings;
import org.apache.commons.mail.EmailException;
import org.apache.commons.mail.HtmlEmail;
import org.junit.BeforeClass;
@ -49,6 +51,7 @@ public class SendMailSSLTest {
public void initFields() throws IOException {
given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("mail@example.org");
given(settings.getProperty(EmailSettings.MAIL_PASSWORD)).willReturn("pass1234");
given(settings.getProperty(PluginSettings.LOG_LEVEL)).willReturn(LogLevel.INFO);
}
@Test
@ -67,6 +70,7 @@ public class SendMailSSLTest {
given(settings.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn(senderAccount);
String senderName = "Server administration";
given(settings.getProperty(EmailSettings.MAIL_SENDER_NAME)).willReturn(senderName);
given(settings.getProperty(PluginSettings.LOG_LEVEL)).willReturn(LogLevel.DEBUG);
// when
HtmlEmail email = sendMailSSL.initializeMail("recipient@example.com");

View File

@ -7,7 +7,6 @@ import fr.xephi.authme.data.limbo.LimboService;
import fr.xephi.authme.datasource.DataSource;
import fr.xephi.authme.events.AuthMeAsyncPreLoginEvent;
import fr.xephi.authme.message.MessageKey;
import fr.xephi.authme.permission.PermissionsManager;
import fr.xephi.authme.permission.PlayerStatePermission;
import fr.xephi.authme.service.BukkitService;
import fr.xephi.authme.service.CommonService;
@ -61,8 +60,6 @@ public class AsynchronousLoginTest {
private LimboService limboService;
@Mock
private BukkitService bukkitService;
@Mock
private PermissionsManager permissionsManager;
@BeforeClass
public static void initLogger() {
@ -182,7 +179,7 @@ public class AsynchronousLoginTest {
// given
Player player = mockPlayer("Carl");
given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(2);
given(permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(false);
given(commonService.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(false);
mockOnlinePlayersInBukkitService();
// when
@ -190,7 +187,7 @@ public class AsynchronousLoginTest {
// then
assertThat(result, equalTo(false));
verify(permissionsManager).hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS);
verify(commonService).hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS);
verify(bukkitService).getOnlinePlayers();
}
@ -213,14 +210,14 @@ public class AsynchronousLoginTest {
// given
Player player = mockPlayer("Frank");
given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(1);
given(permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(true);
given(commonService.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(true);
// when
boolean result = asynchronousLogin.hasReachedMaxLoggedInPlayersForIp(player, "127.0.0.4");
// then
assertThat(result, equalTo(false));
verify(permissionsManager).hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS);
verify(commonService).hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS);
verifyZeroInteractions(bukkitService);
}
@ -229,7 +226,7 @@ public class AsynchronousLoginTest {
// given
Player player = mockPlayer("Ian");
given(commonService.getProperty(RestrictionSettings.MAX_LOGIN_PER_IP)).willReturn(2);
given(permissionsManager.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(false);
given(commonService.hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS)).willReturn(false);
mockOnlinePlayersInBukkitService();
// when
@ -237,7 +234,7 @@ public class AsynchronousLoginTest {
// then
assertThat(result, equalTo(true));
verify(permissionsManager).hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS);
verify(commonService).hasPermission(player, PlayerStatePermission.ALLOW_MULTIPLE_ACCOUNTS);
verify(bukkitService).getOnlinePlayers();
}

View File

@ -84,21 +84,6 @@ public class CommonServiceTest {
verify(messages).send(sender, key, replacements);
}
@Test
public void shouldRetrieveMessage() {
// given
MessageKey key = MessageKey.ACCOUNT_NOT_ACTIVATED;
String[] lines = new String[]{"First message line", "second line"};
given(messages.retrieve(key)).willReturn(lines);
// when
String[] result = commonService.retrieveMessage(key);
// then
assertThat(result, equalTo(lines));
verify(messages).retrieve(key);
}
@Test
public void shouldRetrieveSingleMessage() {
// given

View File

@ -58,7 +58,7 @@ public class PluginHookServiceTest {
assertThat(pluginHookService.isEssentialsAvailable(), equalTo(true));
}
// Note ljacqu 20160312: Cannot test with Multiverse or CombatTagPlus because their classes are declared final
// Note ljacqu 20160312: Cannot test with CombatTagPlus because its class is declared final
@Test
public void shouldHookIntoEssentialsAtInitialization() {

View File

@ -1,13 +1,20 @@
package fr.xephi.authme.util;
import fr.xephi.authme.TestHelper;
import org.bukkit.command.CommandSender;
import org.bukkit.command.ConsoleCommandSender;
import org.bukkit.entity.Player;
import org.junit.BeforeClass;
import org.junit.Test;
import java.util.logging.Logger;
import java.util.regex.Pattern;
import static org.hamcrest.Matchers.equalTo;
import static org.junit.Assert.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.verifyZeroInteractions;
/**
* Test for {@link Utils}.
@ -49,6 +56,49 @@ public class UtilsTest {
TestHelper.validateHasOnlyPrivateEmptyConstructor(Utils.class);
}
@Test
public void shouldLogAndSendMessage() {
// given
Logger logger = TestHelper.setupLogger();
Player player = mock(Player.class);
String message = "Finished adding foo to the bar";
// when
Utils.logAndSendMessage(player, message);
// then
verify(logger).info(message);
verify(player).sendMessage(message);
}
@Test
public void shouldHandleNullAsCommandSender() {
// given
Logger logger = TestHelper.setupLogger();
String message = "Test test, test.";
// when
Utils.logAndSendMessage(null, message);
// then
verify(logger).info(message);
}
@Test
public void shouldNotSendToCommandSenderTwice() {
// given
Logger logger = TestHelper.setupLogger();
CommandSender sender = mock(ConsoleCommandSender.class);
String message = "Test test, test.";
// when
Utils.logAndSendMessage(sender, message);
// then
verify(logger).info(message);
verifyZeroInteractions(sender);
}
@Test
public void shouldCheckIfClassIsLoaded() {
// given / when / then