mirror of
https://github.com/AuthMe/AuthMeReloaded.git
synced 2024-12-28 03:27:34 +01:00
Merge remote-tracking branch 'origin/master' into jsoncache-fix
Conflicts: src/main/java/fr/xephi/authme/settings/Settings.java
This commit is contained in:
commit
7ea0763966
@ -26,7 +26,6 @@ import fr.xephi.authme.listener.AuthMePlayerListener;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener16;
|
||||
import fr.xephi.authme.listener.AuthMePlayerListener18;
|
||||
import fr.xephi.authme.listener.AuthMeServerListener;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.ConsoleFilter;
|
||||
import fr.xephi.authme.output.Log4JFilter;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
@ -80,8 +79,6 @@ import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
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.EmailSettings.RECALL_PLAYERS;
|
||||
|
||||
/**
|
||||
@ -115,7 +112,6 @@ public class AuthMe extends JavaPlugin {
|
||||
private BukkitService bukkitService;
|
||||
private AuthMeServiceInitializer initializer;
|
||||
private GeoLiteAPI geoLiteApi;
|
||||
private SendMailSSL mail;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@ -249,9 +245,6 @@ public class AuthMe extends JavaPlugin {
|
||||
// Set console filter
|
||||
setupConsoleFilter();
|
||||
|
||||
// Set up the mail API
|
||||
setupMailApi();
|
||||
|
||||
// Do a backup on start
|
||||
// TODO: maybe create a backup manager?
|
||||
new PerformBackup(this, newSettings).doBackup(PerformBackup.BackupCause.START);
|
||||
@ -304,16 +297,6 @@ public class AuthMe extends JavaPlugin {
|
||||
initializer.get(API.class);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set up the mail API, if enabled.
|
||||
*/
|
||||
private void setupMailApi() {
|
||||
// Make sure the mail API is enabled
|
||||
if (!newSettings.getProperty(MAIL_ACCOUNT).isEmpty() && !newSettings.getProperty(MAIL_PASSWORD).isEmpty()) {
|
||||
this.mail = new SendMailSSL(this, newSettings);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the settings warnings, for various risky settings.
|
||||
*/
|
||||
@ -687,15 +670,6 @@ public class AuthMe extends JavaPlugin {
|
||||
return commandHandler.processCommand(sender, commandLabel, args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the mailing instance.
|
||||
*
|
||||
* @return The send mail instance.
|
||||
*/
|
||||
public SendMailSSL getMail() {
|
||||
return this.mail;
|
||||
}
|
||||
|
||||
// -------------
|
||||
// Service getters (deprecated)
|
||||
// Use @Inject fields instead
|
||||
|
@ -53,6 +53,16 @@ public class CommandService {
|
||||
return messages.retrieve(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve a message as a single String by its message key.
|
||||
*
|
||||
* @param key The message to retrieve
|
||||
* @return The message
|
||||
*/
|
||||
public String retrieveSingle(MessageKey key) {
|
||||
return messages.retrieveSingle(key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the given property's value.
|
||||
*
|
||||
|
@ -75,7 +75,7 @@ public class ChangePasswordAdminCommand implements ExecutableCommand {
|
||||
|
||||
if (dataSource.updatePassword(auth)) {
|
||||
commandService.send(sender, MessageKey.PASSWORD_CHANGED_SUCCESS);
|
||||
ConsoleLogger.info(playerNameLowerCase + "'s password changed");
|
||||
ConsoleLogger.info(sender.getName() + " changed password of " + playerNameLowerCase);
|
||||
} else {
|
||||
commandService.send(sender, MessageKey.ERROR);
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
package fr.xephi.authme.command.executable.authme;
|
||||
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.ExecutableCommand;
|
||||
import fr.xephi.authme.converter.Converter;
|
||||
@ -51,7 +52,11 @@ public class ConverterCommand implements ExecutableCommand {
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
converter.execute(sender);
|
||||
try {
|
||||
converter.execute(sender);
|
||||
} catch (Exception e) {
|
||||
ConsoleLogger.logException("Error during conversion:", e);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
|
@ -79,7 +79,7 @@ public class RegisterAdminCommand implements ExecutableCommand {
|
||||
bukkitService.scheduleSyncDelayedTask(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
player.kickPlayer("An admin just registered you, please log in again");
|
||||
player.kickPlayer(commandService.retrieveSingle(MessageKey.KICK_FOR_ADMIN_REGISTER));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
package fr.xephi.authme.command.executable.email;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.security.PasswordSecurity;
|
||||
import fr.xephi.authme.security.RandomString;
|
||||
@ -33,17 +33,16 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
private PlayerCache playerCache;
|
||||
|
||||
@Inject
|
||||
// TODO #655: Remove injected AuthMe instance once Authme#mail is encapsulated
|
||||
private AuthMe plugin;
|
||||
private SendMailSSL sendMailSsl;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
final String playerMail = arguments.get(0);
|
||||
final String playerName = player.getName();
|
||||
|
||||
if (plugin.getMail() == null) {
|
||||
if (!sendMailSsl.hasAllInformation()) {
|
||||
ConsoleLogger.showError("Mail API is not set");
|
||||
commandService.send(player, MessageKey.ERROR);
|
||||
commandService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
|
||||
return;
|
||||
}
|
||||
if (dataSource.isAuthAvailable(playerName)) {
|
||||
@ -76,7 +75,7 @@ public class RecoverEmailCommand extends PlayerCommand {
|
||||
}
|
||||
auth.setPassword(hashNew);
|
||||
dataSource.updatePassword(auth);
|
||||
plugin.getMail().main(auth, thePass);
|
||||
sendMailSsl.sendPasswordMail(auth, thePass);
|
||||
commandService.send(player, MessageKey.RECOVERY_EMAIL_SENT_MESSAGE);
|
||||
} else {
|
||||
commandService.send(player, MessageKey.REGISTER_EMAIL_MESSAGE);
|
||||
|
@ -3,6 +3,7 @@ package fr.xephi.authme.command.executable.register;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.command.PlayerCommand;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
@ -14,6 +15,7 @@ import org.bukkit.entity.Player;
|
||||
import javax.inject.Inject;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.output.MessageKey.INCOMPLETE_EMAIL_SETTINGS;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.RECOVERY_PASSWORD_LENGTH;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.ENABLE_CONFIRM_EMAIL;
|
||||
import static fr.xephi.authme.settings.properties.RegistrationSettings.USE_EMAIL_REGISTRATION;
|
||||
@ -27,6 +29,9 @@ public class RegisterCommand extends PlayerCommand {
|
||||
@Inject
|
||||
private CommandService commandService;
|
||||
|
||||
@Inject
|
||||
private SendMailSSL sendMailSsl;
|
||||
|
||||
@Override
|
||||
public void runCommand(Player player, List<String> arguments) {
|
||||
if (commandService.getProperty(SecuritySettings.PASSWORD_HASH) == HashAlgorithm.TWO_FACTOR) {
|
||||
@ -63,11 +68,10 @@ public class RegisterCommand extends PlayerCommand {
|
||||
}
|
||||
|
||||
private void handleEmailRegistration(Player player, List<String> arguments) {
|
||||
if (commandService.getProperty(EmailSettings.MAIL_ACCOUNT).isEmpty()) {
|
||||
player.sendMessage("Cannot register: no email address is set for the server. "
|
||||
+ "Please contact an administrator");
|
||||
ConsoleLogger.showError("Cannot register player '" + player.getName() + "': no email is set "
|
||||
+ "to send emails from. Please add one in your config at " + EmailSettings.MAIL_ACCOUNT.getPath());
|
||||
if (!sendMailSsl.hasAllInformation()) {
|
||||
commandService.send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
|
||||
ConsoleLogger.showError("Cannot register player '" + player.getName() + "': no email or password is set "
|
||||
+ "to send emails from. Please adjust your config at " + EmailSettings.MAIL_ACCOUNT.getPath());
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -1,28 +1,77 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
|
||||
public class vAuthConverter implements Converter {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final DataSource dataSource;
|
||||
private final File vAuthPasswordsFile;
|
||||
|
||||
@Inject
|
||||
vAuthConverter(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
vAuthConverter(@DataFolder File dataFolder, DataSource dataSource) {
|
||||
vAuthPasswordsFile = new File(dataFolder.getParent(), makePath("vAuth", "passwords.yml"));
|
||||
this.dataSource = dataSource;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
try {
|
||||
new vAuthFileReader(plugin).convert();
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage(e.getMessage());
|
||||
ConsoleLogger.showError(e.getMessage());
|
||||
try (Scanner scanner = new Scanner(vAuthPasswordsFile)) {
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
String name = line.split(": ")[0];
|
||||
String password = line.split(": ")[1];
|
||||
PlayerAuth auth;
|
||||
if (isUuidInstance(password)) {
|
||||
String pname;
|
||||
try {
|
||||
pname = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName();
|
||||
} catch (Exception | NoSuchMethodError e) {
|
||||
pname = getName(UUID.fromString(name));
|
||||
}
|
||||
if (pname == null)
|
||||
continue;
|
||||
auth = PlayerAuth.builder()
|
||||
.name(pname.toLowerCase())
|
||||
.realName(pname)
|
||||
.password(password, null).build();
|
||||
} else {
|
||||
auth = PlayerAuth.builder()
|
||||
.name(name.toLowerCase())
|
||||
.realName(name)
|
||||
.password(password, null).build();
|
||||
}
|
||||
dataSource.saveAuth(auth);
|
||||
}
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Error while trying to import some vAuth data", e);
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isUuidInstance(String s) {
|
||||
return s.length() > 8 && s.charAt(8) == '-';
|
||||
}
|
||||
|
||||
private String getName(UUID uuid) {
|
||||
for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {
|
||||
if (op.getUniqueId().compareTo(uuid) == 0) {
|
||||
return op.getName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,83 +0,0 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.OfflinePlayer;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.util.Scanner;
|
||||
import java.util.UUID;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
|
||||
class vAuthFileReader {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final DataSource database;
|
||||
|
||||
/**
|
||||
* Constructor for vAuthFileReader.
|
||||
*
|
||||
* @param plugin AuthMe
|
||||
*/
|
||||
public vAuthFileReader(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
this.database = plugin.getDataSource();
|
||||
}
|
||||
|
||||
public void convert() {
|
||||
final File file = new File(plugin.getDataFolder().getParent(), makePath("vAuth", "passwords.yml"));
|
||||
Scanner scanner;
|
||||
try {
|
||||
scanner = new Scanner(file);
|
||||
while (scanner.hasNextLine()) {
|
||||
String line = scanner.nextLine();
|
||||
String name = line.split(": ")[0];
|
||||
String password = line.split(": ")[1];
|
||||
PlayerAuth auth;
|
||||
if (isUuidInstance(password)) {
|
||||
String pname;
|
||||
try {
|
||||
pname = Bukkit.getOfflinePlayer(UUID.fromString(name)).getName();
|
||||
} catch (Exception | NoSuchMethodError e) {
|
||||
pname = getName(UUID.fromString(name));
|
||||
}
|
||||
if (pname == null)
|
||||
continue;
|
||||
auth = PlayerAuth.builder()
|
||||
.name(pname.toLowerCase())
|
||||
.realName(pname)
|
||||
.password(password, null).build();
|
||||
} else {
|
||||
auth = PlayerAuth.builder()
|
||||
.name(name.toLowerCase())
|
||||
.realName(name)
|
||||
.password(password, null).build();
|
||||
}
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
scanner.close();
|
||||
} catch (IOException e) {
|
||||
ConsoleLogger.logException("Error while trying to import some vAuth data", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static boolean isUuidInstance(String s) {
|
||||
return s.length() > 8 && s.charAt(8) == '-';
|
||||
}
|
||||
|
||||
private String getName(UUID uuid) {
|
||||
for (OfflinePlayer op : Bukkit.getOfflinePlayers()) {
|
||||
if (op.getUniqueId().compareTo(uuid) == 0) {
|
||||
return op.getName();
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
}
|
@ -1,28 +1,146 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import de.luricos.bukkit.xAuth.database.DatabaseTables;
|
||||
import de.luricos.bukkit.xAuth.utils.xAuthLog;
|
||||
import de.luricos.bukkit.xAuth.xAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.initialization.DataFolder;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
import org.bukkit.plugin.PluginManager;
|
||||
|
||||
import javax.inject.Inject;
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static fr.xephi.authme.util.StringUtils.makePath;
|
||||
|
||||
public class xAuthConverter implements Converter {
|
||||
|
||||
private final AuthMe plugin;
|
||||
|
||||
@Inject
|
||||
xAuthConverter(AuthMe plugin) {
|
||||
this.plugin = plugin;
|
||||
@DataFolder
|
||||
private File dataFolder;
|
||||
@Inject
|
||||
private DataSource database;
|
||||
@Inject
|
||||
private PluginManager pluginManager;
|
||||
|
||||
xAuthConverter() {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(CommandSender sender) {
|
||||
try {
|
||||
Class.forName("de.luricos.bukkit.xAuth.xAuth");
|
||||
xAuthToFlat converter = new xAuthToFlat(plugin, sender);
|
||||
converter.convert();
|
||||
convert(sender);
|
||||
} catch (ClassNotFoundException ce) {
|
||||
sender.sendMessage("xAuth has not been found, please put xAuth.jar in your plugin folder and restart!");
|
||||
}
|
||||
}
|
||||
|
||||
private void convert(CommandSender sender) {
|
||||
if (pluginManager.getPlugin("xAuth") == null) {
|
||||
sender.sendMessage("[AuthMe] xAuth plugin not found");
|
||||
return;
|
||||
}
|
||||
// TODO ljacqu 20160702: xAuthDb is not used except for the existence check -- is this intended?
|
||||
File xAuthDb = new File(dataFolder.getParent(), makePath("xAuth", "xAuth.h2.db"));
|
||||
if (!xAuthDb.exists()) {
|
||||
sender.sendMessage("[AuthMe] xAuth H2 database not found, checking for MySQL or SQLite data...");
|
||||
}
|
||||
List<Integer> players = getXAuthPlayers();
|
||||
if (CollectionUtils.isEmpty(players)) {
|
||||
sender.sendMessage("[AuthMe] Error while importing xAuthPlayers: did not find any players");
|
||||
return;
|
||||
}
|
||||
sender.sendMessage("[AuthMe] Starting import...");
|
||||
|
||||
for (int id : players) {
|
||||
String pl = getIdPlayer(id);
|
||||
String psw = getPassword(id);
|
||||
if (psw != null && !psw.isEmpty() && pl != null) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(pl.toLowerCase())
|
||||
.realName(pl)
|
||||
.password(psw, null).build();
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
}
|
||||
sender.sendMessage("[AuthMe] Successfully converted from xAuth database");
|
||||
}
|
||||
|
||||
private String getIdPlayer(int id) {
|
||||
String realPass = "";
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `playername` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, id);
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next())
|
||||
return null;
|
||||
realPass = rs.getString("playername").toLowerCase();
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve name for account: " + id, e);
|
||||
return null;
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return realPass;
|
||||
}
|
||||
|
||||
private List<Integer> getXAuthPlayers() {
|
||||
List<Integer> xP = new ArrayList<>();
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT * FROM `%s`",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
xP.add(rs.getInt("id"));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Cannot import xAuthPlayers", e);
|
||||
return new ArrayList<>();
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return xP;
|
||||
}
|
||||
|
||||
private String getPassword(int accountId) {
|
||||
String realPass = "";
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `password`, `pwtype` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, accountId);
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next())
|
||||
return null;
|
||||
realPass = rs.getString("password");
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve password hash for account: " + accountId, e);
|
||||
return null;
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return realPass;
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -1,136 +0,0 @@
|
||||
package fr.xephi.authme.converter;
|
||||
|
||||
import de.luricos.bukkit.xAuth.database.DatabaseTables;
|
||||
import de.luricos.bukkit.xAuth.utils.xAuthLog;
|
||||
import de.luricos.bukkit.xAuth.xAuth;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.util.CollectionUtils;
|
||||
import org.bukkit.command.CommandSender;
|
||||
|
||||
import java.io.File;
|
||||
import java.sql.Connection;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
import java.sql.SQLException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
class xAuthToFlat {
|
||||
|
||||
private final AuthMe instance;
|
||||
private final DataSource database;
|
||||
private final CommandSender sender;
|
||||
|
||||
public xAuthToFlat(AuthMe instance, CommandSender sender) {
|
||||
this.instance = instance;
|
||||
this.database = instance.getDataSource();
|
||||
this.sender = sender;
|
||||
}
|
||||
|
||||
public boolean convert() {
|
||||
if (instance.getServer().getPluginManager().getPlugin("xAuth") == null) {
|
||||
sender.sendMessage("[AuthMe] xAuth plugin not found");
|
||||
return false;
|
||||
}
|
||||
File xAuthDb = new File(instance.getDataFolder().getParent(), "xAuth" + File.separator + "xAuth.h2.db");
|
||||
if (!xAuthDb.exists()) {
|
||||
sender.sendMessage("[AuthMe] xAuth H2 database not found, checking for MySQL or SQLite data...");
|
||||
}
|
||||
List<Integer> players = getXAuthPlayers();
|
||||
if (CollectionUtils.isEmpty(players)) {
|
||||
sender.sendMessage("[AuthMe] Error while importing xAuthPlayers: did not find any players");
|
||||
return false;
|
||||
}
|
||||
sender.sendMessage("[AuthMe] Starting import...");
|
||||
try {
|
||||
for (int id : players) {
|
||||
String pl = getIdPlayer(id);
|
||||
String psw = getPassword(id);
|
||||
if (psw != null && !psw.isEmpty() && pl != null) {
|
||||
PlayerAuth auth = PlayerAuth.builder()
|
||||
.name(pl.toLowerCase())
|
||||
.realName(pl)
|
||||
.password(psw, null).build();
|
||||
database.saveAuth(auth);
|
||||
}
|
||||
}
|
||||
sender.sendMessage("[AuthMe] Successfully converted from xAuth database");
|
||||
} catch (Exception e) {
|
||||
sender.sendMessage("[AuthMe] An error has occurred while importing the xAuth database."
|
||||
+ " The import may have succeeded partially.");
|
||||
ConsoleLogger.logException("Error during xAuth database import", e);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private String getIdPlayer(int id) {
|
||||
String realPass = "";
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `playername` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, id);
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next())
|
||||
return null;
|
||||
realPass = rs.getString("playername").toLowerCase();
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve name for account: " + id, e);
|
||||
return null;
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return realPass;
|
||||
}
|
||||
|
||||
private List<Integer> getXAuthPlayers() {
|
||||
List<Integer> xP = new ArrayList<>();
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT * FROM `%s`",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
rs = ps.executeQuery();
|
||||
while (rs.next()) {
|
||||
xP.add(rs.getInt("id"));
|
||||
}
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Cannot import xAuthPlayers", e);
|
||||
return new ArrayList<>();
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return xP;
|
||||
}
|
||||
|
||||
private String getPassword(int accountId) {
|
||||
String realPass = "";
|
||||
Connection conn = xAuth.getPlugin().getDatabaseController().getConnection();
|
||||
PreparedStatement ps = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
String sql = String.format("SELECT `password`, `pwtype` FROM `%s` WHERE `id` = ?",
|
||||
xAuth.getPlugin().getDatabaseController().getTable(DatabaseTables.ACCOUNT));
|
||||
ps = conn.prepareStatement(sql);
|
||||
ps.setInt(1, accountId);
|
||||
rs = ps.executeQuery();
|
||||
if (!rs.next())
|
||||
return null;
|
||||
realPass = rs.getString("password");
|
||||
} catch (SQLException e) {
|
||||
xAuthLog.severe("Failed to retrieve password hash for account: " + accountId, e);
|
||||
return null;
|
||||
} finally {
|
||||
xAuth.getPlugin().getDatabaseController().close(conn, ps, rs);
|
||||
}
|
||||
return realPass;
|
||||
}
|
||||
}
|
@ -3,14 +3,12 @@ package fr.xephi.authme.datasource;
|
||||
import com.google.common.annotations.VisibleForTesting;
|
||||
import com.zaxxer.hikari.HikariDataSource;
|
||||
import com.zaxxer.hikari.pool.HikariPool.PoolInitializationException;
|
||||
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.security.crypts.XFBCRYPT;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
@ -56,12 +54,10 @@ public class MySQL implements DataSource {
|
||||
if (e instanceof IllegalArgumentException) {
|
||||
ConsoleLogger.showError("Invalid database arguments! Please check your configuration!");
|
||||
ConsoleLogger.showError("If this error persists, please report it to the developer!");
|
||||
throw e;
|
||||
}
|
||||
if (e instanceof PoolInitializationException) {
|
||||
ConsoleLogger.showError("Can't initialize database connection! Please check your configuration!");
|
||||
ConsoleLogger.showError("If this error persists, please report it to the developer!");
|
||||
throw new PoolInitializationException(e);
|
||||
}
|
||||
ConsoleLogger.showError("Can't use the Hikari Connection Pool! Please, report this error to the developer!");
|
||||
throw e;
|
||||
@ -69,7 +65,7 @@ public class MySQL implements DataSource {
|
||||
|
||||
// Initialize the database
|
||||
try {
|
||||
setupConnection();
|
||||
checkTablesAndColumns();
|
||||
} catch (SQLException e) {
|
||||
close();
|
||||
ConsoleLogger.logException("Can't initialize the MySQL database:", e);
|
||||
@ -140,24 +136,13 @@ public class MySQL implements DataSource {
|
||||
return ds.getConnection();
|
||||
}
|
||||
|
||||
private void setupConnection() throws SQLException {
|
||||
private void checkTablesAndColumns() throws SQLException {
|
||||
try (Connection con = getConnection(); Statement st = con.createStatement()) {
|
||||
// Create table if not exists.
|
||||
// Create table with ID column if it doesn't exist
|
||||
String sql = "CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ col.ID + " MEDIUMINT(8) UNSIGNED AUTO_INCREMENT,"
|
||||
+ col.NAME + " VARCHAR(255) NOT NULL UNIQUE,"
|
||||
+ col.REAL_NAME + " VARCHAR(255) NOT NULL,"
|
||||
+ col.PASSWORD + " VARCHAR(255) CHARACTER SET ascii COLLATE ascii_bin NOT NULL,"
|
||||
+ col.IP + " VARCHAR(40) CHARACTER SET ascii COLLATE ascii_bin NOT NULL DEFAULT '127.0.0.1',"
|
||||
+ col.LAST_LOGIN + " BIGINT NOT NULL DEFAULT 0,"
|
||||
+ col.LASTLOC_X + " DOUBLE NOT NULL DEFAULT '0.0',"
|
||||
+ col.LASTLOC_Y + " DOUBLE NOT NULL DEFAULT '0.0',"
|
||||
+ col.LASTLOC_Z + " DOUBLE NOT NULL DEFAULT '0.0',"
|
||||
+ col.LASTLOC_WORLD + " VARCHAR(255) NOT NULL DEFAULT '" + Settings.defaultWorld + "',"
|
||||
+ col.EMAIL + " VARCHAR(255) DEFAULT 'your@email.com',"
|
||||
+ col.IS_LOGGED + " SMALLINT NOT NULL DEFAULT '0',"
|
||||
+ "PRIMARY KEY (" + col.ID + ")"
|
||||
+ ") CHARACTER SET = utf8";
|
||||
+ ") CHARACTER SET = utf8;";
|
||||
st.executeUpdate(sql);
|
||||
|
||||
DatabaseMetaData md = con.getMetaData();
|
||||
@ -177,8 +162,7 @@ public class MySQL implements DataSource {
|
||||
}
|
||||
|
||||
if (!col.SALT.isEmpty() && isColumnMissing(md, col.SALT)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName
|
||||
+ " ADD COLUMN " + col.SALT + " VARCHAR(255);");
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.SALT + " VARCHAR(255);");
|
||||
}
|
||||
|
||||
if (isColumnMissing(md, col.IP)) {
|
||||
@ -219,8 +203,6 @@ public class MySQL implements DataSource {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ col.IS_LOGGED + " SMALLINT NOT NULL DEFAULT '0' AFTER " + col.EMAIL);
|
||||
}
|
||||
|
||||
st.close();
|
||||
}
|
||||
ConsoleLogger.info("MySQL setup finished");
|
||||
}
|
||||
|
@ -5,11 +5,11 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.security.crypts.HashedPassword;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import fr.xephi.authme.util.StringUtils;
|
||||
|
||||
import java.sql.Connection;
|
||||
import java.sql.DatabaseMetaData;
|
||||
import java.sql.DriverManager;
|
||||
import java.sql.PreparedStatement;
|
||||
import java.sql.ResultSet;
|
||||
@ -69,67 +69,73 @@ public class SQLite implements DataSource {
|
||||
this.con = DriverManager.getConnection("jdbc:sqlite:plugins/AuthMe/" + database + ".db");
|
||||
}
|
||||
|
||||
private void setup() throws SQLException {
|
||||
Statement st = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
st = con.createStatement();
|
||||
st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " (" + col.ID + " INTEGER AUTO_INCREMENT," + col.NAME + " VARCHAR(255) NOT NULL UNIQUE," + col.PASSWORD + " VARCHAR(255) NOT NULL," + col.IP + " VARCHAR(40) NOT NULL," + col.LAST_LOGIN + " BIGINT," + col.LASTLOC_X + " DOUBLE NOT NULL DEFAULT '0.0'," + col.LASTLOC_Y + " DOUBLE NOT NULL DEFAULT '0.0'," + col.LASTLOC_Z + " DOUBLE NOT NULL DEFAULT '0.0'," + col.LASTLOC_WORLD + " VARCHAR(255) NOT NULL DEFAULT '" + Settings.defaultWorld + "'," + col.EMAIL + " VARCHAR(255) DEFAULT 'your@email.com'," + "CONSTRAINT table_const_prim PRIMARY KEY (" + col.ID + "));");
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.PASSWORD);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.PASSWORD + " VARCHAR(255) NOT NULL;");
|
||||
@VisibleForTesting
|
||||
protected void setup() throws SQLException {
|
||||
try (Statement st = con.createStatement()) {
|
||||
// Note: cannot add unique fields later on in SQLite, so we add it on initialization
|
||||
st.executeUpdate("CREATE TABLE IF NOT EXISTS " + tableName + " ("
|
||||
+ col.ID + " INTEGER AUTO_INCREMENT, "
|
||||
+ col.NAME + " VARCHAR(255) NOT NULL UNIQUE, "
|
||||
+ "CONSTRAINT table_const_prim PRIMARY KEY (" + col.ID + "));");
|
||||
|
||||
DatabaseMetaData md = con.getMetaData();
|
||||
|
||||
if (isColumnMissing(md, col.REAL_NAME)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN "
|
||||
+ col.REAL_NAME + " VARCHAR(255) NOT NULL DEFAULT 'Player';");
|
||||
}
|
||||
rs.close();
|
||||
if (!col.SALT.isEmpty()) {
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.SALT);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.SALT + " VARCHAR(255);");
|
||||
}
|
||||
rs.close();
|
||||
|
||||
if (isColumnMissing(md, col.PASSWORD)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName
|
||||
+ " ADD COLUMN " + col.PASSWORD + " VARCHAR(255) NOT NULL DEFAULT '';");
|
||||
}
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.IP);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.IP + " VARCHAR(40) NOT NULL;");
|
||||
|
||||
if (!col.SALT.isEmpty() && isColumnMissing(md, col.SALT)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.SALT + " VARCHAR(255);");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.LAST_LOGIN);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LAST_LOGIN + " TIMESTAMP DEFAULT current_timestamp;");
|
||||
|
||||
if (isColumnMissing(md, col.IP)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName
|
||||
+ " ADD COLUMN " + col.IP + " VARCHAR(40) NOT NULL DEFAULT '';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.LASTLOC_X);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_X + " DOUBLE NOT NULL DEFAULT '0.0';");
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_Y + " DOUBLE NOT NULL DEFAULT '0.0';");
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_Z + " DOUBLE NOT NULL DEFAULT '0.0';");
|
||||
|
||||
if (isColumnMissing(md, col.LAST_LOGIN)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName
|
||||
+ " ADD COLUMN " + col.LAST_LOGIN + " TIMESTAMP;");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.LASTLOC_WORLD);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_WORLD + " VARCHAR(255) NOT NULL DEFAULT 'world';");
|
||||
|
||||
if (isColumnMissing(md, col.LASTLOC_X)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_X
|
||||
+ " DOUBLE NOT NULL DEFAULT '0.0';");
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_Y
|
||||
+ " DOUBLE NOT NULL DEFAULT '0.0';");
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.LASTLOC_Z
|
||||
+ " DOUBLE NOT NULL DEFAULT '0.0';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.EMAIL);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.EMAIL + " VARCHAR(255) DEFAULT 'your@email.com';");
|
||||
|
||||
if (isColumnMissing(md, col.LASTLOC_WORLD)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName
|
||||
+ " ADD COLUMN " + col.LASTLOC_WORLD + " VARCHAR(255) NOT NULL DEFAULT 'world';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.IS_LOGGED);
|
||||
if (!rs.next()) {
|
||||
|
||||
if (isColumnMissing(md, col.EMAIL)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName
|
||||
+ " ADD COLUMN " + col.EMAIL + " VARCHAR(255) DEFAULT 'your@email.com';");
|
||||
}
|
||||
|
||||
if (isColumnMissing(md, col.IS_LOGGED)) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.IS_LOGGED + " INT DEFAULT '0';");
|
||||
}
|
||||
rs.close();
|
||||
rs = con.getMetaData().getColumns(null, null, tableName, col.REAL_NAME);
|
||||
if (!rs.next()) {
|
||||
st.executeUpdate("ALTER TABLE " + tableName + " ADD COLUMN " + col.REAL_NAME + " VARCHAR(255) NOT NULL DEFAULT 'Player';");
|
||||
}
|
||||
} finally {
|
||||
close(rs);
|
||||
close(st);
|
||||
}
|
||||
ConsoleLogger.info("SQLite Setup finished");
|
||||
}
|
||||
|
||||
private boolean isColumnMissing(DatabaseMetaData metaData, String columnName) throws SQLException {
|
||||
try (ResultSet rs = metaData.getColumns(null, null, tableName, columnName)) {
|
||||
return !rs.next();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void reload() {
|
||||
close(con);
|
||||
@ -146,7 +152,7 @@ public class SQLite implements DataSource {
|
||||
PreparedStatement pst = null;
|
||||
ResultSet rs = null;
|
||||
try {
|
||||
pst = con.prepareStatement("SELECT * FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=LOWER(?);");
|
||||
pst = con.prepareStatement("SELECT 1 FROM " + tableName + " WHERE LOWER(" + col.NAME + ")=LOWER(?);");
|
||||
pst.setString(1, user);
|
||||
rs = pst.executeQuery();
|
||||
return rs.next();
|
||||
|
@ -1,120 +0,0 @@
|
||||
package fr.xephi.authme.listener.protocollib;
|
||||
|
||||
import com.comphenix.protocol.PacketType;
|
||||
import com.comphenix.protocol.ProtocolLibrary;
|
||||
import com.comphenix.protocol.ProtocolManager;
|
||||
import com.comphenix.protocol.events.ListenerPriority;
|
||||
import com.comphenix.protocol.events.PacketAdapter;
|
||||
import com.comphenix.protocol.events.PacketContainer;
|
||||
import com.comphenix.protocol.events.PacketEvent;
|
||||
import com.comphenix.protocol.utility.MinecraftVersion;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.NativeGameMode;
|
||||
import com.comphenix.protocol.wrappers.EnumWrappers.PlayerInfoAction;
|
||||
import com.comphenix.protocol.wrappers.PlayerInfoData;
|
||||
import com.comphenix.protocol.wrappers.WrappedChatComponent;
|
||||
import com.comphenix.protocol.wrappers.WrappedGameProfile;
|
||||
import com.google.common.collect.Lists;
|
||||
import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
import org.bukkit.Bukkit;
|
||||
import org.bukkit.entity.Player;
|
||||
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.UUID;
|
||||
import java.util.logging.Level;
|
||||
|
||||
class AuthMeTablistPacketAdapter extends PacketAdapter {
|
||||
|
||||
private final BukkitService bukkitService;
|
||||
private boolean isRegistered;
|
||||
|
||||
public AuthMeTablistPacketAdapter(AuthMe plugin, BukkitService bukkitService) {
|
||||
super(plugin, ListenerPriority.NORMAL, PacketType.Play.Server.PLAYER_INFO);
|
||||
this.bukkitService = bukkitService;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onPacketSending(PacketEvent packetEvent) {
|
||||
Player receiver = packetEvent.getPlayer();
|
||||
if (packetEvent.getPacketType() == PacketType.Play.Server.PLAYER_INFO
|
||||
&& !PlayerCache.getInstance().isAuthenticated(receiver.getName().toLowerCase())) {
|
||||
//this hides the tablist for the new joining players. Already playing users will see the new player
|
||||
try {
|
||||
PacketContainer packet = packetEvent.getPacket();
|
||||
PlayerInfoAction playerInfoAction = packet.getPlayerInfoAction().read(0);
|
||||
if (playerInfoAction == PlayerInfoAction.ADD_PLAYER) {
|
||||
List<PlayerInfoData> playerInfoList = Lists.newArrayList(packet.getPlayerInfoDataLists().read(0));
|
||||
for (Iterator<PlayerInfoData> iterator = playerInfoList.iterator(); iterator.hasNext();) {
|
||||
PlayerInfoData current = iterator.next();
|
||||
UUID uuid = current.getProfile().getUUID();
|
||||
if (Bukkit.getPlayer(uuid) == null) {
|
||||
//player is not online -> a NPC
|
||||
iterator.remove();
|
||||
}
|
||||
}
|
||||
|
||||
packet.getPlayerInfoDataLists().write(0, playerInfoList);
|
||||
}
|
||||
} catch (Exception ex) {
|
||||
ConsoleLogger.logException("Couldn't modify outgoing tablist packet", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void sendTablist(Player receiver) {
|
||||
if (!isRegistered) {
|
||||
return;
|
||||
}
|
||||
|
||||
WrappedGameProfile gameProfile = WrappedGameProfile.fromPlayer(receiver);
|
||||
|
||||
ProtocolManager protocolManager = ProtocolLibrary.getProtocolManager();
|
||||
NativeGameMode gamemode = NativeGameMode.fromBukkit(receiver.getGameMode());
|
||||
|
||||
WrappedChatComponent displayName = WrappedChatComponent.fromText(receiver.getDisplayName());
|
||||
PlayerInfoData playerInfoData = new PlayerInfoData(gameProfile, 0, gamemode, displayName);
|
||||
|
||||
//add info containing the skin data
|
||||
PacketContainer addInfo = protocolManager.createPacket(PacketType.Play.Server.PLAYER_INFO);
|
||||
addInfo.getPlayerInfoAction().write(0, PlayerInfoAction.ADD_PLAYER);
|
||||
addInfo.getPlayerInfoDataLists().write(0, Arrays.asList(playerInfoData));
|
||||
|
||||
try {
|
||||
//adds the skin
|
||||
protocolManager.sendServerPacket(receiver, addInfo);
|
||||
} catch (InvocationTargetException ex) {
|
||||
plugin.getLogger().log(Level.SEVERE, "Exception sending instant skin change packet", ex);
|
||||
}
|
||||
|
||||
//triggers an update for others player to see them
|
||||
for (Player onlinePlayer : bukkitService.getOnlinePlayers()) {
|
||||
if (onlinePlayer.equals(receiver) || !receiver.canSee(onlinePlayer)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
//removes the entity and display them
|
||||
receiver.hidePlayer(onlinePlayer);
|
||||
receiver.showPlayer(onlinePlayer);
|
||||
}
|
||||
}
|
||||
|
||||
public void register() {
|
||||
if (MinecraftVersion.getCurrentVersion().isAtLeast(MinecraftVersion.BOUNTIFUL_UPDATE)) {
|
||||
ProtocolLibrary.getProtocolManager().addPacketListener(this);
|
||||
isRegistered = true;
|
||||
} else {
|
||||
ConsoleLogger.info("The hideTablist feature is not compatible with your minecraft version");
|
||||
ConsoleLogger.info("It requires 1.8+. Disabling the hideTablist feature...");
|
||||
}
|
||||
}
|
||||
|
||||
public void unregister() {
|
||||
ProtocolLibrary.getProtocolManager().removePacketListener(this);
|
||||
isRegistered = false;
|
||||
}
|
||||
}
|
@ -15,12 +15,10 @@ public class ProtocolLibService implements SettingsDependent {
|
||||
/* Packet Adapters */
|
||||
private AuthMeInventoryPacketAdapter inventoryPacketAdapter;
|
||||
private AuthMeTabCompletePacketAdapter tabCompletePacketAdapter;
|
||||
private AuthMeTablistPacketAdapter tablistPacketAdapter;
|
||||
|
||||
/* Settings */
|
||||
private boolean protectInvBeforeLogin;
|
||||
private boolean denyTabCompleteBeforeLogin;
|
||||
private boolean hideTablistBeforeLogin;
|
||||
|
||||
/* Service */
|
||||
private boolean isEnabled;
|
||||
@ -44,12 +42,10 @@ public class ProtocolLibService implements SettingsDependent {
|
||||
if (protectInvBeforeLogin) {
|
||||
ConsoleLogger.showError("WARNING! The protectInventory feature requires ProtocolLib! Disabling it...");
|
||||
}
|
||||
|
||||
if (denyTabCompleteBeforeLogin) {
|
||||
ConsoleLogger.showError("WARNING! The denyTabComplete feature requires ProtocolLib! Disabling it...");
|
||||
}
|
||||
if (hideTablistBeforeLogin) {
|
||||
ConsoleLogger.showError("WARNING! The hideTablist feature requires ProtocolLib! Disabling it...");
|
||||
}
|
||||
|
||||
this.isEnabled = false;
|
||||
return;
|
||||
@ -70,13 +66,6 @@ public class ProtocolLibService implements SettingsDependent {
|
||||
tabCompletePacketAdapter.unregister();
|
||||
tabCompletePacketAdapter = null;
|
||||
}
|
||||
if (hideTablistBeforeLogin && tablistPacketAdapter == null) {
|
||||
tablistPacketAdapter = new AuthMeTablistPacketAdapter(plugin, bukkitService);
|
||||
tablistPacketAdapter.register();
|
||||
} else if (tablistPacketAdapter != null) {
|
||||
tablistPacketAdapter.unregister();
|
||||
tablistPacketAdapter = null;
|
||||
}
|
||||
|
||||
this.isEnabled = true;
|
||||
}
|
||||
@ -92,10 +81,6 @@ public class ProtocolLibService implements SettingsDependent {
|
||||
tabCompletePacketAdapter.unregister();
|
||||
tabCompletePacketAdapter = null;
|
||||
}
|
||||
if (tablistPacketAdapter != null) {
|
||||
tablistPacketAdapter.unregister();
|
||||
tablistPacketAdapter = null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -109,21 +94,9 @@ public class ProtocolLibService implements SettingsDependent {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Send a tab list packet to a player.
|
||||
*
|
||||
* @param player The player to send the packet to.
|
||||
*/
|
||||
public void sendTabList(Player player) {
|
||||
if (isEnabled && tablistPacketAdapter != null) {
|
||||
tablistPacketAdapter.sendTablist(player);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void loadSettings(NewSetting settings) {
|
||||
this.protectInvBeforeLogin = settings.getProperty(RestrictionSettings.PROTECT_INVENTORY_BEFORE_LOGIN);
|
||||
this.denyTabCompleteBeforeLogin = settings.getProperty(RestrictionSettings.DENY_TABCOMPLETE_BEFORE_LOGIN);
|
||||
this.hideTablistBeforeLogin = settings.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN);
|
||||
}
|
||||
}
|
||||
|
@ -5,45 +5,72 @@ import fr.xephi.authme.ConsoleLogger;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
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.inject.Inject;
|
||||
import javax.mail.Session;
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.security.Security;
|
||||
import java.util.Properties;
|
||||
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_ACCOUNT;
|
||||
import static fr.xephi.authme.settings.properties.EmailSettings.MAIL_PASSWORD;
|
||||
|
||||
|
||||
/**
|
||||
* @author Xephi59
|
||||
*/
|
||||
public class SendMailSSL {
|
||||
|
||||
private final AuthMe plugin;
|
||||
private final NewSetting settings;
|
||||
@Inject
|
||||
private AuthMe plugin;
|
||||
@Inject
|
||||
private NewSetting settings;
|
||||
@Inject
|
||||
private BukkitService bukkitService;
|
||||
|
||||
public SendMailSSL(AuthMe plugin, NewSetting settings) {
|
||||
this.plugin = plugin;
|
||||
this.settings = settings;
|
||||
SendMailSSL() {
|
||||
}
|
||||
|
||||
public void main(final PlayerAuth auth, final String newPass) {
|
||||
final String mailText = replaceMailTags(settings.getEmailMessage(), plugin, auth, newPass);
|
||||
Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() {
|
||||
/**
|
||||
* Returns whether all necessary settings are set for sending mails.
|
||||
*
|
||||
* @return true if the necessary email settings are set, false otherwise
|
||||
*/
|
||||
public boolean hasAllInformation() {
|
||||
return !settings.getProperty(MAIL_ACCOUNT).isEmpty()
|
||||
&& !settings.getProperty(MAIL_PASSWORD).isEmpty();
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends an email to the user with his new password.
|
||||
*
|
||||
* @param auth the player auth of the player
|
||||
* @param newPass the new password
|
||||
*/
|
||||
public void sendPasswordMail(final PlayerAuth auth, final String newPass) {
|
||||
if (!hasAllInformation()) {
|
||||
ConsoleLogger.showError("Cannot perform email registration: not all email settings are complete");
|
||||
return;
|
||||
}
|
||||
|
||||
final String mailText = replaceMailTags(settings.getEmailMessage(), auth, newPass);
|
||||
bukkitService.runTaskAsynchronously(new Runnable() {
|
||||
|
||||
@Override
|
||||
public void run() {
|
||||
Thread.currentThread().setContextClassLoader(this.getClass().getClassLoader());
|
||||
HtmlEmail email;
|
||||
try {
|
||||
email = initializeMail(auth, settings);
|
||||
email = initializeMail(auth.getEmail());
|
||||
} catch (EmailException e) {
|
||||
ConsoleLogger.logException("Failed to create email with the given settings:", e);
|
||||
return;
|
||||
@ -54,7 +81,7 @@ public class SendMailSSL {
|
||||
File file = null;
|
||||
if (settings.getProperty(EmailSettings.PASSWORD_AS_IMAGE)) {
|
||||
try {
|
||||
file = generateImage(auth, plugin, newPass);
|
||||
file = generateImage(auth.getNickname(), plugin, newPass);
|
||||
content = embedImageIntoEmailContent(file, email, content);
|
||||
} catch (IOException | EmailException e) {
|
||||
ConsoleLogger.logException(
|
||||
@ -67,13 +94,12 @@ public class SendMailSSL {
|
||||
file.delete();
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private static File generateImage(PlayerAuth auth, AuthMe plugin, String newPass) throws IOException {
|
||||
private static File generateImage(String name, AuthMe plugin, String newPass) throws IOException {
|
||||
ImageGenerator gen = new ImageGenerator(newPass);
|
||||
File file = new File(plugin.getDataFolder(), auth.getNickname() + "_new_pass.jpg");
|
||||
File file = new File(plugin.getDataFolder(), name + "_new_pass.jpg");
|
||||
ImageIO.write(gen.generateImage(), "jpg", file);
|
||||
return file;
|
||||
}
|
||||
@ -85,8 +111,7 @@ public class SendMailSSL {
|
||||
return content.replace("<image />", "<img src=\"cid:" + tag + "\">");
|
||||
}
|
||||
|
||||
private static HtmlEmail initializeMail(PlayerAuth auth, NewSetting settings)
|
||||
throws EmailException {
|
||||
private HtmlEmail initializeMail(String emailAddress) throws EmailException {
|
||||
String senderMail = settings.getProperty(EmailSettings.MAIL_ACCOUNT);
|
||||
String senderName = StringUtils.isEmpty(settings.getProperty(EmailSettings.MAIL_SENDER_NAME))
|
||||
? senderMail
|
||||
@ -98,12 +123,12 @@ public class SendMailSSL {
|
||||
email.setCharset(EmailConstants.UTF_8);
|
||||
email.setSmtpPort(port);
|
||||
email.setHostName(settings.getProperty(EmailSettings.SMTP_HOST));
|
||||
email.addTo(auth.getEmail());
|
||||
email.addTo(emailAddress);
|
||||
email.setFrom(senderMail, senderName);
|
||||
email.setSubject(settings.getProperty(EmailSettings.RECOVERY_MAIL_SUBJECT));
|
||||
email.setAuthentication(senderMail, mailPassword);
|
||||
|
||||
setPropertiesForPort(email, port, settings);
|
||||
setPropertiesForPort(email, port);
|
||||
return email;
|
||||
}
|
||||
|
||||
@ -124,15 +149,14 @@ public class SendMailSSL {
|
||||
}
|
||||
}
|
||||
|
||||
private static String replaceMailTags(String mailText, AuthMe plugin, PlayerAuth auth, String newPass) {
|
||||
private String replaceMailTags(String mailText, PlayerAuth auth, String newPass) {
|
||||
return mailText
|
||||
.replace("<playername />", auth.getNickname())
|
||||
.replace("<servername />", plugin.getServer().getServerName())
|
||||
.replace("<generatedpass />", newPass);
|
||||
}
|
||||
|
||||
private static void setPropertiesForPort(HtmlEmail email, int port, NewSetting settings)
|
||||
throws EmailException {
|
||||
private void setPropertiesForPort(HtmlEmail email, int port) throws EmailException {
|
||||
switch (port) {
|
||||
case 587:
|
||||
String oAuth2Token = settings.getProperty(EmailSettings.OAUTH2_TOKEN);
|
||||
|
@ -143,7 +143,11 @@ public enum MessageKey {
|
||||
|
||||
ACCOUNTS_OWNED_SELF("accounts_owned_self", "%count"),
|
||||
|
||||
ACCOUNTS_OWNED_OTHER("accounts_owned_other", "%name", "%count");
|
||||
ACCOUNTS_OWNED_OTHER("accounts_owned_other", "%name", "%count"),
|
||||
|
||||
KICK_FOR_ADMIN_REGISTER("kicked_admin_registered"),
|
||||
|
||||
INCOMPLETE_EMAIL_SETTINGS("incomplete_email_settings");
|
||||
|
||||
private String key;
|
||||
private String[] tags;
|
||||
|
@ -111,10 +111,6 @@ public class ProcessSyncPlayerLogin implements SynchronousProcess {
|
||||
restoreInventory(player);
|
||||
}
|
||||
|
||||
if (service.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN)) {
|
||||
protocolLibService.sendTabList(player);
|
||||
}
|
||||
|
||||
// Clean up no longer used temporary data
|
||||
limboCache.deleteLimboPlayer(player);
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import fr.xephi.authme.AuthMe;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.cache.auth.PlayerCache;
|
||||
import fr.xephi.authme.datasource.DataSource;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.permission.PermissionsManager;
|
||||
import fr.xephi.authme.process.AsynchronousProcess;
|
||||
@ -55,6 +56,9 @@ public class AsyncRegister implements AsynchronousProcess {
|
||||
@Inject
|
||||
private ValidationService validationService;
|
||||
|
||||
@Inject
|
||||
private SendMailSSL sendMailSsl;
|
||||
|
||||
AsyncRegister() { }
|
||||
|
||||
private boolean preRegisterCheck(Player player, String password) {
|
||||
@ -137,7 +141,7 @@ public class AsyncRegister implements AsynchronousProcess {
|
||||
}
|
||||
database.updateEmail(auth);
|
||||
database.updateSession(auth);
|
||||
plugin.getMail().main(auth, password);
|
||||
sendMailSsl.sendPasswordMail(auth, password);
|
||||
syncProcessManager.processSyncEmailRegister(player);
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,6 @@ import fr.xephi.authme.settings.Settings;
|
||||
import fr.xephi.authme.settings.properties.EmailSettings;
|
||||
import fr.xephi.authme.settings.properties.HooksSettings;
|
||||
import fr.xephi.authme.settings.properties.RegistrationSettings;
|
||||
import fr.xephi.authme.settings.properties.RestrictionSettings;
|
||||
import fr.xephi.authme.settings.properties.SecuritySettings;
|
||||
import fr.xephi.authme.task.LimboPlayerTaskManager;
|
||||
import fr.xephi.authme.util.BukkitService;
|
||||
@ -96,10 +95,6 @@ public class ProcessSyncPasswordRegister implements SynchronousProcess {
|
||||
final String name = player.getName().toLowerCase();
|
||||
LimboPlayer limbo = limboCache.getLimboPlayer(name);
|
||||
if (limbo != null) {
|
||||
if (service.getProperty(RestrictionSettings.HIDE_TABLIST_BEFORE_LOGIN)) {
|
||||
protocolLibService.sendTabList(player);
|
||||
}
|
||||
|
||||
Utils.teleportToSpawn(player);
|
||||
|
||||
if (service.getProperty(PROTECT_INVENTORY_BEFORE_LOGIN)) {
|
||||
|
@ -19,15 +19,15 @@ public final class Settings {
|
||||
public static boolean isPermissionCheckEnabled;
|
||||
public static boolean isTeleportToSpawnEnabled;
|
||||
public static boolean isAllowRestrictedIp;
|
||||
public static boolean isSaveQuitLocationEnabled;
|
||||
public static boolean protectInventoryBeforeLogInEnabled;
|
||||
public static boolean isStopEnabled;
|
||||
public static boolean reloadSupport;
|
||||
public static boolean noTeleport;
|
||||
public static boolean isRemoveSpeedEnabled;
|
||||
public static String getUnloggedinGroup;
|
||||
public static String unRegisteredGroup;
|
||||
public static String getRegisteredGroup;
|
||||
public static String defaultWorld;
|
||||
public static String crazyloginFileName;
|
||||
public static int getNonActivatedGroup;
|
||||
private static FileConfiguration configFile;
|
||||
|
||||
@ -45,6 +45,7 @@ public final class Settings {
|
||||
isPermissionCheckEnabled = load(PluginSettings.ENABLE_PERMISSION_CHECK);
|
||||
isTeleportToSpawnEnabled = load(RestrictionSettings.TELEPORT_UNAUTHED_TO_SPAWN);
|
||||
isAllowRestrictedIp = load(RestrictionSettings.ENABLE_RESTRICTED_USERS);
|
||||
isSaveQuitLocationEnabled = load(RestrictionSettings.SAVE_QUIT_LOCATION);
|
||||
isRemoveSpeedEnabled = load(RestrictionSettings.REMOVE_SPEED);
|
||||
getUnloggedinGroup = load(SecuritySettings.UNLOGGEDIN_GROUP);
|
||||
getNonActivatedGroup = configFile.getInt("ExternalBoardOptions.nonActivedUserGroup", -1);
|
||||
@ -55,7 +56,6 @@ public final class Settings {
|
||||
reloadSupport = configFile.getBoolean("Security.ReloadCommand.useReloadCommandSupport", true);
|
||||
defaultWorld = configFile.getString("Purge.defaultWorld", "world");
|
||||
noTeleport = load(RestrictionSettings.NO_TELEPORT);
|
||||
crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db");
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -92,10 +92,10 @@ public class SettingsMigrationService {
|
||||
|
||||
final File emailFile = new File(pluginFolder, "email.html");
|
||||
final String mailText = configuration.getString(oldSettingPath)
|
||||
.replace("<playername>", "<playername />")
|
||||
.replace("<servername>", "<servername />")
|
||||
.replace("<generatedpass>", "<generatedpass />")
|
||||
.replace("<image>", "<image />");
|
||||
.replace("<playername>", "<playername />").replace("%playername%", "<playername />")
|
||||
.replace("<servername>", "<servername />").replace("%servername%", "<servername />")
|
||||
.replace("<generatedpass>", "<generatedpass />").replace("%generatedpass%", "<generatedpass />")
|
||||
.replace("<image>", "<image />").replace("%image%", "<image />");
|
||||
if (!emailFile.exists()) {
|
||||
try (FileWriter fw = new FileWriter(emailFile)) {
|
||||
fw.write(mailText);
|
||||
|
@ -25,7 +25,6 @@ public class PluginSettings implements SettingsClass {
|
||||
|
||||
@Comment({
|
||||
"After how many minutes should a session expire?",
|
||||
"0 for unlimited time (Very dangerous, use it at your own risk!)",
|
||||
"Remember that sessions will end only after the timeout, and",
|
||||
"if the player's IP has changed but the timeout hasn't expired,",
|
||||
"the player will be kicked from the server due to invalid session"
|
||||
|
@ -141,10 +141,6 @@ public class RestrictionSettings implements SettingsClass {
|
||||
public static final Property<Boolean> DENY_TABCOMPLETE_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.DenyTabCompleteBeforeLogin", true);
|
||||
|
||||
@Comment("Should we hide the tablist before logging in? Requires ProtocolLib.")
|
||||
public static final Property<Boolean> HIDE_TABLIST_BEFORE_LOGIN =
|
||||
newProperty("settings.restrictions.HideTablistBeforeLogin", true);
|
||||
|
||||
@Comment({
|
||||
"Should we display all other accounts from a player when he joins?",
|
||||
"permission: /authme.admin.accounts"})
|
||||
|
@ -54,7 +54,6 @@ settings:
|
||||
# hasn't expired, he will not need to authenticate.
|
||||
enabled: false
|
||||
# After how many minutes a session should expire?
|
||||
# 0 for unlimited time (Very dangerous, use it at your own risk!)
|
||||
# Consider that session will end only after the timeout time, and
|
||||
# if the player's ip has changed but the timeout hasn't expired,
|
||||
# player will be kicked out of sever due to invalidSession!
|
||||
@ -141,8 +140,6 @@ settings:
|
||||
ProtectInventoryBeforeLogIn: true
|
||||
# Should we deny the tabcomplete feature before logging in? Requires ProtocolLib.
|
||||
DenyTabCompleteBeforeLogin: true
|
||||
# Should we hide the tablist before logging in? Requires ProtocolLib.
|
||||
HideTablistBeforeLogin: true
|
||||
# Should we display all other accounts from a player when he joins?
|
||||
# permission: /authme.admin.accounts
|
||||
displayOtherAccounts: true
|
||||
|
@ -68,3 +68,5 @@ invalid_name_case: 'You should join using username %valid, not %invalid.'
|
||||
tempban_max_logins: '&cYou have been temporarily banned for failing to log in too many times.'
|
||||
accounts_owned_self: 'You own %count accounts:'
|
||||
accounts_owned_other: 'The player %name has %count accounts:'
|
||||
kicked_admin_registered: 'An admin just registered you; please log in again'
|
||||
incomplete_email_settings: 'Error: not all required settings are set for sending emails. Please contact an admin.'
|
||||
|
@ -69,3 +69,5 @@ tempban_max_logins: '&cVous êtes temporairement banni suite à plusieurs échec
|
||||
accounts_owned_self: '&fVous avez %count comptes:'
|
||||
accounts_owned_other: '&fLe joueur %name a %count comptes:'
|
||||
denied_command: '&cVous devez être connecté pour pouvoir utiliser cette commande.'
|
||||
kicked_admin_registered: 'Un admin vient de vous enregistrer, veuillez vous reconnecter.'
|
||||
incomplete_email_settings: '&cErreur : Tous les paramètres requis ne sont pas présent pour l''envoi de mail, veuillez contacter un admin.'
|
||||
|
@ -22,12 +22,10 @@ import org.mockito.runners.MockitoJUnitRunner;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.BDDMockito.given;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Matchers.argThat;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.never;
|
||||
import static org.mockito.Mockito.verify;
|
||||
@ -160,6 +158,8 @@ public class RegisterAdminCommandTest {
|
||||
given(passwordSecurity.computeHash(password, user)).willReturn(hashedPassword);
|
||||
Player player = mock(Player.class);
|
||||
given(bukkitService.getPlayerExact(user)).willReturn(player);
|
||||
String kickForAdminRegister = "Admin registered you -- log in again";
|
||||
given(commandService.retrieveSingle(MessageKey.KICK_FOR_ADMIN_REGISTER)).willReturn(kickForAdminRegister);
|
||||
CommandSender sender = mock(CommandSender.class);
|
||||
|
||||
// when
|
||||
@ -174,7 +174,7 @@ public class RegisterAdminCommandTest {
|
||||
verify(dataSource).saveAuth(captor.capture());
|
||||
assertAuthHasInfo(captor.getValue(), user, hashedPassword);
|
||||
verify(dataSource).setUnlogged(user);
|
||||
verify(player).kickPlayer(argThat(containsString("please log in again")));
|
||||
verify(player).kickPlayer(kickForAdminRegister);
|
||||
}
|
||||
|
||||
private void assertAuthHasInfo(PlayerAuth auth, String name, HashedPassword hashedPassword) {
|
||||
|
@ -2,6 +2,7 @@ package fr.xephi.authme.command.executable.register;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.command.CommandService;
|
||||
import fr.xephi.authme.mail.SendMailSSL;
|
||||
import fr.xephi.authme.output.MessageKey;
|
||||
import fr.xephi.authme.process.Management;
|
||||
import fr.xephi.authme.security.HashAlgorithm;
|
||||
@ -49,6 +50,8 @@ public class RegisterCommandTest {
|
||||
@Mock
|
||||
private Management management;
|
||||
|
||||
@Mock
|
||||
private SendMailSSL sendMailSsl;
|
||||
|
||||
@BeforeClass
|
||||
public static void setup() {
|
||||
@ -72,7 +75,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(sender).sendMessage(argThat(containsString("Player only!")));
|
||||
verifyZeroInteractions(management);
|
||||
verifyZeroInteractions(management, sendMailSsl);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -86,6 +89,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(management).performRegister(player, "", "", true);
|
||||
verifyZeroInteractions(sendMailSsl);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -98,7 +102,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.USAGE_REGISTER);
|
||||
verifyZeroInteractions(management);
|
||||
verifyZeroInteractions(management, sendMailSsl);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -112,7 +116,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.USAGE_REGISTER);
|
||||
verifyZeroInteractions(management);
|
||||
verifyZeroInteractions(management, sendMailSsl);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -127,7 +131,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.USAGE_REGISTER);
|
||||
verifyZeroInteractions(management);
|
||||
verifyZeroInteractions(management, sendMailSsl);
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -135,14 +139,15 @@ public class RegisterCommandTest {
|
||||
// given
|
||||
given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
|
||||
given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(false);
|
||||
given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("");
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(false);
|
||||
Player player = mock(Player.class);
|
||||
|
||||
// when
|
||||
command.executeCommand(player, Collections.singletonList("myMail@example.tld"));
|
||||
|
||||
// then
|
||||
verify(player).sendMessage(argThat(containsString("no email address")));
|
||||
verify(commandService).send(player, MessageKey.INCOMPLETE_EMAIL_SETTINGS);
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verifyZeroInteractions(management);
|
||||
}
|
||||
|
||||
@ -155,6 +160,7 @@ public class RegisterCommandTest {
|
||||
given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
|
||||
given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true);
|
||||
given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("server@example.com");
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
Player player = mock(Player.class);
|
||||
|
||||
// when
|
||||
@ -175,6 +181,7 @@ public class RegisterCommandTest {
|
||||
given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
|
||||
given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true);
|
||||
given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("server@example.com");
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
Player player = mock(Player.class);
|
||||
|
||||
// when
|
||||
@ -182,6 +189,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.USAGE_REGISTER);
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verifyZeroInteractions(management);
|
||||
}
|
||||
|
||||
@ -196,6 +204,7 @@ public class RegisterCommandTest {
|
||||
given(commandService.getProperty(RegistrationSettings.USE_EMAIL_REGISTRATION)).willReturn(true);
|
||||
given(commandService.getProperty(RegistrationSettings.ENABLE_CONFIRM_EMAIL)).willReturn(true);
|
||||
given(commandService.getProperty(EmailSettings.MAIL_ACCOUNT)).willReturn("server@example.com");
|
||||
given(sendMailSsl.hasAllInformation()).willReturn(true);
|
||||
Player player = mock(Player.class);
|
||||
|
||||
// when
|
||||
@ -203,6 +212,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(commandService).validateEmail(playerMail);
|
||||
verify(sendMailSsl).hasAllInformation();
|
||||
verify(management).performRegister(eq(player), argThat(stringWithLength(passLength)), eq(playerMail), eq(true));
|
||||
}
|
||||
|
||||
@ -217,7 +227,7 @@ public class RegisterCommandTest {
|
||||
|
||||
// then
|
||||
verify(commandService).send(player, MessageKey.PASSWORD_MATCH_ERROR);
|
||||
verifyZeroInteractions(management);
|
||||
verifyZeroInteractions(management, sendMailSsl);
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -12,6 +12,9 @@ import java.util.Set;
|
||||
import static fr.xephi.authme.AuthMeMatchers.equalToHash;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthBasicData;
|
||||
import static fr.xephi.authme.AuthMeMatchers.hasAuthLocation;
|
||||
import static org.hamcrest.Matchers.contains;
|
||||
import static org.hamcrest.Matchers.containsInAnyOrder;
|
||||
import static org.hamcrest.Matchers.empty;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.hasItem;
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
@ -170,6 +173,22 @@ public abstract class AbstractDataSourceIntegrationTest {
|
||||
assertThat(dataSource.getPassword("user"), equalToHash("new_hash"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldUpdatePasswordWithPlayerAuth() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource("salt");
|
||||
PlayerAuth bobbyAuth = PlayerAuth.builder().name("bobby").password(new HashedPassword("tt", "cc")).build();
|
||||
PlayerAuth invalidAuth = PlayerAuth.builder().name("invalid").password(new HashedPassword("tt", "cc")).build();
|
||||
|
||||
// when
|
||||
boolean response1 = dataSource.updatePassword(bobbyAuth);
|
||||
boolean response2 = dataSource.updatePassword(invalidAuth);
|
||||
|
||||
// then
|
||||
assertThat(response1 && response2, equalTo(true));
|
||||
assertThat(dataSource.getPassword("bobby"), equalToHash("tt", "cc"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldRemovePlayerAuth() {
|
||||
// given
|
||||
@ -321,4 +340,49 @@ public abstract class AbstractDataSourceIntegrationTest {
|
||||
assertThat(dataSource.getAuth("bobby"), hasAuthBasicData("bobby", "BOBBY", "your@email.com", "123.45.67.89"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldGetRecordsToPurge() {
|
||||
// given
|
||||
DataSource dataSource = getDataSource();
|
||||
// 1453242857 -> user, 1449136800 -> bobby
|
||||
|
||||
// when
|
||||
Set<String> records1 = dataSource.getRecordsToPurge(1450000000);
|
||||
Set<String> records2 = dataSource.getRecordsToPurge(1460000000);
|
||||
|
||||
// then
|
||||
assertThat(records1, contains("bobby"));
|
||||
assertThat(records2, containsInAnyOrder("bobby", "user"));
|
||||
// check that the entry was not deleted because of running this command
|
||||
assertThat(dataSource.isAuthAvailable("bobby"), equalTo(true));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldPerformOperationsOnIsLoggedColumnSuccessfully() {
|
||||
DataSource dataSource = getDataSource();
|
||||
// on startup no one should be marked as logged
|
||||
assertThat(dataSource.getLoggedPlayers(), empty());
|
||||
|
||||
// Mark user as logged
|
||||
dataSource.setLogged("user");
|
||||
// non-existent user should not break database
|
||||
dataSource.setLogged("does-not-exist");
|
||||
|
||||
assertThat(dataSource.isLogged("user"), equalTo(true));
|
||||
assertThat(dataSource.isLogged("bobby"), equalTo(false));
|
||||
|
||||
// Set bobby logged and unlog user
|
||||
dataSource.setLogged("bobby");
|
||||
dataSource.setUnlogged("user");
|
||||
assertThat(dataSource.getLoggedPlayers(),
|
||||
contains(hasAuthBasicData("bobby", "Bobby", "your@email.com", "123.45.67.89")));
|
||||
|
||||
// Set both as logged (even if Bobby already is logged)
|
||||
dataSource.setLogged("user");
|
||||
dataSource.setLogged("bobby");
|
||||
dataSource.purgeLogged();
|
||||
assertThat(dataSource.isLogged("user"), equalTo(false));
|
||||
assertThat(dataSource.getLoggedPlayers(), empty());
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -6,6 +6,7 @@ import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
@ -60,7 +61,6 @@ public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
|
||||
@Before
|
||||
public void initializeConnectionAndTable() throws SQLException {
|
||||
silentClose(hikariSource);
|
||||
HikariConfig config = new HikariConfig();
|
||||
config.setDataSourceClassName("org.h2.jdbcx.JdbcDataSource");
|
||||
config.setConnectionTestQuery("VALUES 1");
|
||||
@ -77,6 +77,11 @@ public class MySqlIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
hikariSource = ds;
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeConnection() {
|
||||
silentClose(hikariSource);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSource getDataSource(String saltColumn) {
|
||||
when(settings.getProperty(DatabaseSettings.MYSQL_COL_SALT)).thenReturn(saltColumn);
|
||||
|
@ -1,11 +1,14 @@
|
||||
package fr.xephi.authme.datasource;
|
||||
|
||||
import fr.xephi.authme.TestHelper;
|
||||
import fr.xephi.authme.cache.auth.PlayerAuth;
|
||||
import fr.xephi.authme.settings.NewSetting;
|
||||
import fr.xephi.authme.settings.domain.Property;
|
||||
import fr.xephi.authme.settings.properties.DatabaseSettings;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.BeforeClass;
|
||||
import org.junit.Test;
|
||||
import org.mockito.invocation.InvocationOnMock;
|
||||
import org.mockito.stubbing.Answer;
|
||||
|
||||
@ -17,6 +20,8 @@ import java.sql.DriverManager;
|
||||
import java.sql.SQLException;
|
||||
import java.sql.Statement;
|
||||
|
||||
import static org.hamcrest.Matchers.hasSize;
|
||||
import static org.junit.Assert.assertThat;
|
||||
import static org.mockito.Matchers.any;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
@ -61,7 +66,6 @@ public class SQLiteIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
|
||||
@Before
|
||||
public void initializeConnectionAndTable() throws SQLException {
|
||||
silentClose(con);
|
||||
Connection connection = DriverManager.getConnection("jdbc:sqlite::memory:");
|
||||
try (Statement st = connection.createStatement()) {
|
||||
st.execute("DROP TABLE IF EXISTS authme");
|
||||
@ -72,6 +76,50 @@ public class SQLiteIntegrationTest extends AbstractDataSourceIntegrationTest {
|
||||
con = connection;
|
||||
}
|
||||
|
||||
@After
|
||||
public void closeConnection() {
|
||||
silentClose(con);
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldSetUpTableIfMissing() throws SQLException {
|
||||
// given
|
||||
Statement st = con.createStatement();
|
||||
// table is absent
|
||||
st.execute("DROP TABLE authme");
|
||||
SQLite sqLite = new SQLite(settings, con);
|
||||
|
||||
// when
|
||||
sqLite.setup();
|
||||
|
||||
// then
|
||||
// Save some player to verify database is operational
|
||||
sqLite.saveAuth(PlayerAuth.builder().name("Name").build());
|
||||
assertThat(sqLite.getAllAuths(), hasSize(1));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void shouldCreateMissingColumns() throws SQLException {
|
||||
// given
|
||||
Statement st = con.createStatement();
|
||||
// drop table and create one with only some of the columns: SQLite doesn't support ALTER TABLE t DROP COLUMN c
|
||||
st.execute("DROP TABLE authme");
|
||||
st.execute("CREATE TABLE authme ("
|
||||
+ "id bigint, "
|
||||
+ "username varchar(255) unique, "
|
||||
+ "password varchar(255) not null, "
|
||||
+ "primary key (id));");
|
||||
SQLite sqLite = new SQLite(settings, con);
|
||||
|
||||
// when
|
||||
sqLite.setup();
|
||||
|
||||
// then
|
||||
// Save some player to verify database is operational
|
||||
sqLite.saveAuth(PlayerAuth.builder().name("Name").build());
|
||||
assertThat(sqLite.getAllAuths(), hasSize(1));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected DataSource getDataSource(String saltColumn) {
|
||||
when(settings.getProperty(DatabaseSettings.MYSQL_COL_SALT)).thenReturn(saltColumn);
|
||||
|
@ -22,12 +22,11 @@ public class MessageKeyTest {
|
||||
// when / then
|
||||
for (MessageKey messageKey : messageKeys) {
|
||||
String key = messageKey.getKey();
|
||||
if (keys.contains(key)) {
|
||||
if (!keys.add(key)) {
|
||||
fail("Found key '" + messageKey.getKey() + "' twice!");
|
||||
} else if (StringUtils.isEmpty(key)) {
|
||||
fail("Key for message key '" + messageKey + "' is empty");
|
||||
}
|
||||
keys.add(key);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -33,10 +33,9 @@ public class AdminPermissionTest {
|
||||
|
||||
// when/then
|
||||
for (AdminPermission permission : AdminPermission.values()) {
|
||||
if (nodes.contains(permission.getNode())) {
|
||||
if (!nodes.add(permission.getNode())) {
|
||||
fail("More than one enum value defines the node '" + permission.getNode() + "'");
|
||||
}
|
||||
nodes.add(permission.getNode());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -33,10 +33,9 @@ public class PlayerPermissionTest {
|
||||
|
||||
// when/then
|
||||
for (PlayerPermission permission : PlayerPermission.values()) {
|
||||
if (nodes.contains(permission.getNode())) {
|
||||
if (!nodes.add(permission.getNode())) {
|
||||
fail("More than one enum value defines the node '" + permission.getNode() + "'");
|
||||
}
|
||||
nodes.add(permission.getNode());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -37,10 +37,9 @@ public class PlayerStatePermissionTest {
|
||||
|
||||
// when/then
|
||||
for (PlayerStatePermission permission : PlayerStatePermission.values()) {
|
||||
if (nodes.contains(permission.getNode())) {
|
||||
if (!nodes.add(permission.getNode())) {
|
||||
fail("More than one enum value defines the node '" + permission.getNode() + "'");
|
||||
}
|
||||
nodes.add(permission.getNode());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -43,10 +43,9 @@ public class HashAlgorithmIntegrationTest {
|
||||
// when / then
|
||||
for (HashAlgorithm algorithm : HashAlgorithm.values()) {
|
||||
if (!HashAlgorithm.CUSTOM.equals(algorithm)) {
|
||||
if (classes.contains(algorithm.getClazz())) {
|
||||
if (!classes.add(algorithm.getClazz())) {
|
||||
fail("Found class '" + algorithm.getClazz() + "' twice!");
|
||||
}
|
||||
classes.add(algorithm.getClazz());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -74,10 +74,9 @@ public class SettingsClassConsistencyTest {
|
||||
if (Property.class.isAssignableFrom(field.getType())) {
|
||||
Property<?> property =
|
||||
(Property<?>) ReflectionTestUtils.getFieldValue(clazz, null, field.getName());
|
||||
if (paths.contains(property.getPath())) {
|
||||
if (!paths.add(property.getPath())) {
|
||||
fail("Path '" + property.getPath() + "' should be used by only one constant");
|
||||
}
|
||||
paths.add(property.getPath());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user