diff --git a/.travis.yml b/.travis.yml index 14a4ccf3..f6b0f140 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,3 +9,11 @@ cache: script: - mvn clean install -B && mvn clean -B + +notifications: + webhooks: + urls: + - https://webhooks.gitter.im/e/952357dbd9d3cea70fd5 + on_success: change # options: [always|never|change] default: always + on_failure: always # options: [always|never|change] default: always + on_start: false # default: false diff --git a/README.md b/README.md index bdaacf90..05c1edf2 100644 --- a/README.md +++ b/README.md @@ -4,6 +4,8 @@
#####Development tools: +[![Join the chat at https://gitter.im/Xephi/AuthMeReloaded](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/Xephi/AuthMeReloaded?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) + - Build status: [![Build Status](https://travis-ci.org/Xephi/AuthMeReloaded.svg?branch=master)](https://travis-ci.org/Xephi/AuthMeReloaded) - Build Server: Jenkins diff --git a/pom.xml b/pom.xml index b25cadc8..c6f2877a 100644 --- a/pom.xml +++ b/pom.xml @@ -3,7 +3,7 @@ xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> 4.0.0 - fr.xephi.authme.AuthMe + fr.xephi.authme AuthMe 5.0-SNAPSHOT @@ -79,6 +79,29 @@ + + org.apache.maven.plugins + maven-shade-plugin + 2.3 + + + + com.maxmind.geoip:* + com.sun.mail:* + javax.mail:* + com.comphenix.attribute:* + + + + + + package + + shade + + + + @@ -114,12 +137,6 @@ http://repo.minelink.net/content/repositories/public - - luricos-releases @@ -175,12 +192,7 @@ com.sun.mail javax.mail - 1.5.3 - - - javax.mail - mail - 1.5.0-b01 + 1.5.4 @@ -198,7 +210,7 @@ ${bukkitVersion} - + com.comphenix.attribute AttributeStorage @@ -212,7 +224,7 @@ org.bukkit craftbukkit - + @@ -229,7 +241,7 @@ org.bukkit craftbukkit - + @@ -246,7 +258,7 @@ org.bukkit craftbukkit - + @@ -265,7 +277,7 @@ org.bukkit craftbukkit - + @@ -282,7 +294,7 @@ org.bukkit craftbukkit - + @@ -299,7 +311,7 @@ org.bukkit craftbukkit - + @@ -316,7 +328,7 @@ org.bukkit craftbukkit - + @@ -333,7 +345,7 @@ org.bukkit craftbukkit - + @@ -350,11 +362,11 @@ org.bukkit craftbukkit - + - + com.Acrobot @@ -362,16 +374,6 @@ 3.8.10 system ${project.basedir}/libs/ChestShop.jar - - - org.bukkit - bukkit - - - org.bukkit - craftbukkit - - diff --git a/src/main/java/fr/xephi/authme/SendMailSSL.java b/src/main/java/fr/xephi/authme/SendMailSSL.java index 29e56cba..4d379379 100644 --- a/src/main/java/fr/xephi/authme/SendMailSSL.java +++ b/src/main/java/fr/xephi/authme/SendMailSSL.java @@ -6,7 +6,6 @@ import java.util.Properties; import javax.mail.BodyPart; import javax.mail.Message; -import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.Session; import javax.mail.Transport; @@ -41,53 +40,56 @@ public class SendMailSSL { sendername = Settings.getmailSenderName; } - String port = String.valueOf(Settings.getMailPort); - Properties props = new Properties(); - props.put("mail.smtp.host", Settings.getmailSMTP); - props.put("mail.smtp.auth", "true"); - props.put("mail.smtp.port", port); - props.put("mail.smtp.starttls.enable", true); + final String sender = sendername; + final String port = String.valueOf(Settings.getMailPort); + final String acc = Settings.getmailAccount; + final String subject = Settings.getMailSubject; + final String smtp = Settings.getmailSMTP; + final String password = Settings.getmailPassword; + final String mailText = Settings.getMailText; + final String mail = auth.getEmail(); - try { - Session session = Session.getInstance(props, null); + Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - final Message message = new MimeMessage(session); - try { - message.setFrom(new InternetAddress(Settings.getmailAccount, sendername)); - } catch (UnsupportedEncodingException uee) { - message.setFrom(new InternetAddress(Settings.getmailAccount)); - } - message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(auth.getEmail())); - message.setSubject(Settings.getMailSubject); - message.setSentDate(new Date()); - BodyPart messageBodyPart = new MimeBodyPart(); - String text = Settings.getMailText; - messageBodyPart.setText(text); + @Override + public void run() { + try { + Properties props = new Properties(); + props.put("mail.smtp.host", smtp); + props.put("mail.smtp.auth", "true"); + props.put("mail.smtp.port", port); + props.put("mail.smtp.starttls.enable", true); + Session session = Session.getInstance(props, null); - Multipart multipart = new MimeMultipart(); - - multipart.addBodyPart(messageBodyPart); - - messageBodyPart = new MimeBodyPart(); - - multipart.addBodyPart(messageBodyPart); - message.setContent(multipart); - final Transport transport = session.getTransport("smtp"); - transport.connect(Settings.getmailSMTP, Settings.getmailAccount, Settings.getmailPassword); - Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable() { - - @Override - public void run() { + Message message = new MimeMessage(session); try { - transport.sendMessage(message, message.getAllRecipients()); - } catch (MessagingException e) { - System.out.println("Some error occured while trying to send a mail to " + auth.getEmail()); + message.setFrom(new InternetAddress(acc, sender)); + } catch (UnsupportedEncodingException uee) { + message.setFrom(new InternetAddress(acc)); } - } + message.setRecipients(Message.RecipientType.TO, InternetAddress.parse(mail)); + message.setSubject(subject); + message.setSentDate(new Date()); + BodyPart messageBodyPart = new MimeBodyPart(); + messageBodyPart.setText(mailText); - }); - } catch (Exception e) { - System.out.println("Some error occured while trying to send a mail to " + auth.getEmail()); - } + Multipart multipart = new MimeMultipart(); + + multipart.addBodyPart(messageBodyPart); + + messageBodyPart = new MimeBodyPart(); + + multipart.addBodyPart(messageBodyPart); + message.setContent(multipart); + Transport transport = session.getTransport("smtp"); + transport.connect(smtp, acc, password); + transport.sendMessage(message, message.getAllRecipients()); + + } catch (Exception e) { + System.out.println("Some error occured while trying to send a mail to " + mail); + } + } + + }); } } diff --git a/src/main/java/fr/xephi/authme/Utils.java b/src/main/java/fr/xephi/authme/Utils.java index c2011c8c..b545dda4 100644 --- a/src/main/java/fr/xephi/authme/Utils.java +++ b/src/main/java/fr/xephi/authme/Utils.java @@ -1,10 +1,8 @@ package fr.xephi.authme; -import java.io.File; -import java.io.FileWriter; +import java.util.ArrayList; import java.util.Iterator; -import java.util.Random; -import java.util.Scanner; +import java.util.List; import org.bukkit.Bukkit; import org.bukkit.GameMode; @@ -12,10 +10,10 @@ import org.bukkit.Location; import org.bukkit.World; import org.bukkit.entity.Player; -import fr.xephi.authme.api.API; import fr.xephi.authme.cache.limbo.LimboCache; import fr.xephi.authme.cache.limbo.LimboPlayer; import fr.xephi.authme.events.AuthMeTeleportEvent; +import fr.xephi.authme.security.RandomString; import fr.xephi.authme.settings.Settings; public class Utils { @@ -24,6 +22,7 @@ public class Utils { private static Utils singleton; int id; public AuthMe plugin; + private static List tokens = new ArrayList(); public Utils(AuthMe plugin) { this.plugin = plugin; @@ -167,19 +166,18 @@ public class Utils { * Random Token for passpartu */ public boolean obtainToken() { - File file = new File("plugins" + File.separator + "AuthMe" + File.separator + "passpartu.token"); - if (file.exists()) - file.delete(); - - FileWriter writer = null; try { - file.createNewFile(); - writer = new FileWriter(file); - String token = generateToken(); - writer.write(token + ":" + System.currentTimeMillis() / 1000 + API.newline); - writer.flush(); + final String token = new RandomString(10).nextString(); + tokens.add(token); ConsoleLogger.info("[AuthMe] Security passpartu token: " + token); - writer.close(); + Bukkit.getScheduler().runTaskLaterAsynchronously(plugin, new Runnable() { + + @Override + public void run() { + tokens.remove(token); + } + + }, 600); return true; } catch (Exception e) { e.printStackTrace(); @@ -191,46 +189,11 @@ public class Utils { * Read Token */ public boolean readToken(String inputToken) { - File file = new File("plugins" + File.separator + "AuthMe" + File.separator + "passpartu.token"); - - if (!file.exists()) - return false; - - if (inputToken.isEmpty()) - return false; - Scanner reader = null; - try { - reader = new Scanner(file); - while (reader.hasNextLine()) { - final String line = reader.nextLine(); - if (line.contains(":")) { - String[] tokenInfo = line.split(":"); - if (tokenInfo[0].equals(inputToken) && System.currentTimeMillis() / 1000 - 30 <= Integer.parseInt(tokenInfo[1])) { - file.delete(); - reader.close(); - return true; - } - } - } - } catch (Exception e) { - e.printStackTrace(); - } - reader.close(); - return false; - } - - /* - * Generate Random Token - */ - private String generateToken() { - // obtain new random token - Random rnd = new Random(); - char[] arr = new char[5]; - for (int i = 0; i < 5; i++) { - int n = rnd.nextInt(36); - arr[i] = (char) (n < 10 ? '0' + n : 'a' + n - 10); - } - return new String(arr); + boolean ret = false; + if (tokens.contains(inputToken)) + ret = true; + tokens.remove(inputToken); + return (ret); } /* diff --git a/src/main/java/fr/xephi/authme/commands/AdminCommand.java b/src/main/java/fr/xephi/authme/commands/AdminCommand.java index 052b405a..2d2467eb 100644 --- a/src/main/java/fr/xephi/authme/commands/AdminCommand.java +++ b/src/main/java/fr/xephi/authme/commands/AdminCommand.java @@ -73,6 +73,7 @@ public class AdminCommand implements CommandExecutor { sender.sendMessage("/authme getemail - Get player email"); sender.sendMessage("/authme purgelastpos - Purge last position for a player"); sender.sendMessage("/authme switchantibot on/off - Enable/Disable antibot method"); + sender.sendMessage("/authme forcelogin "); return true; } @@ -552,6 +553,26 @@ public class AdminCommand implements CommandExecutor { database.updateQuitLoc(auth); sender.sendMessage("[AuthMe] Successfully reset position for " + auth.getNickname()); return true; + } else if (args[0].equalsIgnoreCase("forcelogin")) { + if (args.length < 2) { + sender.sendMessage("Usage : /authme forcelogin "); + return true; + } + try { + Player player = Bukkit.getPlayer(args[1]); + if (player == null || !player.isOnline()) { + sender.sendMessage("Online player only !"); + return true; + } + if (!plugin.authmePermissible(player, "authme.canbeforced")) { + sender.sendMessage("You cannot force login for this player!"); + return true; + } + plugin.management.performLogin(player, "dontneed", true); + sender.sendMessage("Force Login performed !"); + } catch (Exception e) { + sender.sendMessage("An error occured while trying to get that player!"); + } } else { sender.sendMessage("Usage: /authme reload|register playername password|changepassword playername password|unregister playername"); } diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java index f15529c8..e9137b18 100644 --- a/src/main/java/fr/xephi/authme/settings/Settings.java +++ b/src/main/java/fr/xephi/authme/settings/Settings.java @@ -263,7 +263,7 @@ public final class Settings extends YamlConfiguration { delayJoinMessage = configFile.getBoolean("settings.delayJoinMessage", false); noTeleport = configFile.getBoolean("settings.restrictions.noTeleport", false); crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db"); - getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[a-zA-Z0-9_?!@+&-]*"); + getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*"); applyBlindEffect = configFile.getBoolean("settings.applyBlindEffect", false); emailBlacklist = configFile.getStringList("Email.emailBlacklisted"); emailWhitelist = configFile.getStringList("Email.emailWhitelisted"); @@ -430,7 +430,7 @@ public final class Settings extends YamlConfiguration { delayJoinMessage = configFile.getBoolean("settings.delayJoinMessage", false); noTeleport = configFile.getBoolean("settings.restrictions.noTeleport", false); crazyloginFileName = configFile.getString("Converter.CrazyLogin.fileName", "accounts.db"); - getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[a-zA-Z0-9_?!@+&-]*"); + getPassRegex = configFile.getString("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*"); applyBlindEffect = configFile.getBoolean("settings.applyBlindEffect", false); emailBlacklist = configFile.getStringList("Email.emailBlacklisted"); emailWhitelist = configFile.getStringList("Email.emailWhitelisted"); @@ -554,7 +554,7 @@ public final class Settings extends YamlConfiguration { changes = true; } if (!contains("settings.restrictions.allowedPasswordCharacters")) { - set("settings.restrictions.allowedPasswordCharacters", "[a-zA-Z0-9_?!@+&-]*"); + set("settings.restrictions.allowedPasswordCharacters", "[\\x21-\\x7E]*"); changes = true; } if (!contains("settings.applyBlindEffect")) { @@ -579,13 +579,11 @@ public final class Settings extends YamlConfiguration { set("settings.forceRegisterCommandsAsConsole", new ArrayList()); changes = true; } - if (!contains("Hooks.customAttributes")) - { + if (!contains("Hooks.customAttributes")) { set("Hooks.customAttributes", false); changes = true; } - if (!contains("Purge.removePermissions")) - { + if (!contains("Purge.removePermissions")) { set("Purge.removePermissions", false); changes = true; } diff --git a/src/main/resources/messages_it.yml b/src/main/resources/messages_it.yml index 247a4f3b..978e29fb 100644 --- a/src/main/resources/messages_it.yml +++ b/src/main/resources/messages_it.yml @@ -1,56 +1,56 @@ -unknown_user: "L'utente non è presente nel database" -unsafe_spawn: 'Il tuo punto di logout non era sicuro, sei stato teletrasportato allo Spawn' -not_logged_in: '&cNon loggato!' -reg_voluntarily: 'Puoi registrare il tuo nickname nel server con "/register "' +unknown_user: "L'utente non è presente nel database." +unsafe_spawn: 'Il punto di disconnessione è attualmente ostruito o insicuro, sei stato teletrasportato al punto di rigenerazione!' +not_logged_in: "&cL'utente non ha ancora eseguito l'autenticazione!" +reg_voluntarily: 'Per eseguire la registrazione al server devi eseguire il seguente comando: "/register "' usage_log: '&cUtilizzo: /login ' -wrong_pwd: '&cPassword sbagliata' -unregistered: '&cCancellato correttamente!' -reg_disabled: '&cLe registrazioni sono disabilitate' -valid_session: '&cLoggato attraverso la sessione' -login: '&cLoggato correttamente!' -vb_nonActiv: 'Il tuo account non è ancora attivo, controlla le tue Email!' -user_regged: '&cUtente già registrato' +wrong_pwd: '&cPassword non corretta!' +unregistered: "&cL'utente è stato rimosso dal database con successo!" +reg_disabled: '&cLa registrazione tramite i comandi del gioco è disabilitata.' +valid_session: '&cAutenticato attraverso la sessione ripresa!' +login: '&cAutenticazone effettuata correttamente!' +vb_nonActiv: 'Il tuo Account non è stato ancora verificato, controlla le tue Email per scoprire come attivarlo!' +user_regged: "&cL'utente si è già registrato, impossibile eseguire nuovamente la registrazione." usage_reg: '&cUtilizzo: /register ' -max_reg: 'Hai raggiunto il numero massimo di registrazioni per il tuo account' -no_perm: '&cNessun Permesso' -error: "Errore; Perfavore, contatta l'admin" -login_msg: '&cPerfavore, loggati con "/login "' -reg_msg: '&cPerfavore, registrati con "/register "' -reg_email_msg: '&cPerfavore, registrati con "/register "' +max_reg: 'Hai raggiunto il numero massimo di registrazioni per indirizzo IP!' +no_perm: '&cNon hai il permesso di eseguire questa operazione.' +login_msg: '&cPerfavore, per giocare devi effettuare l'autenticazione con il comando: "/login "' +reg_msg: '&cPerfavore, per connetterti al server devi prima registrarti con il comando: "/register "' +reg_email_msg: '&cPerfavore, per connetterti al server devi prima registrarti con il comando: "/register "' usage_unreg: '&cUtilizzo: /unregister ' -pwd_changed: '&cPassword cambiata correttamente!' -user_unknown: '&cUtente non registrato' -password_error: 'Le Password non corrispondono' -unvalid_session: "I tuoi dati non combaciano con l'ultima sessione. Per favore attendi la fine della sessione attuale" -reg_only: 'Possono entrare solo utenti registrati! Perfavore, vai su http://example.com per registrarti' -logged_in: '&cSei già loggato!' -logout: '&cDisconnesso correttamente' -same_nick: 'Lo stesso nickname è già online' +pwd_changed: '&cPassword cambiata con successo!' +user_unknown: "&cL'utente non ha ancora eseguito la registrazione." +password_error: 'Le Password non corrispondono!' +invalid_session: "I tuoi dati di connessione attuali non sono quelli utilizzati in precedenza. Attendere la fine della sessione attuale." +reg_only: 'La registrazione è effettuabile soltanto attraverso il sito web! Perfavore, vai su http://example.com per procedere!' +logged_in: '&cHai già eseguito l'autenticazione!' +logout: '&cDisconnessione avvenuta correttamente!' +same_nick: 'Lo stesso nickname è già online sul server!' registered: '&cRegistrato correttamente!' -pass_len: 'La tua password è troppo corta o troppo lunga' -reload: 'La configurazione e il database sono stati ricaricati' -timeout: 'Timeout di Login' +pass_len: 'La tua password è troppo corta o troppo lunga, prova a cambiarla!' +reload: 'La configurazione e il database sono stati ricaricati con successo!' +timeout: "Tempo scaduto per effettuare l'autenticazione" usage_changepassword: 'Utilizzo: /changepassword ' -name_len: '&cIl tuo nickname è troppo corto o troppo lungo' -regex: '&cIl tuo nickname contiene caratteri strani. Caratteri abilitati: REG_EX' -add_email: '&cPer una maggiore sicurezza, aggiungi una mail con : /email add ' -bad_database_email: '[AuthMe] Il comando /email è utilizzabile solo con MySQL o SQLite, contatta un admin' -recovery_email: '&cDimenticata la tua password? Perfavore, fai /email recovery ' +name_len: '&cIl tuo nickname è troppo corto o troppo lungo!' +regex: '&cIl tuo nickname contiene caratteri non consentiti. I caratteri consentiti sono: REG_EX' +add_email: '&cPer poter recuperare la password in futuro, aggiungi una email al tuo account con il comando: "/email add tuaEmail confermaEmail"' +bad_database_email: 'Il comando /email è utilizzabile solo con database MySQL o SQLite, riporta questo errore ad un Admin!' +recovery_email: '&cHai dimenticato la tua password? Puoi recuperarla eseguendo il comando: "/email recovery "' usage_captcha: '&cUtilizzo: /captcha ' -wrong_captcha: '&cCaptcha sbagliato, perfavore fai: /captcha THE_CAPTCHA' +wrong_captcha: '&cCodice captcha sbagliato, perfavore riprova eseguendo il comando: "/captcha THE_CAPTCHA"' valid_captcha: '&cIl tuo captcha è valido!' kick_forvip: '&cUn utente VIP è entrato mentre il server era pieno!' kick_fullserver: '&cIl server è attualmente pieno, riprova più tardi!' usage_email_add: '&fUtilizzo: /email add ' usage_email_change: '&fUtilizzo: /email change ' usage_email_recovery: '&fUtilizzo: /email recovery ' -new_email_invalid: '[AuthMe] La nuova Email non è valida!' -old_email_invalid: '[AuthMe] La vecchia Email non è valida!' -email_invalid: "[AuthMe] L'Email non è valida" -email_added: '[AuthMe] Email aggiunta!' -email_confirm: '[AuthMe] Conferma la tua Email!' -email_changed: '[AuthMe] Email cambiata!' -email_send: '[AuthMe] Email di recupero inviata!' -country_banned: 'Il tuo paese è bannato su questo server' -antibot_auto_enabled: '[AuthMe] AntiBotMod è stato automaticamente abilitato a seguito delle numerose connessioni!' -antibot_auto_disabled: "[AuthMe] AntiBotMod è stato automaticamente disabilitato dopo %m Minuti, sperando che l'invasione sia finita" +new_email_invalid: 'La nuova Email non è valida!' +old_email_invalid: 'La vecchia Email non è valida!' +email_invalid: "L'Email non è valida" +email_added: 'Email aggiunta correttamente!' +email_confirm: 'Conferma la tua Email!' +email_changed: 'Email cambiata correttamente!' +email_send: 'Email di recupero inviata al tuo indirizzo!' +email_exists: 'Il tuo account ha già una Email configurata. Se vuoi, puoi cambiarla con il seguente comando:' +country_banned: 'Il tuo paese è bandito su questo server!' +antibot_auto_enabled: 'Il servizio di AntiBot è stato automaticamente abilitato a seguito delle numerose connessioni!' +antibot_auto_disabled: "Il servizio di AntiBot è stato automaticamente disabilitato dopo %m Minuti, sperando che l'attacco sia finito!" diff --git a/src/main/resources/messages_zhhk.yml b/src/main/resources/messages_zhhk.yml index 96906a53..55ef0981 100644 --- a/src/main/resources/messages_zhhk.yml +++ b/src/main/resources/messages_zhhk.yml @@ -1,5 +1,4 @@ # Translator: uSoc_lifehome (http://lifeho.me) # -# '-- Last edit: 1405878032 UTC # # -------------------------------------------- # unknown_user: '&8[&6用戶系統&8] &f用戶資料並不存在於資料庫中。' unsafe_spawn: '&8[&6用戶系統&8] &f你的登出位置不安全,現在將傳送你到重生點。' @@ -25,7 +24,7 @@ pwd_changed: '&8[&6用戶系統&8] &c你成功的更換了你的密碼 !' user_unknown: '&8[&6用戶系統&8] &c此用戶名沒有已登記資料。' password_error: '&8[&6用戶系統&8] &f密碼不符合。' unvalid_session: '&8[&6用戶系統&8] &f登入階段資料已損壞,請等待登入階段結束。' -reg_only: '&8[&6用戶系統&8] &f限已註冊會員,請先到 https://www.craftinghk.com/ 註冊。' +reg_only: '&8[&6用戶系統&8] &f限已註冊會員,請先到 https://www.example.com/ 註冊。' logged_in: '&8[&6用戶系統&8] &c你已經登入過了。' logout: '&8[&6用戶系統&8] &b你成功的登出了。' same_nick: '&8[&6用戶系統&8] &f同名玩家已在遊玩。' diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml index 560ac19b..d74b46c9 100644 --- a/src/main/resources/plugin.yml +++ b/src/main/resources/plugin.yml @@ -69,6 +69,7 @@ permissions: authme.admin.getip: true authme.admin.converter: true authme.admin.resetposition: true + authme.admin.forcelogin: true authme.register: description: Register an account default: true @@ -165,3 +166,9 @@ permissions: authme.admin.resetposition: description: Reset last position for a player default: op + authme.admin.forcelogin: + description: Force login for that player + default: op + authme.canbeforced: + description: Can this player be forced to login + default: true \ No newline at end of file