mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-12-25 18:17:34 +01:00
Merge pull request #92 from AuthMe-Team/450-new-settings-rewrite
450 new settings rewrite
This commit is contained in:
commit
ad9625bb4e
1
pom.xml
1
pom.xml
@ -97,6 +97,7 @@
|
||||
<directory>src/main/resources/</directory>
|
||||
<includes>
|
||||
<include>email.html</include>
|
||||
<include>welcome.txt</include>
|
||||
</includes>
|
||||
</resource>
|
||||
<resource>
|
||||
|
@ -13,6 +13,7 @@ import java.util.logging.Logger;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Resources;
|
||||
import fr.xephi.authme.settings.SettingsMigrationService;
|
||||
import org.apache.logging.log4j.LogManager;
|
||||
|
||||
import org.bukkit.Bukkit;
|
||||
@ -60,7 +61,6 @@ import fr.xephi.authme.listener.AuthMePlayerListener18;
|
||||
import fr.xephi.authme.listener.AuthMeServerListener;
|
||||
import fr.xephi.authme.listener.AuthMeTabCompletePacketAdapter;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.modules.ModuleManager;
|
||||
import fr.xephi.authme.output.ConsoleFilter;
|
||||
import fr.xephi.authme.output.Log4JFilter;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
@ -71,15 +71,25 @@ import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.OtherAccounts;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.Spawn;
|
||||
import fr.xephi.authme.settings.custom.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
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.CollectionUtils;
|
||||
import fr.xephi.authme.util.GeoLiteAPI;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
|
||||
/**
|
||||
* The AuthMe main class.
|
||||
*/
|
||||
@ -103,7 +113,6 @@ public class AuthMe extends JavaPlugin {
|
||||
private NewSetting newSettings;
|
||||
private Messages messages;
|
||||
private JsonCache playerBackup;
|
||||
private ModuleManager moduleManager;
|
||||
private PasswordSecurity passwordSecurity;
|
||||
private DataSource database;
|
||||
|
||||
@ -169,15 +178,6 @@ public class AuthMe extends JavaPlugin {
|
||||
return pluginBuildNumber;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the plugin's Settings.
|
||||
*
|
||||
* @return Plugin's settings.
|
||||
*/
|
||||
public Settings getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the Messages instance.
|
||||
*
|
||||
@ -208,19 +208,28 @@ public class AuthMe extends JavaPlugin {
|
||||
// Set various instances
|
||||
server = getServer();
|
||||
plugin = this;
|
||||
ConsoleLogger.setLogger(getLogger());
|
||||
|
||||
setPluginInfos();
|
||||
|
||||
// Load settings and custom configurations, if it fails, stop the server due to security reasons.
|
||||
newSettings = createNewSetting();
|
||||
if (newSettings == null) {
|
||||
ConsoleLogger.showError("Could not load configuration. Aborting.");
|
||||
server.shutdown();
|
||||
return;
|
||||
}
|
||||
ConsoleLogger.setLoggingOptions(newSettings.getProperty(SecuritySettings.USE_LOGGING),
|
||||
new File(getDataFolder(), "authme.log"));
|
||||
|
||||
// Old settings manager
|
||||
if (!loadSettings()) {
|
||||
server.shutdown();
|
||||
setEnabled(false);
|
||||
return;
|
||||
}
|
||||
newSettings = createNewSetting();
|
||||
|
||||
// Set up messages & password security
|
||||
messages = Messages.getInstance();
|
||||
messages = new Messages(newSettings.getMessagesFile());
|
||||
|
||||
// Connect to the database and setup tables
|
||||
try {
|
||||
@ -239,15 +248,11 @@ public class AuthMe extends JavaPlugin {
|
||||
permsMan = initializePermissionsManager();
|
||||
commandHandler = initializeCommandHandler(permsMan, messages, passwordSecurity, newSettings);
|
||||
|
||||
// Set up the module manager
|
||||
setupModuleManager();
|
||||
|
||||
// Setup otherAccounts file
|
||||
this.otherAccounts = OtherAccounts.getInstance();
|
||||
|
||||
// Set up Metrics
|
||||
final MetricsStarter metrics = new MetricsStarter(this);
|
||||
metrics.setupMetrics();
|
||||
MetricsStarter.setupMetrics(plugin, newSettings);
|
||||
|
||||
// Set console filter
|
||||
setupConsoleFilter();
|
||||
@ -277,7 +282,7 @@ public class AuthMe extends JavaPlugin {
|
||||
// End of Hooks
|
||||
|
||||
// Do a backup on start
|
||||
new PerformBackup(plugin).doBackup(PerformBackup.BackupCause.START);
|
||||
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.START);
|
||||
|
||||
|
||||
// Setup the inventory backup
|
||||
@ -290,7 +295,7 @@ public class AuthMe extends JavaPlugin {
|
||||
setupApi();
|
||||
|
||||
// Set up the management
|
||||
management = new Management(this);
|
||||
management = new Management(this, newSettings);
|
||||
|
||||
// Set up the BungeeCord hook
|
||||
setupBungeeCordHook();
|
||||
@ -319,32 +324,14 @@ public class AuthMe extends JavaPlugin {
|
||||
ConsoleLogger.info("AuthMe " + this.getDescription().getVersion() + " correctly enabled!");
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the module manager.
|
||||
*/
|
||||
private void setupModuleManager() {
|
||||
// TODO: Clean this up!
|
||||
// TODO: split the plugin in more modules
|
||||
// TODO: log number of loaded modules
|
||||
|
||||
// Define the module manager instance
|
||||
moduleManager = new ModuleManager(this);
|
||||
|
||||
// Load the modules
|
||||
// int loaded = moduleManager.loadModules();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the mail API, if enabled.
|
||||
*/
|
||||
private void setupMailApi() {
|
||||
// Make sure the mail API is enabled
|
||||
if (Settings.getmailAccount.isEmpty() || Settings.getmailPassword.isEmpty()) {
|
||||
return;
|
||||
if (!newSettings.getProperty(MAIL_ACCOUNT).isEmpty() && !newSettings.getProperty(MAIL_PASSWORD).isEmpty()) {
|
||||
this.mail = new SendMailSSL(this, newSettings);
|
||||
}
|
||||
|
||||
// Set up the mail API
|
||||
this.mail = new SendMailSSL(this);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -352,12 +339,13 @@ public class AuthMe extends JavaPlugin {
|
||||
*/
|
||||
private void showSettingsWarnings() {
|
||||
// Force single session disabled
|
||||
if (!Settings.isForceSingleSessionEnabled) {
|
||||
if (!newSettings.getProperty(RestrictionSettings.FORCE_SINGLE_SESSION)) {
|
||||
ConsoleLogger.showError("WARNING!!! By disabling ForceSingleSession, your server protection is inadequate!");
|
||||
}
|
||||
|
||||
// Session timeout disabled
|
||||
if (Settings.getSessionTimeout == 0 && Settings.isSessionsEnabled) {
|
||||
if (newSettings.getProperty(PluginSettings.SESSIONS_TIMEOUT) == 0
|
||||
&& newSettings.getProperty(PluginSettings.SESSIONS_ENABLED)) {
|
||||
ConsoleLogger.showError("WARNING!!! You set session timeout to 0, this may cause security issues!");
|
||||
}
|
||||
}
|
||||
@ -412,7 +400,7 @@ public class AuthMe extends JavaPlugin {
|
||||
* Set up the BungeeCord hook.
|
||||
*/
|
||||
private void setupBungeeCordHook() {
|
||||
if (Settings.bungee) {
|
||||
if (newSettings.getProperty(HooksSettings.BUNGEECORD)) {
|
||||
Bukkit.getMessenger().registerOutgoingPluginChannel(this, "BungeeCord");
|
||||
Bukkit.getMessenger().registerIncomingPluginChannel(this, "BungeeCord", new BungeeCordMessage(this));
|
||||
}
|
||||
@ -420,7 +408,7 @@ public class AuthMe extends JavaPlugin {
|
||||
|
||||
private CommandHandler initializeCommandHandler(PermissionsManager permissionsManager, Messages messages,
|
||||
PasswordSecurity passwordSecurity, NewSetting settings) {
|
||||
HelpProvider helpProvider = new HelpProvider(permissionsManager);
|
||||
HelpProvider helpProvider = new HelpProvider(permissionsManager, settings.getProperty(HELP_HEADER));
|
||||
Set<CommandDescription> baseCommands = CommandInitializer.buildCommands();
|
||||
CommandMapper mapper = new CommandMapper(baseCommands, permissionsManager);
|
||||
CommandService commandService = new CommandService(
|
||||
@ -448,7 +436,6 @@ public class AuthMe extends JavaPlugin {
|
||||
private boolean loadSettings() {
|
||||
try {
|
||||
settings = new Settings(this);
|
||||
Settings.reload();
|
||||
return true;
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.logException("Can't load the configuration file... Something went wrong. "
|
||||
@ -459,8 +446,10 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
private NewSetting createNewSetting() {
|
||||
File configFile = new File(getDataFolder() + "config.yml");
|
||||
return new NewSetting(getConfig(), configFile);
|
||||
File configFile = new File(getDataFolder(), "config.yml");
|
||||
return SettingsMigrationService.copyFileFromResource(configFile, "config.yml")
|
||||
? new NewSetting(configFile, getDataFolder())
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -491,11 +480,8 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
// Do backup on stop if enabled
|
||||
new PerformBackup(plugin).doBackup(PerformBackup.BackupCause.STOP);
|
||||
|
||||
// Unload modules
|
||||
if (moduleManager != null) {
|
||||
moduleManager.unloadModules();
|
||||
if (newSettings != null) {
|
||||
new PerformBackup(plugin, newSettings).doBackup(PerformBackup.BackupCause.STOP);
|
||||
}
|
||||
|
||||
// Close the database
|
||||
@ -522,7 +508,7 @@ public class AuthMe extends JavaPlugin {
|
||||
database.close();
|
||||
// Backend MYSQL - FILE - SQLITE - SQLITEHIKARI
|
||||
boolean isSQLite = false;
|
||||
switch (Settings.getDataSource) {
|
||||
switch (newSettings.getProperty(DatabaseSettings.BACKEND)) {
|
||||
case FILE:
|
||||
database = new FlatFile();
|
||||
break;
|
||||
@ -551,7 +537,7 @@ public class AuthMe extends JavaPlugin {
|
||||
if (Settings.getDataSource == DataSource.DataSourceType.FILE) {
|
||||
ConsoleLogger.showError("FlatFile backend has been detected and is now deprecated, it will be changed " +
|
||||
"to SQLite... Connection will be impossible until conversion is done!");
|
||||
ForceFlatToSqlite converter = new ForceFlatToSqlite(database);
|
||||
ForceFlatToSqlite converter = new ForceFlatToSqlite(database, newSettings);
|
||||
DataSource source = converter.run();
|
||||
if (source != null) {
|
||||
database = source;
|
||||
@ -559,7 +545,7 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
// TODO: Move this to another place maybe ?
|
||||
if (Settings.getPasswordHash == HashAlgorithm.PLAINTEXT) {
|
||||
if (HashAlgorithm.PLAINTEXT == newSettings.getProperty(SecuritySettings.PASSWORD_HASH)) {
|
||||
ConsoleLogger.showError("Your HashAlgorithm has been detected as plaintext and is now deprecated; " +
|
||||
"it will be changed and hashed now to the AuthMe default hashing method");
|
||||
for (PlayerAuth auth : database.getAllAuths()) {
|
||||
@ -568,11 +554,11 @@ public class AuthMe extends JavaPlugin {
|
||||
auth.setPassword(hashedPassword);
|
||||
database.updatePassword(auth);
|
||||
}
|
||||
Settings.setValue("settings.security.passwordHash", "SHA256");
|
||||
Settings.reload();
|
||||
newSettings.setProperty(SecuritySettings.PASSWORD_HASH, HashAlgorithm.SHA256);
|
||||
newSettings.save();
|
||||
}
|
||||
|
||||
if (Settings.isCachingEnabled) {
|
||||
if (newSettings.getProperty(DatabaseSettings.USE_CACHING)) {
|
||||
database = new CacheDataSource(database);
|
||||
}
|
||||
}
|
||||
@ -663,24 +649,20 @@ public class AuthMe extends JavaPlugin {
|
||||
// Check the presence of the ProtocolLib plugin
|
||||
public void checkProtocolLib() {
|
||||
if (!server.getPluginManager().isPluginEnabled("ProtocolLib")) {
|
||||
if (Settings.protectInventoryBeforeLogInEnabled) {
|
||||
ConsoleLogger.showError("WARNING!!! The protectInventory feature requires ProtocolLib! Disabling it...");
|
||||
if (newSettings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||
ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
|
||||
Settings.protectInventoryBeforeLogInEnabled = false;
|
||||
getSettings().set("settings.restrictions.ProtectInventoryBeforeLogIn", false);
|
||||
newSettings.setProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN, false);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.protectInventoryBeforeLogInEnabled) {
|
||||
if (inventoryProtector == null) {
|
||||
inventoryProtector = new AuthMeInventoryPacketAdapter(this);
|
||||
inventoryProtector.register();
|
||||
}
|
||||
} else {
|
||||
if (inventoryProtector != null) {
|
||||
inventoryProtector.unregister();
|
||||
inventoryProtector = null;
|
||||
}
|
||||
if (newSettings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN) && inventoryProtector == null) {
|
||||
inventoryProtector = new AuthMeInventoryPacketAdapter(this);
|
||||
inventoryProtector.register();
|
||||
} else if (inventoryProtector != null) {
|
||||
inventoryProtector.unregister();
|
||||
inventoryProtector = null;
|
||||
}
|
||||
if (tabComplete == null) {
|
||||
tabComplete = new AuthMeTabCompletePacketAdapter(this);
|
||||
@ -715,16 +697,14 @@ public class AuthMe extends JavaPlugin {
|
||||
PlayerCache.getInstance().removePlayer(name);
|
||||
}
|
||||
|
||||
// Select the player to kick when a vip player join the server when full
|
||||
// Select the player to kick when a vip player joins the server when full
|
||||
public Player generateKickPlayer(Collection<? extends Player> collection) {
|
||||
Player player = null;
|
||||
for (Player p : collection) {
|
||||
if (!getPermissionsManager().hasPermission(p, PlayerPermission.IS_VIP)) {
|
||||
player = p;
|
||||
break;
|
||||
for (Player player : collection) {
|
||||
if (!getPermissionsManager().hasPermission(player, PlayerPermission.IS_VIP)) {
|
||||
return player;
|
||||
}
|
||||
}
|
||||
return player;
|
||||
return null;
|
||||
}
|
||||
|
||||
// Purge inactive players from the database, as defined in the configuration
|
||||
@ -736,10 +716,7 @@ public class AuthMe extends JavaPlugin {
|
||||
calendar.add(Calendar.DATE, -(Settings.purgeDelay));
|
||||
long until = calendar.getTimeInMillis();
|
||||
List<String> cleared = database.autoPurgeDatabase(until);
|
||||
if (cleared == null) {
|
||||
return;
|
||||
}
|
||||
if (cleared.isEmpty()) {
|
||||
if (CollectionUtils.isEmpty(cleared)) {
|
||||
return;
|
||||
}
|
||||
ConsoleLogger.info("AutoPurging the Database: " + cleared.size() + " accounts removed!");
|
||||
@ -823,12 +800,12 @@ public class AuthMe extends JavaPlugin {
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (player.isOnline()) {
|
||||
String name = player.getName().toLowerCase();
|
||||
if (database.isAuthAvailable(name))
|
||||
if (PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
String email = database.getAuth(name).getEmail();
|
||||
if (email == null || email.isEmpty() || email.equalsIgnoreCase("your@email.com"))
|
||||
messages.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
if (database.isAuthAvailable(name) && PlayerCache.getInstance().isAuthenticated(name)) {
|
||||
String email = database.getAuth(name).getEmail();
|
||||
if (email == null || email.isEmpty() || email.equalsIgnoreCase("your@email.com")) {
|
||||
messages.send(player, MessageKey.ADD_EMAIL_MESSAGE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -836,18 +813,18 @@ public class AuthMe extends JavaPlugin {
|
||||
}
|
||||
|
||||
public String replaceAllInfo(String message, Player player) {
|
||||
int playersOnline = Utils.getOnlinePlayers().size();
|
||||
message = message.replace("&", "\u00a7");
|
||||
message = message.replace("{PLAYER}", player.getName());
|
||||
message = message.replace("{ONLINE}", "" + playersOnline);
|
||||
message = message.replace("{MAXPLAYERS}", "" + server.getMaxPlayers());
|
||||
message = message.replace("{IP}", getIP(player));
|
||||
message = message.replace("{LOGINS}", "" + PlayerCache.getInstance().getLogged());
|
||||
message = message.replace("{WORLD}", player.getWorld().getName());
|
||||
message = message.replace("{SERVER}", server.getServerName());
|
||||
message = message.replace("{VERSION}", server.getBukkitVersion());
|
||||
message = message.replace("{COUNTRY}", GeoLiteAPI.getCountryName(getIP(player)));
|
||||
return message;
|
||||
String playersOnline = Integer.toString(Utils.getOnlinePlayers().size());
|
||||
return message
|
||||
.replace("&", "\u00a7")
|
||||
.replace("{PLAYER}", player.getName())
|
||||
.replace("{ONLINE}", playersOnline)
|
||||
.replace("{MAXPLAYERS}", Integer.toString(server.getMaxPlayers()))
|
||||
.replace("{IP}", getIP(player))
|
||||
.replace("{LOGINS}", Integer.toString(PlayerCache.getInstance().getLogged()))
|
||||
.replace("{WORLD}", player.getWorld().getName())
|
||||
.replace("{SERVER}", server.getServerName())
|
||||
.replace("{VERSION}", server.getBukkitVersion())
|
||||
.replace("{COUNTRY}", GeoLiteAPI.getCountryName(getIP(player)));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -903,10 +880,6 @@ public class AuthMe extends JavaPlugin {
|
||||
return count >= Settings.getMaxJoinPerIp;
|
||||
}
|
||||
|
||||
public ModuleManager getModuleManager() {
|
||||
return moduleManager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle Bukkit commands.
|
||||
*
|
||||
|
@ -1,16 +1,16 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import com.google.common.base.Throwables;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardOpenOption;
|
||||
import java.text.DateFormat;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* The plugin's static logger.
|
||||
@ -19,21 +19,31 @@ public final class ConsoleLogger {
|
||||
|
||||
private static final String NEW_LINE = System.getProperty("line.separator");
|
||||
private static final DateFormat DATE_FORMAT = new SimpleDateFormat("[MM-dd HH:mm:ss]");
|
||||
|
||||
private static Wrapper wrapper = Wrapper.getInstance();
|
||||
private static Logger logger;
|
||||
private static boolean useLogging = false;
|
||||
private static File logFile;
|
||||
|
||||
private ConsoleLogger() {
|
||||
// Service class
|
||||
}
|
||||
|
||||
public static void setLogger(Logger logger) {
|
||||
ConsoleLogger.logger = logger;
|
||||
}
|
||||
|
||||
public static void setLoggingOptions(boolean useLogging, File logFile) {
|
||||
ConsoleLogger.useLogging = useLogging;
|
||||
ConsoleLogger.logFile = logFile;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print an info message.
|
||||
*
|
||||
* @param message String
|
||||
*/
|
||||
public static void info(String message) {
|
||||
wrapper.getLogger().info(message);
|
||||
if (Settings.useLogging) {
|
||||
logger.info(message);
|
||||
if (useLogging) {
|
||||
writeLog(message);
|
||||
}
|
||||
}
|
||||
@ -44,8 +54,8 @@ public final class ConsoleLogger {
|
||||
* @param message String
|
||||
*/
|
||||
public static void showError(String message) {
|
||||
wrapper.getLogger().warning(message);
|
||||
if (Settings.useLogging) {
|
||||
logger.warning(message);
|
||||
if (useLogging) {
|
||||
writeLog("ERROR: " + message);
|
||||
}
|
||||
}
|
||||
@ -61,7 +71,7 @@ public final class ConsoleLogger {
|
||||
dateTime = DATE_FORMAT.format(new Date());
|
||||
}
|
||||
try {
|
||||
Files.write(Settings.LOG_FILE.toPath(), (dateTime + ": " + message + NEW_LINE).getBytes(),
|
||||
Files.write(logFile.toPath(), (dateTime + ": " + message + NEW_LINE).getBytes(),
|
||||
StandardOpenOption.APPEND,
|
||||
StandardOpenOption.CREATE);
|
||||
} catch (IOException ignored) {
|
||||
@ -74,7 +84,7 @@ public final class ConsoleLogger {
|
||||
* @param th The Throwable whose stack trace should be logged
|
||||
*/
|
||||
public static void writeStackTrace(Throwable th) {
|
||||
if (Settings.useLogging) {
|
||||
if (useLogging) {
|
||||
writeLog(Throwables.getStackTraceAsString(th));
|
||||
}
|
||||
}
|
||||
|
@ -1,26 +1,25 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import org.mcstats.Metrics;
|
||||
import org.mcstats.Metrics.Graph;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import java.io.IOException;
|
||||
|
||||
public class MetricsStarter {
|
||||
|
||||
public AuthMe plugin;
|
||||
|
||||
public MetricsStarter(final AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
private MetricsStarter() {
|
||||
}
|
||||
|
||||
public void setupMetrics() {
|
||||
public static void setupMetrics(AuthMe plugin, NewSetting settings) {
|
||||
try {
|
||||
final Metrics metrics = new Metrics(plugin);
|
||||
|
||||
final Graph messagesLanguage = metrics.createGraph("Messages Language");
|
||||
messagesLanguage.addPlotter(new Metrics.Plotter(Settings.messagesLanguage) {
|
||||
final Graph languageGraph = metrics.createGraph("Messages Language");
|
||||
final String messagesLanguage = settings.getProperty(PluginSettings.MESSAGES_LANGUAGE);
|
||||
languageGraph.addPlotter(new Metrics.Plotter(messagesLanguage) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
@ -28,7 +27,8 @@ public class MetricsStarter {
|
||||
});
|
||||
|
||||
final Graph databaseBackend = metrics.createGraph("Database Backend");
|
||||
databaseBackend.addPlotter(new Metrics.Plotter(Settings.getDataSource.toString()) {
|
||||
final String dataSource = settings.getProperty(DatabaseSettings.BACKEND).toString();
|
||||
databaseBackend.addPlotter(new Metrics.Plotter(dataSource) {
|
||||
@Override
|
||||
public int getValue() {
|
||||
return 1;
|
||||
@ -37,7 +37,7 @@ public class MetricsStarter {
|
||||
|
||||
// Submit metrics
|
||||
metrics.start();
|
||||
} catch (final IOException e) {
|
||||
} catch (IOException e) {
|
||||
// Failed to submit the metrics data
|
||||
ConsoleLogger.logException("Can't start Metrics! The plugin will work anyway...", e);
|
||||
}
|
||||
|
@ -1,8 +1,17 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.BackupSettings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.io.*;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.io.OutputStream;
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
@ -10,54 +19,56 @@ import java.util.Date;
|
||||
* The backup management class
|
||||
*
|
||||
* @author stefano
|
||||
* @version $Revision: 1.0 $
|
||||
*/
|
||||
public class PerformBackup {
|
||||
|
||||
final SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd_HH-mm");
|
||||
final String dateString = format.format(new Date());
|
||||
private final String dbName = Settings.getMySQLDatabase;
|
||||
private final String dbUserName = Settings.getMySQLUsername;
|
||||
private final String dbPassword = Settings.getMySQLPassword;
|
||||
private final String tblname = Settings.getMySQLTablename;
|
||||
private final String path = AuthMe.getInstance().getDataFolder() + File.separator + "backups" + File.separator + "backup" + dateString;
|
||||
private AuthMe instance;
|
||||
private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd_HH-mm");
|
||||
|
||||
private final String dbName;
|
||||
private final String dbUserName;
|
||||
private final String dbPassword;
|
||||
private final String tblname;
|
||||
private final String path;
|
||||
private final File dataFolder;
|
||||
private final NewSetting settings;
|
||||
|
||||
/**
|
||||
* Constructor for PerformBackup.
|
||||
*
|
||||
* @param instance AuthMe
|
||||
*/
|
||||
public PerformBackup(AuthMe instance) {
|
||||
this.setInstance(instance);
|
||||
public PerformBackup(AuthMe instance, NewSetting settings) {
|
||||
this.dataFolder = instance.getDataFolder();
|
||||
this.settings = settings;
|
||||
this.dbName = settings.getProperty(DatabaseSettings.MYSQL_DATABASE);
|
||||
this.dbUserName = settings.getProperty(DatabaseSettings.MYSQL_USERNAME);
|
||||
this.dbPassword = settings.getProperty(DatabaseSettings.MYSQL_PASSWORD);
|
||||
this.tblname = settings.getProperty(DatabaseSettings.MYSQL_TABLE);
|
||||
|
||||
String dateString = DATE_FORMAT.format(new Date());
|
||||
this.path = StringUtils.join(File.separator,
|
||||
instance.getDataFolder().getPath(), "backups", "backup" + dateString);
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a backup with the given reason.
|
||||
*
|
||||
* @param cause BackupCause The cause of the backup.
|
||||
* @param cause The cause of the backup.
|
||||
*/
|
||||
public void doBackup(BackupCause cause) {
|
||||
|
||||
// Do nothing if backup is disabled
|
||||
if (!Settings.isBackupActivated) {
|
||||
if (!settings.getProperty(BackupSettings.ENABLED)) {
|
||||
// Print a warning if the backup was requested via command or by another plugin
|
||||
if (cause == BackupCause.COMMAND || cause == BackupCause.OTHER) {
|
||||
ConsoleLogger.showError("Can't perform a Backup: disabled in configuration. Cause of the Backup: " + cause.name());
|
||||
ConsoleLogger.showError("Can't perform a Backup: disabled in configuration. Cause of the Backup: "
|
||||
+ cause.name());
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Check whether a backup should be made at the specified point in time
|
||||
switch (cause) {
|
||||
case START:
|
||||
if (!Settings.isBackupOnStart)
|
||||
return;
|
||||
case STOP:
|
||||
if (!Settings.isBackupOnStop)
|
||||
return;
|
||||
case COMMAND:
|
||||
case OTHER:
|
||||
if (BackupCause.START.equals(cause) && !settings.getProperty(BackupSettings.ON_SERVER_START)
|
||||
|| BackupCause.STOP.equals(cause) && !settings.getProperty(BackupSettings.ON_SERVER_STOP)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Do backup and check return value!
|
||||
@ -68,37 +79,31 @@ public class PerformBackup {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method doBackup.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public boolean doBackup() {
|
||||
|
||||
switch (Settings.getDataSource) {
|
||||
DataSource.DataSourceType dataSourceType = settings.getProperty(DatabaseSettings.BACKEND);
|
||||
switch (dataSourceType) {
|
||||
case FILE:
|
||||
return FileBackup("auths.db");
|
||||
return fileBackup("auths.db");
|
||||
case MYSQL:
|
||||
return MySqlBackup();
|
||||
return mySqlBackup();
|
||||
case SQLITE:
|
||||
return FileBackup(Settings.getMySQLDatabase + ".db");
|
||||
return fileBackup(dbName + ".db");
|
||||
default:
|
||||
ConsoleLogger.showError("Unknown data source type '" + dataSourceType + "' for backup");
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method MySqlBackup.
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean MySqlBackup() {
|
||||
File dirBackup = new File(AuthMe.getInstance().getDataFolder() + "/backups");
|
||||
private boolean mySqlBackup() {
|
||||
File dirBackup = new File(dataFolder + File.separator + "backups");
|
||||
|
||||
if (!dirBackup.exists())
|
||||
if (!dirBackup.exists()) {
|
||||
dirBackup.mkdir();
|
||||
if (checkWindows(Settings.backupWindowsPath)) {
|
||||
String executeCmd = Settings.backupWindowsPath + "\\bin\\mysqldump.exe -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path + ".sql";
|
||||
}
|
||||
String backupWindowsPath = settings.getProperty(BackupSettings.MYSQL_WINDOWS_PATH);
|
||||
if (checkWindows(backupWindowsPath)) {
|
||||
String executeCmd = backupWindowsPath + "\\bin\\mysqldump.exe -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path + ".sql";
|
||||
Process runtimeProcess;
|
||||
try {
|
||||
runtimeProcess = Runtime.getRuntime().exec(executeCmd);
|
||||
@ -109,8 +114,12 @@ public class PerformBackup {
|
||||
} else {
|
||||
ConsoleLogger.showError("Could not create the backup!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError("Error during backup: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
} catch (InterruptedException e) {
|
||||
ConsoleLogger.showError("Backup was interrupted: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
} else {
|
||||
String executeCmd = "mysqldump -u " + dbUserName + " -p" + dbPassword + " " + dbName + " --tables " + tblname + " -r " + path + ".sql";
|
||||
@ -124,69 +133,54 @@ public class PerformBackup {
|
||||
} else {
|
||||
ConsoleLogger.showError("Could not create the backup!");
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError("Error during backup: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
} catch (InterruptedException e) {
|
||||
ConsoleLogger.showError("Backup was interrupted: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method FileBackup.
|
||||
*
|
||||
* @param backend String
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
private boolean FileBackup(String backend) {
|
||||
File dirBackup = new File(AuthMe.getInstance().getDataFolder() + "/backups");
|
||||
private boolean fileBackup(String backend) {
|
||||
File dirBackup = new File(dataFolder + File.separator + "backups");
|
||||
|
||||
if (!dirBackup.exists())
|
||||
dirBackup.mkdir();
|
||||
|
||||
try {
|
||||
copy(new File("plugins" + File.separator + "AuthMe" + File.separator + backend), new File(path + ".db"));
|
||||
copy("plugins" + File.separator + "AuthMe" + File.separator + backend, path + ".db");
|
||||
return true;
|
||||
|
||||
} catch (Exception ex) {
|
||||
ex.printStackTrace();
|
||||
} catch (IOException ex) {
|
||||
ConsoleLogger.showError("Encountered an error during file backup: " + StringUtils.formatException(ex));
|
||||
ConsoleLogger.writeStackTrace(ex);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method checkWindows.
|
||||
* Check if we are under Windows and correct location of mysqldump.exe
|
||||
* otherwise return error.
|
||||
*
|
||||
* @param windowsPath String
|
||||
*
|
||||
* @return boolean
|
||||
* @param windowsPath The path to check
|
||||
* @return True if the path is correct, false if it is incorrect or the OS is not Windows
|
||||
*/
|
||||
private boolean checkWindows(String windowsPath) {
|
||||
private static boolean checkWindows(String windowsPath) {
|
||||
String isWin = System.getProperty("os.name").toLowerCase();
|
||||
if (isWin.contains("win")) {
|
||||
if (new File(windowsPath + "\\bin\\mysqldump.exe").exists()) {
|
||||
return true;
|
||||
} else {
|
||||
ConsoleLogger.showError("Mysql Windows Path is incorrect please check it");
|
||||
return true;
|
||||
ConsoleLogger.showError("Mysql Windows Path is incorrect. Please check it");
|
||||
return false;
|
||||
}
|
||||
} else return false;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if we are under Windows and correct location of mysqldump.exe
|
||||
* otherwise return error.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Method copy.
|
||||
*
|
||||
* @param src File
|
||||
* @param dst File
|
||||
*
|
||||
* @throws IOException
|
||||
*/
|
||||
void copy(File src, File dst) throws IOException {
|
||||
private static void copy(String src, String dst) throws IOException {
|
||||
InputStream in = new FileInputStream(src);
|
||||
OutputStream out = new FileOutputStream(dst);
|
||||
|
||||
@ -200,27 +194,6 @@ public class PerformBackup {
|
||||
out.close();
|
||||
}
|
||||
|
||||
/*
|
||||
* Copyr src bytefile into dst file
|
||||
*/
|
||||
|
||||
/**
|
||||
* Method getInstance.
|
||||
*
|
||||
* @return AuthMe
|
||||
*/
|
||||
public AuthMe getInstance() {
|
||||
return instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method setInstance.
|
||||
*
|
||||
* @param instance AuthMe
|
||||
*/
|
||||
public void setInstance(AuthMe instance) {
|
||||
this.instance = instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Possible backup causes.
|
||||
@ -229,7 +202,7 @@ public class PerformBackup {
|
||||
START,
|
||||
STOP,
|
||||
COMMAND,
|
||||
OTHER,
|
||||
OTHER
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,10 +8,11 @@ import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.custom.NewSetting;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@ -101,6 +102,16 @@ public class CommandService {
|
||||
return authMe.getDataSource();
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the AuthMe instance for further manipulation. Use only if other methods from
|
||||
* the command service cannot be used.
|
||||
*
|
||||
* @return The AuthMe instance
|
||||
*/
|
||||
public AuthMe getAuthMe() {
|
||||
return authMe;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the PasswordSecurity instance.
|
||||
*
|
||||
@ -152,6 +163,15 @@ public class CommandService {
|
||||
return messages.retrieve(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Change the messages instance to retrieve messages from the given file.
|
||||
*
|
||||
* @param file The new file to read messages from
|
||||
*/
|
||||
public void reloadMessages(File file) {
|
||||
messages.reload(file);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given property's value.
|
||||
*
|
||||
@ -163,4 +183,13 @@ public class CommandService {
|
||||
return settings.getProperty(property);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the settings manager.
|
||||
*
|
||||
* @return The settings manager
|
||||
*/
|
||||
public NewSetting getSettings() {
|
||||
return settings;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -8,8 +8,8 @@ import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.custom.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
@ -7,7 +7,7 @@ import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
|
@ -1,35 +1,31 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* The reload command.
|
||||
*/
|
||||
public class ReloadCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// AuthMe plugin instance
|
||||
AuthMe plugin = AuthMe.getInstance();
|
||||
|
||||
AuthMe plugin = commandService.getAuthMe();
|
||||
try {
|
||||
Settings.reload();
|
||||
Messages.getInstance().reloadManager();
|
||||
plugin.getModuleManager().reloadModules();
|
||||
commandService.getSettings().reload();
|
||||
commandService.reloadMessages(commandService.getSettings().getMessagesFile());
|
||||
plugin.setupDatabase();
|
||||
commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage("Error occurred during reload of AuthMe: aborting");
|
||||
ConsoleLogger.logException("Aborting! Encountered exception during reload of AuthMe:", e);
|
||||
plugin.stopOrUnload();
|
||||
}
|
||||
|
||||
commandService.send(sender, MessageKey.CONFIG_RELOAD_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.util.List;
|
||||
@ -20,7 +20,7 @@ public class SetEmailCommand implements ExecutableCommand {
|
||||
final String playerEmail = arguments.get(1);
|
||||
|
||||
// Validate the email address
|
||||
if (!Settings.isEmailCorrect(playerEmail)) {
|
||||
if (!Utils.isEmailCorrect(playerEmail, commandService.getSettings())) {
|
||||
commandService.send(sender, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
@ -3,7 +3,6 @@ package fr.xephi.authme.command.executable.authme;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -11,12 +10,15 @@ import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.PluginSettings.HELP_HEADER;
|
||||
|
||||
public class VersionCommand implements ExecutableCommand {
|
||||
|
||||
@Override
|
||||
public void executeCommand(CommandSender sender, List<String> arguments, CommandService commandService) {
|
||||
// Show some version info
|
||||
sender.sendMessage(ChatColor.GOLD + "==========[ " + Settings.helpHeader + " ABOUT ]==========");
|
||||
sender.sendMessage(ChatColor.GOLD + "==========[ " + commandService.getProperty(HELP_HEADER)
|
||||
+ " ABOUT ]==========");
|
||||
sender.sendMessage(ChatColor.GOLD + "Version: " + ChatColor.WHITE + AuthMe.getPluginName()
|
||||
+ " v" + AuthMe.getPluginVersion() + ChatColor.GRAY + " (build: " + AuthMe.getPluginBuildNumber() + ")");
|
||||
sender.sendMessage(ChatColor.GOLD + "Developers:");
|
||||
|
@ -6,7 +6,7 @@ import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
|
@ -5,8 +5,8 @@ import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.custom.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.ChangePasswordTask;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.entity.Player;
|
||||
|
@ -6,6 +6,7 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.util.List;
|
||||
@ -26,7 +27,7 @@ public class RegisterCommand extends PlayerCommand {
|
||||
return;
|
||||
}
|
||||
final String email = arguments.get(0);
|
||||
if (!Settings.isEmailCorrect(email)) {
|
||||
if (!Utils.isEmailCorrect(email, commandService.getSettings())) {
|
||||
commandService.send(player, MessageKey.INVALID_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
@ -10,7 +10,6 @@ import fr.xephi.authme.command.FoundCommandResult;
|
||||
import fr.xephi.authme.permission.DefaultPermission;
|
||||
import fr.xephi.authme.permission.PermissionNode;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -44,9 +43,11 @@ public class HelpProvider {
|
||||
public static final int ALL_OPTIONS = ~HIDE_COMMAND;
|
||||
|
||||
private final PermissionsManager permissionsManager;
|
||||
private final String helpHeader;
|
||||
|
||||
public HelpProvider(PermissionsManager permissionsManager) {
|
||||
public HelpProvider(PermissionsManager permissionsManager, String helpHeader) {
|
||||
this.permissionsManager = permissionsManager;
|
||||
this.helpHeader = helpHeader;
|
||||
}
|
||||
|
||||
public List<String> printHelp(CommandSender sender, FoundCommandResult result, int options) {
|
||||
@ -55,7 +56,7 @@ public class HelpProvider {
|
||||
}
|
||||
|
||||
List<String> lines = new ArrayList<>();
|
||||
lines.add(ChatColor.GOLD + "==========[ " + Settings.helpHeader + " HELP ]==========");
|
||||
lines.add(ChatColor.GOLD + "==========[ " + helpHeader + " HELP ]==========");
|
||||
|
||||
CommandDescription command = result.getCommandDescription();
|
||||
List<String> labels = ImmutableList.copyOf(result.getLabels());
|
||||
|
@ -4,32 +4,41 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.SQLite;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.sql.SQLException;
|
||||
|
||||
/**
|
||||
* Mandatory migration from the deprecated flat file datasource to SQLite.
|
||||
*/
|
||||
public class ForceFlatToSqlite {
|
||||
|
||||
private final DataSource data;
|
||||
private final DataSource database;
|
||||
private final NewSetting settings;
|
||||
|
||||
public ForceFlatToSqlite(DataSource data) {
|
||||
this.data = data;
|
||||
public ForceFlatToSqlite(DataSource database, NewSetting settings) {
|
||||
this.database = database;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public DataSource run() {
|
||||
DataSource sqlite = null;
|
||||
try {
|
||||
sqlite = new SQLite();
|
||||
for (PlayerAuth auth : data.getAllAuths()) {
|
||||
DataSource sqlite = new SQLite();
|
||||
for (PlayerAuth auth : database.getAllAuths()) {
|
||||
auth.setRealName("Player");
|
||||
sqlite.saveAuth(auth);
|
||||
}
|
||||
Settings.setValue("DataSource.backend", "sqlite");
|
||||
ConsoleLogger.info("Database successfully converted to sqlite !");
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.showError("An error occurred while trying to convert flatfile to sqlite ...");
|
||||
return null;
|
||||
settings.setProperty(DatabaseSettings.BACKEND, DataSource.DataSourceType.SQLITE);
|
||||
settings.save();
|
||||
ConsoleLogger.info("Database successfully converted to sqlite!");
|
||||
return sqlite;
|
||||
} catch (SQLException | ClassNotFoundException e) {
|
||||
ConsoleLogger.showError("An error occurred while trying to convert flatfile to sqlite: "
|
||||
+ StringUtils.formatException(e));
|
||||
ConsoleLogger.writeStackTrace(e);
|
||||
}
|
||||
return sqlite;
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
@ -36,17 +36,19 @@ public class FlatFile implements DataSource {
|
||||
private final File source;
|
||||
|
||||
public FlatFile() {
|
||||
source = Settings.AUTH_FILE;
|
||||
AuthMe instance = AuthMe.getInstance();
|
||||
|
||||
source = new File(instance.getDataFolder(), "auths.db");
|
||||
try {
|
||||
source.createNewFile();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
if (Settings.isStopEnabled) {
|
||||
ConsoleLogger.showError("Can't use FLAT FILE... SHUTDOWN...");
|
||||
AuthMe.getInstance().getServer().shutdown();
|
||||
instance.getServer().shutdown();
|
||||
}
|
||||
if (!Settings.isStopEnabled) {
|
||||
AuthMe.getInstance().getServer().getPluginManager().disablePlugin(AuthMe.getInstance());
|
||||
instance.getServer().getPluginManager().disablePlugin(instance);
|
||||
}
|
||||
e.printStackTrace();
|
||||
}
|
||||
|
@ -1,25 +1,26 @@
|
||||
package fr.xephi.authme.mail;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.Security;
|
||||
import java.util.Properties;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.activation.FileDataSource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.mail.Session;
|
||||
|
||||
import org.apache.commons.mail.EmailException;
|
||||
import org.apache.commons.mail.HtmlEmail;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.ImageGenerator;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.apache.commons.mail.EmailConstants;
|
||||
import org.apache.commons.mail.EmailException;
|
||||
import org.apache.commons.mail.HtmlEmail;
|
||||
import org.bukkit.Bukkit;
|
||||
|
||||
import javax.activation.DataSource;
|
||||
import javax.activation.FileDataSource;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.mail.Session;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.Security;
|
||||
import java.util.Properties;
|
||||
|
||||
|
||||
/**
|
||||
* @author Xephi59
|
||||
@ -27,13 +28,15 @@ import fr.xephi.authme.util.StringUtils;
|
||||
public class SendMailSSL {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final NewSetting settings;
|
||||
|
||||
public SendMailSSL(AuthMe plugin) {
|
||||
public SendMailSSL(AuthMe plugin, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void main(final PlayerAuth auth, final String newPass) {
|
||||
final String mailText = replaceMailTags(Settings.getMailText, plugin, auth, newPass);
|
||||
final String mailText = replaceMailTags(settings.getEmailMessage(), plugin, auth, newPass);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
@ -41,21 +44,23 @@ public class SendMailSSL {
|
||||
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
|
||||
HtmlEmail email;
|
||||
try {
|
||||
email = initializeMail(auth);
|
||||
email = initializeMail(auth, settings);
|
||||
} catch (EmailException e) {
|
||||
ConsoleLogger.showError("Failed to create email with the given settings: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.showError("Failed to create email with the given settings: "
|
||||
+ StringUtils.formatException(e));
|
||||
return;
|
||||
}
|
||||
|
||||
String content = mailText;
|
||||
// Generate an image?
|
||||
File file = null;
|
||||
if (Settings.generateImage) {
|
||||
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
|
||||
try {
|
||||
file = generateImage(auth, plugin, newPass);
|
||||
content = embedImageIntoEmailContent(file, email, content);
|
||||
} catch (IOException | EmailException e) {
|
||||
ConsoleLogger.showError("Unable to send new password as image for email " + auth.getEmail() + ": " + StringUtils.formatException(e));
|
||||
ConsoleLogger.showError("Unable to send new password as image for email " + auth.getEmail()
|
||||
+ ": " + StringUtils.formatException(e));
|
||||
}
|
||||
}
|
||||
|
||||
@ -68,43 +73,39 @@ public class SendMailSSL {
|
||||
});
|
||||
}
|
||||
|
||||
private static File generateImage(PlayerAuth auth, AuthMe plugin,
|
||||
String newPass) throws IOException {
|
||||
private static File generateImage(PlayerAuth auth, AuthMe plugin, String newPass) throws IOException {
|
||||
ImageGenerator gen = new ImageGenerator(newPass);
|
||||
File file = new File(plugin.getDataFolder() + File.separator + auth.getNickname() + "_new_pass.jpg");
|
||||
File file = new File(plugin.getDataFolder(), auth.getNickname() + "_new_pass.jpg");
|
||||
ImageIO.write(gen.generateImage(), "jpg", file);
|
||||
return file;
|
||||
}
|
||||
|
||||
private static String embedImageIntoEmailContent(File image,
|
||||
HtmlEmail email, String content) throws EmailException {
|
||||
private static String embedImageIntoEmailContent(File image, HtmlEmail email, String content)
|
||||
throws EmailException {
|
||||
DataSource source = new FileDataSource(image);
|
||||
String tag = email.embed(source, image.getName());
|
||||
return content.replace("<image />", "<img src=\"cid:" + tag + "\">");
|
||||
}
|
||||
|
||||
private static HtmlEmail initializeMail(PlayerAuth auth)
|
||||
private static HtmlEmail initializeMail(PlayerAuth auth, NewSetting settings)
|
||||
throws EmailException {
|
||||
String senderName;
|
||||
if (StringUtils.isEmpty(Settings.getmailSenderName)) {
|
||||
senderName = Settings.getmailAccount;
|
||||
} else {
|
||||
senderName = Settings.getmailSenderName;
|
||||
}
|
||||
String senderMail = Settings.getmailAccount;
|
||||
String mailPassword = Settings.getmailPassword;
|
||||
int port = Settings.getMailPort;
|
||||
String senderMail = settings.getProperty(EmailSettings.MAIL_ACCOUNT);
|
||||
String senderName = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_SENDER_NAME))
|
||||
? senderMail
|
||||
: settings.getProperty(EmailSettings.MAIL_SENDER_NAME);
|
||||
String mailPassword = settings.getProperty(EmailSettings.MAIL_PASSWORD);
|
||||
int port = settings.getProperty(EmailSettings.SMTP_PORT);
|
||||
|
||||
HtmlEmail email = new HtmlEmail();
|
||||
email.setCharset(org.apache.commons.mail.EmailConstants.UTF_8);
|
||||
email.setCharset(EmailConstants.UTF_8);
|
||||
email.setSmtpPort(port);
|
||||
email.setHostName(Settings.getmailSMTP);
|
||||
email.setHostName(settings.getProperty(EmailSettings.SMTP_HOST));
|
||||
email.addTo(auth.getEmail());
|
||||
email.setFrom(senderMail, senderName);
|
||||
email.setSubject(Settings.getMailSubject);
|
||||
email.setSubject(settings.getProperty(EmailSettings.RECOVERY_MAIL_SUBJECT));
|
||||
email.setAuthentication(senderMail, mailPassword);
|
||||
|
||||
setPropertiesForPort(email, port);
|
||||
setPropertiesForPort(email, port, settings);
|
||||
return email;
|
||||
}
|
||||
|
||||
@ -113,7 +114,8 @@ public class SendMailSSL {
|
||||
email.setHtmlMsg(content);
|
||||
email.setTextMsg(content);
|
||||
} catch (EmailException e) {
|
||||
ConsoleLogger.showError("Your email.html config contains an error and cannot be sent: " + StringUtils.formatException(e));
|
||||
ConsoleLogger.showError("Your email.html config contains an error and cannot be sent: "
|
||||
+ StringUtils.formatException(e));
|
||||
return false;
|
||||
}
|
||||
try {
|
||||
@ -125,17 +127,19 @@ public class SendMailSSL {
|
||||
}
|
||||
}
|
||||
|
||||
private static String replaceMailTags(String mailText, AuthMe plugin,
|
||||
PlayerAuth auth, String newPass) {
|
||||
return mailText.replace("<playername />", auth.getNickname()).replace("<servername />", plugin.getServer().getServerName()).replace("<generatedpass />", newPass);
|
||||
private static String replaceMailTags(String mailText, AuthMe plugin, PlayerAuth auth, String newPass) {
|
||||
return mailText
|
||||
.replace("<playername />", auth.getNickname())
|
||||
.replace("<servername />", plugin.getServer().getServerName())
|
||||
.replace("<generatedpass />", newPass);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
private static void setPropertiesForPort(HtmlEmail email, int port)
|
||||
private static void setPropertiesForPort(HtmlEmail email, int port, NewSetting settings)
|
||||
throws EmailException {
|
||||
switch (port) {
|
||||
case 587:
|
||||
if (!Settings.emailOauth2Token.isEmpty()) {
|
||||
String oAuth2Token = settings.getProperty(EmailSettings.OAUTH2_TOKEN);
|
||||
if (!oAuth2Token.isEmpty()) {
|
||||
if (Security.getProvider("Google OAuth2 Provider") == null) {
|
||||
Security.addProvider(new OAuth2Provider());
|
||||
}
|
||||
@ -146,7 +150,7 @@ public class SendMailSSL {
|
||||
mailProperties.setProperty("mail.smtp.sasl.mechanisms", "XOAUTH2");
|
||||
mailProperties.setProperty("mail.smtp.auth.login.disable", "true");
|
||||
mailProperties.setProperty("mail.smtp.auth.plain.disable", "true");
|
||||
mailProperties.setProperty(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, Settings.emailOauth2Token);
|
||||
mailProperties.setProperty(OAuth2SaslClientFactory.OAUTH_TOKEN_PROP, oAuth2Token);
|
||||
email.setMailSession(Session.getInstance(mailProperties));
|
||||
} else {
|
||||
email.setStartTLSEnabled(true);
|
||||
@ -159,7 +163,7 @@ public class SendMailSSL {
|
||||
email.setSSLCheckServerIdentity(true);
|
||||
break;
|
||||
case 465:
|
||||
email.setSslSmtpPort("" + port);
|
||||
email.setSslSmtpPort(Integer.toString(port));
|
||||
email.setSSL(true);
|
||||
break;
|
||||
default:
|
||||
|
@ -1,9 +1,10 @@
|
||||
package fr.xephi.authme.output;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
/**
|
||||
* Class for retrieving and sending translatable messages to players.
|
||||
* This class detects when the language settings have changed and will
|
||||
@ -11,27 +12,15 @@ import org.bukkit.command.CommandSender;
|
||||
*/
|
||||
public class Messages {
|
||||
|
||||
private static Messages singleton;
|
||||
private final String language;
|
||||
private MessagesManager manager;
|
||||
|
||||
|
||||
private Messages(String language, MessagesManager manager) {
|
||||
this.language = language;
|
||||
this.manager = manager;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the instance of Messages.
|
||||
* Constructor.
|
||||
*
|
||||
* @return The Messages instance
|
||||
* @param messageFile The messages file to use
|
||||
*/
|
||||
public static Messages getInstance() {
|
||||
if (singleton == null) {
|
||||
MessagesManager manager = new MessagesManager(Settings.messageFile);
|
||||
singleton = new Messages(Settings.messagesLanguage, manager);
|
||||
}
|
||||
return singleton;
|
||||
public Messages(File messageFile) {
|
||||
manager = new MessagesManager(messageFile);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -60,7 +49,8 @@ public class Messages {
|
||||
String message = retrieveSingle(key);
|
||||
String[] tags = key.getTags();
|
||||
if (replacements.length != tags.length) {
|
||||
throw new RuntimeException("Given replacement size does not match the tags in message key '" + key + "'");
|
||||
throw new IllegalStateException(
|
||||
"Given replacement size does not match the tags in message key '" + key + "'");
|
||||
}
|
||||
|
||||
for (int i = 0; i < tags.length; ++i) {
|
||||
@ -80,9 +70,6 @@ public class Messages {
|
||||
* @return The message split by new lines
|
||||
*/
|
||||
public String[] retrieve(MessageKey key) {
|
||||
if (!Settings.messagesLanguage.equalsIgnoreCase(language)) {
|
||||
reloadManager();
|
||||
}
|
||||
return manager.retrieve(key.getKey());
|
||||
}
|
||||
|
||||
@ -100,8 +87,8 @@ public class Messages {
|
||||
/**
|
||||
* Reload the messages manager.
|
||||
*/
|
||||
public void reloadManager() {
|
||||
manager = new MessagesManager(Settings.messageFile);
|
||||
public void reload(File messagesFile) {
|
||||
manager = new MessagesManager(messagesFile);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,8 +1,8 @@
|
||||
package fr.xephi.authme.output;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.CustomConfiguration;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
|
||||
@ -12,7 +12,10 @@ import java.io.File;
|
||||
* This class is used within {@link Messages}, which offers a high-level interface for accessing
|
||||
* or sending messages from a properties file.
|
||||
*/
|
||||
class MessagesManager extends CustomConfiguration {
|
||||
class MessagesManager {
|
||||
|
||||
private final YamlConfiguration configuration;
|
||||
private final String fileName;
|
||||
|
||||
/**
|
||||
* Constructor for Messages.
|
||||
@ -20,8 +23,8 @@ class MessagesManager extends CustomConfiguration {
|
||||
* @param file the configuration file
|
||||
*/
|
||||
MessagesManager(File file) {
|
||||
super(file);
|
||||
load();
|
||||
this.fileName = file.getName();
|
||||
this.configuration = YamlConfiguration.loadConfiguration(file);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,24 +34,22 @@ class MessagesManager extends CustomConfiguration {
|
||||
*
|
||||
* @return The message
|
||||
*/
|
||||
String[] retrieve(String key) {
|
||||
String message = (String) get(key);
|
||||
public String[] retrieve(String key) {
|
||||
String message = configuration.getString(key);
|
||||
if (message != null) {
|
||||
return formatMessage(message);
|
||||
}
|
||||
|
||||
// Message is null: log key not being found and send error back as message
|
||||
String retrievalError = "Error getting message with key '" + key + "'. ";
|
||||
ConsoleLogger.showError(retrievalError + "Please verify your config file at '"
|
||||
+ getConfigFile().getName() + "'");
|
||||
ConsoleLogger.showError(retrievalError + "Please verify your config file at '" + fileName + "'");
|
||||
return new String[]{
|
||||
retrievalError + "Please contact the admin to verify or update the AuthMe messages file."};
|
||||
}
|
||||
|
||||
static String[] formatMessage(String message) {
|
||||
private static String[] formatMessage(String message) {
|
||||
String[] lines = message.split("&n");
|
||||
for (int i = 0; i < lines.length; ++i) {
|
||||
// We don't initialize a StringBuilder here because mostly we will only have one entry
|
||||
lines[i] = ChatColor.translateAlternateColorCodes('&', lines[i]);
|
||||
}
|
||||
return lines;
|
||||
|
@ -8,6 +8,7 @@ import fr.xephi.authme.process.logout.AsynchronousLogout;
|
||||
import fr.xephi.authme.process.quit.AsynchronousQuit;
|
||||
import fr.xephi.authme.process.register.AsyncRegister;
|
||||
import fr.xephi.authme.process.unregister.AsynchronousUnregister;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.scheduler.BukkitScheduler;
|
||||
|
||||
@ -17,15 +18,17 @@ public class Management {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final BukkitScheduler sched;
|
||||
private final NewSetting settings;
|
||||
|
||||
/**
|
||||
* Constructor for Management.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
*/
|
||||
public Management(AuthMe plugin) {
|
||||
public Management(AuthMe plugin, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
this.sched = this.plugin.getServer().getScheduler();
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public void performLogin(final Player player, final String password, final boolean forceLogin) {
|
||||
@ -33,7 +36,8 @@ public class Management {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsynchronousLogin(player, password, forceLogin, plugin, plugin.getDataSource()).process();
|
||||
new AsynchronousLogin(player, password, forceLogin, plugin, plugin.getDataSource(), settings)
|
||||
.process();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -53,7 +57,7 @@ public class Management {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncRegister(player, password, email, plugin, plugin.getDataSource()).process();
|
||||
new AsyncRegister(player, password, email, plugin, plugin.getDataSource(), settings).process();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -94,7 +98,7 @@ public class Management {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncChangeEmail(player, plugin, null, newEmail, newEmailVerify).process();
|
||||
new AsyncChangeEmail(player, plugin, null, newEmail, newEmailVerify, settings).process();
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -103,7 +107,7 @@ public class Management {
|
||||
sched.runTaskAsynchronously(plugin, new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
new AsyncChangeEmail(player, plugin, oldEmail, newEmail).process();
|
||||
new AsyncChangeEmail(player, plugin, oldEmail, newEmail, settings).process();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -5,8 +5,10 @@ import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
/**
|
||||
@ -19,18 +21,21 @@ public class AsyncChangeEmail {
|
||||
private final String newEmail;
|
||||
private final String newEmailVerify;
|
||||
private final Messages m;
|
||||
private final NewSetting settings;
|
||||
|
||||
public AsyncChangeEmail(Player player, AuthMe plugin, String oldEmail, String newEmail, String newEmailVerify) {
|
||||
public AsyncChangeEmail(Player player, AuthMe plugin, String oldEmail, String newEmail, String newEmailVerify,
|
||||
NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
this.player = player;
|
||||
this.plugin = plugin;
|
||||
this.oldEmail = oldEmail;
|
||||
this.newEmail = newEmail;
|
||||
this.newEmailVerify = newEmailVerify;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
public AsyncChangeEmail(Player player, AuthMe plugin, String oldEmail, String newEmail) {
|
||||
this(player, plugin, oldEmail, newEmail, newEmail);
|
||||
public AsyncChangeEmail(Player player, AuthMe plugin, String oldEmail, String newEmail, NewSetting settings) {
|
||||
this(player, plugin, oldEmail, newEmail, newEmail, settings);
|
||||
}
|
||||
|
||||
public void process() {
|
||||
@ -57,7 +62,7 @@ public class AsyncChangeEmail {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!Settings.isEmailCorrect(newEmail)) {
|
||||
if (!Utils.isEmailCorrect(newEmail, settings)) {
|
||||
m.send(player, MessageKey.INVALID_NEW_EMAIL);
|
||||
return;
|
||||
}
|
||||
|
@ -49,14 +49,14 @@ public class AsynchronousJoin {
|
||||
}
|
||||
|
||||
public void process() {
|
||||
if (Settings.checkVeryGames) {
|
||||
plugin.getVerygamesIp(player);
|
||||
}
|
||||
|
||||
if (Utils.isUnrestricted(player)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (Settings.checkVeryGames) {
|
||||
plugin.getVerygamesIp(player);
|
||||
}
|
||||
|
||||
if (plugin.ess != null && Settings.disableSocialSpy) {
|
||||
plugin.ess.getUser(player).setSocialSpyEnabled(false);
|
||||
}
|
||||
@ -64,13 +64,13 @@ public class AsynchronousJoin {
|
||||
final String ip = plugin.getIP(player);
|
||||
|
||||
|
||||
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip, player.getAddress().getHostName())) {
|
||||
if (Settings.isAllowRestrictedIp && !isNameRestricted(name, ip, player.getAddress().getHostName())) {
|
||||
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
AuthMePlayerListener.causeByAuthMe.putIfAbsent(name, true);
|
||||
player.kickPlayer("You are not the Owner of this account, please try another name!");
|
||||
player.kickPlayer("You are not the owner of this account. Please try another name!");
|
||||
if (Settings.banUnsafeIp)
|
||||
plugin.getServer().banIP(ip);
|
||||
}
|
||||
@ -282,4 +282,30 @@ public class AsynchronousJoin {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the name is restricted based on the restriction setting.
|
||||
*
|
||||
* @param name The name to check
|
||||
* @param ip The IP address of the player
|
||||
* @param domain The hostname of the IP address
|
||||
* @return True if the name is restricted (IP/domain is not allowed for the given name),
|
||||
* false if the restrictions are met or if the name has no restrictions to it
|
||||
*/
|
||||
private static boolean isNameRestricted(String name, String ip, String domain) {
|
||||
boolean nameFound = false;
|
||||
for (String entry : Settings.getRestrictedIp) {
|
||||
String[] args = entry.split(";");
|
||||
String testName = args[0];
|
||||
String testIp = args[1];
|
||||
if (testName.equalsIgnoreCase(name)) {
|
||||
nameFound = true;
|
||||
if ((ip != null && testIp.equals(ip))
|
||||
|| (domain != null && testIp.equalsIgnoreCase(domain))) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nameFound;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -11,8 +11,11 @@ import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.task.MessageTask;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -34,6 +37,7 @@ public class AsynchronousLogin {
|
||||
private final DataSource database;
|
||||
private final Messages m;
|
||||
private final String ip;
|
||||
private final NewSetting settings;
|
||||
|
||||
/**
|
||||
* Constructor for AsynchronousLogin.
|
||||
@ -43,8 +47,10 @@ public class AsynchronousLogin {
|
||||
* @param forceLogin boolean
|
||||
* @param plugin AuthMe
|
||||
* @param data DataSource
|
||||
* @param settings The settings
|
||||
*/
|
||||
public AsynchronousLogin(Player player, String password, boolean forceLogin, AuthMe plugin, DataSource data) {
|
||||
public AsynchronousLogin(Player player, String password, boolean forceLogin, AuthMe plugin, DataSource data,
|
||||
NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
@ -54,6 +60,7 @@ public class AsynchronousLogin {
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.ip = plugin.getIP(player);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
protected boolean needsCaptcha() {
|
||||
@ -98,7 +105,7 @@ public class AsynchronousLogin {
|
||||
msg = m.retrieve(MessageKey.REGISTER_MESSAGE);
|
||||
}
|
||||
BukkitTask msgT = Bukkit.getScheduler().runTaskAsynchronously(plugin,
|
||||
new MessageTask(plugin, name, msg, Settings.getWarnMessageInterval));
|
||||
new MessageTask(plugin, name, msg, settings.getProperty(RegistrationSettings.MESSAGE_INTERVAL)));
|
||||
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
|
||||
}
|
||||
return null;
|
||||
@ -165,12 +172,10 @@ public class AsynchronousLogin {
|
||||
if (!forceLogin)
|
||||
m.send(player, MessageKey.LOGIN_SUCCESS);
|
||||
|
||||
displayOtherAccounts(auth, player);
|
||||
displayOtherAccounts(auth);
|
||||
|
||||
if (Settings.recallEmail) {
|
||||
if (email == null || email.isEmpty() || email.equalsIgnoreCase("your@email.com")) {
|
||||
m.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
}
|
||||
if (Settings.recallEmail && (StringUtils.isEmpty(email) || "your@email.com".equalsIgnoreCase(email))) {
|
||||
m.send(player, MessageKey.EMAIL_ADDED_SUCCESS);
|
||||
}
|
||||
|
||||
if (!Settings.noConsoleSpam) {
|
||||
@ -186,7 +191,7 @@ public class AsynchronousLogin {
|
||||
// task, we schedule it in the end
|
||||
// so that we can be sure, and have not to care if it might be
|
||||
// processed in other order.
|
||||
ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(player, plugin, database);
|
||||
ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(player, plugin, database, settings);
|
||||
if (syncPlayerLogin.getLimbo() != null) {
|
||||
if (syncPlayerLogin.getLimbo().getTimeoutTaskId() != null) {
|
||||
syncPlayerLogin.getLimbo().getTimeoutTaskId().cancel();
|
||||
@ -215,7 +220,7 @@ public class AsynchronousLogin {
|
||||
}
|
||||
}
|
||||
|
||||
public void displayOtherAccounts(PlayerAuth auth, Player p) {
|
||||
public void displayOtherAccounts(PlayerAuth auth) {
|
||||
if (!Settings.displayOtherAccounts) {
|
||||
return;
|
||||
}
|
||||
@ -223,30 +228,16 @@ public class AsynchronousLogin {
|
||||
return;
|
||||
}
|
||||
List<String> auths = this.database.getAllAuthsByName(auth);
|
||||
if (auths.isEmpty()) {
|
||||
if (auths.isEmpty() || auths.size() == 1) {
|
||||
return;
|
||||
}
|
||||
if (auths.size() == 1) {
|
||||
return;
|
||||
}
|
||||
StringBuilder message = new StringBuilder("[AuthMe] ");
|
||||
int i = 0;
|
||||
for (String account : auths) {
|
||||
i++;
|
||||
message.append(account);
|
||||
if (i != auths.size()) {
|
||||
message.append(", ");
|
||||
} else {
|
||||
message.append('.');
|
||||
}
|
||||
}
|
||||
|
||||
String message = "[AuthMe] " + StringUtils.join(", ", auths) + ".";
|
||||
for (Player player : Utils.getOnlinePlayers()) {
|
||||
if (plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OTHER_ACCOUNTS)
|
||||
|| (player.getName().equals(this.player.getName())
|
||||
&& plugin.getPermissionsManager().hasPermission(player, PlayerPermission.SEE_OWN_ACCOUNTS))) {
|
||||
player.sendMessage("[AuthMe] The player " + auth.getNickname() + " has " + auths.size() + " accounts");
|
||||
player.sendMessage(message.toString());
|
||||
player.sendMessage(message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package fr.xephi.authme.process.login;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -24,6 +26,8 @@ import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.Utils;
|
||||
import fr.xephi.authme.util.Utils.GroupType;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN;
|
||||
|
||||
/**
|
||||
*/
|
||||
public class ProcessSyncPlayerLogin implements Runnable {
|
||||
@ -36,24 +40,26 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
private final DataSource database;
|
||||
private final PluginManager pm;
|
||||
private final JsonCache playerCache;
|
||||
private final NewSetting settings;
|
||||
|
||||
/**
|
||||
* Constructor for ProcessSyncPlayerLogin.
|
||||
*
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
* @param data DataSource
|
||||
* @param database DataSource
|
||||
*/
|
||||
public ProcessSyncPlayerLogin(Player player, AuthMe plugin,
|
||||
DataSource data) {
|
||||
DataSource database, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.database = database;
|
||||
this.pm = plugin.getServer().getPluginManager();
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
this.auth = database.getAuth(name);
|
||||
this.playerCache = new JsonCache();
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -152,7 +158,7 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
if (Settings.protectInventoryBeforeLogInEnabled) {
|
||||
if (settings.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||
restoreInventory();
|
||||
}
|
||||
|
||||
@ -188,27 +194,27 @@ public class ProcessSyncPlayerLogin implements Runnable {
|
||||
// Login is finish, display welcome message if we use email registration
|
||||
if (Settings.useWelcomeMessage && Settings.emailRegistration)
|
||||
if (Settings.broadcastWelcomeMessage) {
|
||||
for (String s : Settings.welcomeMsg) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
Bukkit.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
} else {
|
||||
for (String s : Settings.welcomeMsg) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
player.sendMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
}
|
||||
|
||||
// Login is now finish , we can force all commands
|
||||
// Login is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
sendTo();
|
||||
}
|
||||
|
||||
private void sendTo() {
|
||||
if (Settings.sendPlayerTo.isEmpty())
|
||||
return;
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(Settings.sendPlayerTo);
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
if (!settings.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(settings.getProperty(HooksSettings.BUNGEECORD_SERVER));
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
@ -24,8 +25,10 @@ public class AsyncRegister {
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
private final Messages m;
|
||||
private final NewSetting settings;
|
||||
|
||||
public AsyncRegister(Player player, String password, String email, AuthMe plugin, DataSource data) {
|
||||
public AsyncRegister(Player player, String password, String email, AuthMe plugin, DataSource data,
|
||||
NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
this.player = player;
|
||||
this.password = password;
|
||||
@ -34,6 +37,7 @@ public class AsyncRegister {
|
||||
this.plugin = plugin;
|
||||
this.database = data;
|
||||
this.ip = plugin.getIP(player);
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
private boolean preRegisterCheck() throws Exception {
|
||||
@ -136,7 +140,7 @@ public class AsyncRegister {
|
||||
plugin.getManagement().performLogin(player, "dontneed", true);
|
||||
}
|
||||
plugin.otherAccounts.addPlayer(player.getUniqueId());
|
||||
ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin);
|
||||
ProcessSyncPasswordRegister sync = new ProcessSyncPasswordRegister(player, plugin, settings);
|
||||
plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, sync);
|
||||
}
|
||||
}
|
||||
|
@ -1,5 +1,7 @@
|
||||
package fr.xephi.authme.process.register;
|
||||
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.bukkit.potion.PotionEffectType;
|
||||
@ -30,6 +32,7 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
protected final String name;
|
||||
private final AuthMe plugin;
|
||||
private final Messages m;
|
||||
private final NewSetting settings;
|
||||
|
||||
/**
|
||||
* Constructor for ProcessSyncPasswordRegister.
|
||||
@ -37,11 +40,12 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
* @param player Player
|
||||
* @param plugin AuthMe
|
||||
*/
|
||||
public ProcessSyncPasswordRegister(Player player, AuthMe plugin) {
|
||||
public ProcessSyncPasswordRegister(Player player, AuthMe plugin, NewSetting settings) {
|
||||
this.m = plugin.getMessages();
|
||||
this.player = player;
|
||||
this.name = player.getName().toLowerCase();
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
}
|
||||
|
||||
private void sendBungeeMessage() {
|
||||
@ -63,11 +67,6 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method forceLogin.
|
||||
*
|
||||
* @param player Player
|
||||
*/
|
||||
private void forceLogin(Player player) {
|
||||
Utils.teleportToSpawn(player);
|
||||
LimboCache cache = LimboCache.getInstance();
|
||||
@ -88,11 +87,6 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method run.
|
||||
*
|
||||
* @see java.lang.Runnable#run()
|
||||
*/
|
||||
@Override
|
||||
public void run() {
|
||||
LimboPlayer limbo = LimboCache.getInstance().getLimboPlayer(name);
|
||||
@ -141,11 +135,11 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
// Register is finish and player is logged, display welcome message
|
||||
if (Settings.useWelcomeMessage) {
|
||||
if (Settings.broadcastWelcomeMessage) {
|
||||
for (String s : Settings.welcomeMsg) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
plugin.getServer().broadcastMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
} else {
|
||||
for (String s : Settings.welcomeMsg) {
|
||||
for (String s : settings.getWelcomeMessage()) {
|
||||
player.sendMessage(plugin.replaceAllInfo(s, player));
|
||||
}
|
||||
}
|
||||
@ -161,18 +155,18 @@ public class ProcessSyncPasswordRegister implements Runnable {
|
||||
sendBungeeMessage();
|
||||
}
|
||||
|
||||
// Register is now finish , we can force all commands
|
||||
// Register is now finished; we can force all commands
|
||||
forceCommands();
|
||||
|
||||
sendTo();
|
||||
}
|
||||
|
||||
private void sendTo() {
|
||||
if (Settings.sendPlayerTo.isEmpty())
|
||||
return;
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(Settings.sendPlayerTo);
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
if (!settings.getProperty(HooksSettings.BUNGEECORD_SERVER).isEmpty()) {
|
||||
ByteArrayDataOutput out = ByteStreams.newDataOutput();
|
||||
out.writeUTF("Connect");
|
||||
out.writeUTF(settings.getProperty(HooksSettings.BUNGEECORD_SERVER));
|
||||
player.sendPluginMessage(plugin, "BungeeCord", out.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
274
src/main/java/fr/xephi/authme/settings/NewSetting.java
Normal file
274
src/main/java/fr/xephi/authme/settings/NewSetting.java
Normal file
@ -0,0 +1,274 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.PluginSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.yaml.snakeyaml.DumperOptions;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static fr.xephi.authme.settings.SettingsMigrationService.copyFileFromResource;
|
||||
|
||||
/**
|
||||
* The new settings manager.
|
||||
*/
|
||||
public class NewSetting {
|
||||
|
||||
private final File pluginFolder;
|
||||
private final File configFile;
|
||||
private FileConfiguration configuration;
|
||||
/** The file with the localized messages based on {@link PluginSettings#MESSAGES_LANGUAGE}. */
|
||||
private File messagesFile;
|
||||
private List<String> welcomeMessage;
|
||||
private String emailMessage;
|
||||
|
||||
/**
|
||||
* Constructor. Checks the given {@link FileConfiguration} object for completeness.
|
||||
*
|
||||
* @param configFile The configuration file
|
||||
* @param pluginFolder The AuthMe plugin folder
|
||||
*/
|
||||
public NewSetting(File configFile, File pluginFolder) {
|
||||
this.configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
this.configFile = configFile;
|
||||
this.pluginFolder = pluginFolder;
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for testing purposes, allowing more options.
|
||||
*
|
||||
* @param configuration The FileConfiguration object to use
|
||||
* @param configFile The file to write to
|
||||
* @param propertyMap The property map whose properties should be verified for presence, or null to skip this
|
||||
*/
|
||||
@VisibleForTesting
|
||||
NewSetting(FileConfiguration configuration, File configFile, PropertyMap propertyMap) {
|
||||
this.configuration = configuration;
|
||||
this.configFile = configFile;
|
||||
this.pluginFolder = new File("");
|
||||
|
||||
if (propertyMap != null && SettingsMigrationService.checkAndMigrate(configuration, propertyMap, pluginFolder)) {
|
||||
save(propertyMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given property from the configuration.
|
||||
*
|
||||
* @param property The property to retrieve
|
||||
* @param <T> The property's type
|
||||
* @return The property's value
|
||||
*/
|
||||
public <T> T getProperty(Property<T> property) {
|
||||
return property.getFromFile(configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a new value for the given property.
|
||||
*
|
||||
* @param property The property to modify
|
||||
* @param value The new value to assign to the property
|
||||
* @param <T> The property's type
|
||||
*/
|
||||
public <T> void setProperty(Property<T> property, T value) {
|
||||
configuration.set(property.getPath(), value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Save the config file. Use after migrating one or more settings.
|
||||
*/
|
||||
public void save() {
|
||||
save(SettingsFieldRetriever.getAllPropertyFields());
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the messages file based on the messages language config.
|
||||
*
|
||||
* @return The messages file to read messages from
|
||||
*/
|
||||
public File getMessagesFile() {
|
||||
return messagesFile;
|
||||
}
|
||||
|
||||
public String getEmailMessage() {
|
||||
return emailMessage;
|
||||
}
|
||||
|
||||
public List<String> getWelcomeMessage() {
|
||||
return welcomeMessage;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reload the configuration.
|
||||
*/
|
||||
public void reload() {
|
||||
configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
validateAndLoadOptions();
|
||||
}
|
||||
|
||||
private void save(PropertyMap propertyMap) {
|
||||
try (FileWriter writer = new FileWriter(configFile)) {
|
||||
Yaml simpleYaml = newYaml(false);
|
||||
Yaml singleQuoteYaml = newYaml(true);
|
||||
|
||||
writer.write("");
|
||||
// Contains all but the last node of the setting, e.g. [DataSource, mysql] for "DataSource.mysql.username"
|
||||
List<String> currentPath = new ArrayList<>();
|
||||
for (Map.Entry<Property<?>, String[]> entry : propertyMap.entrySet()) {
|
||||
Property<?> property = entry.getKey();
|
||||
|
||||
// Handle properties
|
||||
List<String> propertyPath = Arrays.asList(property.getPath().split("\\."));
|
||||
List<String> commonPathParts = CollectionUtils.filterCommonStart(
|
||||
currentPath, propertyPath.subList(0, propertyPath.size() - 1));
|
||||
List<String> newPathParts = CollectionUtils.getRange(propertyPath, commonPathParts.size());
|
||||
|
||||
if (commonPathParts.isEmpty()) {
|
||||
writer.append("\n");
|
||||
}
|
||||
|
||||
int indentationLevel = commonPathParts.size();
|
||||
if (newPathParts.size() > 1) {
|
||||
for (String path : newPathParts.subList(0, newPathParts.size() - 1)) {
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append(path)
|
||||
.append(": ");
|
||||
++indentationLevel;
|
||||
}
|
||||
}
|
||||
for (String comment : entry.getValue()) {
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append("# ")
|
||||
.append(comment);
|
||||
}
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append(CollectionUtils.getRange(newPathParts, newPathParts.size() - 1).get(0))
|
||||
.append(": ")
|
||||
.append(toYaml(property, indentationLevel, simpleYaml, singleQuoteYaml));
|
||||
|
||||
currentPath = propertyPath.subList(0, propertyPath.size() - 1);
|
||||
}
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not save config file:", e);
|
||||
}
|
||||
}
|
||||
|
||||
private void validateAndLoadOptions() {
|
||||
PropertyMap propertyMap = SettingsFieldRetriever.getAllPropertyFields();
|
||||
if (SettingsMigrationService.checkAndMigrate(configuration, propertyMap, pluginFolder)) {
|
||||
ConsoleLogger.info("Merged new config options");
|
||||
ConsoleLogger.info("Please check your config.yml file for new settings!");
|
||||
save(propertyMap);
|
||||
}
|
||||
|
||||
messagesFile = buildMessagesFile();
|
||||
welcomeMessage = readWelcomeMessage();
|
||||
emailMessage = readEmailMessage();
|
||||
}
|
||||
|
||||
private <T> String toYaml(Property<T> property, int indent, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
String representation = property.toYaml(configuration, simpleYaml, singleQuoteYaml);
|
||||
return join("\n" + indent(indent), representation.split("\\n"));
|
||||
}
|
||||
|
||||
private File buildMessagesFile() {
|
||||
String languageCode = getProperty(PluginSettings.MESSAGES_LANGUAGE);
|
||||
File messagesFile = buildMessagesFileFromCode(languageCode);
|
||||
if (messagesFile.exists()) {
|
||||
return messagesFile;
|
||||
}
|
||||
|
||||
return copyFileFromResource(messagesFile, buildMessagesFilePathFromCode(languageCode))
|
||||
? messagesFile
|
||||
: buildMessagesFileFromCode("en");
|
||||
}
|
||||
|
||||
private File buildMessagesFileFromCode(String language) {
|
||||
return new File(pluginFolder, buildMessagesFilePathFromCode(language));
|
||||
}
|
||||
|
||||
private static String buildMessagesFilePathFromCode(String language) {
|
||||
return StringUtils.makePath("messages", "messages_" + language + ".yml");
|
||||
}
|
||||
|
||||
private List<String> readWelcomeMessage() {
|
||||
if (getProperty(RegistrationSettings.USE_WELCOME_MESSAGE)) {
|
||||
final File welcomeFile = new File(pluginFolder, "welcome.txt");
|
||||
final Charset charset = Charset.forName("UTF-8");
|
||||
if (copyFileFromResource(welcomeFile, "welcome.txt")) {
|
||||
try {
|
||||
return Files.readLines(welcomeFile, charset);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Failed to read file '" + welcomeFile.getPath() + "':", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
return new ArrayList<>(0);
|
||||
}
|
||||
|
||||
private String readEmailMessage() {
|
||||
final File emailFile = new File(pluginFolder, "email.html");
|
||||
final Charset charset = Charset.forName("UTF-8");
|
||||
if (copyFileFromResource(emailFile, "email.html")) {
|
||||
try {
|
||||
return StringUtils.join("", Files.readLines(emailFile, charset));
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Failed to read file '" + emailFile.getPath() + "':", e);
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private static Yaml newYaml(boolean useSingleQuotes) {
|
||||
DumperOptions options = new DumperOptions();
|
||||
options.setDefaultFlowStyle(DumperOptions.FlowStyle.BLOCK);
|
||||
options.setAllowUnicode(true);
|
||||
if (useSingleQuotes) {
|
||||
options.setDefaultScalarStyle(DumperOptions.ScalarStyle.SINGLE_QUOTED);
|
||||
}
|
||||
return new Yaml(options);
|
||||
}
|
||||
|
||||
private static String join(String delimiter, String[] items) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
String delim = "";
|
||||
for (String item : items) {
|
||||
sb.append(delim).append(item);
|
||||
delim = delimiter;
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
private static String indent(int level) {
|
||||
// We use an indentation of 4 spaces
|
||||
StringBuilder sb = new StringBuilder(level * 4);
|
||||
for (int i = 0; i < level; ++i) {
|
||||
sb.append(" ");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,42 +1,32 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.google.common.base.Charsets;
|
||||
import com.google.common.io.Files;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.datasource.DataSource.DataSourceType;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import fr.xephi.authme.util.Wrapper;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.BufferedReader;
|
||||
import java.io.BufferedWriter;
|
||||
import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
/**
|
||||
* Old settings manager. See {@link NewSetting} for the new manager.
|
||||
*/
|
||||
public final class Settings {
|
||||
|
||||
public static final File PLUGIN_FOLDER = Wrapper.getInstance().getDataFolder();
|
||||
public static final File MODULE_FOLDER = new File(PLUGIN_FOLDER, "modules");
|
||||
public static final File CACHE_FOLDER = new File(PLUGIN_FOLDER, "cache");
|
||||
public static final File AUTH_FILE = new File(PLUGIN_FOLDER, "auths.db");
|
||||
public static final File EMAIL_FILE = new File(PLUGIN_FOLDER, "email.html");
|
||||
public static final File SETTINGS_FILE = new File(PLUGIN_FOLDER, "config.yml");
|
||||
private static final File SETTINGS_FILE = new File(PLUGIN_FOLDER, "config.yml");
|
||||
public static final File LOG_FILE = new File(PLUGIN_FOLDER, "authme.log");
|
||||
// This is not an option!
|
||||
public static boolean antiBotInAction = false;
|
||||
public static File messageFile;
|
||||
public static List<String> allowCommands;
|
||||
public static List<String> getJoinPermissions;
|
||||
public static List<String> getUnrestrictedName;
|
||||
@ -49,7 +39,6 @@ public final class Settings {
|
||||
public static List<String> forceCommandsAsConsole;
|
||||
public static List<String> forceRegisterCommands;
|
||||
public static List<String> forceRegisterCommandsAsConsole;
|
||||
public static List<String> welcomeMsg;
|
||||
public static List<String> unsafePasswords;
|
||||
public static List<String> emailBlacklist;
|
||||
public static List<String> emailWhitelist;
|
||||
@ -66,8 +55,7 @@ public final class Settings {
|
||||
isSaveQuitLocationEnabled, isForceSurvivalModeEnabled,
|
||||
isCachingEnabled,
|
||||
isKickOnWrongPasswordEnabled, enablePasswordConfirmation,
|
||||
protectInventoryBeforeLogInEnabled, isBackupActivated,
|
||||
isBackupOnStart, isBackupOnStop, isStopEnabled, reloadSupport,
|
||||
protectInventoryBeforeLogInEnabled, isStopEnabled, reloadSupport,
|
||||
rakamakUseIp, noConsoleSpam, removePassword, displayOtherAccounts,
|
||||
useCaptcha, emailRegistration, multiverse, bungee,
|
||||
banUnsafeIp, doubleEmailCheck, sessionExpireOnIpChange,
|
||||
@ -79,19 +67,18 @@ public final class Settings {
|
||||
checkVeryGames, delayJoinLeaveMessages, noTeleport, applyBlindEffect,
|
||||
kickPlayersBeforeStopping, allowAllCommandsIfRegIsOptional,
|
||||
customAttributes, generateImage, isRemoveSpeedEnabled, preventOtherCase;
|
||||
public static String helpHeader, getNickRegex, getUnloggedinGroup, getMySQLHost,
|
||||
public static String getNickRegex, getUnloggedinGroup, getMySQLHost,
|
||||
getMySQLPort, getMySQLUsername, getMySQLPassword, getMySQLDatabase,
|
||||
getMySQLTablename, getMySQLColumnName, getMySQLColumnPassword,
|
||||
getMySQLColumnIp, getMySQLColumnLastLogin, getMySQLColumnSalt,
|
||||
getMySQLColumnGroup, getMySQLColumnEmail, unRegisteredGroup,
|
||||
backupWindowsPath, getRegisteredGroup,
|
||||
messagesLanguage, getMySQLlastlocX, getMySQLlastlocY,
|
||||
getMySQLlastlocX, getMySQLlastlocY,
|
||||
getMySQLlastlocZ, rakamakUsers, rakamakUsersIp, getmailAccount,
|
||||
getmailPassword, getmailSMTP, getMySQLColumnId, getmailSenderName,
|
||||
getMailSubject, getMailText, getMySQLlastlocWorld, defaultWorld,
|
||||
getMySQLColumnId, getMySQLlastlocWorld, defaultWorld,
|
||||
getPhpbbPrefix, getWordPressPrefix, getMySQLColumnLogged,
|
||||
spawnPriority, crazyloginFileName, getPassRegex,
|
||||
getMySQLColumnRealName, emailOauth2Token, sendPlayerTo;
|
||||
getMySQLColumnRealName, sendPlayerTo;
|
||||
public static int getWarnMessageInterval, getSessionTimeout,
|
||||
getRegistrationTimeout, getMaxNickLength, getMinNickLength,
|
||||
getPasswordMinLen, getMovementRadius, getmaxRegPerIp,
|
||||
@ -100,7 +87,7 @@ public final class Settings {
|
||||
getmaxRegPerEmail, bCryptLog2Rounds, getPhpbbGroup,
|
||||
antiBotSensibility, antiBotDuration, delayRecall, getMaxLoginPerIp,
|
||||
getMaxJoinPerIp;
|
||||
protected static YamlConfiguration configFile;
|
||||
protected static FileConfiguration configFile;
|
||||
private static AuthMe plugin;
|
||||
private static Settings instance;
|
||||
|
||||
@ -112,34 +99,11 @@ public final class Settings {
|
||||
public Settings(AuthMe pl) {
|
||||
instance = this;
|
||||
plugin = pl;
|
||||
configFile = (YamlConfiguration) plugin.getConfig();
|
||||
}
|
||||
|
||||
/**
|
||||
* Method reload.
|
||||
*
|
||||
* @throws Exception if something went wrong
|
||||
*/
|
||||
public static void reload() throws Exception {
|
||||
plugin.getLogger().info("Loading Configuration File...");
|
||||
boolean exist = SETTINGS_FILE.exists();
|
||||
if (!exist) {
|
||||
plugin.saveDefaultConfig();
|
||||
}
|
||||
configFile.load(SETTINGS_FILE);
|
||||
if (exist) {
|
||||
instance.mergeConfig();
|
||||
}
|
||||
configFile = plugin.getConfig();
|
||||
loadVariables();
|
||||
if (exist) {
|
||||
instance.saveDefaults();
|
||||
}
|
||||
messageFile = new File(PLUGIN_FOLDER, "messages" + File.separator + "messages_" + messagesLanguage + ".yml");
|
||||
}
|
||||
|
||||
public static void loadVariables() {
|
||||
helpHeader = configFile.getString("settings.helpHeader", "AuthMeReloaded");
|
||||
messagesLanguage = checkLang(configFile.getString("settings.messagesLanguage", "en").toLowerCase());
|
||||
isPermissionCheckEnabled = configFile.getBoolean("permission.EnablePermissionCheck", false);
|
||||
isForcedRegistrationEnabled = configFile.getBoolean("settings.registration.force", true);
|
||||
isRegistrationEnabled = configFile.getBoolean("settings.registration.enabled", true);
|
||||
@ -204,9 +168,6 @@ public final class Settings {
|
||||
plugin.checkProtocolLib();
|
||||
|
||||
passwordMaxLength = configFile.getInt("settings.security.passwordMaxLength", 20);
|
||||
isBackupActivated = configFile.getBoolean("BackupSystem.ActivateBackup", false);
|
||||
isBackupOnStart = configFile.getBoolean("BackupSystem.OnServerStart", false);
|
||||
isBackupOnStop = configFile.getBoolean("BackupSystem.OnServeStop", false);
|
||||
backupWindowsPath = configFile.getString("BackupSystem.MysqlWindowsPath", "C:\\Program Files\\MySQL\\MySQL Server 5.1\\");
|
||||
isStopEnabled = configFile.getBoolean("Security.SQLProblem.stopServer", true);
|
||||
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
@ -227,19 +188,14 @@ public final class Settings {
|
||||
noConsoleSpam = configFile.getBoolean("Security.console.noConsoleSpam", false);
|
||||
removePassword = configFile.getBoolean("Security.console.removePassword", true);
|
||||
getmailAccount = configFile.getString("Email.mailAccount", "");
|
||||
getmailPassword = configFile.getString("Email.mailPassword", "");
|
||||
getmailSMTP = configFile.getString("Email.mailSMTP", "smtp.gmail.com");
|
||||
getMailPort = configFile.getInt("Email.mailPort", 465);
|
||||
getRecoveryPassLength = configFile.getInt("Email.RecoveryPasswordLength", 8);
|
||||
getMySQLOtherUsernameColumn = configFile.getStringList("ExternalBoardOptions.mySQLOtherUsernameColumns");
|
||||
displayOtherAccounts = configFile.getBoolean("settings.restrictions.displayOtherAccounts", true);
|
||||
getMySQLColumnId = configFile.getString("DataSource.mySQLColumnId", "id");
|
||||
getmailSenderName = configFile.getString("Email.mailSenderName", "");
|
||||
useCaptcha = configFile.getBoolean("Security.captcha.useCaptcha", false);
|
||||
maxLoginTry = configFile.getInt("Security.captcha.maxLoginTry", 5);
|
||||
captchaLength = configFile.getInt("Security.captcha.captchaLength", 5);
|
||||
getMailSubject = configFile.getString("Email.mailSubject", "Your new AuthMe Password");
|
||||
getMailText = loadEmailText();
|
||||
emailRegistration = configFile.getBoolean("settings.registration.enableEmailRegistrationSystem", false);
|
||||
saltLength = configFile.getInt("settings.security.doubleMD5SaltLength", 8);
|
||||
getmaxRegPerEmail = configFile.getInt("Email.maxRegPerEmail", 1);
|
||||
@ -298,33 +254,8 @@ public final class Settings {
|
||||
generateImage = configFile.getBoolean("Email.generateImage", false);
|
||||
preventOtherCase = configFile.getBoolean("settings.preventOtherCase", false);
|
||||
kickPlayersBeforeStopping = configFile.getBoolean("Security.stop.kickPlayersBeforeStopping", true);
|
||||
emailOauth2Token = configFile.getString("Email.emailOauth2Token", "");
|
||||
sendPlayerTo = configFile.getString("Hooks.sendPlayerTo", "");
|
||||
|
||||
// Load the welcome message
|
||||
getWelcomeMessage();
|
||||
|
||||
}
|
||||
|
||||
private static String loadEmailText() {
|
||||
if (!EMAIL_FILE.exists()) {
|
||||
plugin.saveResource("email.html", false);
|
||||
}
|
||||
try {
|
||||
return Files.toString(EMAIL_FILE, Charsets.UTF_8);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Error loading email text:", e);
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param key the key to set
|
||||
* @param value the value to set
|
||||
*/
|
||||
public static void setValue(String key, Object value) {
|
||||
instance.set(key, value);
|
||||
save();
|
||||
}
|
||||
|
||||
/**
|
||||
@ -357,49 +288,12 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Config option for setting and check restricted user by username;ip ,
|
||||
* return false if ip and name doesn't match with player that join the
|
||||
* server, so player has a restricted access
|
||||
*
|
||||
* @param name String
|
||||
* @param ip String
|
||||
* @param domain String
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean getRestrictedIp(String name, String ip, String domain) {
|
||||
|
||||
Iterator<String> iterator = getRestrictedIp.iterator();
|
||||
boolean trueOnce = false;
|
||||
boolean nameFound = false;
|
||||
while (iterator.hasNext()) {
|
||||
String[] args = iterator.next().split(";");
|
||||
String testName = args[0];
|
||||
String testIp = args[1];
|
||||
if (testName.equalsIgnoreCase(name)) {
|
||||
nameFound = true;
|
||||
if (ip != null) {
|
||||
if (testIp.equalsIgnoreCase(ip)) {
|
||||
trueOnce = true;
|
||||
}
|
||||
}
|
||||
if (domain != null) {
|
||||
if (testIp.equalsIgnoreCase(domain)) {
|
||||
trueOnce = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return !nameFound || trueOnce;
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves the configuration to disk
|
||||
*
|
||||
* @return True if saved successfully
|
||||
*/
|
||||
public static boolean save() {
|
||||
private static boolean save() {
|
||||
try {
|
||||
configFile.save(SETTINGS_FILE);
|
||||
return true;
|
||||
@ -415,7 +309,7 @@ public final class Settings {
|
||||
*
|
||||
* @return String
|
||||
*/
|
||||
public static String checkLang(String lang) {
|
||||
private static String checkLang(String lang) {
|
||||
if (new File(PLUGIN_FOLDER, "messages" + File.separator + "messages_" + lang + ".yml").exists()) {
|
||||
ConsoleLogger.info("Set Language to: " + lang);
|
||||
return lang;
|
||||
@ -443,325 +337,6 @@ public final class Settings {
|
||||
}
|
||||
}
|
||||
|
||||
private static void getWelcomeMessage() {
|
||||
AuthMe plugin = AuthMe.getInstance();
|
||||
welcomeMsg = new ArrayList<>();
|
||||
if (!useWelcomeMessage) {
|
||||
return;
|
||||
}
|
||||
if (!(new File(plugin.getDataFolder() + File.separator + "welcome.txt").exists())) {
|
||||
try {
|
||||
FileWriter fw = new FileWriter(plugin.getDataFolder() + File.separator + "welcome.txt", true);
|
||||
BufferedWriter w = new BufferedWriter(fw);
|
||||
w.write("Welcome {PLAYER} on {SERVER} server");
|
||||
w.newLine();
|
||||
w.write("This server uses " + AuthMe.getPluginName() + " protection!");
|
||||
w.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
try {
|
||||
FileReader fr = new FileReader(plugin.getDataFolder() + File.separator + "welcome.txt");
|
||||
BufferedReader br = new BufferedReader(fr);
|
||||
String line;
|
||||
while ((line = br.readLine()) != null) {
|
||||
welcomeMsg.add(line);
|
||||
}
|
||||
br.close();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method isEmailCorrect.
|
||||
*
|
||||
* @param email String
|
||||
*
|
||||
* @return boolean
|
||||
*/
|
||||
public static boolean isEmailCorrect(String email) {
|
||||
if (!email.contains("@"))
|
||||
return false;
|
||||
if (email.equalsIgnoreCase("your@email.com"))
|
||||
return false;
|
||||
String emailDomain = email.split("@")[1];
|
||||
boolean correct = true;
|
||||
if (emailWhitelist != null && !emailWhitelist.isEmpty()) {
|
||||
for (String domain : emailWhitelist) {
|
||||
if (!domain.equalsIgnoreCase(emailDomain)) {
|
||||
correct = false;
|
||||
} else {
|
||||
correct = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return correct;
|
||||
}
|
||||
if (emailBlacklist != null && !emailBlacklist.isEmpty()) {
|
||||
for (String domain : emailBlacklist) {
|
||||
if (domain.equalsIgnoreCase(emailDomain)) {
|
||||
correct = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
return correct;
|
||||
}
|
||||
|
||||
public void mergeConfig() {
|
||||
boolean changes = false;
|
||||
if (contains("Xenoforo.predefinedSalt")) {
|
||||
set("Xenoforo.predefinedSalt", null);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Protection.enableProtection")) {
|
||||
set("Protection.enableProtection", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.removeSpeed")) {
|
||||
set("settings.restrictions.removeSpeed", true);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Protection.countries")) {
|
||||
countries = new ArrayList<>();
|
||||
countries.add("US");
|
||||
countries.add("GB");
|
||||
set("Protection.countries", countries);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Protection.enableAntiBot")) {
|
||||
set("Protection.enableAntiBot", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Protection.antiBotSensibility")) {
|
||||
set("Protection.antiBotSensibility", 5);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Protection.antiBotDuration")) {
|
||||
set("Protection.antiBotDuration", 10);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.forceCommands")) {
|
||||
set("settings.forceCommands", new ArrayList<String>());
|
||||
changes = true;
|
||||
}
|
||||
if (contains("settings.delayJoinMessage")) {
|
||||
set("settings.delayJoinLeaveMessages", false);
|
||||
set("settings.delayJoinMessage", null);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.forceCommandsAsConsole")) {
|
||||
set("settings.forceCommandsAsConsole", new ArrayList<String>());
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Email.recallPlayers")) {
|
||||
set("Email.recallPlayers", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Email.delayRecall")) {
|
||||
set("Email.delayRecall", 5);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.useWelcomeMessage")) {
|
||||
set("settings.useWelcomeMessage", true);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.enablePasswordConfirmation")) {
|
||||
set("settings.restrictions.enablePasswordConfirmation", true);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("settings.restrictions.enablePasswordVerifier")) {
|
||||
set("settings.restrictions.enablePasswordVerifier", null);
|
||||
changes = true;
|
||||
}
|
||||
if(!contains("settings.restrictions.allowAllCommandsIfRegistrationIsOptional")) {
|
||||
set("settings.restrictions.allowAllCommandsIfRegistrationIsOptional", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.security.unsafePasswords")) {
|
||||
List<String> str = new ArrayList<>();
|
||||
str.add("123456");
|
||||
str.add("password");
|
||||
set("settings.security.unsafePasswords", str);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Protection.countriesBlacklist")) {
|
||||
countriesBlacklist = new ArrayList<>();
|
||||
countriesBlacklist.add("A1");
|
||||
set("Protection.countriesBlacklist", countriesBlacklist);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.helpHeader")) {
|
||||
set("settings.helpHeader", "AuthMeReloaded");
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.broadcastWelcomeMessage")) {
|
||||
set("settings.broadcastWelcomeMessage", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.registration.forceKickAfterRegister")) {
|
||||
set("settings.registration.forceKickAfterRegister", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.registration.forceLoginAfterRegister")) {
|
||||
set("settings.registration.forceLoginAfterRegister", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("DataSource.mySQLColumnLogged")) {
|
||||
set("DataSource.mySQLColumnLogged", "isLogged");
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.spawnPriority")) {
|
||||
set("settings.restrictions.spawnPriority", "authme,essentials,multiverse,default");
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.maxLoginPerIp")) {
|
||||
set("settings.restrictions.maxLoginPerIp", 0);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.maxJoinPerIp")) {
|
||||
set("settings.restrictions.maxJoinPerIp", 0);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("VeryGames.enableIpCheck")) {
|
||||
set("VeryGames.enableIpCheck", false);
|
||||
changes = true;
|
||||
}
|
||||
if (configFile.getString("settings.restrictions.allowedNicknameCharacters").equals("[a-zA-Z0-9_?]*")) {
|
||||
set("settings.restrictions.allowedNicknameCharacters", "[a-zA-Z0-9_]*");
|
||||
changes = true;
|
||||
}
|
||||
if (contains("settings.delayJoinMessage")) {
|
||||
set("settings.delayJoinMessage", null);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.delayJoinLeaveMessages")) {
|
||||
set("settings.delayJoinLeaveMessages", true);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.noTeleport")) {
|
||||
set("settings.restrictions.noTeleport", false);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Converter.Rakamak.newPasswordHash")) {
|
||||
set("Converter.Rakamak.newPasswordHash", null);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Converter.CrazyLogin.fileName")) {
|
||||
set("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.restrictions.allowedPasswordCharacters")) {
|
||||
set("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*");
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.applyBlindEffect")) {
|
||||
set("settings.applyBlindEffect", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Email.emailBlacklisted")) {
|
||||
set("Email.emailBlacklisted", new ArrayList<String>());
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Performances")) {
|
||||
set("Performances", null);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Passpartu.enablePasspartu")) {
|
||||
set("Passpartu.enablePasspartu", null);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Passpartu")) {
|
||||
set("Passpartu", null);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Email.emailWhitelisted")) {
|
||||
set("Email.emailWhitelisted", new ArrayList<String>());
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.forceRegisterCommands")) {
|
||||
set("settings.forceRegisterCommands", new ArrayList<String>());
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("settings.forceRegisterCommandsAsConsole")) {
|
||||
set("settings.forceRegisterCommandsAsConsole", new ArrayList<String>());
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Hooks.customAttributes")) {
|
||||
set("Hooks.customAttributes", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Purge.removePermissions")) {
|
||||
set("Purge.removePermissions", false);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Hooks.notifications")) {
|
||||
set("Hooks.notifications", null);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Hooks.chestshop")) {
|
||||
set("Hooks.chestshop", null);
|
||||
changes = true;
|
||||
}
|
||||
if (contains("Hooks.legacyChestshop")) {
|
||||
set("Hooks.legacyChestshop", null);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("Email.generateImage")) {
|
||||
set("Email.generateImage", false);
|
||||
changes = true;
|
||||
}
|
||||
if (!contains("DataSource.mySQLRealName")) {
|
||||
set("DataSource.mySQLRealName", "realname");
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if (!contains("settings.preventOtherCase")) {
|
||||
set("settings.preventOtherCase", false);
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if (contains("Email.mailText")) {
|
||||
set("Email.mailText", null);
|
||||
ConsoleLogger.showError("Remove Email.mailText from config, we now use the email.html file");
|
||||
}
|
||||
|
||||
if (!contains("Security.stop.kickPlayersBeforeStopping")) {
|
||||
set("Security.stop.kickPlayersBeforeStopping", true);
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if (!contains("Email.emailOauth2Token"))
|
||||
set("Email.emailOauth2Token", "");
|
||||
|
||||
if (!contains("Hooks.sendPlayerTo")) {
|
||||
set("Hooks.sendPlayerTo", "");
|
||||
changes = true;
|
||||
}
|
||||
|
||||
if (changes) {
|
||||
save();
|
||||
plugin.getLogger().warning("Merged new Config Options - I'm not an error, please don't report me");
|
||||
plugin.getLogger().warning("Please check your config.yml file for new configs!");
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean contains(String path) {
|
||||
return configFile.contains(path);
|
||||
}
|
||||
|
||||
// public because it's used in AuthMe at one place
|
||||
|
||||
/**
|
||||
* @param path String
|
||||
* @param value String
|
||||
*/
|
||||
public void set(String path, Object value) {
|
||||
configFile.set(path, value);
|
||||
}
|
||||
|
||||
/**
|
||||
* Saves current configuration (plus defaults) to disk.
|
||||
* <p>
|
||||
@ -769,7 +344,7 @@ public final class Settings {
|
||||
*
|
||||
* @return True if saved successfully
|
||||
*/
|
||||
public final boolean saveDefaults() {
|
||||
private boolean saveDefaults() {
|
||||
configFile.options()
|
||||
.copyDefaults(true)
|
||||
.copyHeader(true);
|
||||
|
@ -0,0 +1,139 @@
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.RestrictionSettings.ALLOWED_NICKNAME_CHARACTERS;
|
||||
import static java.lang.String.format;
|
||||
|
||||
/**
|
||||
* Service for verifying that the configuration is up-to-date.
|
||||
*/
|
||||
public final class SettingsMigrationService {
|
||||
|
||||
private SettingsMigrationService() {
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks the config file and does any necessary migrations.
|
||||
*
|
||||
* @param configuration The file configuration to check and migrate
|
||||
* @param propertyMap The property map of all existing properties
|
||||
* @param pluginFolder The plugin folder
|
||||
* @return True if there is a change and the config must be saved, false if the config is up-to-date
|
||||
*/
|
||||
public static boolean checkAndMigrate(FileConfiguration configuration, PropertyMap propertyMap, File pluginFolder) {
|
||||
return performMigrations(configuration, pluginFolder) || hasDeprecatedProperties(configuration)
|
||||
|| !containsAllSettings(configuration, propertyMap);
|
||||
}
|
||||
|
||||
private static boolean performMigrations(FileConfiguration configuration, File pluginFolder) {
|
||||
boolean changes = false;
|
||||
if ("[a-zA-Z0-9_?]*".equals(configuration.getString(ALLOWED_NICKNAME_CHARACTERS.getPath()))) {
|
||||
configuration.set(ALLOWED_NICKNAME_CHARACTERS.getPath(), "[a-zA-Z0-9_]*");
|
||||
changes = true;
|
||||
}
|
||||
changes = changes || performMailTextToFileMigration(configuration, pluginFolder);
|
||||
|
||||
return changes;
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
static boolean containsAllSettings(FileConfiguration configuration, PropertyMap propertyMap) {
|
||||
for (Property<?> property : propertyMap.keySet()) {
|
||||
if (!property.isPresent(configuration)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static boolean hasDeprecatedProperties(FileConfiguration configuration) {
|
||||
String[] deprecatedProperties = {
|
||||
"Converter.Rakamak.newPasswordHash", "Hooks.chestshop", "Hooks.legacyChestshop", "Hooks.notifications",
|
||||
"Passpartu", "Performances", "settings.delayJoinMessage", "settings.restrictions.enablePasswordVerifier",
|
||||
"Xenoforo.predefinedSalt"};
|
||||
for (String deprecatedPath : deprecatedProperties) {
|
||||
if (configuration.contains(deprecatedPath)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// --------
|
||||
// Specific migrations
|
||||
// --------
|
||||
|
||||
/**
|
||||
* Check if {@code Email.mailText} is present and move it to the Email.html file if it doesn't exist yet.
|
||||
*
|
||||
* @param configuration The file configuration to verify
|
||||
* @param dataFolder The plugin data folder
|
||||
* @return True if a migration has been completed, false otherwise
|
||||
*/
|
||||
private static boolean performMailTextToFileMigration(FileConfiguration configuration, File dataFolder) {
|
||||
final String oldSettingPath = "Email.mailText";
|
||||
if (!configuration.contains(oldSettingPath)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
final File emailFile = new File(dataFolder, "email.html");
|
||||
final String mailText = configuration.getString(oldSettingPath)
|
||||
.replace("<playername>", "<playername />")
|
||||
.replace("<servername>", "<servername />")
|
||||
.replace("<generatedpass>", "<generatedpass />")
|
||||
.replace("<image>", "<image />");
|
||||
if (!emailFile.exists()) {
|
||||
try (FileWriter fw = new FileWriter(emailFile)) {
|
||||
fw.write(mailText);
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not create email.html configuration file:", e);
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Copy a resource file (from the JAR) to the given file if it doesn't exist.
|
||||
*
|
||||
* @param destinationFile The file to check and copy to (outside of JAR)
|
||||
* @param resourcePath Absolute path to the resource file (path to file within JAR)
|
||||
* @return False if the file does not exist and could not be copied, true otherwise
|
||||
*/
|
||||
public static boolean copyFileFromResource(File destinationFile, String resourcePath) {
|
||||
if (destinationFile.exists()) {
|
||||
return true;
|
||||
} else if (!destinationFile.getParentFile().exists() && !destinationFile.getParentFile().mkdirs()) {
|
||||
ConsoleLogger.showError("Cannot create parent directories for '" + destinationFile + "'");
|
||||
return false;
|
||||
}
|
||||
|
||||
// ClassLoader#getResourceAsStream does not deal with the '\' path separator: replace to '/'
|
||||
final String normalizedPath = resourcePath.replace("\\", "/");
|
||||
try (InputStream is = AuthMe.class.getClassLoader().getResourceAsStream(normalizedPath)) {
|
||||
if (is == null) {
|
||||
ConsoleLogger.showError(format("Cannot copy resource '%s' to file '%s': cannot load resource",
|
||||
resourcePath, destinationFile.getPath()));
|
||||
} else {
|
||||
Files.copy(is, destinationFile.toPath());
|
||||
return true;
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException(format("Cannot copy resource '%s' to file '%s':",
|
||||
resourcePath, destinationFile.getPath()), e);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@ -1,155 +0,0 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* The new settings manager.
|
||||
*/
|
||||
public class NewSetting {
|
||||
|
||||
private File file;
|
||||
private FileConfiguration configuration;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* Loads the file as YAML and checks its integrity.
|
||||
*
|
||||
* @param configuration The configuration to interact with
|
||||
* @param file The configuration file
|
||||
*/
|
||||
public NewSetting(FileConfiguration configuration, File file) {
|
||||
this.configuration = configuration;
|
||||
this.file = file;
|
||||
|
||||
// TODO ljacqu 20160109: Ensure that save() works as desired (i.e. that it always produces valid YAML)
|
||||
// and then uncomment the lines below. Once this is uncommented, the checks in the old Settings.java should
|
||||
// be removed as we should check to rewrite the config.yml file only at one place
|
||||
// --------
|
||||
// PropertyMap propertyMap = SettingsFieldRetriever.getAllPropertyFields();
|
||||
// if (!containsAllSettings(propertyMap)) {
|
||||
// save(propertyMap);
|
||||
// }
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor for testing purposes, allowing more options.
|
||||
*
|
||||
* @param configuration The FileConfiguration object to use
|
||||
* @param file The file to write to
|
||||
* @param propertyMap The property map whose properties should be verified for presence, or null to skip this
|
||||
*/
|
||||
@VisibleForTesting
|
||||
NewSetting(FileConfiguration configuration, File file, PropertyMap propertyMap) {
|
||||
this.configuration = configuration;
|
||||
this.file = file;
|
||||
|
||||
if (propertyMap != null && !containsAllSettings(propertyMap)) {
|
||||
save(propertyMap);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the given property from the configuration.
|
||||
*
|
||||
* @param property The property to retrieve
|
||||
* @param <T> The property's type
|
||||
* @return The property's value
|
||||
*/
|
||||
public <T> T getProperty(Property<T> property) {
|
||||
return property.getFromFile(configuration);
|
||||
}
|
||||
|
||||
public void save() {
|
||||
save(SettingsFieldRetriever.getAllPropertyFields());
|
||||
}
|
||||
|
||||
public void save(PropertyMap propertyMap) {
|
||||
try (FileWriter writer = new FileWriter(file)) {
|
||||
writer.write("");
|
||||
|
||||
// Contains all but the last node of the setting, e.g. [DataSource, mysql] for "DataSource.mysql.username"
|
||||
List<String> currentPath = new ArrayList<>();
|
||||
for (Map.Entry<Property<?>, String[]> entry : propertyMap.entrySet()) {
|
||||
Property<?> property = entry.getKey();
|
||||
|
||||
// Handle properties
|
||||
List<String> propertyPath = Arrays.asList(property.getPath().split("\\."));
|
||||
List<String> commonPathParts = CollectionUtils.filterCommonStart(
|
||||
currentPath, propertyPath.subList(0, propertyPath.size() - 1));
|
||||
List<String> newPathParts = CollectionUtils.getRange(propertyPath, commonPathParts.size());
|
||||
|
||||
if (commonPathParts.isEmpty()) {
|
||||
writer.append("\n");
|
||||
}
|
||||
|
||||
int indentationLevel = commonPathParts.size();
|
||||
if (newPathParts.size() > 1) {
|
||||
for (String path : newPathParts.subList(0, newPathParts.size() - 1)) {
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append(path)
|
||||
.append(": ");
|
||||
++indentationLevel;
|
||||
}
|
||||
}
|
||||
for (String comment : entry.getValue()) {
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append("# ")
|
||||
.append(comment);
|
||||
}
|
||||
writer.append("\n")
|
||||
.append(indent(indentationLevel))
|
||||
.append(CollectionUtils.getRange(newPathParts, newPathParts.size() - 1).get(0))
|
||||
.append(": ");
|
||||
|
||||
List<String> yamlLines = property.formatValueAsYaml(configuration);
|
||||
String delim = "";
|
||||
for (String yamlLine : yamlLines) {
|
||||
writer.append(delim).append(yamlLine);
|
||||
delim = "\n" + indent(indentationLevel);
|
||||
}
|
||||
|
||||
currentPath = propertyPath.subList(0, propertyPath.size() - 1);
|
||||
}
|
||||
writer.flush();
|
||||
writer.close();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Could not save config file:", e);
|
||||
}
|
||||
}
|
||||
|
||||
@VisibleForTesting
|
||||
boolean containsAllSettings(PropertyMap propertyMap) {
|
||||
for (Property<?> property : propertyMap.keySet()) {
|
||||
if (!property.isPresent(configuration)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private static String indent(int level) {
|
||||
// YAML uses indentation of 4 spaces
|
||||
StringBuilder sb = new StringBuilder(level * 4);
|
||||
for (int i = 0; i < level; ++i) {
|
||||
sb.append(" ");
|
||||
}
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
}
|
@ -1,13 +1,11 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
/**
|
||||
* Enum property type.
|
||||
*
|
||||
* @param <E> The enum class
|
||||
*/
|
||||
class EnumPropertyType<E extends Enum<E>> extends PropertyType<E> {
|
||||
@ -28,17 +26,17 @@ class EnumPropertyType<E extends Enum<E>> extends PropertyType<E> {
|
||||
return mappedValue != null ? mappedValue : property.getDefaultValue();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> asYaml(E value) {
|
||||
return asList("'" + value + "'");
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Property<E> property, FileConfiguration configuration) {
|
||||
return super.contains(property, configuration)
|
||||
&& mapToEnum(configuration.getString(property.getPath())) != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toYaml(E value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return singleQuoteYaml.dump(value.name());
|
||||
}
|
||||
|
||||
private E mapToEnum(String value) {
|
||||
for (E entry : clazz.getEnumConstants()) {
|
||||
if (entry.name().equalsIgnoreCase(value)) {
|
||||
|
@ -1,13 +1,14 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
* Properties (i.e. a <i>setting</i> that is read from the config.yml file).
|
||||
* Property class, representing a <i>setting</i> that is read from the config.yml file.
|
||||
*/
|
||||
public class Property<T> {
|
||||
|
||||
@ -22,15 +23,43 @@ public class Property<T> {
|
||||
this.defaultValue = defaultValue;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new property. See also {@link #newProperty(PropertyType, String, Object[])} for lists and
|
||||
* {@link #newProperty(Class, String, Enum)}.
|
||||
*
|
||||
* @param type The property type
|
||||
* @param path The property's path
|
||||
* @param defaultValue The default value
|
||||
* @param <T> The type of the property
|
||||
* @return The created property
|
||||
*/
|
||||
public static <T> Property<T> newProperty(PropertyType<T> type, String path, T defaultValue) {
|
||||
return new Property<>(type, path, defaultValue);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new list property.
|
||||
*
|
||||
* @param type The list type of the property
|
||||
* @param path The property's path
|
||||
* @param defaultValues The default value's items
|
||||
* @param <U> The list type
|
||||
* @return The created list property
|
||||
*/
|
||||
@SafeVarargs
|
||||
public static <U> Property<List<U>> newProperty(PropertyType<List<U>> type, String path, U... defaultValues) {
|
||||
return new Property<>(type, path, Arrays.asList(defaultValues));
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new enum property.
|
||||
*
|
||||
* @param clazz The enum class
|
||||
* @param path The property's path
|
||||
* @param defaultValue The default value
|
||||
* @param <E> The enum type
|
||||
* @return The created enum property
|
||||
*/
|
||||
public static <E extends Enum<E>> Property<E> newProperty(Class<E> clazz, String path, E defaultValue) {
|
||||
return new Property<>(new EnumPropertyType<>(clazz), path, defaultValue);
|
||||
}
|
||||
@ -53,9 +82,8 @@ public class Property<T> {
|
||||
// -----
|
||||
// Hooks to the PropertyType methods
|
||||
// -----
|
||||
|
||||
/**
|
||||
* Get the property value from the given configuration.
|
||||
* Get the property value from the given configuration – guaranteed to never return null.
|
||||
*
|
||||
* @param configuration The configuration to read the value from
|
||||
* @return The value, or default if not present
|
||||
@ -64,16 +92,6 @@ public class Property<T> {
|
||||
return type.getFromFile(this, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the property value as YAML.
|
||||
*
|
||||
* @param configuration The configuration to read the value from
|
||||
* @return The property value as YAML
|
||||
*/
|
||||
public List<String> formatValueAsYaml(FileConfiguration configuration) {
|
||||
return type.asYaml(this, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the given configuration file contains the property.
|
||||
*
|
||||
@ -84,10 +102,21 @@ public class Property<T> {
|
||||
return type.contains(this, configuration);
|
||||
}
|
||||
|
||||
/**
|
||||
* Format the property's value as YAML.
|
||||
*
|
||||
* @param configuration The file configuration
|
||||
* @param simpleYaml YAML object (default)
|
||||
* @param singleQuoteYaml YAML object using single quotes
|
||||
* @return The generated YAML
|
||||
*/
|
||||
public String toYaml(FileConfiguration configuration, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return type.toYaml(getFromFile(configuration), simpleYaml, singleQuoteYaml);
|
||||
}
|
||||
|
||||
// -----
|
||||
// Trivial getters
|
||||
// -----
|
||||
|
||||
/**
|
||||
* Return the default value of the property.
|
||||
*
|
||||
|
@ -1,12 +1,10 @@
|
||||
package fr.xephi.authme.settings.domain;
|
||||
|
||||
import org.bukkit.configuration.file.FileConfiguration;
|
||||
import org.yaml.snakeyaml.Yaml;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static java.util.Arrays.asList;
|
||||
|
||||
/**
|
||||
* Handles a certain property type and provides type-specific functionality.
|
||||
*
|
||||
@ -16,7 +14,6 @@ import static java.util.Arrays.asList;
|
||||
public abstract class PropertyType<T> {
|
||||
|
||||
public static final PropertyType<Boolean> BOOLEAN = new BooleanProperty();
|
||||
public static final PropertyType<Double> DOUBLE = new DoubleProperty();
|
||||
public static final PropertyType<Integer> INTEGER = new IntegerProperty();
|
||||
public static final PropertyType<String> STRING = new StringProperty();
|
||||
public static final PropertyType<List<String>> STRING_LIST = new StringListProperty();
|
||||
@ -30,17 +27,6 @@ public abstract class PropertyType<T> {
|
||||
*/
|
||||
public abstract T getFromFile(Property<T> property, FileConfiguration configuration);
|
||||
|
||||
/**
|
||||
* Return the property's value (or its default) as YAML.
|
||||
*
|
||||
* @param property The property to transform
|
||||
* @param configuration The YAML configuration to read from
|
||||
* @return The read value or its default in YAML format
|
||||
*/
|
||||
public List<String> asYaml(Property<T> property, FileConfiguration configuration) {
|
||||
return asYaml(getFromFile(property, configuration));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether the property is present in the given configuration.
|
||||
*
|
||||
@ -53,12 +39,16 @@ public abstract class PropertyType<T> {
|
||||
}
|
||||
|
||||
/**
|
||||
* Transform the given value to YAML.
|
||||
* Format the value as YAML.
|
||||
*
|
||||
* @param value The value to transform
|
||||
* @return The value as YAML
|
||||
* @param value The value to export
|
||||
* @param simpleYaml YAML object (default)
|
||||
* @param singleQuoteYaml YAML object set to use single quotes
|
||||
* @return The generated YAML
|
||||
*/
|
||||
protected abstract List<String> asYaml(T value);
|
||||
public String toYaml(T value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return simpleYaml.dump(value);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
@ -69,26 +59,6 @@ public abstract class PropertyType<T> {
|
||||
public Boolean getFromFile(Property<Boolean> property, FileConfiguration configuration) {
|
||||
return configuration.getBoolean(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> asYaml(Boolean value) {
|
||||
return asList(value ? "true" : "false");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Double property.
|
||||
*/
|
||||
private static final class DoubleProperty extends PropertyType<Double> {
|
||||
@Override
|
||||
public Double getFromFile(Property<Double> property, FileConfiguration configuration) {
|
||||
return configuration.getDouble(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> asYaml(Double value) {
|
||||
return asList(String.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -99,11 +69,6 @@ public abstract class PropertyType<T> {
|
||||
public Integer getFromFile(Property<Integer> property, FileConfiguration configuration) {
|
||||
return configuration.getInt(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> asYaml(Integer value) {
|
||||
return asList(String.valueOf(value));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -114,15 +79,9 @@ public abstract class PropertyType<T> {
|
||||
public String getFromFile(Property<String> property, FileConfiguration configuration) {
|
||||
return configuration.getString(property.getPath(), property.getDefaultValue());
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> asYaml(String value) {
|
||||
return asList(toYamlLiteral(value));
|
||||
}
|
||||
|
||||
public static String toYamlLiteral(String str) {
|
||||
// TODO: Need to handle new lines properly
|
||||
return "'" + str.replace("'", "''") + "'";
|
||||
public String toYaml(String value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
return singleQuoteYaml.dump(value);
|
||||
}
|
||||
}
|
||||
|
||||
@ -139,23 +98,18 @@ public abstract class PropertyType<T> {
|
||||
}
|
||||
|
||||
@Override
|
||||
protected List<String> asYaml(List<String> value) {
|
||||
if (value.isEmpty()) {
|
||||
return asList("[]");
|
||||
}
|
||||
|
||||
List<String> resultLines = new ArrayList<>();
|
||||
resultLines.add(""); // add
|
||||
for (String entry : value) {
|
||||
// TODO: StringProperty#toYamlLiteral will return List<String>...
|
||||
resultLines.add(" - " + StringProperty.toYamlLiteral(entry));
|
||||
}
|
||||
return resultLines;
|
||||
public boolean contains(Property<List<String>> property, FileConfiguration configuration) {
|
||||
return configuration.contains(property.getPath()) && configuration.isList(property.getPath());
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean contains(Property<List<String>> property, FileConfiguration configuration) {
|
||||
return configuration.contains(property.getPath()) && configuration.isList(property.getPath());
|
||||
public String toYaml(List<String> value, Yaml simpleYaml, Yaml singleQuoteYaml) {
|
||||
String yaml = singleQuoteYaml.dump(value);
|
||||
// If the property is a non-empty list we need to append a new line because it will be
|
||||
// something like the following, which requires a new line:
|
||||
// - 'item 1'
|
||||
// - 'second item in list'
|
||||
return value.isEmpty() ? yaml : "\n" + yaml;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
@ -30,6 +30,10 @@ public class SecuritySettings implements SettingsClass {
|
||||
public static final Property<Boolean> REMOVE_PASSWORD_FROM_CONSOLE =
|
||||
newProperty("Security.console.removePassword", true);
|
||||
|
||||
@Comment("Copy AuthMe log output in a separate file as well?")
|
||||
public static final Property<Boolean> USE_LOGGING =
|
||||
newProperty("Security.console.logConsole", true);
|
||||
|
||||
@Comment("Player need to put a captcha when he fails too lot the password")
|
||||
public static final Property<Boolean> USE_CAPTCHA =
|
||||
newProperty("Security.captcha.useCaptcha", false);
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Comment;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
@ -12,9 +12,10 @@ import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class responsible for the retrieval of all {@link Property} fields via reflections.
|
||||
* Utility class responsible for retrieving all {@link Property} fields
|
||||
* from {@link SettingsClass} implementations via reflection.
|
||||
*/
|
||||
final class SettingsFieldRetriever {
|
||||
public final class SettingsFieldRetriever {
|
||||
|
||||
/** The classes to scan for properties. */
|
||||
private static final List<Class<? extends SettingsClass>> CONFIGURATION_CLASSES = Arrays.asList(
|
||||
@ -37,7 +38,7 @@ final class SettingsFieldRetriever {
|
||||
for (Class<?> clazz : CONFIGURATION_CLASSES) {
|
||||
Field[] declaredFields = clazz.getDeclaredFields();
|
||||
for (Field field : declaredFields) {
|
||||
Property property = getFieldIfRelevant(field);
|
||||
Property property = getPropertyField(field);
|
||||
if (property != null) {
|
||||
properties.put(property, getCommentsForField(field));
|
||||
}
|
||||
@ -53,7 +54,13 @@ final class SettingsFieldRetriever {
|
||||
return new String[0];
|
||||
}
|
||||
|
||||
private static Property<?> getFieldIfRelevant(Field field) {
|
||||
/**
|
||||
* Return the given field's value if it is a static {@link Property}.
|
||||
*
|
||||
* @param field The field's value to return
|
||||
* @return The property the field defines, or null if not applicable
|
||||
*/
|
||||
private static Property<?> getPropertyField(Field field) {
|
||||
field.setAccessible(true);
|
||||
if (field.isAccessible() && Property.class.equals(field.getType()) && Modifier.isStatic(field.getModifiers())) {
|
||||
try {
|
@ -52,11 +52,12 @@ public final class CollectionUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* @param <T> element
|
||||
* @param coll Collection
|
||||
* @return boolean Boolean
|
||||
* Null-safe way to check whether a collection is empty or not.
|
||||
*
|
||||
* @param coll The collection to verify
|
||||
* @return True if the collection is null or empty, false otherwise
|
||||
*/
|
||||
public static <T> boolean isEmpty(Collection<T> coll) {
|
||||
public static boolean isEmpty(Collection<?> coll) {
|
||||
return coll == null || coll.isEmpty();
|
||||
}
|
||||
|
||||
|
@ -4,6 +4,7 @@ import net.ricecode.similarity.LevenshteinDistanceStrategy;
|
||||
import net.ricecode.similarity.StringSimilarityService;
|
||||
import net.ricecode.similarity.StringSimilarityServiceImpl;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
|
||||
/**
|
||||
@ -37,12 +38,12 @@ public final class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether the given string contains any of the provided elements.
|
||||
* Return whether the given string contains any of the provided elements.
|
||||
*
|
||||
* @param str the string to analyze
|
||||
* @param pieces the items to check the string for
|
||||
* @param str The string to analyze
|
||||
* @param pieces The items to check the string for
|
||||
*
|
||||
* @return true if the string contains at least one of the items
|
||||
* @return True if the string contains at least one of the items
|
||||
*/
|
||||
public static boolean containsAny(String str, String... pieces) {
|
||||
if (str == null) {
|
||||
@ -60,21 +61,21 @@ public final class StringUtils {
|
||||
* Null-safe method for checking whether a string is empty. Note that the string
|
||||
* is trimmed, so this method also considers a string with whitespace as empty.
|
||||
*
|
||||
* @param str the string to verify
|
||||
* @param str The string to verify
|
||||
*
|
||||
* @return true if the string is empty, false otherwise
|
||||
* @return True if the string is empty, false otherwise
|
||||
*/
|
||||
public static boolean isEmpty(String str) {
|
||||
return str == null || str.trim().isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins a list of elements into a single string with the specified delimiter.
|
||||
* Join a list of elements into a single string with the specified delimiter.
|
||||
*
|
||||
* @param delimiter the delimiter to use
|
||||
* @param elements the elements to join
|
||||
* @param delimiter The delimiter to use
|
||||
* @param elements The elements to join
|
||||
*
|
||||
* @return a new String that is composed of the elements separated by the delimiter
|
||||
* @return A new String that is composed of the elements separated by the delimiter
|
||||
*/
|
||||
public static String join(String delimiter, Iterable<String> elements) {
|
||||
if (delimiter == null) {
|
||||
@ -95,12 +96,12 @@ public final class StringUtils {
|
||||
}
|
||||
|
||||
/**
|
||||
* Joins a list of elements into a single string with the specified delimiter.
|
||||
* Join a list of elements into a single string with the specified delimiter.
|
||||
*
|
||||
* @param delimiter the delimiter to use
|
||||
* @param elements the elements to join
|
||||
* @param delimiter The delimiter to use
|
||||
* @param elements The elements to join
|
||||
*
|
||||
* @return a new String that is composed of the elements separated by the delimiter
|
||||
* @return A new String that is composed of the elements separated by the delimiter
|
||||
*/
|
||||
public static String join(String delimiter, String... elements) {
|
||||
return join(delimiter, Arrays.asList(elements));
|
||||
@ -117,4 +118,15 @@ public final class StringUtils {
|
||||
return "[" + th.getClass().getSimpleName() + "]: " + th.getMessage();
|
||||
}
|
||||
|
||||
/**
|
||||
* Construct a file path from the given elements, i.e. separate the given elements by the file separator.
|
||||
*
|
||||
* @param elements The elements to create a path with
|
||||
*
|
||||
* @return The created path
|
||||
*/
|
||||
public static String makePath(String... elements) {
|
||||
return join(File.separator, elements);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -7,8 +7,10 @@ import fr.xephi.authme.cache.limbo.LimboCache;
|
||||
import fr.xephi.authme.cache.limbo.LimboPlayer;
|
||||
import fr.xephi.authme.events.AuthMeTeleportEvent;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.Location;
|
||||
import org.bukkit.World;
|
||||
@ -19,6 +21,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Utility class for various operations used in the codebase.
|
||||
@ -254,6 +257,30 @@ public final class Utils {
|
||||
}
|
||||
}
|
||||
|
||||
public static boolean isEmailCorrect(String email, NewSetting settings) {
|
||||
if (!email.contains("@") || "your@email.com".equalsIgnoreCase(email)) {
|
||||
return false;
|
||||
}
|
||||
final String emailDomain = email.split("@")[1];
|
||||
|
||||
List<String> whitelist = settings.getProperty(EmailSettings.DOMAIN_WHITELIST);
|
||||
if (!CollectionUtils.isEmpty(whitelist)) {
|
||||
return containsIgnoreCase(whitelist, emailDomain);
|
||||
}
|
||||
|
||||
List<String> blacklist = settings.getProperty(EmailSettings.DOMAIN_BLACKLIST);
|
||||
return CollectionUtils.isEmpty(blacklist) || !containsIgnoreCase(blacklist, emailDomain);
|
||||
}
|
||||
|
||||
private static boolean containsIgnoreCase(Collection<String> coll, String needle) {
|
||||
for (String entry : coll) {
|
||||
if (entry.equalsIgnoreCase(needle)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
*/
|
||||
public enum GroupType {
|
||||
|
@ -308,6 +308,8 @@ Security:
|
||||
noConsoleSpam: false
|
||||
# Replace passwords in the console when player type a command like /login
|
||||
removePassword: true
|
||||
# Copy AuthMe log output in a separate file as well?
|
||||
logConsole: true
|
||||
captcha:
|
||||
# Player need to put a captcha when he fails too lot the password
|
||||
useCaptcha: false
|
||||
|
3
src/main/resources/welcome.txt
Normal file
3
src/main/resources/welcome.txt
Normal file
@ -0,0 +1,3 @@
|
||||
Welcome {PLAYER} on {SERVER} server
|
||||
|
||||
This server uses AuthMeReloaded protection!
|
@ -0,0 +1,20 @@
|
||||
package fr.xephi.authme;
|
||||
|
||||
import org.mockito.Mockito;
|
||||
|
||||
import java.util.logging.Logger;
|
||||
|
||||
/**
|
||||
* Test initializer for {@link ConsoleLogger}.
|
||||
*/
|
||||
public class ConsoleLoggerTestInitializer {
|
||||
|
||||
private ConsoleLoggerTestInitializer() {
|
||||
}
|
||||
|
||||
public static Logger setupLogger() {
|
||||
Logger logger = Mockito.mock(Logger.class);
|
||||
ConsoleLogger.setLogger(logger);
|
||||
return logger;
|
||||
}
|
||||
}
|
@ -8,8 +8,8 @@ import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.settings.custom.NewSetting;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
@ -18,6 +18,7 @@ import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
@ -95,19 +96,6 @@ public class CommandServiceTest {
|
||||
verify(commandMapper).mapPartsToCommand(sender, commandParts);
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void shouldRunTaskInAsync() {
|
||||
// given
|
||||
Runnable runnable = mock(Runnable.class);
|
||||
|
||||
// when
|
||||
commandService.runTaskAsynchronously(runnable);
|
||||
|
||||
// then
|
||||
// TODO ljacqu 20151226: AuthMe#getServer() is final, i.e. not mockable
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetDataSource() {
|
||||
// given
|
||||
@ -193,10 +181,40 @@ public class CommandServiceTest {
|
||||
given(settings.getProperty(property)).willReturn(7);
|
||||
|
||||
// when
|
||||
int result = settings.getProperty(property);
|
||||
int result = commandService.getProperty(property);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(7));
|
||||
verify(settings).getProperty(property);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReloadMessages() {
|
||||
// given
|
||||
File file = new File("some/bogus-file.test");
|
||||
|
||||
// when
|
||||
commandService.reloadMessages(file);
|
||||
|
||||
// then
|
||||
verify(messages).reload(file);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnSettings() {
|
||||
// given/when
|
||||
NewSetting result = commandService.getSettings();
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(settings));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldReturnAuthMe() {
|
||||
// given/when
|
||||
AuthMe result = commandService.getAuthMe();
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(authMe));
|
||||
}
|
||||
}
|
||||
|
@ -5,7 +5,7 @@ import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.output.Messages;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.command.BlockCommandSender;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
@ -4,8 +4,8 @@ import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.settings.custom.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.custom.SecuritySettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.ChangePasswordTask;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.Server;
|
||||
|
@ -6,7 +6,6 @@ import fr.xephi.authme.command.FoundResultStatus;
|
||||
import fr.xephi.authme.command.TestCommandsUtil;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.permission.PlayerPermission;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.ChatColor;
|
||||
import org.bukkit.command.CommandSender;
|
||||
@ -40,22 +39,22 @@ import static org.mockito.Mockito.mock;
|
||||
*/
|
||||
public class HelpProviderTest {
|
||||
|
||||
private static final String HELP_HEADER = "Help";
|
||||
private static Set<CommandDescription> commands;
|
||||
private HelpProvider helpProvider;
|
||||
private PermissionsManager permissionsManager;
|
||||
private CommandSender sender;
|
||||
private static Set<CommandDescription> commands;
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpCommands() {
|
||||
WrapperMock.createInstance();
|
||||
Settings.helpHeader = "Help";
|
||||
commands = TestCommandsUtil.generateCommands();
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUpHelpProvider() {
|
||||
permissionsManager = mock(PermissionsManager.class);
|
||||
helpProvider = new HelpProvider(permissionsManager);
|
||||
helpProvider = new HelpProvider(permissionsManager, HELP_HEADER);
|
||||
sender = mock(CommandSender.class);
|
||||
}
|
||||
|
||||
@ -70,7 +69,7 @@ public class HelpProviderTest {
|
||||
|
||||
// then
|
||||
assertThat(lines, hasSize(5));
|
||||
assertThat(lines.get(0), containsString(Settings.helpHeader + " HELP"));
|
||||
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
|
||||
assertThat(removeColors(lines.get(1)), containsString("Command: /authme login <password>"));
|
||||
assertThat(removeColors(lines.get(2)), containsString("Short description: login cmd"));
|
||||
assertThat(removeColors(lines.get(3)), equalTo("Detailed description:"));
|
||||
@ -88,7 +87,7 @@ public class HelpProviderTest {
|
||||
|
||||
// then
|
||||
assertThat(lines, hasSize(4));
|
||||
assertThat(lines.get(0), containsString(Settings.helpHeader + " HELP"));
|
||||
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
|
||||
assertThat(removeColors(lines.get(1)), equalTo("Arguments:"));
|
||||
assertThat(removeColors(lines.get(2)), containsString("password: 'password' argument description"));
|
||||
assertThat(removeColors(lines.get(3)), containsString("confirmation: 'confirmation' argument description"));
|
||||
@ -279,7 +278,7 @@ public class HelpProviderTest {
|
||||
|
||||
// then
|
||||
assertThat(lines, hasSize(2));
|
||||
assertThat(lines.get(0), containsString(Settings.helpHeader + " HELP"));
|
||||
assertThat(lines.get(0), containsString(HELP_HEADER + " HELP"));
|
||||
assertThat(removeColors(lines.get(1)), containsString("Command: /authme register <password> <confirmation>"));
|
||||
}
|
||||
|
||||
|
@ -219,8 +219,8 @@ public class Log4JFilterTest {
|
||||
* Mocks a {@link Message} object and makes it return the given formatted message.
|
||||
*
|
||||
* @param formattedMessage the formatted message the mock should return
|
||||
|
||||
* @return Message mock */
|
||||
* @return Message mock
|
||||
*/
|
||||
private static Message mockMessage(String formattedMessage) {
|
||||
Message message = Mockito.mock(Message.class);
|
||||
when(message.getFormattedMessage()).thenReturn(formattedMessage);
|
||||
|
@ -1,10 +1,11 @@
|
||||
package fr.xephi.authme.output;
|
||||
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.ArgumentCaptor;
|
||||
import org.mockito.Mockito;
|
||||
@ -28,6 +29,12 @@ public class MessagesIntegrationTest {
|
||||
private static final String YML_TEST_FILE = "messages_test.yml";
|
||||
private Messages messages;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
WrapperMock.createInstance();
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the messages in the file {@code messages_test.yml} in the test resources folder.
|
||||
* The file does not contain all messages defined in {@link MessageKey} and its contents
|
||||
@ -35,17 +42,12 @@ public class MessagesIntegrationTest {
|
||||
*/
|
||||
@Before
|
||||
public void setUpMessages() {
|
||||
WrapperMock.createInstance();
|
||||
|
||||
Settings.messagesLanguage = "en";
|
||||
URL url = getClass().getClassLoader().getResource(YML_TEST_FILE);
|
||||
if (url == null) {
|
||||
throw new RuntimeException("File '" + YML_TEST_FILE + "' could not be loaded");
|
||||
}
|
||||
|
||||
Settings.messageFile = new File(url.getFile());
|
||||
Settings.messagesLanguage = "en";
|
||||
messages = Messages.getInstance();
|
||||
messages = new Messages(new File(url.getFile()));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.BeforeClass;
|
||||
@ -13,6 +14,7 @@ public class BcryptTest extends AbstractEncryptionMethodTest {
|
||||
public static void setUpSettings() {
|
||||
WrapperMock.createInstance();
|
||||
Settings.bCryptLog2Rounds = 8;
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
public BcryptTest() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package fr.xephi.authme.security.crypts;
|
||||
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.junit.BeforeClass;
|
||||
|
||||
@ -9,8 +10,9 @@ import org.junit.BeforeClass;
|
||||
public class XFBCRYPTTest extends AbstractEncryptionMethodTest {
|
||||
|
||||
@BeforeClass
|
||||
public static void setUpWrapper() {
|
||||
public static void setup() {
|
||||
WrapperMock.createInstance();
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
public XFBCRYPTTest() {
|
||||
|
@ -1,7 +1,7 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.SettingsFieldRetriever;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
import org.bukkit.configuration.MemorySection;
|
||||
@ -34,16 +34,14 @@ public class ConfigFileConsistencyTest {
|
||||
// given
|
||||
URL url = this.getClass().getResource(CONFIG_FILE);
|
||||
File configFile = new File(url.getFile());
|
||||
NewSetting settings = new NewSetting(YamlConfiguration.loadConfiguration(configFile), new File("bogus"), null);
|
||||
FileConfiguration configuration = YamlConfiguration.loadConfiguration(configFile);
|
||||
|
||||
// when
|
||||
boolean result = settings.containsAllSettings(SettingsFieldRetriever.getAllPropertyFields());
|
||||
boolean result = SettingsMigrationService.containsAllSettings(
|
||||
configuration, SettingsFieldRetriever.getAllPropertyFields());
|
||||
|
||||
// then
|
||||
if (!result) {
|
||||
FileConfiguration configuration =
|
||||
(FileConfiguration) ReflectionTestUtils.getFieldValue(NewSetting.class, settings, "configuration");
|
||||
|
||||
Set<String> knownProperties = getAllKnownPropertyPaths();
|
||||
List<String> missingProperties = new ArrayList<>();
|
||||
for (String path : knownProperties) {
|
@ -1,11 +1,13 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.TestConfiguration;
|
||||
import fr.xephi.authme.settings.properties.TestEnum;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import fr.xephi.authme.util.WrapperMock;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
@ -13,8 +15,10 @@ import java.lang.reflect.Field;
|
||||
import java.net.URL;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.junit.Assume.assumeThat;
|
||||
@ -28,40 +32,28 @@ public class NewSettingIntegrationTest {
|
||||
private static final String COMPLETE_FILE = "config-sample-values.yml";
|
||||
/** File name of the sample config missing certain {@link TestConfiguration} values. */
|
||||
private static final String INCOMPLETE_FILE = "config-incomplete-sample.yml";
|
||||
/** File name for testing difficult values. */
|
||||
private static final String DIFFICULT_FILE = "config-difficult-values.yml";
|
||||
|
||||
private static PropertyMap propertyMap;
|
||||
|
||||
@BeforeClass
|
||||
public static void generatePropertyMap() {
|
||||
propertyMap = new PropertyMap();
|
||||
for (Field field : TestConfiguration.class.getDeclaredFields()) {
|
||||
Object fieldValue = ReflectionTestUtils.getFieldValue(TestConfiguration.class, null, field.getName());
|
||||
if (fieldValue instanceof Property<?>) {
|
||||
Property<?> property = (Property<?>) fieldValue;
|
||||
String[] comments = new String[]{"Comment for '" + property.getPath() + "'"};
|
||||
propertyMap.put(property, comments);
|
||||
}
|
||||
}
|
||||
}
|
||||
private static PropertyMap propertyMap = generatePropertyMap();
|
||||
|
||||
@Test
|
||||
public void shouldLoadAndReadAllProperties() {
|
||||
// given
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(getConfigFile(COMPLETE_FILE));
|
||||
File file = new File("unused");
|
||||
assumeThat(file.exists(), equalTo(false));
|
||||
|
||||
// when / then
|
||||
NewSetting settings = new NewSetting(configuration, file, propertyMap);
|
||||
Map<Property<?>, Object> expectedValues = ImmutableMap.<Property<?>, Object>builder()
|
||||
.put(TestConfiguration.DURATION_IN_SECONDS, 22)
|
||||
.put(TestConfiguration.SYSTEM_NAME, "Custom sys name")
|
||||
.put(TestConfiguration.RATIO_LIMIT, -4.1)
|
||||
.put(TestConfiguration.RATIO_ORDER, TestEnum.FIRST)
|
||||
.put(TestConfiguration.RATIO_FIELDS, Arrays.asList("Australia", "Burundi", "Colombia"))
|
||||
.put(TestConfiguration.VERSION_NUMBER, 2492)
|
||||
.put(TestConfiguration.SKIP_BORING_FEATURES, false)
|
||||
.put(TestConfiguration.BORING_COLORS, Arrays.asList("beige", "gray"))
|
||||
.put(TestConfiguration.DUST_LEVEL, 0.81)
|
||||
.put(TestConfiguration.DUST_LEVEL, 2)
|
||||
.put(TestConfiguration.USE_COOL_FEATURES, true)
|
||||
.put(TestConfiguration.COOL_OPTIONS, Arrays.asList("Dinosaurs", "Explosions", "Big trucks"))
|
||||
.build();
|
||||
@ -89,12 +81,12 @@ public class NewSettingIntegrationTest {
|
||||
Map<Property<?>, Object> expectedValues = ImmutableMap.<Property<?>, Object>builder()
|
||||
.put(TestConfiguration.DURATION_IN_SECONDS, 22)
|
||||
.put(TestConfiguration.SYSTEM_NAME, "[TestDefaultValue]")
|
||||
.put(TestConfiguration.RATIO_LIMIT, 3.0)
|
||||
.put(TestConfiguration.RATIO_ORDER, TestEnum.SECOND)
|
||||
.put(TestConfiguration.RATIO_FIELDS, Arrays.asList("Australia", "Burundi", "Colombia"))
|
||||
.put(TestConfiguration.VERSION_NUMBER, 32046)
|
||||
.put(TestConfiguration.SKIP_BORING_FEATURES, false)
|
||||
.put(TestConfiguration.BORING_COLORS, Collections.EMPTY_LIST)
|
||||
.put(TestConfiguration.DUST_LEVEL, 0.2)
|
||||
.put(TestConfiguration.DUST_LEVEL, -1)
|
||||
.put(TestConfiguration.USE_COOL_FEATURES, false)
|
||||
.put(TestConfiguration.COOL_OPTIONS, Arrays.asList("Dinosaurs", "Explosions", "Big trucks"))
|
||||
.build();
|
||||
@ -104,6 +96,62 @@ public class NewSettingIntegrationTest {
|
||||
}
|
||||
}
|
||||
|
||||
/** Verify that "difficult cases" such as apostrophes in strings etc. are handled properly. */
|
||||
@Test
|
||||
public void shouldProperlyExportAnyValues() {
|
||||
// given
|
||||
File file = getConfigFile(DIFFICULT_FILE);
|
||||
YamlConfiguration configuration = YamlConfiguration.loadConfiguration(file);
|
||||
assumeThat(configuration.contains(TestConfiguration.DUST_LEVEL.getPath()), equalTo(false));
|
||||
|
||||
// Additional string properties
|
||||
List<Property<String>> additionalProperties = Arrays.asList(
|
||||
newProperty("more.string1", "it's a text with some \\'apostrophes'"),
|
||||
newProperty("more.string2", "\tthis one\nhas some\nnew '' lines-test")
|
||||
);
|
||||
PropertyMap propertyMap = generatePropertyMap();
|
||||
for (Property<?> property : additionalProperties) {
|
||||
propertyMap.put(property, new String[0]);
|
||||
}
|
||||
|
||||
// when
|
||||
new NewSetting(configuration, file, propertyMap);
|
||||
// reload the file as settings should hav been rewritten
|
||||
configuration = YamlConfiguration.loadConfiguration(file);
|
||||
|
||||
// then
|
||||
// assert that we won't rewrite the settings again! One rewrite should produce a valid, complete configuration
|
||||
File unusedFile = new File("config-difficult-values.unused.yml");
|
||||
NewSetting settings = new NewSetting(configuration, unusedFile, propertyMap);
|
||||
assertThat(unusedFile.exists(), equalTo(false));
|
||||
assertThat(configuration.contains(TestConfiguration.DUST_LEVEL.getPath()), equalTo(true));
|
||||
|
||||
Map<Property<?>, Object> expectedValues = ImmutableMap.<Property<?>, Object>builder()
|
||||
.put(TestConfiguration.DURATION_IN_SECONDS, 20)
|
||||
.put(TestConfiguration.SYSTEM_NAME, "A 'test' name")
|
||||
.put(TestConfiguration.RATIO_ORDER, TestEnum.FOURTH)
|
||||
.put(TestConfiguration.RATIO_FIELDS, Arrays.asList("Australia\\", "\tBurundi'", "Colombia?\n''"))
|
||||
.put(TestConfiguration.VERSION_NUMBER, -1337)
|
||||
.put(TestConfiguration.SKIP_BORING_FEATURES, false)
|
||||
.put(TestConfiguration.BORING_COLORS, Arrays.asList("it's a difficult string!", "gray\nwith new lines\n"))
|
||||
.put(TestConfiguration.DUST_LEVEL, -1)
|
||||
.put(TestConfiguration.USE_COOL_FEATURES, true)
|
||||
.put(TestConfiguration.COOL_OPTIONS, Collections.EMPTY_LIST)
|
||||
.put(additionalProperties.get(0), additionalProperties.get(0).getDefaultValue())
|
||||
.put(additionalProperties.get(1), additionalProperties.get(1).getDefaultValue())
|
||||
.build();
|
||||
for (Map.Entry<Property<?>, Object> entry : expectedValues.entrySet()) {
|
||||
assertThat("Property '" + entry.getKey().getPath() + "' has expected value"
|
||||
+ entry.getValue() + " but found " + settings.getProperty(entry.getKey()),
|
||||
settings.getProperty(entry.getKey()), equalTo(entry.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a {@link File} instance to an existing file in the target/test-classes folder.
|
||||
*
|
||||
* @return The generated File
|
||||
*/
|
||||
private File getConfigFile(String file) {
|
||||
URL url = getClass().getClassLoader().getResource(file);
|
||||
if (url == null) {
|
||||
@ -112,4 +160,23 @@ public class NewSettingIntegrationTest {
|
||||
return new File(url.getFile());
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a property map with all properties in {@link TestConfiguration}.
|
||||
*
|
||||
* @return The generated property map
|
||||
*/
|
||||
private static PropertyMap generatePropertyMap() {
|
||||
WrapperMock.createInstance();
|
||||
PropertyMap propertyMap = new PropertyMap();
|
||||
for (Field field : TestConfiguration.class.getDeclaredFields()) {
|
||||
Object fieldValue = ReflectionTestUtils.getFieldValue(TestConfiguration.class, null, field.getName());
|
||||
if (fieldValue instanceof Property<?>) {
|
||||
Property<?> property = (Property<?>) fieldValue;
|
||||
String[] comments = new String[]{"Comment for '" + property.getPath() + "'"};
|
||||
propertyMap.put(property, comments);
|
||||
}
|
||||
}
|
||||
return propertyMap;
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,9 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.TestConfiguration;
|
||||
import fr.xephi.authme.settings.properties.TestEnum;
|
||||
import fr.xephi.authme.settings.propertymap.PropertyMap;
|
||||
import org.bukkit.configuration.file.YamlConfiguration;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@ -35,15 +38,15 @@ public class NewSettingTest {
|
||||
|
||||
setReturnValue(file, TestConfiguration.VERSION_NUMBER, 20);
|
||||
setReturnValue(file, TestConfiguration.SKIP_BORING_FEATURES, true);
|
||||
setReturnValue(file, TestConfiguration.RATIO_LIMIT, 4.25);
|
||||
setReturnValue(file, TestConfiguration.RATIO_ORDER, TestEnum.THIRD);
|
||||
setReturnValue(file, TestConfiguration.SYSTEM_NAME, "myTestSys");
|
||||
|
||||
// when / then
|
||||
NewSetting settings = new NewSetting(file, new File("conf.txt"), null);
|
||||
NewSetting settings = new NewSetting(file, new File("conf.txt"), (PropertyMap) null);
|
||||
|
||||
assertThat(settings.getProperty(TestConfiguration.VERSION_NUMBER), equalTo(20));
|
||||
assertThat(settings.getProperty(TestConfiguration.SKIP_BORING_FEATURES), equalTo(true));
|
||||
assertThat(settings.getProperty(TestConfiguration.RATIO_LIMIT), equalTo(4.25));
|
||||
assertThat(settings.getProperty(TestConfiguration.RATIO_ORDER), equalTo(TestEnum.THIRD));
|
||||
assertThat(settings.getProperty(TestConfiguration.SYSTEM_NAME), equalTo("myTestSys"));
|
||||
|
||||
assertDefaultValue(TestConfiguration.DURATION_IN_SECONDS, settings);
|
||||
@ -58,8 +61,8 @@ public class NewSettingTest {
|
||||
when(config.getInt(eq(property.getPath()), anyInt())).thenReturn((Integer) value);
|
||||
} else if (value instanceof Boolean) {
|
||||
when(config.getBoolean(eq(property.getPath()), anyBoolean())).thenReturn((Boolean) value);
|
||||
} else if (value instanceof Double) {
|
||||
when(config.getDouble(eq(property.getPath()), anyDouble())).thenReturn((Double) value);
|
||||
} else if (value instanceof Enum<?>) {
|
||||
when(config.getString(property.getPath())).thenReturn(((Enum<?>) value).name());
|
||||
} else {
|
||||
throw new UnsupportedOperationException("Value has unsupported type '"
|
||||
+ (value == null ? "null" : value.getClass().getSimpleName()) + "'");
|
@ -13,7 +13,6 @@ import static org.hamcrest.MatcherAssert.assertThat;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.mockito.Matchers.anyBoolean;
|
||||
import static org.mockito.Matchers.anyDouble;
|
||||
import static org.mockito.Matchers.anyInt;
|
||||
import static org.mockito.Matchers.anyString;
|
||||
import static org.mockito.Matchers.eq;
|
||||
@ -33,8 +32,6 @@ public class PropertyTypeTest {
|
||||
|
||||
when(configuration.getBoolean(eq("bool.path.test"), anyBoolean())).thenReturn(true);
|
||||
when(configuration.getBoolean(eq("bool.path.wrong"), anyBoolean())).thenAnswer(secondParameter());
|
||||
when(configuration.getDouble(eq("double.path.test"), anyDouble())).thenReturn(-6.4);
|
||||
when(configuration.getDouble(eq("double.path.wrong"), anyDouble())).thenAnswer(secondParameter());
|
||||
when(configuration.getInt(eq("int.path.test"), anyInt())).thenReturn(27);
|
||||
when(configuration.getInt(eq("int.path.wrong"), anyInt())).thenAnswer(secondParameter());
|
||||
when(configuration.getString(eq("str.path.test"), anyString())).thenReturn("Test value");
|
||||
@ -69,31 +66,6 @@ public class PropertyTypeTest {
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
/* Double */
|
||||
@Test
|
||||
public void shouldGetDoubleValue() {
|
||||
// given
|
||||
Property<Double> property = Property.newProperty(PropertyType.DOUBLE, "double.path.test", 3.8);
|
||||
|
||||
// when
|
||||
double result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(-6.4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetDoubleDefault() {
|
||||
// given
|
||||
Property<Double> property = Property.newProperty(PropertyType.DOUBLE, "double.path.wrong", 12.0);
|
||||
|
||||
// when
|
||||
double result = property.getFromFile(configuration);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(12.0));
|
||||
}
|
||||
|
||||
/* Integer */
|
||||
@Test
|
||||
public void shouldGetIntValue() {
|
||||
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
@ -25,7 +25,7 @@ import static org.junit.Assert.fail;
|
||||
*/
|
||||
public class SettingsClassConsistencyTest {
|
||||
|
||||
private static final String SETTINGS_FOLDER = "src/main/java/fr/xephi/authme/settings/custom";
|
||||
private static final String SETTINGS_FOLDER = "src/main/java/fr/xephi/authme/settings/properties";
|
||||
private static List<Class<? extends SettingsClass>> classes;
|
||||
|
||||
@BeforeClass
|
@ -1,4 +1,4 @@
|
||||
package fr.xephi.authme.settings.custom;
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.domain.PropertyType;
|
||||
@ -11,7 +11,7 @@ import static fr.xephi.authme.settings.domain.Property.newProperty;
|
||||
/**
|
||||
* Sample properties for testing purposes.
|
||||
*/
|
||||
class TestConfiguration implements SettingsClass {
|
||||
public final class TestConfiguration implements SettingsClass {
|
||||
|
||||
public static final Property<Integer> DURATION_IN_SECONDS =
|
||||
newProperty("test.duration", 4);
|
||||
@ -19,8 +19,8 @@ class TestConfiguration implements SettingsClass {
|
||||
public static final Property<String> SYSTEM_NAME =
|
||||
newProperty("test.systemName", "[TestDefaultValue]");
|
||||
|
||||
public static final Property<Double> RATIO_LIMIT =
|
||||
newProperty(PropertyType.DOUBLE, "sample.ratio.limit", 3.0);
|
||||
public static final Property<TestEnum> RATIO_ORDER =
|
||||
newProperty(TestEnum.class, "sample.ratio.order", TestEnum.SECOND);
|
||||
|
||||
public static final Property<List<String>> RATIO_FIELDS =
|
||||
newProperty(PropertyType.STRING_LIST, "sample.ratio.fields", "a", "b", "c");
|
||||
@ -34,8 +34,8 @@ class TestConfiguration implements SettingsClass {
|
||||
public static final Property<List<String>> BORING_COLORS =
|
||||
newProperty(PropertyType.STRING_LIST, "features.boring.colors");
|
||||
|
||||
public static final Property<Double> DUST_LEVEL =
|
||||
newProperty(PropertyType.DOUBLE, "features.boring.dustLevel", 0.2);
|
||||
public static final Property<Integer> DUST_LEVEL =
|
||||
newProperty(PropertyType.INTEGER, "features.boring.dustLevel", -1);
|
||||
|
||||
public static final Property<Boolean> USE_COOL_FEATURES =
|
||||
newProperty("features.cool.enabled", false);
|
||||
@ -43,4 +43,8 @@ class TestConfiguration implements SettingsClass {
|
||||
public static final Property<List<String>> COOL_OPTIONS =
|
||||
newProperty(PropertyType.STRING_LIST, "features.cool.options", "Sparks", "Sprinkles");
|
||||
|
||||
|
||||
private TestConfiguration() {
|
||||
}
|
||||
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
package fr.xephi.authme.settings.properties;
|
||||
|
||||
/**
|
||||
* Test enum used in {@link TestConfiguration}.
|
||||
*/
|
||||
public enum TestEnum {
|
||||
|
||||
FIRST,
|
||||
|
||||
SECOND,
|
||||
|
||||
THIRD,
|
||||
|
||||
FOURTH
|
||||
|
||||
}
|
@ -2,6 +2,7 @@ package fr.xephi.authme.util;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import java.io.File;
|
||||
import java.net.MalformedURLException;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
@ -135,4 +136,13 @@ public class StringUtilsTest {
|
||||
assertThat(StringUtils.getDifference("test", "bear"), equalTo(0.75));
|
||||
assertThat(StringUtils.getDifference("test", "something"), greaterThan(0.88));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldConstructPath() {
|
||||
// given/when
|
||||
String result = StringUtils.makePath("path", "to", "test-file.txt");
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo("path" + File.separator + "to" + File.separator + "test-file.txt"));
|
||||
}
|
||||
}
|
||||
|
@ -1,16 +1,21 @@
|
||||
package fr.xephi.authme.util;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLoggerTestInitializer;
|
||||
import fr.xephi.authme.ReflectionTestUtils;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import org.bukkit.entity.Player;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
@ -35,6 +40,7 @@ public class UtilsTest {
|
||||
public static void setUpMocks() {
|
||||
WrapperMock wrapperMock = WrapperMock.createInstance();
|
||||
authMeMock = wrapperMock.getAuthMe();
|
||||
ConsoleLoggerTestInitializer.setupLogger();
|
||||
}
|
||||
|
||||
@Before
|
||||
@ -92,6 +98,95 @@ public class UtilsTest {
|
||||
assertThat(players, hasSize(2));
|
||||
}
|
||||
|
||||
// ----------------
|
||||
// Tests for Utils#isEmailCorrect()
|
||||
// ----------------
|
||||
@Test
|
||||
public void shouldAcceptEmailWithEmptyLists() {
|
||||
// given
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.EMPTY_LIST);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.EMPTY_LIST);
|
||||
|
||||
// when
|
||||
boolean result = Utils.isEmailCorrect("test@example.org", settings);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptEmailWithWhitelist() {
|
||||
// given
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
|
||||
.willReturn(Arrays.asList("domain.tld", "example.com"));
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.EMPTY_LIST);
|
||||
|
||||
// when
|
||||
boolean result = Utils.isEmailCorrect("TesT@Example.com", settings);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectEmailNotInWhitelist() {
|
||||
// given
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST))
|
||||
.willReturn(Arrays.asList("domain.tld", "example.com"));
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST)).willReturn(Collections.EMPTY_LIST);
|
||||
|
||||
// when
|
||||
boolean result = Utils.isEmailCorrect("email@other-domain.abc", settings);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldAcceptEmailNotInBlacklist() {
|
||||
// given
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.EMPTY_LIST);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
|
||||
.willReturn(Arrays.asList("Example.org", "a-test-name.tld"));
|
||||
|
||||
// when
|
||||
boolean result = Utils.isEmailCorrect("sample@valid-name.tld", settings);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectEmailInBlacklist() {
|
||||
// given
|
||||
NewSetting settings = mock(NewSetting.class);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_WHITELIST)).willReturn(Collections.EMPTY_LIST);
|
||||
given(settings.getProperty(EmailSettings.DOMAIN_BLACKLIST))
|
||||
.willReturn(Arrays.asList("Example.org", "a-test-name.tld"));
|
||||
|
||||
// when
|
||||
boolean result = Utils.isEmailCorrect("sample@a-Test-name.tld", settings);
|
||||
|
||||
// then
|
||||
assertThat(result, equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectInvalidEmail() {
|
||||
// given/when/then
|
||||
assertThat(Utils.isEmailCorrect("invalidinput", mock(NewSetting.class)), equalTo(false));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRejectDefaultEmail() {
|
||||
// given/when/then
|
||||
assertThat(Utils.isEmailCorrect("your@email.com", mock(NewSetting.class)), equalTo(false));
|
||||
}
|
||||
|
||||
// Note: This method is used through reflections
|
||||
public static Player[] onlinePlayersImpl() {
|
||||
return new Player[]{
|
||||
|
29
src/test/resources/config-difficult-values.yml
Normal file
29
src/test/resources/config-difficult-values.yml
Normal file
@ -0,0 +1,29 @@
|
||||
# Test config file with some "difficult" values
|
||||
|
||||
test:
|
||||
duration: 20.102
|
||||
systemName: 'A ''test'' name'
|
||||
sample:
|
||||
ratio:
|
||||
order: Fourth
|
||||
fields:
|
||||
- Australia\
|
||||
- ' Burundi'''
|
||||
- 'Colombia?
|
||||
|
||||
'''''
|
||||
# The last element above represents "Colombia?\n''"
|
||||
version: -1337
|
||||
features:
|
||||
boring:
|
||||
# YAML allows both "yes"/"no" and "true"/"false" for expressing booleans
|
||||
skip: no
|
||||
colors:
|
||||
- 'it''s a difficult string!'
|
||||
- |
|
||||
gray
|
||||
with new lines
|
||||
# dustLevel: 8 <-- missing property triggering rewrite
|
||||
cool:
|
||||
enabled: yes
|
||||
options: []
|
@ -6,7 +6,7 @@ test:
|
||||
# systemName: 'Custom sys name'
|
||||
sample:
|
||||
ratio:
|
||||
# limit: 3.0
|
||||
# order: 'THIRD'
|
||||
fields:
|
||||
- 'Australia'
|
||||
- 'Burundi'
|
||||
@ -18,7 +18,7 @@ features:
|
||||
# colors:
|
||||
# - 'beige'
|
||||
# - 'gray'
|
||||
# dustLevel: 0.81
|
||||
# dustLevel: 1
|
||||
cool:
|
||||
# enabled: true
|
||||
options:
|
||||
|
@ -6,7 +6,7 @@ test:
|
||||
systemName: 'Custom sys name'
|
||||
sample:
|
||||
ratio:
|
||||
limit: -4.1
|
||||
order: 'first'
|
||||
fields:
|
||||
- 'Australia'
|
||||
- 'Burundi'
|
||||
@ -18,7 +18,7 @@ features:
|
||||
colors:
|
||||
- 'beige'
|
||||
- 'gray'
|
||||
dustLevel: 0.81
|
||||
dustLevel: 2
|
||||
cool:
|
||||
enabled: true
|
||||
options:
|
||||
|
Loading…
Reference in New Issue
Block a user