Date: Thu, 31 Dec 2015 13:32:41 +0100
Subject: [PATCH 04/24] Minor - Javadoc changes - Add/replace/improve javadoc
in the commands and encryption section - Note: A simple is the javadoc
way to make a new paragraph
http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html#format
- Note: Do not escape '<' and '>' inside of {@code } - Note: '>' does not
need to be escaped
---
.../authme/command/CommandDescription.java | 16 +++++++------
.../xephi/authme/command/CommandHandler.java | 7 +++---
.../xephi/authme/command/CommandService.java | 23 +++++++++++--------
.../authme/command/FoundCommandResult.java | 3 +--
.../xephi/authme/command/PlayerCommand.java | 2 +-
.../crypts/description/AsciiRestricted.java | 2 +-
.../security/crypts/description/HasSalt.java | 12 ++++++----
.../crypts/description/Recommendation.java | 10 +++++---
.../security/crypts/description/SaltType.java | 2 +-
.../security/crypts/description/Usage.java | 6 +++++
.../crypts/AbstractEncryptionMethodTest.java | 18 +++++++++++++--
11 files changed, 67 insertions(+), 34 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/command/CommandDescription.java b/src/main/java/fr/xephi/authme/command/CommandDescription.java
index d398af674..22a3f05cd 100644
--- a/src/main/java/fr/xephi/authme/command/CommandDescription.java
+++ b/src/main/java/fr/xephi/authme/command/CommandDescription.java
@@ -12,12 +12,13 @@ import static com.google.common.base.Preconditions.checkArgument;
import static java.util.Arrays.asList;
/**
- * Command description - defines which labels ("names") will lead to a command and points to the
+ * Command description – defines which labels ("names") will lead to a command and points to the
* {@link ExecutableCommand} implementation that executes the logic of the command.
*
- * CommandDescription instances are built hierarchically and have one parent or {@code null} for base commands
- * (main commands such as /authme) and may have multiple children extending the mapping of the parent: e.g. if
- * /authme has a child whose label is "register", then "/authme register" is the command that the child defines.
+ * CommandDescription instances are built hierarchically: they have one parent, or {@code null} for base commands
+ * (main commands such as {@code /authme}), and may have multiple children extending the mapping of the parent: e.g. if
+ * {@code /authme} has a child whose label is {@code "register"}, then {@code /authme register} is the command that
+ * the child defines.
*/
public class CommandDescription {
@@ -102,10 +103,11 @@ public class CommandDescription {
}
/**
- * Get all relative labels of this command. For example, if this object describes "/authme register" and
- * "/authme r", then "r" and "register" are the relative labels, whereas "authme" is the label of the parent.
+ * Return all relative labels of this command. For example, if this object describes {@code /authme register} and
+ * {@code /authme r}, then it will return a list with {@code register} and {@code r}. The parent label
+ * {@code authme} is not returned.
*
- * @return All relative labels.
+ * @return All labels of the command description.
*/
public List getLabels() {
return labels;
diff --git a/src/main/java/fr/xephi/authme/command/CommandHandler.java b/src/main/java/fr/xephi/authme/command/CommandHandler.java
index 3d6d3d243..e3ab671b4 100644
--- a/src/main/java/fr/xephi/authme/command/CommandHandler.java
+++ b/src/main/java/fr/xephi/authme/command/CommandHandler.java
@@ -49,9 +49,10 @@ public class CommandHandler {
}
/**
- *
- * @param sender
- * @param result
+ * Execute the command for the given command sender.
+ *
+ * @param sender The sender which initiated the command
+ * @param result The mapped result
*/
private void executeCommand(CommandSender sender, FoundCommandResult result) {
ExecutableCommand executableCommand = result.getCommandDescription().getExecutableCommand();
diff --git a/src/main/java/fr/xephi/authme/command/CommandService.java b/src/main/java/fr/xephi/authme/command/CommandService.java
index f8b7f8529..08a2790e8 100644
--- a/src/main/java/fr/xephi/authme/command/CommandService.java
+++ b/src/main/java/fr/xephi/authme/command/CommandService.java
@@ -54,10 +54,11 @@ public class CommandService {
}
/**
- *
- * @param sender CommandSender
- * @param messageKey MessageKey
- * @param replacements String...
+ * Send a message to a player.
+ *
+ * @param sender The command sender to send the message to
+ * @param messageKey The message key to send
+ * @param replacements The replacement arguments for the message key's tags
*/
public void send(CommandSender sender, MessageKey messageKey, String... replacements) {
messages.send(sender, messageKey, replacements);
@@ -127,7 +128,7 @@ public class CommandService {
}
/**
- * Returns the management instance of the plugin.
+ * Return the management instance of the plugin.
*
* @return The Management instance linked to the AuthMe instance
*/
@@ -136,8 +137,9 @@ public class CommandService {
}
/**
- *
- * @return PermissionManager the PermissionManager
+ * Return the permissions manager.
+ *
+ * @return the permissions manager
*/
public PermissionsManager getPermissionsManager() {
// TODO ljacqu 20151226: Might be nicer to pass the perm manager via constructor
@@ -145,9 +147,10 @@ public class CommandService {
}
/**
- *
- * @param key MessageKey
- * @return StringArray Array of String
+ * Retrieve a message by its message key.
+ *
+ * @param key The message to retrieve
+ * @return The message
*/
public String[] retrieveMessage(MessageKey key) {
return messages.retrieve(key);
diff --git a/src/main/java/fr/xephi/authme/command/FoundCommandResult.java b/src/main/java/fr/xephi/authme/command/FoundCommandResult.java
index 7f19a4f09..520eec243 100644
--- a/src/main/java/fr/xephi/authme/command/FoundCommandResult.java
+++ b/src/main/java/fr/xephi/authme/command/FoundCommandResult.java
@@ -3,10 +3,9 @@ package fr.xephi.authme.command;
import java.util.List;
/**
- *
* Result of a command mapping by {@link CommandHandler}. An object of this class represents a successful mapping
* as well as erroneous ones, as communicated with {@link FoundResultStatus}.
- *
+ *
* Fields other than {@link FoundResultStatus} are available depending, among other factors, on the status:
*
* - {@link FoundResultStatus#SUCCESS} entails that mapping the input to a command was successful. Therefore,
diff --git a/src/main/java/fr/xephi/authme/command/PlayerCommand.java b/src/main/java/fr/xephi/authme/command/PlayerCommand.java
index 5792dd975..2d7aca0b9 100644
--- a/src/main/java/fr/xephi/authme/command/PlayerCommand.java
+++ b/src/main/java/fr/xephi/authme/command/PlayerCommand.java
@@ -35,7 +35,7 @@ public abstract class PlayerCommand implements ExecutableCommand {
/**
* Return an alternative command (textual representation) that is not restricted to players only.
- * Example: "authme register <playerName> <password>"
+ * Example: {@code "authme register "}
*
* @return Alternative command not only for players, or null if not applicable
*/
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java b/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java
index f515717e7..bf179fff2 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/description/AsciiRestricted.java
@@ -6,7 +6,7 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Denotes an encryption algorithm that is restricted to the ASCII charset.
+ * Denotes a hashing algorithm that is restricted to the ASCII charset.
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java b/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java
index 85ad06080..0723a4ddb 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/description/HasSalt.java
@@ -13,13 +13,17 @@ import java.lang.annotation.Target;
@Retention(RetentionPolicy.RUNTIME)
public @interface HasSalt {
- /** The type of the salt.
- * @return salttype The SaltType
+ /**
+ * The type of the salt.
+ *
+ * @return The salt type
*/
SaltType value();
- /** For text salts, the length of the salt.
- * @return int Integer
+ /**
+ * For text salts, the length of the salt.
+ *
+ * @return The length of the salt the algorithm uses, or 0 if not defined or not applicable.
*/
int length() default 0;
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java b/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java
index e57a0c401..4b832a681 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/description/Recommendation.java
@@ -6,14 +6,18 @@ import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
- * Annotation to mark a hash algorithm with the usage recommendation, see {@link Usage}.
+ * Annotation to mark a hash algorithm with the usage recommendation.
+ *
+ * @see Usage
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
public @interface Recommendation {
- /** The recommendation for using the hash algorithm.
- * @return Usage The Usage
+ /**
+ * The recommendation for using the hash algorithm.
+ *
+ * @return The recommended usage
*/
Usage value();
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java b/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java
index 7d6b225ca..40b923fa9 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/description/SaltType.java
@@ -8,7 +8,7 @@ public enum SaltType {
/** Random, newly generated text. */
TEXT,
- /** Salt is based on the username, including variations and repetitions. */
+ /** Salt is based on the username, including variations and repetitions thereof. */
USERNAME,
/** No salt. */
diff --git a/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java b/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java
index ecf37a980..c11c335ac 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/description/Usage.java
@@ -2,6 +2,12 @@ package fr.xephi.authme.security.crypts.description;
/**
* Usage recommendation that can be provided for a hash algorithm.
+ *
+ * Use the following rules of thumb:
+ *
+ * - Hashes using MD5 may be {@link #ACCEPTABLE} but never {@link #RECOMMENDED}.
+ * - Hashes using no salt or one based on the username should be {@link #DO_NOT_USE}.
+ *
*/
public enum Usage {
diff --git a/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java b/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java
index 9acc3c25e..ef78c5fda 100644
--- a/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java
+++ b/src/test/java/fr/xephi/authme/security/crypts/AbstractEncryptionMethodTest.java
@@ -142,30 +142,44 @@ public abstract class AbstractEncryptionMethodTest {
return method.comparePassword(password, hashes.get(password), USERNAME);
}
- // @org.junit.Test public void a() { AbstractEncryptionMethodTest.generateTest(); }
- // TODO #364: Remove this method
+ /**
+ * Generates a test class for a given encryption method. Simply create a test class and run the following code,
+ * replacing {@code XXX} with the actual class:
+ *
+ * @org.junit.Test public void generate() { AbstractEncryptionMethodTest.generateTest(new XXX()); }
+ *
+ * The output is the entire test class.
+ *
+ * @param method The method to create a test class for
+ */
static void generateTest(EncryptionMethod method) {
String className = method.getClass().getSimpleName();
+ // Create javadoc and "public class extends" and the constructor call "super(new Class(),"
System.out.println("/**\n * Test for {@link " + className + "}.\n */");
System.out.println("public class " + className + "Test extends AbstractEncryptionMethodTest {");
System.out.println("\n\tpublic " + className + "Test() {");
System.out.println("\t\tsuper(new " + className + "(),");
+ // Iterate through the GIVEN_PASSWORDS and generate a hash so we can always check it later
String delim = ", ";
for (String password : GIVEN_PASSWORDS) {
if (password.equals(GIVEN_PASSWORDS[GIVEN_PASSWORDS.length - 1])) {
delim = "); ";
}
+ // Encr. method uses separate salt, so we need to call the constructor that takes HashedPassword instances
if (method.hasSeparateSalt()) {
HashedPassword hashedPassword = method.computeHash(password, USERNAME);
System.out.println(String.format("\t\tnew HashedPassword(\"%s\", \"%s\")%s// %s",
hashedPassword.getHash(), hashedPassword.getSalt(), delim, password));
} else {
+ // Encryption method doesn't have separate salt, so simply pass the generated hash to the constructor
System.out.println("\t\t\"" + method.computeHash(password, USERNAME).getHash()
+ "\"" + delim + "// " + password);
}
}
+
+ // Close the constructor and class declarations
System.out.println("\t}");
System.out.println("\n}");
}
From 6475cecd795511b12fe07653a0c54394828a2f53 Mon Sep 17 00:00:00 2001
From: ljacqu
Date: Thu, 31 Dec 2015 13:33:00 +0100
Subject: [PATCH 05/24] Add tools task to generate an encryption algorithm
overview
---
.../authme/security/crypts/CRAZYCRYPT1.java | 2 -
.../fr/xephi/authme/security/crypts/IPB3.java | 2 +-
.../fr/xephi/authme/security/crypts/MYBB.java | 6 +
.../fr/xephi/authme/security/crypts/WBB3.java | 6 +
src/tools/docs/hash_algorithms.md | 78 ++++++++++
.../EncryptionMethodInfoGatherer.java | 135 ++++++++++++++++++
.../HashAlgorithmsDescriptionTask.java | 100 +++++++++++++
src/tools/hashmethods/MethodDescription.java | 85 +++++++++++
src/tools/hashmethods/hash_algorithms.tpl.md | 53 +++++++
.../hashmethods/hash_algorithms_row.tpl.md | 1 +
10 files changed, 465 insertions(+), 3 deletions(-)
create mode 100644 src/tools/docs/hash_algorithms.md
create mode 100644 src/tools/hashmethods/EncryptionMethodInfoGatherer.java
create mode 100644 src/tools/hashmethods/HashAlgorithmsDescriptionTask.java
create mode 100644 src/tools/hashmethods/MethodDescription.java
create mode 100644 src/tools/hashmethods/hash_algorithms.tpl.md
create mode 100644 src/tools/hashmethods/hash_algorithms_row.tpl.md
diff --git a/src/main/java/fr/xephi/authme/security/crypts/CRAZYCRYPT1.java b/src/main/java/fr/xephi/authme/security/crypts/CRAZYCRYPT1.java
index 269c1365e..cd8af9249 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/CRAZYCRYPT1.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/CRAZYCRYPT1.java
@@ -10,8 +10,6 @@ import fr.xephi.authme.security.crypts.description.HasSalt;
import java.nio.charset.Charset;
import java.security.MessageDigest;
-@Recommendation(Usage.DO_NOT_USE)
-@HasSalt(SaltType.USERNAME)
public class CRAZYCRYPT1 extends UsernameSaltMethod {
private static final char[] CRYPTCHARS =
diff --git a/src/main/java/fr/xephi/authme/security/crypts/IPB3.java b/src/main/java/fr/xephi/authme/security/crypts/IPB3.java
index 85789b881..4abfe5d45 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/IPB3.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/IPB3.java
@@ -8,7 +8,7 @@ import fr.xephi.authme.security.crypts.description.Usage;
import static fr.xephi.authme.security.HashUtils.md5;
-@Recommendation(Usage.DO_NOT_USE)
+@Recommendation(Usage.ACCEPTABLE)
@HasSalt(value = SaltType.TEXT, length = 5)
public class IPB3 extends SeparateSaltMethod {
diff --git a/src/main/java/fr/xephi/authme/security/crypts/MYBB.java b/src/main/java/fr/xephi/authme/security/crypts/MYBB.java
index 97418640c..555f3213a 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/MYBB.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/MYBB.java
@@ -1,9 +1,15 @@
package fr.xephi.authme.security.crypts;
import fr.xephi.authme.security.RandomString;
+import fr.xephi.authme.security.crypts.description.HasSalt;
+import fr.xephi.authme.security.crypts.description.Recommendation;
+import fr.xephi.authme.security.crypts.description.SaltType;
+import fr.xephi.authme.security.crypts.description.Usage;
import static fr.xephi.authme.security.HashUtils.md5;
+@Recommendation(Usage.ACCEPTABLE)
+@HasSalt(value = SaltType.TEXT, length = 8)
public class MYBB extends SeparateSaltMethod {
@Override
diff --git a/src/main/java/fr/xephi/authme/security/crypts/WBB3.java b/src/main/java/fr/xephi/authme/security/crypts/WBB3.java
index 6cc123005..28e975856 100644
--- a/src/main/java/fr/xephi/authme/security/crypts/WBB3.java
+++ b/src/main/java/fr/xephi/authme/security/crypts/WBB3.java
@@ -1,9 +1,15 @@
package fr.xephi.authme.security.crypts;
import fr.xephi.authme.security.RandomString;
+import fr.xephi.authme.security.crypts.description.HasSalt;
+import fr.xephi.authme.security.crypts.description.Recommendation;
+import fr.xephi.authme.security.crypts.description.SaltType;
+import fr.xephi.authme.security.crypts.description.Usage;
import static fr.xephi.authme.security.HashUtils.sha1;
+@Recommendation(Usage.ACCEPTABLE)
+@HasSalt(value = SaltType.TEXT, length = 40)
public class WBB3 extends SeparateSaltMethod {
@Override
diff --git a/src/tools/docs/hash_algorithms.md b/src/tools/docs/hash_algorithms.md
new file mode 100644
index 000000000..2996fd8ce
--- /dev/null
+++ b/src/tools/docs/hash_algorithms.md
@@ -0,0 +1,78 @@
+
+
+
+## Hash Algorithms
+AuthMe supports the following hash algorithms for storing your passwords safely.
+
+
+Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate? |
+--------- | -------------- | ----------- | ----- | - | --------- | ------ | --------- |
+BCRYPT | Recommended | 60 | | | Text | |
+BCRYPT2Y | Recommended | 60 | | | Text | 22 |
+CRAZYCRYPT1 | Do not use | 128 | | | Username | |
+DOUBLEMD5 | Do not use | 32 | | | None | |
+IPB3 | Acceptable | 32 | | | Text | 5 | Y
+JOOMLA | Recommended | 65 | | | Text | 32 |
+MD5 | Do not use | 32 | | | None | |
+MD5VB | Acceptable | 56 | | | Text | 16 |
+MYBB | Acceptable | 32 | | | Text | 8 | Y
+PBKDF2 | Does not work | 329 | | | Text | 12 |
+PBKDF2DJANGO | Acceptable | 77 | Y | | Text | 12 |
+PHPBB | Acceptable | 34 | | | Text | 16 |
+PHPFUSION | Do not use | 64 | Y | | | | Y
+ROYALAUTH | Do not use | 128 | | | None | |
+SALTED2MD5 | Acceptable | 32 | | | Text | | Y
+SALTEDSHA512 | Recommended | 128 | | | | | Y
+SHA1 | Do not use | 40 | | | None | |
+SHA256 | Recommended | 86 | | | Text | 16 |
+SHA512 | Do not use | 128 | | | None | |
+SMF | Do not use | 40 | | | Username | |
+WBB3 | Acceptable | 40 | | | Text | 40 | Y
+WBB4 | Does not work | 60 | | | Text | 8 |
+WHIRLPOOL | Do not use | 128 | | | None | |
+WORDPRESS | Do not use | 34 | | | Text | 9 |
+XAUTH | Recommended | 140 | | | Text | 12 |
+CUSTOM | | | | | | | |
+
+
+
+### Columns
+#### Algorithm
+The algorithm is the hashing algorithm used to store passwords with. Default is SHA256 and is recommended.
+You can change the hashing algorithm in the config.yml: under `security`, locate `passwordHash`.
+
+#### Recommendation
+The recommendation lists our usage recommendation in terms of how secure it is (not how _well_ the algorithm works!).
+- Recommended: The hash algorithm appears to be cryptographically secure and is one we recommend.
+- Acceptable: There are safer algorithms that can be chosen but using the algorithm is generally OK.
+- Do not use: Hash algorithm isn't sufficiently secure. Use only if required to hook into another system.
+- Does not work: The algorithm does not work properly; do not use.
+
+#### Hash Length
+The length of the hashes the algorithm produces. Note that the hash length is not (primarily) indicative of
+whether an algorithm is secure or not.
+
+#### ASCII
+If denoted with a **y**, means that the algorithm is restricted to ASCII characters only, i.e. it will simply ignore
+"special characters" such as `ÿ` or `Â`. Note that we do not recommend the use of "special characters" in passwords.
+
+#### Salt Columns
+Before hashing, a _salt_ may be appended to the password to make the hash more secure. The following columns describe
+the salt the algorithm uses.
+
+
+##### Salt Type
+We do not recommend the usage
+of any algorithm that doesn't use a randomly generated text as salt. This "salt type" column indicates what type of
+salt the algorithm uses:
+- Text: randomly generated text (see also the following column, "Length")
+- Username: the salt is constructed from the username (bad)
+- None: the algorithm uses no salt (bad)
+
+##### Length
+If applicable (salt type is "Text"), indicates the length of the generated salt. The longer the better.
+If this column is empty when the salt type is "Text", it typically means the salt length can be defined in config.yml.
+
+##### Separate
+If denoted with a **y**, it means that the salt is stored in a separate column in the database. This is neither good
+or bad.
diff --git a/src/tools/hashmethods/EncryptionMethodInfoGatherer.java b/src/tools/hashmethods/EncryptionMethodInfoGatherer.java
new file mode 100644
index 000000000..07c588ea5
--- /dev/null
+++ b/src/tools/hashmethods/EncryptionMethodInfoGatherer.java
@@ -0,0 +1,135 @@
+package hashmethods;
+
+import fr.xephi.authme.security.HashAlgorithm;
+import fr.xephi.authme.security.crypts.EncryptionMethod;
+import fr.xephi.authme.security.crypts.HexSaltedMethod;
+import fr.xephi.authme.security.crypts.description.AsciiRestricted;
+import fr.xephi.authme.security.crypts.description.HasSalt;
+import fr.xephi.authme.security.crypts.description.Recommendation;
+
+import java.lang.annotation.Annotation;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.Map;
+import java.util.Set;
+
+import static com.google.common.collect.Sets.newHashSet;
+
+/**
+ * Gathers information on {@link fr.xephi.authme.security.crypts.EncryptionMethod} implementations based on
+ * the annotations in {@link fr.xephi.authme.security.crypts.description}.
+ */
+public class EncryptionMethodInfoGatherer {
+
+ @SuppressWarnings("unchecked")
+ private final static Set> RELEVANT_ANNOTATIONS =
+ newHashSet(HasSalt.class, Recommendation.class, AsciiRestricted.class);
+
+ private Map descriptions;
+
+ public EncryptionMethodInfoGatherer() {
+ descriptions = new LinkedHashMap<>();
+ constructDescriptions();
+ }
+
+ public Map getDescriptions() {
+ return descriptions;
+ }
+
+ private void constructDescriptions() {
+ for (HashAlgorithm algorithm : HashAlgorithm.values()) {
+ Class extends EncryptionMethod> methodClazz = algorithm.getClazz();
+ if (!HashAlgorithm.CUSTOM.equals(algorithm) && !methodClazz.isAnnotationPresent(Deprecated.class)) {
+ MethodDescription description = createDescription(methodClazz);
+ descriptions.put(algorithm, description);
+ }
+ }
+ }
+
+ private static MethodDescription createDescription(Class extends EncryptionMethod> clazz) {
+ EncryptionMethod method = instantiateMethod(clazz);
+ MethodDescription description = new MethodDescription(clazz);
+ description.setHashLength(method.computeHash("test", "user").getHash().length());
+ description.setHasSeparateSalt(method.hasSeparateSalt());
+
+ Map, Annotation> annotationMap = gatherAnnotations(clazz);
+ if (annotationMap.containsKey(HasSalt.class)) {
+ setSaltInformation(description, returnTyped(annotationMap, HasSalt.class), method);
+ }
+ if (annotationMap.containsKey(Recommendation.class)) {
+ description.setUsage(returnTyped(annotationMap, Recommendation.class).value());
+ }
+ if (annotationMap.containsKey(AsciiRestricted.class)) {
+ description.setAsciiRestricted(true);
+ }
+ return description;
+ }
+
+ private static Map, Annotation> gatherAnnotations(Class> methodClass) {
+ // Note ljacqu 20151231: The map could be Map, Annotation> and it has the constraint
+ // that for a key Class, the value is of type T. We write a simple "Class>" for brevity.
+ Map, Annotation> collection = new HashMap<>();
+ Class> currentMethodClass = methodClass;
+ while (currentMethodClass != null) {
+ getRelevantAnnotations(currentMethodClass, collection);
+ currentMethodClass = getSuperClass(currentMethodClass);
+ }
+ return collection;
+ }
+
+ // Parameters could be Class extends EncryptionMethod>; Map, Annotation>
+ // but the constraint doesn't have any technical relevance, so just clutters the code
+ private static void getRelevantAnnotations(Class> methodClass, Map, Annotation> collection) {
+ for (Annotation annotation : methodClass.getAnnotations()) {
+ if (RELEVANT_ANNOTATIONS.contains(annotation.annotationType())
+ && !collection.containsKey(annotation.annotationType())) {
+ collection.put(annotation.annotationType(), annotation);
+ }
+ }
+ }
+
+ /**
+ * Returns the super class of the given encryption method if it is also of EncryptionMethod type.
+ * (Anything beyond EncryptionMethod is not of interest.)
+ */
+ private static Class> getSuperClass(Class> methodClass) {
+ Class> zuper = methodClass.getSuperclass();
+ if (EncryptionMethod.class.isAssignableFrom(zuper)) {
+ return zuper;
+ }
+ return null;
+ }
+
+ /**
+ * Set the salt information for the given encryption method and the found {@link HasSalt} annotation.
+ * Also gets the salt length from {@link HexSaltedMethod#getSaltLength()} for such instances.
+ *
+ * @param description The description to update
+ * @param hasSalt The associated HasSalt annotation
+ * @param method The encryption method
+ */
+ private static void setSaltInformation(MethodDescription description, HasSalt hasSalt, EncryptionMethod method) {
+ description.setSaltType(hasSalt.value());
+ if (hasSalt.length() != 0) {
+ description.setSaltLength(hasSalt.length());
+ } else if (method instanceof HexSaltedMethod) {
+ int saltLength = ((HexSaltedMethod) method).getSaltLength();
+ description.setSaltLength(saltLength);
+ }
+ }
+
+ private static EncryptionMethod instantiateMethod(Class extends EncryptionMethod> clazz) {
+ try {
+ return clazz.newInstance();
+ } catch (InstantiationException | IllegalAccessException e) {
+ throw new RuntimeException("Could not instantiate " + clazz, e);
+ }
+ }
+
+ // Convenience method for retrieving an annotation in a typed fashion.
+ // We know implicitly that the key of the map always corresponds to the type of the value
+ private static T returnTyped(Map, Annotation> map, Class key) {
+ return key.cast(map.get(key));
+ }
+
+}
diff --git a/src/tools/hashmethods/HashAlgorithmsDescriptionTask.java b/src/tools/hashmethods/HashAlgorithmsDescriptionTask.java
new file mode 100644
index 000000000..5213d6b7d
--- /dev/null
+++ b/src/tools/hashmethods/HashAlgorithmsDescriptionTask.java
@@ -0,0 +1,100 @@
+package hashmethods;
+
+import fr.xephi.authme.security.HashAlgorithm;
+import fr.xephi.authme.settings.Settings;
+import fr.xephi.authme.util.WrapperMock;
+import utils.ANewMap;
+import utils.FileUtils;
+import utils.TagReplacer;
+import utils.ToolTask;
+import utils.ToolsConstants;
+
+import java.util.Map;
+import java.util.Scanner;
+
+/**
+ * Task for generating the markdown page describing the AuthMe hash algorithms.
+ *
+ * @see {@link fr.xephi.authme.security.HashAlgorithm}
+ */
+public class HashAlgorithmsDescriptionTask implements ToolTask {
+
+ private static final String CUR_FOLDER = ToolsConstants.TOOLS_SOURCE_ROOT + "hashmethods/";
+ private static final String OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "hash_algorithms.md";
+
+ @Override
+ public void execute(Scanner scanner) {
+ // Unfortunately, we need the Wrapper to be around to work with Settings, and certain encryption methods
+ // directly read from the Settings file
+ WrapperMock.createInstance();
+ Settings.bCryptLog2Rounds = 8;
+ Settings.saltLength = 8;
+
+ // Gather info and construct a row for each method
+ EncryptionMethodInfoGatherer infoGatherer = new EncryptionMethodInfoGatherer();
+ Map descriptions = infoGatherer.getDescriptions();
+ final String methodRows = constructMethodRows(descriptions);
+
+ // Write to the docs file
+ Map tags = ANewMap.with("method_rows", methodRows).build();
+ FileUtils.generateFileFromTemplate(CUR_FOLDER + "hash_algorithms.tpl.md", OUTPUT_FILE, tags);
+ }
+
+ private static String constructMethodRows(Map descriptions) {
+ final String rowTemplate = FileUtils.readFromFile(CUR_FOLDER + "hash_algorithms_row.tpl.md");
+ StringBuilder result = new StringBuilder();
+ for (Map.Entry entry : descriptions.entrySet()) {
+ MethodDescription description = entry.getValue();
+ Map tags = ANewMap
+ .with("name", asString(entry.getKey()))
+ .and("recommendation", asString(description.getUsage()))
+ .and("hash_length", asString(description.getHashLength()))
+ .and("ascii_restricted", asString(description.isAsciiRestricted()))
+ .and("salt_type", asString(description.getSaltType()))
+ .and("salt_length", asString(description.getSaltLength()))
+ .and("separate_salt", asString(description.hasSeparateSalt()))
+ .build();
+ result.append(TagReplacer.applyReplacements(rowTemplate, tags));
+ }
+ return result.toString();
+ }
+
+ @Override
+ public String getTaskName() {
+ return "describeHashAlgos";
+ }
+
+ // ----
+ // String representations
+ // ----
+ private static String asString(boolean value) {
+ return value ? "Y" : "";
+ }
+
+ private static String asString(int value) {
+ return String.valueOf(value);
+ }
+
+ private static String asString(Integer value) {
+ if (value == null) {
+ return "";
+ }
+ return String.valueOf(value);
+ }
+
+ private static String asString(HashAlgorithm value) {
+ return value.toString();
+ }
+
+ private static > String asString(E value) {
+ if (value == null) {
+ return "";
+ }
+ // Get the enum name and replace something like "DO_NOT_USE" to "Do not use"
+ String enumName = value.toString().replace("_", " ");
+ return enumName.length() > 2
+ ? enumName.substring(0, 1) + enumName.substring(1).toLowerCase()
+ : enumName;
+ }
+
+}
diff --git a/src/tools/hashmethods/MethodDescription.java b/src/tools/hashmethods/MethodDescription.java
new file mode 100644
index 000000000..45aaf448e
--- /dev/null
+++ b/src/tools/hashmethods/MethodDescription.java
@@ -0,0 +1,85 @@
+package hashmethods;
+
+import fr.xephi.authme.security.crypts.EncryptionMethod;
+import fr.xephi.authme.security.crypts.description.SaltType;
+import fr.xephi.authme.security.crypts.description.Usage;
+
+/**
+ * Description of a {@link EncryptionMethod}.
+ */
+public class MethodDescription {
+
+ /** The implementation class the description belongs to. */
+ private final Class extends EncryptionMethod> method;
+ /** The type of the salt that is used. */
+ private SaltType saltType;
+ /** The length of the salt for SaltType.TEXT salts. */
+ private Integer saltLength;
+ /** The usage recommendation. */
+ private Usage usage;
+ /** Whether or not the encryption method is restricted to ASCII characters for proper functioning. */
+ private boolean asciiRestricted;
+ /** Whether or not the encryption method requires its salt stored separately. */
+ private boolean hasSeparateSalt;
+ /** The length of the hash output, based on a test hash (i.e. assumes same length for all hashes.) */
+ private int hashLength;
+
+ public MethodDescription(Class extends EncryptionMethod> method) {
+ this.method = method;
+ }
+
+
+ // Trivial getters and setters
+ public Class extends EncryptionMethod> getMethod() {
+ return method;
+ }
+
+ public SaltType getSaltType() {
+ return saltType;
+ }
+
+ public void setSaltType(SaltType saltType) {
+ this.saltType = saltType;
+ }
+
+ public Integer getSaltLength() {
+ return saltLength;
+ }
+
+ public void setSaltLength(int saltLength) {
+ this.saltLength = saltLength;
+ }
+
+ public Usage getUsage() {
+ return usage;
+ }
+
+ public void setUsage(Usage usage) {
+ this.usage = usage;
+ }
+
+ public boolean isAsciiRestricted() {
+ return asciiRestricted;
+ }
+
+ public void setAsciiRestricted(boolean asciiRestricted) {
+ this.asciiRestricted = asciiRestricted;
+ }
+
+ public boolean hasSeparateSalt() {
+ return hasSeparateSalt;
+ }
+
+ public void setHasSeparateSalt(boolean hasSeparateSalt) {
+ this.hasSeparateSalt = hasSeparateSalt;
+ }
+
+ public int getHashLength() {
+ return hashLength;
+ }
+
+ public void setHashLength(int hashLength) {
+ this.hashLength = hashLength;
+ }
+
+}
diff --git a/src/tools/hashmethods/hash_algorithms.tpl.md b/src/tools/hashmethods/hash_algorithms.tpl.md
new file mode 100644
index 000000000..c11237284
--- /dev/null
+++ b/src/tools/hashmethods/hash_algorithms.tpl.md
@@ -0,0 +1,53 @@
+
+
+
+## Hash Algorithms
+AuthMe supports the following hash algorithms for storing your passwords safely.
+
+
+Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate? |
+--------- | -------------- | ----------- | ----- | - | --------- | ------ | --------- |
+{method_rows}CUSTOM | | | | | | | |
+
+
+
+### Columns
+#### Algorithm
+The algorithm is the hashing algorithm used to store passwords with. Default is SHA256 and is recommended.
+You can change the hashing algorithm in the config.yml: under `security`, locate `passwordHash`.
+
+#### Recommendation
+The recommendation lists our usage recommendation in terms of how secure it is (not how _well_ the algorithm works!).
+- Recommended: The hash algorithm appears to be cryptographically secure and is one we recommend.
+- Acceptable: There are safer algorithms that can be chosen but using the algorithm is generally OK.
+- Do not use: Hash algorithm isn't sufficiently secure. Use only if required to hook into another system.
+- Does not work: The algorithm does not work properly; do not use.
+
+#### Hash Length
+The length of the hashes the algorithm produces. Note that the hash length is not (primarily) indicative of
+whether an algorithm is secure or not.
+
+#### ASCII
+If denoted with a **y**, means that the algorithm is restricted to ASCII characters only, i.e. it will simply ignore
+"special characters" such as `ÿ` or `Â`. Note that we do not recommend the use of "special characters" in passwords.
+
+#### Salt Columns
+Before hashing, a _salt_ may be appended to the password to make the hash more secure. The following columns describe
+the salt the algorithm uses.
+
+
+##### Salt Type
+We do not recommend the usage
+of any algorithm that doesn't use a randomly generated text as salt. This "salt type" column indicates what type of
+salt the algorithm uses:
+- Text: randomly generated text (see also the following column, "Length")
+- Username: the salt is constructed from the username (bad)
+- None: the algorithm uses no salt (bad)
+
+##### Length
+If applicable (salt type is "Text"), indicates the length of the generated salt. The longer the better.
+If this column is empty when the salt type is "Text", it typically means the salt length can be defined in config.yml.
+
+##### Separate
+If denoted with a **y**, it means that the salt is stored in a separate column in the database. This is neither good
+or bad.
diff --git a/src/tools/hashmethods/hash_algorithms_row.tpl.md b/src/tools/hashmethods/hash_algorithms_row.tpl.md
new file mode 100644
index 000000000..411d11271
--- /dev/null
+++ b/src/tools/hashmethods/hash_algorithms_row.tpl.md
@@ -0,0 +1 @@
+{name} | {recommendation} | {hash_length} | {ascii_restricted} | | {salt_type} | {salt_length} | {separate_salt}
From 209cc23c4baf4f5ebc487e0bcaf0d70ed098d881 Mon Sep 17 00:00:00 2001
From: ljacqu
Date: Thu, 31 Dec 2015 13:42:41 +0100
Subject: [PATCH 06/24] Fix markdown table in hash algorithms overview - GitHub
requires at least 3 dashes between two column separators |. Most markdown
previewers don't have this restriction.
---
src/tools/docs/hash_algorithms.md | 8 ++++----
src/tools/hashmethods/hash_algorithms.tpl.md | 4 ++--
2 files changed, 6 insertions(+), 6 deletions(-)
diff --git a/src/tools/docs/hash_algorithms.md b/src/tools/docs/hash_algorithms.md
index 2996fd8ce..60a011b4c 100644
--- a/src/tools/docs/hash_algorithms.md
+++ b/src/tools/docs/hash_algorithms.md
@@ -1,12 +1,12 @@
-
+
## Hash Algorithms
AuthMe supports the following hash algorithms for storing your passwords safely.
-Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate? |
---------- | -------------- | ----------- | ----- | - | --------- | ------ | --------- |
+Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate?
+--------- | -------------- | ----------- | ----- | --- | --------- | ------ | ---------
BCRYPT | Recommended | 60 | | | Text | |
BCRYPT2Y | Recommended | 60 | | | Text | 22 |
CRAZYCRYPT1 | Do not use | 128 | | | Username | |
@@ -16,7 +16,7 @@ JOOMLA | Recommended | 65 | | | Text | 32 |
MD5 | Do not use | 32 | | | None | |
MD5VB | Acceptable | 56 | | | Text | 16 |
MYBB | Acceptable | 32 | | | Text | 8 | Y
-PBKDF2 | Does not work | 329 | | | Text | 12 |
+PBKDF2 | Does not work | 330 | | | Text | 12 |
PBKDF2DJANGO | Acceptable | 77 | Y | | Text | 12 |
PHPBB | Acceptable | 34 | | | Text | 16 |
PHPFUSION | Do not use | 64 | Y | | | | Y
diff --git a/src/tools/hashmethods/hash_algorithms.tpl.md b/src/tools/hashmethods/hash_algorithms.tpl.md
index c11237284..b466eeebd 100644
--- a/src/tools/hashmethods/hash_algorithms.tpl.md
+++ b/src/tools/hashmethods/hash_algorithms.tpl.md
@@ -5,8 +5,8 @@
AuthMe supports the following hash algorithms for storing your passwords safely.
-Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate? |
---------- | -------------- | ----------- | ----- | - | --------- | ------ | --------- |
+Algorithm | Recommendation | Hash length | ASCII | | Salt type | Length | Separate?
+--------- | -------------- | ----------- | ----- | --- | --------- | ------ | ---------
{method_rows}CUSTOM | | | | | | | |
From 1f55e851723f76f6832e05f96342f1df2e7987e3 Mon Sep 17 00:00:00 2001
From: Xephi
Date: Thu, 31 Dec 2015 16:35:08 +0100
Subject: [PATCH 07/24] Start rework of Settings
---
src/main/java/fr/xephi/authme/AuthMe.java | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index 3e602e5fd..26ec824f2 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -75,6 +75,7 @@ import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.OtherAccounts;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
+import fr.xephi.authme.settings.custom.DatabaseSettings;
import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
@@ -451,6 +452,7 @@ public class AuthMe extends JavaPlugin {
try {
settings = new Settings(this);
Settings.reload();
+ // DatabaseSettings databaseSettings = new DatabaseSettings();
} catch (Exception e) {
ConsoleLogger.writeStackTrace(e);
ConsoleLogger.showError("Can't load the configuration file... Something went wrong, to avoid security issues the server will shutdown!");
@@ -985,7 +987,7 @@ public class AuthMe extends JavaPlugin {
/**
* Return the management instance.
- *
+ *
* @return management The Management
*/
public Management getManagement() {
From 0c5d835f474d16a4e9e571d66f2b30d94b223e1d Mon Sep 17 00:00:00 2001
From: Xephi
Date: Thu, 31 Dec 2015 16:35:38 +0100
Subject: [PATCH 08/24] Start rework of Settings Please move to another branch
:3
---
.../settings/custom/ConverterSettings.java | 46 ++++++
.../authme/settings/custom/CustomSetting.java | 156 ++++++++++++++++++
.../settings/custom/DatabaseSettings.java | 121 ++++++++++++++
.../authme/settings/custom/EmailSettings.java | 83 ++++++++++
.../authme/settings/custom/HooksSettings.java | 54 ++++++
.../settings/custom/ProtectionSettings.java | 63 +++++++
.../authme/settings/custom/PurgeSettings.java | 62 +++++++
.../settings/custom/SecuritySettings.java | 60 +++++++
.../settings/custom/annotations/Comment.java | 20 +++
.../settings/custom/annotations/Type.java | 43 +++++
10 files changed, 708 insertions(+)
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java
create mode 100644 src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java
diff --git a/src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java b/src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java
new file mode 100644
index 000000000..7cee6a521
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java
@@ -0,0 +1,46 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class ConverterSettings extends CustomSetting {
+
+ @Comment("Rakamak file name")
+ @Type(SettingType.String)
+ public String rakamakFileName = "users.rak";
+
+ @Comment("Rakamak use Ip ?")
+ @Type(SettingType.Boolean)
+ public boolean rakamakeUseIP = false;
+
+ @Comment("Rakamak IP file name")
+ @Type(SettingType.String)
+ public String rakamakIPFileName = "UsersIp.rak";
+
+ @Comment("CrazyLogin database file name")
+ @Type(SettingType.String)
+ public String crazyLoginFileName = "accounts.db";
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "converter.yml");
+
+ private ConverterSettings instance;
+
+ public ConverterSettings()
+ {
+ super(configFile);
+ instance = this;
+ }
+
+ public ConverterSettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(ConverterSettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java b/src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java
new file mode 100644
index 000000000..27792efd9
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java
@@ -0,0 +1,156 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.lang.reflect.Field;
+import java.util.List;
+
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.settings.CustomConfiguration;
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+
+public class CustomSetting extends CustomConfiguration {
+
+ private File configFile;
+ public boolean isFirstLaunch = false;
+
+ public CustomSetting(File file) {
+ super(file);
+ this.configFile = file;
+ try {
+ if (!configFile.exists())
+ {
+ isFirstLaunch = true;
+ configFile.createNewFile();
+ }
+ else
+ {
+ load();
+ loadValues();
+ }
+ save();
+ } catch (IOException e)
+ {
+ ConsoleLogger.writeStackTrace(e);
+ }
+ }
+
+ @Override
+ public boolean reLoad()
+ {
+ boolean out = true;
+ if (!configFile.exists()) {
+ try {
+ configFile.createNewFile();
+ save();
+ } catch (IOException e) {
+ out = false;
+ }
+ }
+ if (out)
+ {
+ load();
+ loadValues();
+ }
+ return out;
+ }
+
+ public void loadValues()
+ {
+ for (Field f : this.getClass().getDeclaredFields())
+ {
+ if (!f.isAnnotationPresent(Type.class))
+ continue;
+ f.setAccessible(true);
+ try {
+ switch (f.getAnnotation(Type.class).value())
+ {
+ case Boolean:
+ f.setBoolean(this, this.getBoolean(f.getName()));
+ break;
+ case Double:
+ f.setDouble(this, this.getDouble(f.getName()));
+ break;
+ case Int:
+ f.setInt(this, this.getInt(f.getName()));
+ break;
+ case Long:
+ f.setLong(this, this.getLong(f.getName()));
+ break;
+ case String:
+ f.set(this, this.getString(f.getName()));
+ break;
+ case StringList:
+ f.set(this, this.getStringList(f.getName()));
+ break;
+ default:
+ break;
+ }
+ } catch (Exception e)
+ {
+ ConsoleLogger.writeStackTrace(e);
+ }
+ }
+ }
+
+ @Override
+ public void save()
+ {
+ FileWriter writer = null;
+ try {
+ writer = new FileWriter(configFile);
+ writer.write("");
+ for (Field f : this.getClass().getDeclaredFields())
+ {
+ if (!f.isAnnotationPresent(Comment.class))
+ continue;
+ if (!f.isAnnotationPresent(Type.class))
+ continue;
+ for (String s : f.getAnnotation(Comment.class).value())
+ {
+ writer.append("# " + s + "\n");
+ }
+ writer.append(f.getName() + ": ");
+ switch (f.getAnnotation(Type.class).value())
+ {
+ case Boolean:
+ writer.append(f.getBoolean(this) ? "true" : "false");
+ break;
+ case Double:
+ writer.append("" + f.getDouble(this));
+ break;
+ case Int:
+ writer.append("" + f.getInt(this));
+ break;
+ case String:
+ writer.append("'" + f.get(this).toString() + "'");
+ break;
+ case StringList:
+ @SuppressWarnings("unchecked")
+ List list = (List) f.get(this);
+ writer.append("\n");
+ if (list.isEmpty())
+ writer.write("[]");
+ else
+ for (String s : list)
+ writer.append(" - '" + s + "'\n");
+ break;
+ case Long:
+ writer.append("" + f.getLong(this));
+ break;
+ default:
+ break;
+
+ }
+ writer.append("\n");
+ writer.flush();
+ }
+ writer.close();
+ } catch (Exception e) {
+ ConsoleLogger.writeStackTrace(e);
+ }
+ }
+
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java b/src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java
new file mode 100644
index 000000000..c3c20c6bd
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java
@@ -0,0 +1,121 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class DatabaseSettings extends CustomSetting {
+
+ @Comment({"What type of database do you want to use?",
+ "Valid values: sqlite, mysql"})
+ @Type(SettingType.String)
+ public String backend = "sqlite";
+
+ @Comment("Enable database caching, should improve database performance")
+ @Type(SettingType.Boolean)
+ public boolean caching = true;
+
+ @Comment("Database host address")
+ @Type(SettingType.String)
+ public String mySQLHost = "127.0.0.1";
+
+ @Comment("Database port")
+ @Type(SettingType.String)
+ public String mySQLPort = "3306";
+
+ @Comment("Username about Database Connection Infos")
+ @Type(SettingType.String)
+ public String mySQLUsername = "authme";
+
+ @Comment("Password about Database Connection Infos")
+ @Type(SettingType.String)
+ public String mySQLPassword = "12345";
+
+ @Comment("Database Name, use with converters or as SQLITE database name")
+ @Type(SettingType.String)
+ public String mySQLDatabase = "authme";
+
+ @Comment("Table of the database")
+ @Type(SettingType.String)
+ public String mySQLTablename = "authme";
+
+ @Comment("Column of IDs to sort data")
+ @Type(SettingType.String)
+ public String mySQLColumnId = "id";
+
+ @Comment("Column for storing or checking players nickname")
+ @Type(SettingType.String)
+ public String mySQLColumnName = "username";
+
+ @Comment("Column for storing or checking players RealName ")
+ @Type(SettingType.String)
+ public String mySQLColumnRealName = "realname";
+
+ @Comment("Column for storing players passwords")
+ @Type(SettingType.String)
+ public String mySQLColumnPassword = "password";
+
+ @Comment("Column for storing players passwords salts")
+ @Type(SettingType.String)
+ public String mySQLColumnSalt = "";
+
+ @Comment("Column for storing players emails")
+ @Type(SettingType.String)
+ public String mySQLColumnEmail = "email";
+
+ @Comment("Column for storing if a player is logged in or not")
+ @Type(SettingType.String)
+ public String mySQLColumnLogged = "isLogged";
+
+ @Comment("Column for storing players ips")
+ @Type(SettingType.String)
+ public String mySQLColumnIp = "ip";
+
+ @Comment("Column for storing players lastlogins")
+ @Type(SettingType.String)
+ public String mySQLColumnLastLogin = "lastlogin";
+
+ @Comment("Column for storing player LastLocation - X")
+ @Type(SettingType.String)
+ public String mySQLColumnLastLocX = "x";
+
+ @Comment("Column for storing player LastLocation - Y")
+ @Type(SettingType.String)
+ public String mySQLColumnLastLocY = "y";
+
+ @Comment("Column for storing player LastLocation - Z")
+ @Type(SettingType.String)
+ public String mySQLColumnLastLocZ = "z";
+
+ @Comment("Column for storing player LastLocation - World Name")
+ @Type(SettingType.String)
+ public String mySQLColumnLastLocWorld = "world";
+
+ @Comment("Column for storing players groups")
+ @Type(SettingType.String)
+ public String mySQLColumnGroup = "";
+
+ @Comment("Enable this when you allow registration through a website")
+ @Type(SettingType.Boolean)
+ public boolean mySQLWebsite = false;
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "database.yml");
+
+ private DatabaseSettings instance;
+
+ public DatabaseSettings()
+ {
+ super(configFile);
+ instance = this;
+ }
+
+ public DatabaseSettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(DatabaseSettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java b/src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java
new file mode 100644
index 000000000..d6cc36753
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java
@@ -0,0 +1,83 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class EmailSettings extends CustomSetting {
+
+ @Comment("Email SMTP server host")
+ @Type(SettingType.String)
+ public String mailSMTP = "smtp.gmail.com";
+
+ @Comment("Email SMTP server port")
+ @Type(SettingType.Int)
+ public int mailPort = 465;
+
+ @Comment("Email account whose send the mail")
+ @Type(SettingType.String)
+ public String mailAccount = "";
+
+ @Comment("Email account password")
+ @Type(SettingType.String)
+ public String mailPassword = "";
+
+ @Comment("Random password length")
+ @Type(SettingType.Int)
+ public int recoveryPasswordLength = 8;
+
+ @Comment("Mail Subject")
+ @Type(SettingType.String)
+ public String mailSubject = "Your new AuthMe password";
+
+ @Comment("Like maxRegPerIP but with email")
+ @Type(SettingType.Int)
+ public int maxRegPerEmail = 1;
+
+ @Comment("Recall players to add an email ?")
+ @Type(SettingType.Boolean)
+ public boolean recallPlayers = false;
+
+ @Comment("Delay in minute for the recall scheduler")
+ @Type(SettingType.Int)
+ public int delayRecall = 5;
+
+ @Comment("Blacklist these domains for emails")
+ @Type(SettingType.StringList)
+ public List emailBlackListed = new ArrayList();
+
+ @Comment("Whitelist ONLY these domains for emails")
+ @Type(SettingType.StringList)
+ public List emailWhiteListed = new ArrayList();
+
+ @Comment("Do we need to send new password draw in an image ?")
+ @Type(SettingType.Boolean)
+ public boolean generateImage = false;
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "emails.yml");
+
+ private EmailSettings instance;
+
+ public EmailSettings()
+ {
+ super(configFile);
+ instance = this;
+ if (this.isFirstLaunch)
+ {
+ this.emailBlackListed.add("10minutemail.com");
+ save();
+ }
+ }
+
+ public EmailSettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(EmailSettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java b/src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java
new file mode 100644
index 000000000..307c79062
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java
@@ -0,0 +1,54 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class HooksSettings extends CustomSetting {
+
+ @Comment("Do we need to hook with multiverse for spawn checking?")
+ @Type(SettingType.Boolean)
+ public boolean multiverse = true;
+
+ @Comment("Do we need to hook with BungeeCord ?")
+ @Type(SettingType.Boolean)
+ public boolean bungeecord = false;
+
+ @Comment("Send player to this BungeeCord server after register/login")
+ @Type(SettingType.String)
+ public String sendPlayerTo = "";
+
+ @Comment("Do we need to disable Essentials SocialSpy on join?")
+ @Type(SettingType.Boolean)
+ public boolean disableSocialSpy = false;
+
+ @Comment("Do we need to force /motd Essentials command on join?")
+ @Type(SettingType.Boolean)
+ public boolean useEssentialsMotd = false;
+
+ @Comment("Do we need to cache custom Attributes?")
+ @Type(SettingType.Boolean)
+ public boolean customAttributes = false;
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "hooks.yml");
+
+ private HooksSettings instance;
+
+ public HooksSettings()
+ {
+ super(configFile);
+ instance = this;
+ }
+
+ public HooksSettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(HooksSettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java
new file mode 100644
index 000000000..e8e2d059c
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java
@@ -0,0 +1,63 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class ProtectionSettings extends CustomSetting {
+
+ @Comment("Enable some servers protection ( country based login, antibot )")
+ @Type(SettingType.Boolean)
+ public boolean enableProtection = false;
+
+ @Comment({"Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes",
+ "PLEASE USE QUOTES !"})
+ @Type(SettingType.StringList)
+ public List countriesWhitelist = new ArrayList();
+
+ @Comment({"Countries not allowed to join the server and register",
+ "PLEASE USE QUOTES !"})
+ @Type(SettingType.StringList)
+ public List countriesBlacklist = new ArrayList();
+
+ @Comment("Do we need to enable automatic antibot system?")
+ @Type(SettingType.Boolean)
+ public boolean enableAntiBot = false;
+
+ @Comment("Max number of player allowed to login in 5 secs before enable AntiBot system automatically")
+ @Type(SettingType.Int)
+ public int antiBotSensibility = 5;
+
+ @Comment("Duration in minutes of the antibot automatic system")
+ @Type(SettingType.Int)
+ public int antiBotDuration = 10;
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "protection.yml");
+
+ private ProtectionSettings instance;
+
+ public ProtectionSettings()
+ {
+ super(configFile);
+ instance = this;
+ if (this.isFirstLaunch)
+ {
+ this.countriesWhitelist.add("US");
+ this.countriesWhitelist.add("GB");
+ this.countriesBlacklist.add("A1");
+ save();
+ }
+ }
+
+ public ProtectionSettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(ProtectionSettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java b/src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java
new file mode 100644
index 000000000..3b85e2fb0
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java
@@ -0,0 +1,62 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class PurgeSettings extends CustomSetting {
+
+ @Comment("If enabled, AuthMe automatically purges old, unused accounts")
+ @Type(SettingType.Boolean)
+ public boolean useAutoPurge = false;
+
+ @Comment("Number of Days an account become Unused")
+ @Type(SettingType.Int)
+ public int daysBeforeRemovePlayer = 60;
+
+ @Comment("Do we need to remove the player.dat file during purge process?")
+ @Type(SettingType.Boolean)
+ public boolean removePlayerDat = false;
+
+ @Comment("Do we need to remove the Essentials/users/player.yml file during purge process?")
+ @Type(SettingType.Boolean)
+ public boolean removeEssentialsFiles = false;
+
+ @Comment("World where are players.dat stores")
+ @Type(SettingType.String)
+ public String defaultWorld = "world";
+
+ @Comment("Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ?")
+ @Type(SettingType.Boolean)
+ public boolean removeLimiteCreativeInventories = false;
+
+ @Comment("Do we need to remove the AntiXRayData/PlayerData/player file during purge process?")
+ @Type(SettingType.Boolean)
+ public boolean removeAntiXRayFile = false;
+
+ @Comment("Do we need to remove permissions?")
+ @Type(SettingType.Boolean)
+ public boolean removePermissions = false;
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "purge.yml");
+
+ private PurgeSettings instance;
+
+ public PurgeSettings()
+ {
+ super(configFile);
+ instance = this;
+ }
+
+ public PurgeSettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(PurgeSettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java
new file mode 100644
index 000000000..3166cbe26
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java
@@ -0,0 +1,60 @@
+package fr.xephi.authme.settings.custom;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import fr.xephi.authme.settings.custom.annotations.Comment;
+import fr.xephi.authme.settings.custom.annotations.Type;
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+public class SecuritySettings extends CustomSetting {
+
+ @Comment({"Stop the server if we can't contact the sql database",
+ "Take care with this, if you set that to false,",
+ "AuthMe automatically disable and the server is not protected!"})
+ @Type(SettingType.Boolean)
+ public boolean stopServerOnProblem = true;
+
+ @Comment("/reload support")
+ @Type(SettingType.Boolean)
+ public boolean useReloadCommandSupport = true;
+
+ @Comment("Remove Spam from Console ?")
+ @Type(SettingType.Boolean)
+ public boolean removeSpamFromConsole = false;
+
+ @Comment("Remove Password from Console ?")
+ @Type(SettingType.Boolean)
+ public boolean removePasswordFromConsole = true;
+
+ @Comment("Player need to put a captcha when he fails too lot the password")
+ @Type(SettingType.Boolean)
+ public boolean useCaptcha = false;
+
+ @Comment("Max allowed tries before request a captcha")
+ @Type(SettingType.Int)
+ public int maxLoginTryBeforeCaptcha = 5;
+
+ @Comment("Captcha length ")
+ @Type(SettingType.Int)
+ public int captchaLength = 5;
+
+ private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "security.yml");
+
+ private SecuritySettings instance;
+
+ public SecuritySettings()
+ {
+ super(configFile);
+ instance = this;
+ }
+
+ public SecuritySettings getInstance() {
+ return instance;
+ }
+
+ public void setInstance(SecuritySettings instance) {
+ this.instance = instance;
+ }
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java b/src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java
new file mode 100644
index 000000000..d711a1943
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java
@@ -0,0 +1,20 @@
+package fr.xephi.authme.settings.custom.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+/**
+ *
+ * Add a comment to a field value
+ *
+ * @author xephi59
+ *
+ */
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Comment {
+
+ public String[] value() default "";
+}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java b/src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java
new file mode 100644
index 000000000..aae0af52b
--- /dev/null
+++ b/src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java
@@ -0,0 +1,43 @@
+package fr.xephi.authme.settings.custom.annotations;
+
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+
+import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
+
+/**
+*
+* Set the type of a field value
+*
+* @author xephi59
+*
+*/
+@Retention(RetentionPolicy.RUNTIME)
+@Target(ElementType.FIELD)
+public @interface Type {
+
+ public enum SettingType {
+ String(0),
+ Int(1),
+ Boolean(2),
+ Double(3),
+ StringList(4),
+ Long(5);
+
+ private int type;
+
+ SettingType(int type)
+ {
+ this.type = type;
+ }
+
+ public int getType()
+ {
+ return this.type;
+ }
+ }
+
+ public SettingType value() default SettingType.String;
+}
From 94c836376ef222e8dd090426393b60d92200e6b9 Mon Sep 17 00:00:00 2001
From: ljacqu
Date: Thu, 31 Dec 2015 17:02:15 +0100
Subject: [PATCH 09/24] Revert "Start rework of Settings" from master - Revert
1f55e85 because it's simpler to have ljacqu revert a commit on master, create
a new branch and cherry-pick the reverted commit than to enter one command to
change branch
---
.../settings/custom/ConverterSettings.java | 46 ------
.../authme/settings/custom/CustomSetting.java | 156 ------------------
.../settings/custom/DatabaseSettings.java | 121 --------------
.../authme/settings/custom/EmailSettings.java | 83 ----------
.../authme/settings/custom/HooksSettings.java | 54 ------
.../settings/custom/ProtectionSettings.java | 63 -------
.../authme/settings/custom/PurgeSettings.java | 62 -------
.../settings/custom/SecuritySettings.java | 60 -------
.../settings/custom/annotations/Comment.java | 20 ---
.../settings/custom/annotations/Type.java | 43 -----
10 files changed, 708 deletions(-)
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java
delete mode 100644 src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java
diff --git a/src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java b/src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java
deleted file mode 100644
index 7cee6a521..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/ConverterSettings.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class ConverterSettings extends CustomSetting {
-
- @Comment("Rakamak file name")
- @Type(SettingType.String)
- public String rakamakFileName = "users.rak";
-
- @Comment("Rakamak use Ip ?")
- @Type(SettingType.Boolean)
- public boolean rakamakeUseIP = false;
-
- @Comment("Rakamak IP file name")
- @Type(SettingType.String)
- public String rakamakIPFileName = "UsersIp.rak";
-
- @Comment("CrazyLogin database file name")
- @Type(SettingType.String)
- public String crazyLoginFileName = "accounts.db";
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "converter.yml");
-
- private ConverterSettings instance;
-
- public ConverterSettings()
- {
- super(configFile);
- instance = this;
- }
-
- public ConverterSettings getInstance() {
- return instance;
- }
-
- public void setInstance(ConverterSettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java b/src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java
deleted file mode 100644
index 27792efd9..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/CustomSetting.java
+++ /dev/null
@@ -1,156 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.lang.reflect.Field;
-import java.util.List;
-
-import fr.xephi.authme.ConsoleLogger;
-import fr.xephi.authme.settings.CustomConfiguration;
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-
-public class CustomSetting extends CustomConfiguration {
-
- private File configFile;
- public boolean isFirstLaunch = false;
-
- public CustomSetting(File file) {
- super(file);
- this.configFile = file;
- try {
- if (!configFile.exists())
- {
- isFirstLaunch = true;
- configFile.createNewFile();
- }
- else
- {
- load();
- loadValues();
- }
- save();
- } catch (IOException e)
- {
- ConsoleLogger.writeStackTrace(e);
- }
- }
-
- @Override
- public boolean reLoad()
- {
- boolean out = true;
- if (!configFile.exists()) {
- try {
- configFile.createNewFile();
- save();
- } catch (IOException e) {
- out = false;
- }
- }
- if (out)
- {
- load();
- loadValues();
- }
- return out;
- }
-
- public void loadValues()
- {
- for (Field f : this.getClass().getDeclaredFields())
- {
- if (!f.isAnnotationPresent(Type.class))
- continue;
- f.setAccessible(true);
- try {
- switch (f.getAnnotation(Type.class).value())
- {
- case Boolean:
- f.setBoolean(this, this.getBoolean(f.getName()));
- break;
- case Double:
- f.setDouble(this, this.getDouble(f.getName()));
- break;
- case Int:
- f.setInt(this, this.getInt(f.getName()));
- break;
- case Long:
- f.setLong(this, this.getLong(f.getName()));
- break;
- case String:
- f.set(this, this.getString(f.getName()));
- break;
- case StringList:
- f.set(this, this.getStringList(f.getName()));
- break;
- default:
- break;
- }
- } catch (Exception e)
- {
- ConsoleLogger.writeStackTrace(e);
- }
- }
- }
-
- @Override
- public void save()
- {
- FileWriter writer = null;
- try {
- writer = new FileWriter(configFile);
- writer.write("");
- for (Field f : this.getClass().getDeclaredFields())
- {
- if (!f.isAnnotationPresent(Comment.class))
- continue;
- if (!f.isAnnotationPresent(Type.class))
- continue;
- for (String s : f.getAnnotation(Comment.class).value())
- {
- writer.append("# " + s + "\n");
- }
- writer.append(f.getName() + ": ");
- switch (f.getAnnotation(Type.class).value())
- {
- case Boolean:
- writer.append(f.getBoolean(this) ? "true" : "false");
- break;
- case Double:
- writer.append("" + f.getDouble(this));
- break;
- case Int:
- writer.append("" + f.getInt(this));
- break;
- case String:
- writer.append("'" + f.get(this).toString() + "'");
- break;
- case StringList:
- @SuppressWarnings("unchecked")
- List list = (List) f.get(this);
- writer.append("\n");
- if (list.isEmpty())
- writer.write("[]");
- else
- for (String s : list)
- writer.append(" - '" + s + "'\n");
- break;
- case Long:
- writer.append("" + f.getLong(this));
- break;
- default:
- break;
-
- }
- writer.append("\n");
- writer.flush();
- }
- writer.close();
- } catch (Exception e) {
- ConsoleLogger.writeStackTrace(e);
- }
- }
-
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java b/src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java
deleted file mode 100644
index c3c20c6bd..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/DatabaseSettings.java
+++ /dev/null
@@ -1,121 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class DatabaseSettings extends CustomSetting {
-
- @Comment({"What type of database do you want to use?",
- "Valid values: sqlite, mysql"})
- @Type(SettingType.String)
- public String backend = "sqlite";
-
- @Comment("Enable database caching, should improve database performance")
- @Type(SettingType.Boolean)
- public boolean caching = true;
-
- @Comment("Database host address")
- @Type(SettingType.String)
- public String mySQLHost = "127.0.0.1";
-
- @Comment("Database port")
- @Type(SettingType.String)
- public String mySQLPort = "3306";
-
- @Comment("Username about Database Connection Infos")
- @Type(SettingType.String)
- public String mySQLUsername = "authme";
-
- @Comment("Password about Database Connection Infos")
- @Type(SettingType.String)
- public String mySQLPassword = "12345";
-
- @Comment("Database Name, use with converters or as SQLITE database name")
- @Type(SettingType.String)
- public String mySQLDatabase = "authme";
-
- @Comment("Table of the database")
- @Type(SettingType.String)
- public String mySQLTablename = "authme";
-
- @Comment("Column of IDs to sort data")
- @Type(SettingType.String)
- public String mySQLColumnId = "id";
-
- @Comment("Column for storing or checking players nickname")
- @Type(SettingType.String)
- public String mySQLColumnName = "username";
-
- @Comment("Column for storing or checking players RealName ")
- @Type(SettingType.String)
- public String mySQLColumnRealName = "realname";
-
- @Comment("Column for storing players passwords")
- @Type(SettingType.String)
- public String mySQLColumnPassword = "password";
-
- @Comment("Column for storing players passwords salts")
- @Type(SettingType.String)
- public String mySQLColumnSalt = "";
-
- @Comment("Column for storing players emails")
- @Type(SettingType.String)
- public String mySQLColumnEmail = "email";
-
- @Comment("Column for storing if a player is logged in or not")
- @Type(SettingType.String)
- public String mySQLColumnLogged = "isLogged";
-
- @Comment("Column for storing players ips")
- @Type(SettingType.String)
- public String mySQLColumnIp = "ip";
-
- @Comment("Column for storing players lastlogins")
- @Type(SettingType.String)
- public String mySQLColumnLastLogin = "lastlogin";
-
- @Comment("Column for storing player LastLocation - X")
- @Type(SettingType.String)
- public String mySQLColumnLastLocX = "x";
-
- @Comment("Column for storing player LastLocation - Y")
- @Type(SettingType.String)
- public String mySQLColumnLastLocY = "y";
-
- @Comment("Column for storing player LastLocation - Z")
- @Type(SettingType.String)
- public String mySQLColumnLastLocZ = "z";
-
- @Comment("Column for storing player LastLocation - World Name")
- @Type(SettingType.String)
- public String mySQLColumnLastLocWorld = "world";
-
- @Comment("Column for storing players groups")
- @Type(SettingType.String)
- public String mySQLColumnGroup = "";
-
- @Comment("Enable this when you allow registration through a website")
- @Type(SettingType.Boolean)
- public boolean mySQLWebsite = false;
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "database.yml");
-
- private DatabaseSettings instance;
-
- public DatabaseSettings()
- {
- super(configFile);
- instance = this;
- }
-
- public DatabaseSettings getInstance() {
- return instance;
- }
-
- public void setInstance(DatabaseSettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java b/src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java
deleted file mode 100644
index d6cc36753..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/EmailSettings.java
+++ /dev/null
@@ -1,83 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class EmailSettings extends CustomSetting {
-
- @Comment("Email SMTP server host")
- @Type(SettingType.String)
- public String mailSMTP = "smtp.gmail.com";
-
- @Comment("Email SMTP server port")
- @Type(SettingType.Int)
- public int mailPort = 465;
-
- @Comment("Email account whose send the mail")
- @Type(SettingType.String)
- public String mailAccount = "";
-
- @Comment("Email account password")
- @Type(SettingType.String)
- public String mailPassword = "";
-
- @Comment("Random password length")
- @Type(SettingType.Int)
- public int recoveryPasswordLength = 8;
-
- @Comment("Mail Subject")
- @Type(SettingType.String)
- public String mailSubject = "Your new AuthMe password";
-
- @Comment("Like maxRegPerIP but with email")
- @Type(SettingType.Int)
- public int maxRegPerEmail = 1;
-
- @Comment("Recall players to add an email ?")
- @Type(SettingType.Boolean)
- public boolean recallPlayers = false;
-
- @Comment("Delay in minute for the recall scheduler")
- @Type(SettingType.Int)
- public int delayRecall = 5;
-
- @Comment("Blacklist these domains for emails")
- @Type(SettingType.StringList)
- public List emailBlackListed = new ArrayList();
-
- @Comment("Whitelist ONLY these domains for emails")
- @Type(SettingType.StringList)
- public List emailWhiteListed = new ArrayList();
-
- @Comment("Do we need to send new password draw in an image ?")
- @Type(SettingType.Boolean)
- public boolean generateImage = false;
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "emails.yml");
-
- private EmailSettings instance;
-
- public EmailSettings()
- {
- super(configFile);
- instance = this;
- if (this.isFirstLaunch)
- {
- this.emailBlackListed.add("10minutemail.com");
- save();
- }
- }
-
- public EmailSettings getInstance() {
- return instance;
- }
-
- public void setInstance(EmailSettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java b/src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java
deleted file mode 100644
index 307c79062..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/HooksSettings.java
+++ /dev/null
@@ -1,54 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class HooksSettings extends CustomSetting {
-
- @Comment("Do we need to hook with multiverse for spawn checking?")
- @Type(SettingType.Boolean)
- public boolean multiverse = true;
-
- @Comment("Do we need to hook with BungeeCord ?")
- @Type(SettingType.Boolean)
- public boolean bungeecord = false;
-
- @Comment("Send player to this BungeeCord server after register/login")
- @Type(SettingType.String)
- public String sendPlayerTo = "";
-
- @Comment("Do we need to disable Essentials SocialSpy on join?")
- @Type(SettingType.Boolean)
- public boolean disableSocialSpy = false;
-
- @Comment("Do we need to force /motd Essentials command on join?")
- @Type(SettingType.Boolean)
- public boolean useEssentialsMotd = false;
-
- @Comment("Do we need to cache custom Attributes?")
- @Type(SettingType.Boolean)
- public boolean customAttributes = false;
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "hooks.yml");
-
- private HooksSettings instance;
-
- public HooksSettings()
- {
- super(configFile);
- instance = this;
- }
-
- public HooksSettings getInstance() {
- return instance;
- }
-
- public void setInstance(HooksSettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java b/src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java
deleted file mode 100644
index e8e2d059c..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/ProtectionSettings.java
+++ /dev/null
@@ -1,63 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class ProtectionSettings extends CustomSetting {
-
- @Comment("Enable some servers protection ( country based login, antibot )")
- @Type(SettingType.Boolean)
- public boolean enableProtection = false;
-
- @Comment({"Countries allowed to join the server and register, see http://dev.bukkit.org/bukkit-plugins/authme-reloaded/pages/countries-codes/ for countries' codes",
- "PLEASE USE QUOTES !"})
- @Type(SettingType.StringList)
- public List countriesWhitelist = new ArrayList();
-
- @Comment({"Countries not allowed to join the server and register",
- "PLEASE USE QUOTES !"})
- @Type(SettingType.StringList)
- public List countriesBlacklist = new ArrayList();
-
- @Comment("Do we need to enable automatic antibot system?")
- @Type(SettingType.Boolean)
- public boolean enableAntiBot = false;
-
- @Comment("Max number of player allowed to login in 5 secs before enable AntiBot system automatically")
- @Type(SettingType.Int)
- public int antiBotSensibility = 5;
-
- @Comment("Duration in minutes of the antibot automatic system")
- @Type(SettingType.Int)
- public int antiBotDuration = 10;
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "protection.yml");
-
- private ProtectionSettings instance;
-
- public ProtectionSettings()
- {
- super(configFile);
- instance = this;
- if (this.isFirstLaunch)
- {
- this.countriesWhitelist.add("US");
- this.countriesWhitelist.add("GB");
- this.countriesBlacklist.add("A1");
- save();
- }
- }
-
- public ProtectionSettings getInstance() {
- return instance;
- }
-
- public void setInstance(ProtectionSettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java b/src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java
deleted file mode 100644
index 3b85e2fb0..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/PurgeSettings.java
+++ /dev/null
@@ -1,62 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class PurgeSettings extends CustomSetting {
-
- @Comment("If enabled, AuthMe automatically purges old, unused accounts")
- @Type(SettingType.Boolean)
- public boolean useAutoPurge = false;
-
- @Comment("Number of Days an account become Unused")
- @Type(SettingType.Int)
- public int daysBeforeRemovePlayer = 60;
-
- @Comment("Do we need to remove the player.dat file during purge process?")
- @Type(SettingType.Boolean)
- public boolean removePlayerDat = false;
-
- @Comment("Do we need to remove the Essentials/users/player.yml file during purge process?")
- @Type(SettingType.Boolean)
- public boolean removeEssentialsFiles = false;
-
- @Comment("World where are players.dat stores")
- @Type(SettingType.String)
- public String defaultWorld = "world";
-
- @Comment("Do we need to remove LimitedCreative/inventories/player.yml, player_creative.yml files during purge process ?")
- @Type(SettingType.Boolean)
- public boolean removeLimiteCreativeInventories = false;
-
- @Comment("Do we need to remove the AntiXRayData/PlayerData/player file during purge process?")
- @Type(SettingType.Boolean)
- public boolean removeAntiXRayFile = false;
-
- @Comment("Do we need to remove permissions?")
- @Type(SettingType.Boolean)
- public boolean removePermissions = false;
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "purge.yml");
-
- private PurgeSettings instance;
-
- public PurgeSettings()
- {
- super(configFile);
- instance = this;
- }
-
- public PurgeSettings getInstance() {
- return instance;
- }
-
- public void setInstance(PurgeSettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java b/src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java
deleted file mode 100644
index 3166cbe26..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/SecuritySettings.java
+++ /dev/null
@@ -1,60 +0,0 @@
-package fr.xephi.authme.settings.custom;
-
-import java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-import fr.xephi.authme.settings.custom.annotations.Comment;
-import fr.xephi.authme.settings.custom.annotations.Type;
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-public class SecuritySettings extends CustomSetting {
-
- @Comment({"Stop the server if we can't contact the sql database",
- "Take care with this, if you set that to false,",
- "AuthMe automatically disable and the server is not protected!"})
- @Type(SettingType.Boolean)
- public boolean stopServerOnProblem = true;
-
- @Comment("/reload support")
- @Type(SettingType.Boolean)
- public boolean useReloadCommandSupport = true;
-
- @Comment("Remove Spam from Console ?")
- @Type(SettingType.Boolean)
- public boolean removeSpamFromConsole = false;
-
- @Comment("Remove Password from Console ?")
- @Type(SettingType.Boolean)
- public boolean removePasswordFromConsole = true;
-
- @Comment("Player need to put a captcha when he fails too lot the password")
- @Type(SettingType.Boolean)
- public boolean useCaptcha = false;
-
- @Comment("Max allowed tries before request a captcha")
- @Type(SettingType.Int)
- public int maxLoginTryBeforeCaptcha = 5;
-
- @Comment("Captcha length ")
- @Type(SettingType.Int)
- public int captchaLength = 5;
-
- private static File configFile = new File("." + File.separator + "plugins" + File.separator + "AuthMe" + File.separator + "security.yml");
-
- private SecuritySettings instance;
-
- public SecuritySettings()
- {
- super(configFile);
- instance = this;
- }
-
- public SecuritySettings getInstance() {
- return instance;
- }
-
- public void setInstance(SecuritySettings instance) {
- this.instance = instance;
- }
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java b/src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java
deleted file mode 100644
index d711a1943..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/annotations/Comment.java
+++ /dev/null
@@ -1,20 +0,0 @@
-package fr.xephi.authme.settings.custom.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-/**
- *
- * Add a comment to a field value
- *
- * @author xephi59
- *
- */
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface Comment {
-
- public String[] value() default "";
-}
diff --git a/src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java b/src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java
deleted file mode 100644
index aae0af52b..000000000
--- a/src/main/java/fr/xephi/authme/settings/custom/annotations/Type.java
+++ /dev/null
@@ -1,43 +0,0 @@
-package fr.xephi.authme.settings.custom.annotations;
-
-import java.lang.annotation.ElementType;
-import java.lang.annotation.Retention;
-import java.lang.annotation.RetentionPolicy;
-import java.lang.annotation.Target;
-
-import fr.xephi.authme.settings.custom.annotations.Type.SettingType;
-
-/**
-*
-* Set the type of a field value
-*
-* @author xephi59
-*
-*/
-@Retention(RetentionPolicy.RUNTIME)
-@Target(ElementType.FIELD)
-public @interface Type {
-
- public enum SettingType {
- String(0),
- Int(1),
- Boolean(2),
- Double(3),
- StringList(4),
- Long(5);
-
- private int type;
-
- SettingType(int type)
- {
- this.type = type;
- }
-
- public int getType()
- {
- return this.type;
- }
- }
-
- public SettingType value() default SettingType.String;
-}
From 071800481a19761fbf85a5a508d2927ac1516c48 Mon Sep 17 00:00:00 2001
From: ljacqu
Date: Fri, 1 Jan 2016 10:34:38 +0100
Subject: [PATCH 10/24] Minor - fix failing build
---
src/main/java/fr/xephi/authme/AuthMe.java | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index 26ec824f2..3243c21d9 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -75,7 +75,6 @@ import fr.xephi.authme.security.crypts.HashedPassword;
import fr.xephi.authme.settings.OtherAccounts;
import fr.xephi.authme.settings.Settings;
import fr.xephi.authme.settings.Spawn;
-import fr.xephi.authme.settings.custom.DatabaseSettings;
import fr.xephi.authme.util.GeoLiteAPI;
import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
@@ -438,7 +437,7 @@ public class AuthMe extends JavaPlugin {
// Set up the API
api = new NewAPI(this);
- // Setup the old deprecated API
+ // Set up the deprecated API
new API(this);
}
@@ -452,7 +451,6 @@ public class AuthMe extends JavaPlugin {
try {
settings = new Settings(this);
Settings.reload();
- // DatabaseSettings databaseSettings = new DatabaseSettings();
} catch (Exception e) {
ConsoleLogger.writeStackTrace(e);
ConsoleLogger.showError("Can't load the configuration file... Something went wrong, to avoid security issues the server will shutdown!");
@@ -987,7 +985,7 @@ public class AuthMe extends JavaPlugin {
/**
* Return the management instance.
- *
+ *
* @return management The Management
*/
public Management getManagement() {
From 266c979319d3b04604863f9936f815c183f769c0 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sat, 2 Jan 2016 06:16:35 +0700
Subject: [PATCH 11/24] Use Bukkit API to extract "email.html" from plugin
file.
---
.../fr/xephi/authme/settings/Settings.java | 20 +++----------------
1 file changed, 3 insertions(+), 17 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java
index e28ddc3f8..ac5207638 100644
--- a/src/main/java/fr/xephi/authme/settings/Settings.java
+++ b/src/main/java/fr/xephi/authme/settings/Settings.java
@@ -310,8 +310,9 @@ public final class Settings {
}
private static String loadEmailText() {
- if (!EMAIL_FILE.exists())
- saveDefaultEmailText();
+ if (!EMAIL_FILE.exists()) {
+ plugin.saveResource("email.html", false);
+ }
StringBuilder str = new StringBuilder();
try {
BufferedReader in = new BufferedReader(new FileReader(EMAIL_FILE));
@@ -324,21 +325,6 @@ public final class Settings {
return str.toString();
}
- private static void saveDefaultEmailText() {
- InputStream file = plugin.getResource("email.html");
- StringBuilder str = new StringBuilder();
- try {
- BufferedReader in = new BufferedReader(new InputStreamReader(file, Charset.forName("utf-8")));
- String s;
- while ((s = in.readLine()) != null)
- str.append(s);
- in.close();
- Files.touch(EMAIL_FILE);
- Files.write(str.toString(), EMAIL_FILE, Charsets.UTF_8);
- } catch (Exception ignored) {
- }
- }
-
/**
*
* @param key the key to set
From 6cae5206049f9d7b2383655716887795a2463848 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sat, 2 Jan 2016 06:23:38 +0700
Subject: [PATCH 12/24] Use Guava's Files.toString API to read the email file.
---
.../fr/xephi/authme/settings/Settings.java | 73 ++++++++-----------
1 file changed, 30 insertions(+), 43 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/settings/Settings.java b/src/main/java/fr/xephi/authme/settings/Settings.java
index ac5207638..cfb28f75e 100644
--- a/src/main/java/fr/xephi/authme/settings/Settings.java
+++ b/src/main/java/fr/xephi/authme/settings/Settings.java
@@ -1,32 +1,27 @@
package fr.xephi.authme.settings;
+import com.google.common.base.Charsets;
+import com.google.common.io.Files;
+import fr.xephi.authme.AuthMe;
+import fr.xephi.authme.ConsoleLogger;
+import fr.xephi.authme.datasource.DataSource;
+import fr.xephi.authme.datasource.DataSource.DataSourceType;
+import fr.xephi.authme.security.HashAlgorithm;
+import fr.xephi.authme.util.Wrapper;
+import org.bukkit.configuration.file.YamlConfiguration;
+
import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
-import java.io.InputStream;
-import java.io.InputStreamReader;
-import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Iterator;
import java.util.List;
import java.util.regex.Pattern;
-import org.bukkit.configuration.file.YamlConfiguration;
-
-import com.google.common.base.Charsets;
-import com.google.common.io.Files;
-
-import fr.xephi.authme.AuthMe;
-import fr.xephi.authme.ConsoleLogger;
-import fr.xephi.authme.datasource.DataSource;
-import fr.xephi.authme.datasource.DataSource.DataSourceType;
-import fr.xephi.authme.security.HashAlgorithm;
-import fr.xephi.authme.util.Wrapper;
-
/**
*/
public final class Settings {
@@ -313,21 +308,17 @@ public final class Settings {
if (!EMAIL_FILE.exists()) {
plugin.saveResource("email.html", false);
}
- StringBuilder str = new StringBuilder();
try {
- BufferedReader in = new BufferedReader(new FileReader(EMAIL_FILE));
- String s;
- while ((s = in.readLine()) != null)
- str.append(s);
- in.close();
- } catch (IOException ignored) {
+ return Files.toString(EMAIL_FILE, Charsets.UTF_8);
+ } catch (IOException e) {
+ ConsoleLogger.showError(e.getMessage());
+ ConsoleLogger.writeStackTrace(e);
+ return "";
}
- return str.toString();
}
/**
- *
- * @param key the key to set
+ * @param key the key to set
* @param value the value to set
*/
public static void setValue(String key, Object value) {
@@ -370,8 +361,8 @@ public final class Settings {
* return false if ip and name doesn't match with player that join the
* server, so player has a restricted access
*
- * @param name String
- * @param ip String
+ * @param name String
+ * @param ip String
* @param domain String
*
* @return boolean
@@ -387,14 +378,12 @@ public final class Settings {
String testIp = args[1];
if (testName.equalsIgnoreCase(name)) {
nameFound = true;
- if (ip != null)
- {
+ if (ip != null) {
if (testIp.equalsIgnoreCase(ip)) {
trueOnce = true;
}
}
- if (domain != null)
- {
+ if (domain != null) {
if (testIp.equalsIgnoreCase(domain)) {
trueOnce = true;
}
@@ -728,10 +717,9 @@ public final class Settings {
changes = true;
}
- if (!contains("settings.preventOtherCase"))
- {
- set("settings.preventOtherCase", false);
- changes = true;
+ if (!contains("settings.preventOtherCase")) {
+ set("settings.preventOtherCase", false);
+ changes = true;
}
if (contains("Email.mailText")) {
@@ -740,15 +728,14 @@ public final class Settings {
}
if (!contains("Security.stop.kickPlayersBeforeStopping")) {
- set("Security.stop.kickPlayersBeforeStopping", true);
- changes = true;
+ set("Security.stop.kickPlayersBeforeStopping", true);
+ changes = true;
}
if (!contains("Email.emailOauth2Token"))
- set("Email.emailOauth2Token", "");
+ set("Email.emailOauth2Token", "");
- if (!contains("Hook.sendPlayerTo"))
- {
+ if (!contains("Hook.sendPlayerTo")) {
set("Hooks.sendPlayerTo", "");
changes = true;
}
@@ -760,8 +747,8 @@ public final class Settings {
}
/**
- *
* @param path
+ *
* @return
*/
private static boolean contains(String path) {
@@ -769,9 +756,9 @@ public final class Settings {
}
// public because it's used in AuthMe at one place
+
/**
- *
- * @param path String
+ * @param path String
* @param value String
*/
public void set(String path, Object value) {
From 9533965095dee7b963caa4724c5956e56ad97d17 Mon Sep 17 00:00:00 2001
From: ljacqu
Date: Sat, 2 Jan 2016 01:09:25 +0100
Subject: [PATCH 13/24] Minor - update JavaDoc for HashAlgorithm - Replace
incorrect description
---
src/main/java/fr/xephi/authme/security/HashAlgorithm.java | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
index 24a702dd0..469a02585 100644
--- a/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
+++ b/src/main/java/fr/xephi/authme/security/HashAlgorithm.java
@@ -3,9 +3,8 @@ package fr.xephi.authme.security;
import fr.xephi.authme.security.crypts.EncryptionMethod;
/**
- * The list of hash algorithms supported by AuthMe. The implementing class must define a public
- * constructor which takes either no arguments, or a DataSource object (when the salt is stored
- * separately, writes to the database are necessary).
+ * The list of hash algorithms supported by AuthMe. The linked {@link EncryptionMethod} implementation
+ * must be able to be instantiated with the default constructor.
*/
public enum HashAlgorithm {
From 4ea6cc9d69f8345ef65f62a3b8a242097ba7feb7 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sun, 3 Jan 2016 08:34:27 +0700
Subject: [PATCH 14/24] Fix player name case check.
---
.../authme/listener/AuthMePlayerListener.java | 32 +++++++++++--------
.../process/login/AsynchronousLogin.java | 1 -
2 files changed, 18 insertions(+), 15 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
index 42a11b3ff..fd8418cb9 100644
--- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
+++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
@@ -206,8 +206,9 @@ public class AuthMePlayerListener implements Listener {
joinMessage.put(name, joinMsg);
}
- if (Settings.checkVeryGames)
- plugin.getVerygamesIp(player);
+ if (Settings.checkVeryGames) {
+ plugin.getVerygamesIp(player);
+ }
// Shedule login task so works after the prelogin
// (Fix found by Koolaid5000)
@@ -222,21 +223,24 @@ public class AuthMePlayerListener implements Listener {
@EventHandler(priority = EventPriority.HIGHEST)
public void onPreLogin(AsyncPlayerPreLoginEvent event) {
PlayerAuth auth = plugin.getDataSource().getAuth(event.getName());
- if (auth != null && auth.getRealName() != null && !auth.getRealName().isEmpty() &&
- !auth.getRealName().equals("Player") && !auth.getRealName().equals(event.getName())) {
- event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
- event.setKickMessage("You should join using username: " + ChatColor.AQUA + auth.getRealName() +
- ChatColor.RESET + "\nnot: " + ChatColor.RED + event.getName()); // TODO: write a better message
- return;
- }
-
- if (auth != null && auth.getRealName().equals("Player")) {
- auth.setRealName(event.getName());
- plugin.getDataSource().saveAuth(auth);
+ if (Settings.preventOtherCase && auth != null && auth.getRealName() != null) {
+ String realName = auth.getRealName();
+ if(!realName.isEmpty() && !realName.equals("Player") && !realName.equals(event.getName())) {
+ event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
+ // TODO: Add a message like : MessageKey.INVALID_NAME_CASE
+ event.setKickMessage("You should join using username: " + ChatColor.AQUA + realName +
+ ChatColor.RESET + "\nnot: " + ChatColor.RED + event.getName());
+ return;
+ }
+ if (realName.isEmpty() || realName.equals("Player")) {
+ auth.setRealName(event.getName());
+ plugin.getDataSource().saveAuth(auth);
+ }
}
+ String playerIP = event.getAddress().getHostAddress();
if (auth == null && Settings.enableProtection) {
- String countryCode = GeoLiteAPI.getCountryCode(event.getAddress().getHostAddress());
+ String countryCode = GeoLiteAPI.getCountryCode(playerIP);
if (!Settings.countriesBlacklist.isEmpty() && Settings.countriesBlacklist.contains(countryCode)) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
event.setKickMessage(m.retrieveSingle(MessageKey.COUNTRY_BANNED_ERROR));
diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
index 8297224bf..7993c6c06 100644
--- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
+++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
@@ -119,7 +119,6 @@ public class AsynchronousLogin {
}
if (Settings.preventOtherCase && !player.getName().equals(pAuth.getRealName())) {
- // TODO: Add a message like : MessageKey.INVALID_NAME_CASE
m.send(player, MessageKey.USERNAME_ALREADY_ONLINE_ERROR);
return null;
}
From 052e414ff31573e23ead2c1ec7b14fa537a501f9 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sun, 3 Jan 2016 09:00:25 +0700
Subject: [PATCH 15/24] Moved VeryGames IP check into AsyncJoin process. -
Updated VeryGames IP check method. - Remove player's IP from realIp map on
quit.
---
src/main/java/fr/xephi/authme/AuthMe.java | 139 ++++++++----------
.../authme/process/join/AsynchronousJoin.java | 4 +
.../authme/process/quit/AsynchronousQuit.java | 1 +
3 files changed, 67 insertions(+), 77 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index 3243c21d9..cdaceb19e 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -1,35 +1,9 @@
package fr.xephi.authme;
-import java.io.BufferedReader;
-import java.io.IOException;
-import java.io.InputStreamReader;
-import java.net.URL;
-import java.net.URLConnection;
-import java.util.Calendar;
-import java.util.Collection;
-import java.util.Date;
-import java.util.List;
-import java.util.Set;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.logging.Logger;
-
-import org.apache.logging.log4j.LogManager;
-import org.bukkit.Bukkit;
-import org.bukkit.Location;
-import org.bukkit.Server;
-import org.bukkit.World;
-import org.bukkit.command.Command;
-import org.bukkit.command.CommandSender;
-import org.bukkit.entity.Player;
-import org.bukkit.plugin.PluginManager;
-import org.bukkit.plugin.java.JavaPlugin;
-import org.bukkit.scheduler.BukkitTask;
-import org.mcstats.Metrics;
-import org.mcstats.Metrics.Graph;
-
import com.earth2me.essentials.Essentials;
+import com.google.common.base.Charsets;
+import com.google.common.io.Resources;
import com.onarandombox.MultiverseCore.MultiverseCore;
-
import fr.xephi.authme.api.API;
import fr.xephi.authme.api.NewAPI;
import fr.xephi.authme.cache.auth.PlayerAuth;
@@ -80,6 +54,29 @@ import fr.xephi.authme.util.StringUtils;
import fr.xephi.authme.util.Utils;
import fr.xephi.authme.util.Wrapper;
import net.minelink.ctplus.CombatTagPlus;
+import org.apache.logging.log4j.LogManager;
+import org.bukkit.Bukkit;
+import org.bukkit.Location;
+import org.bukkit.Server;
+import org.bukkit.World;
+import org.bukkit.command.Command;
+import org.bukkit.command.CommandSender;
+import org.bukkit.entity.Player;
+import org.bukkit.plugin.PluginManager;
+import org.bukkit.plugin.java.JavaPlugin;
+import org.bukkit.scheduler.BukkitTask;
+import org.mcstats.Metrics;
+import org.mcstats.Metrics.Graph;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.Calendar;
+import java.util.Collection;
+import java.util.Date;
+import java.util.List;
+import java.util.Set;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.logging.Logger;
/**
* The AuthMe main class.
@@ -135,6 +132,7 @@ public class AuthMe extends JavaPlugin {
/**
* Get the plugin's instance.
+ *
* @return AuthMe
*/
public static AuthMe getInstance() {
@@ -143,6 +141,7 @@ public class AuthMe extends JavaPlugin {
/**
* Get the plugin's name.
+ *
* @return The plugin's name.
*/
public static String getPluginName() {
@@ -151,6 +150,7 @@ public class AuthMe extends JavaPlugin {
/**
* Get the plugin's version.
+ *
* @return The plugin's version.
*/
public static String getPluginVersion() {
@@ -159,6 +159,7 @@ public class AuthMe extends JavaPlugin {
/**
* Get the plugin's build number.
+ *
* @return The plugin's build number.
*/
public static String getPluginBuildNumber() {
@@ -167,6 +168,7 @@ public class AuthMe extends JavaPlugin {
/**
* Get the plugin's Settings.
+ *
* @return Plugin's settings.
*/
public Settings getSettings() {
@@ -175,6 +177,7 @@ public class AuthMe extends JavaPlugin {
/**
* Get the Messages instance.
+ *
* @return Plugin's messages.
*/
public Messages getMessages() {
@@ -274,7 +277,6 @@ public class AuthMe extends JavaPlugin {
new PerformBackup(plugin).doBackup(PerformBackup.BackupCause.START);
-
// Setup the inventory backup
playerBackup = new JsonCache();
@@ -308,8 +310,8 @@ public class AuthMe extends JavaPlugin {
// Register a server shutdown hook
try {
Runtime.getRuntime().addShutdownHook(new AuthMeServerStop(this));
- } catch (Exception e){
- e.printStackTrace();
+ } catch (Exception e) {
+ e.printStackTrace();
}
// Sponsor messages
@@ -595,16 +597,16 @@ public class AuthMe extends JavaPlugin {
// TODO: Move this to another place maybe ?
if (Settings.getPasswordHash == HashAlgorithm.PLAINTEXT) {
- ConsoleLogger.showError("Your HashAlgorithm has been detected as plaintext and is now deprecated; " +
+ ConsoleLogger.showError("Your HashAlgorithm has been detected as plaintext and is now deprecated; " +
"it will be changed and hashed now to the AuthMe default hashing method");
- for (PlayerAuth auth : database.getAllAuths()) {
+ for (PlayerAuth auth : database.getAllAuths()) {
HashedPassword hashedPassword = passwordSecurity.computeHash(
HashAlgorithm.SHA256, auth.getPassword().getHash(), auth.getNickname());
auth.setPassword(hashedPassword);
- database.updatePassword(auth);
- }
- Settings.setValue("settings.security.passwordHash", "SHA256");
- Settings.reload();
+ database.updatePassword(auth);
+ }
+ Settings.setValue("settings.security.passwordHash", "SHA256");
+ Settings.reload();
}
if (Settings.isCachingEnabled) {
@@ -717,10 +719,9 @@ public class AuthMe extends JavaPlugin {
inventoryProtector = null;
}
}
- if (tabComplete == null)
- {
- tabComplete = new AuthMeTabCompletePacketAdapter(this);
- tabComplete.register();
+ if (tabComplete == null) {
+ tabComplete = new AuthMeTabCompletePacketAdapter(this);
+ tabComplete.register();
}
}
@@ -891,50 +892,34 @@ public class AuthMe extends JavaPlugin {
* Gets a player's real IP through VeryGames method.
*
* @param player The player to process.
- *
*/
@Deprecated
public void getVerygamesIp(final Player player) {
- final String name = player.getName().toLowerCase();
- Bukkit.getScheduler().runTaskAsynchronously(plugin, new Runnable(){
- @Override
- public void run() {
- String realIP = player.getAddress().getAddress().getHostAddress();
- if (realIp.containsKey(name))
- realIP = realIp.get(name);
- String sUrl = "http://monitor-1.verygames.net/api/?action=ipclean-real-ip&out=raw&ip=%IP%&port=%PORT%";
- sUrl = sUrl.replace("%IP%", realIP)
- .replace("%PORT%", "" + player.getAddress().getPort());
- try {
- URL url = new URL(sUrl);
- URLConnection urlCon = url.openConnection();
- urlCon.setConnectTimeout(5000);
- urlCon.setReadTimeout(5000);
- try (BufferedReader in = new BufferedReader(new InputStreamReader(urlCon.getInputStream()))) {
- String inputLine = in.readLine();
- if (!StringUtils.isEmpty(inputLine) && !inputLine.equalsIgnoreCase("error")
- && !inputLine.contains("error")) {
- realIP = inputLine;
- }
- } catch (IOException e) {
- ConsoleLogger.showError("Could not read from Very Games API - " + StringUtils.formatException(e));
- }
- } catch (IOException e) {
- ConsoleLogger.showError("Could not fetch Very Games API with URL '" + sUrl + "' - "
- + StringUtils.formatException(e));
- }
- if (realIp.containsKey(name))
- realIp.remove(name);
- realIp.putIfAbsent(name, realIP);
- }
- });
+ final String name = player.getName().toLowerCase();
+ String currentIp = player.getAddress().getAddress().getHostAddress();
+ if (realIp.containsKey(name)) {
+ currentIp = realIp.get(name);
+ }
+ String sUrl = "http://monitor-1.verygames.net/api/?action=ipclean-real-ip&out=raw&ip=%IP%&port=%PORT%";
+ sUrl = sUrl.replace("%IP%", currentIp).replace("%PORT%", "" + player.getAddress().getPort());
+ try {
+ String result = Resources.toString(new URL(sUrl), Charsets.UTF_8);
+ if (!StringUtils.isEmpty(result) && !result.equalsIgnoreCase("error") && !result.contains("error")) {
+ currentIp = result;
+ realIp.put(name, currentIp);
+ }
+ } catch (IOException e) {
+ ConsoleLogger.showError("Could not fetch Very Games API with URL '" +
+ sUrl + "' - " + StringUtils.formatException(e));
+ }
}
public String getIP(final Player player) {
final String name = player.getName().toLowerCase();
String ip = player.getAddress().getAddress().getHostAddress();
- if (realIp.containsKey(name))
+ if (realIp.containsKey(name)) {
ip = realIp.get(name);
+ }
return ip;
}
@@ -985,7 +970,7 @@ public class AuthMe extends JavaPlugin {
/**
* Return the management instance.
- *
+ *
* @return management The Management
*/
public Management getManagement() {
diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
index 56656e97f..9c763db3e 100644
--- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
+++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
@@ -49,6 +49,10 @@ public class AsynchronousJoin {
}
public void process() {
+ if (Settings.checkVeryGames) {
+ plugin.getVerygamesIp(player);
+ }
+
if (Utils.isUnrestricted(player)) {
return;
}
diff --git a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
index 42c633afc..2a3a5d3e0 100644
--- a/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
+++ b/src/main/java/fr/xephi/authme/process/quit/AsynchronousQuit.java
@@ -93,6 +93,7 @@ public class AsynchronousQuit {
database.setUnlogged(name);
}
+ plugin.realIp.remove(name);
Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, new ProcessSyncronousPlayerQuit(plugin, player, isOp, needToChange));
}
}
From 4161dcaa9485c83d03810480edc3aeb4387d664e Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sun, 3 Jan 2016 09:07:48 +0700
Subject: [PATCH 16/24] Fix SingleSession check order.
---
.../authme/process/join/AsynchronousJoin.java | 38 +++++++++----------
1 file changed, 19 insertions(+), 19 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
index 9c763db3e..cbdac41eb 100644
--- a/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
+++ b/src/main/java/fr/xephi/authme/process/join/AsynchronousJoin.java
@@ -62,6 +62,8 @@ public class AsynchronousJoin {
}
final String ip = plugin.getIP(player);
+
+
if (Settings.isAllowRestrictedIp && !Settings.getRestrictedIp(name, ip, player.getAddress().getHostName())) {
sched.scheduleSyncDelayedTask(plugin, new Runnable() {
@@ -114,7 +116,6 @@ public class AsynchronousJoin {
});
}
}
-
placePlayerSafely(player, spawnLoc);
LimboCache.getInstance().updateLimboPlayer(player);
@@ -130,6 +131,22 @@ public class AsynchronousJoin {
}
}
+ if (Settings.isSessionsEnabled && (PlayerCache.getInstance().isAuthenticated(name) || database.isLogged(name))) {
+ if (plugin.sessions.containsKey(name)) {
+ plugin.sessions.get(name).cancel();
+ plugin.sessions.remove(name);
+ }
+ PlayerAuth auth = database.getAuth(name);
+ database.setUnlogged(name);
+ PlayerCache.getInstance().removePlayer(name);
+ if (auth != null && auth.getIp().equals(ip)) {
+ m.send(player, MessageKey.SESSION_RECONNECTION);
+ plugin.getManagement().performLogin(player, "dontneed", true);
+ return;
+ } else if (Settings.sessionExpireOnIpChange) {
+ m.send(player, MessageKey.SESSION_EXPIRED);
+ }
+ }
} else {
if (!Settings.unRegisteredGroup.isEmpty()) {
Utils.setGroup(player, Utils.GroupType.UNREGISTERED);
@@ -183,7 +200,7 @@ public class AsynchronousJoin {
if (Settings.applyBlindEffect) {
int blindTimeOut;
// Allow infinite blindness effect
- if(timeOut <= 0) {
+ if (timeOut <= 0) {
blindTimeOut = 99999;
} else {
blindTimeOut = timeOut;
@@ -200,23 +217,6 @@ public class AsynchronousJoin {
LimboCache.getInstance().getLimboPlayer(name).setTimeoutTaskId(id);
}
- if (Settings.isSessionsEnabled && isAuthAvailable && (PlayerCache.getInstance().isAuthenticated(name) || database.isLogged(name))) {
- if (plugin.sessions.containsKey(name)) {
- plugin.sessions.get(name).cancel();
- plugin.sessions.remove(name);
- }
- PlayerAuth auth = database.getAuth(name);
- database.setUnlogged(name);
- PlayerCache.getInstance().removePlayer(name);
- if (auth != null && auth.getIp().equals(ip)) {
- m.send(player, MessageKey.SESSION_RECONNECTION);
- plugin.getManagement().performLogin(player, "dontneed", true);
- return;
- } else if (Settings.sessionExpireOnIpChange) {
- m.send(player, MessageKey.SESSION_EXPIRED);
- }
- }
-
String[] msg;
if (isAuthAvailable) {
msg = m.retrieve(MessageKey.LOGIN_MESSAGE);
From 774b7513c9ef49f6eaf1294455c87f872429ed60 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sun, 3 Jan 2016 09:33:47 +0700
Subject: [PATCH 17/24] Attempt to update player's IP on login if they have
default IP in database.
---
.../process/login/AsynchronousLogin.java | 65 ++++++++++---------
...Login.java => ProcessSyncPlayerLogin.java} | 8 +--
2 files changed, 39 insertions(+), 34 deletions(-)
rename src/main/java/fr/xephi/authme/process/login/{ProcessSyncronousPlayerLogin.java => ProcessSyncPlayerLogin.java} (96%)
diff --git a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
index 7993c6c06..9b911da17 100644
--- a/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
+++ b/src/main/java/fr/xephi/authme/process/login/AsynchronousLogin.java
@@ -33,6 +33,7 @@ public class AsynchronousLogin {
private final AuthMe plugin;
private final DataSource database;
private final Messages m;
+ private final String ip;
/**
* Constructor for AsynchronousLogin.
@@ -52,10 +53,7 @@ public class AsynchronousLogin {
this.forceLogin = forceLogin;
this.plugin = plugin;
this.database = data;
- }
-
- protected String getIP() {
- return plugin.getIP(player);
+ this.ip = plugin.getIP(player);
}
protected boolean needsCaptcha() {
@@ -87,7 +85,9 @@ public class AsynchronousLogin {
m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
return null;
}
- if (!database.isAuthAvailable(name)) {
+
+ PlayerAuth pAuth = database.getAuth(name);
+ if (pAuth == null) {
m.send(player, MessageKey.USER_NOT_REGISTERED);
if (LimboCache.getInstance().hasLimboPlayer(name)) {
LimboCache.getInstance().getLimboPlayer(name).getMessageTaskId().cancel();
@@ -97,42 +97,45 @@ public class AsynchronousLogin {
} else {
msg = m.retrieve(MessageKey.REGISTER_MESSAGE);
}
- BukkitTask msgT = Bukkit.getScheduler().runTaskAsynchronously(plugin, new MessageTask(plugin, name, msg, Settings.getWarnMessageInterval));
+ BukkitTask msgT = Bukkit.getScheduler().runTaskAsynchronously(plugin,
+ new MessageTask(plugin, name, msg, Settings.getWarnMessageInterval));
LimboCache.getInstance().getLimboPlayer(name).setMessageTaskId(msgT);
}
return null;
}
- if (Settings.getMaxLoginPerIp > 0 && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS) && !getIP().equalsIgnoreCase("127.0.0.1") && !getIP().equalsIgnoreCase("localhost")) {
- if (plugin.isLoggedIp(name, getIP())) {
- m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
- return null;
- }
- }
- PlayerAuth pAuth = database.getAuth(name);
- if (pAuth == null) {
- m.send(player, MessageKey.USER_NOT_REGISTERED);
- return null;
- }
+
if (!Settings.getMySQLColumnGroup.isEmpty() && pAuth.getGroupId() == Settings.getNonActivatedGroup) {
m.send(player, MessageKey.ACCOUNT_NOT_ACTIVATED);
return null;
}
- if (Settings.preventOtherCase && !player.getName().equals(pAuth.getRealName())) {
- m.send(player, MessageKey.USERNAME_ALREADY_ONLINE_ERROR);
- return null;
+ if (Settings.getMaxLoginPerIp > 0
+ && !plugin.getPermissionsManager().hasPermission(player, PlayerPermission.ALLOW_MULTIPLE_ACCOUNTS)
+ && !ip.equalsIgnoreCase("127.0.0.1") && !ip.equalsIgnoreCase("localhost")) {
+ if (plugin.isLoggedIp(name, ip)) {
+ m.send(player, MessageKey.ALREADY_LOGGED_IN_ERROR);
+ return null;
+ }
}
+
AuthMeAsyncPreLoginEvent event = new AuthMeAsyncPreLoginEvent(player);
Bukkit.getServer().getPluginManager().callEvent(event);
- if (!event.canLogin())
+ if (!event.canLogin()) {
return null;
+ }
return pAuth;
}
public void process() {
PlayerAuth pAuth = preAuth();
- if (pAuth == null || needsCaptcha())
+ if (pAuth == null || needsCaptcha()) {
return;
+ }
+
+ if (pAuth.getIp().equals("127.0.0.1") && !pAuth.getIp().equals(ip)) {
+ pAuth.setIp(ip);
+ database.saveAuth(pAuth);
+ }
String email = pAuth.getEmail();
boolean passwordVerified = forceLogin || plugin.getPasswordSecurity()
@@ -142,7 +145,7 @@ public class AsynchronousLogin {
PlayerAuth auth = PlayerAuth.builder()
.name(name)
.realName(realName)
- .ip(getIP())
+ .ip(ip)
.lastLogin(new Date().getTime())
.email(email)
.password(pAuth.getPassword())
@@ -183,14 +186,16 @@ public class AsynchronousLogin {
// task, we schedule it in the end
// so that we can be sure, and have not to care if it might be
// processed in other order.
- ProcessSyncronousPlayerLogin syncronousPlayerLogin = new ProcessSyncronousPlayerLogin(player, plugin, database);
- if (syncronousPlayerLogin.getLimbo() != null) {
- if (syncronousPlayerLogin.getLimbo().getTimeoutTaskId() != null)
- syncronousPlayerLogin.getLimbo().getTimeoutTaskId().cancel();
- if (syncronousPlayerLogin.getLimbo().getMessageTaskId() != null)
- syncronousPlayerLogin.getLimbo().getMessageTaskId().cancel();
+ ProcessSyncPlayerLogin syncPlayerLogin = new ProcessSyncPlayerLogin(player, plugin, database);
+ if (syncPlayerLogin.getLimbo() != null) {
+ if (syncPlayerLogin.getLimbo().getTimeoutTaskId() != null) {
+ syncPlayerLogin.getLimbo().getTimeoutTaskId().cancel();
+ }
+ if (syncPlayerLogin.getLimbo().getMessageTaskId() != null) {
+ syncPlayerLogin.getLimbo().getMessageTaskId().cancel();
+ }
}
- Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, syncronousPlayerLogin);
+ Bukkit.getScheduler().scheduleSyncDelayedTask(plugin, syncPlayerLogin);
} else if (player.isOnline()) {
if (!Settings.noConsoleSpam)
ConsoleLogger.info(realName + " used the wrong password");
diff --git a/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
similarity index 96%
rename from src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java
rename to src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
index c4562d506..27c09174e 100644
--- a/src/main/java/fr/xephi/authme/process/login/ProcessSyncronousPlayerLogin.java
+++ b/src/main/java/fr/xephi/authme/process/login/ProcessSyncPlayerLogin.java
@@ -26,7 +26,7 @@ import fr.xephi.authme.util.Utils.GroupType;
/**
*/
-public class ProcessSyncronousPlayerLogin implements Runnable {
+public class ProcessSyncPlayerLogin implements Runnable {
private final LimboPlayer limbo;
private final Player player;
@@ -38,14 +38,14 @@ public class ProcessSyncronousPlayerLogin implements Runnable {
private final JsonCache playerCache;
/**
- * Constructor for ProcessSyncronousPlayerLogin.
+ * Constructor for ProcessSyncPlayerLogin.
*
* @param player Player
* @param plugin AuthMe
* @param data DataSource
*/
- public ProcessSyncronousPlayerLogin(Player player, AuthMe plugin,
- DataSource data) {
+ public ProcessSyncPlayerLogin(Player player, AuthMe plugin,
+ DataSource data) {
this.plugin = plugin;
this.database = data;
this.pm = plugin.getServer().getPluginManager();
From fe31b5cabb5e1a3b4dc8a9e6cb859b6d6c1f2add Mon Sep 17 00:00:00 2001
From: DNx5
Date: Sun, 3 Jan 2016 09:38:30 +0700
Subject: [PATCH 18/24] I forgot to remove the old check.
---
.../java/fr/xephi/authme/listener/AuthMePlayerListener.java | 4 ----
1 file changed, 4 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
index fd8418cb9..4f6e17794 100644
--- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
+++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
@@ -206,10 +206,6 @@ public class AuthMePlayerListener implements Listener {
joinMessage.put(name, joinMsg);
}
- if (Settings.checkVeryGames) {
- plugin.getVerygamesIp(player);
- }
-
// Shedule login task so works after the prelogin
// (Fix found by Koolaid5000)
Bukkit.getScheduler().runTask(plugin, new Runnable() {
From 6d7d856ebea0e755a116596dd9bdbdbb6c7ef7de Mon Sep 17 00:00:00 2001
From: DNx5
Date: Mon, 4 Jan 2016 05:04:52 +0700
Subject: [PATCH 19/24] Wait executor to complete the submitted task before
shutting down * Fix #403
---
.../authme/datasource/CacheDataSource.java | 21 ++++++++++++-------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
index b80bac117..9b346bcba 100644
--- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
+++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
@@ -1,11 +1,5 @@
package fr.xephi.authme.datasource;
-import java.util.ArrayList;
-import java.util.List;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
-
import com.google.common.base.Optional;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
@@ -13,10 +7,16 @@ import com.google.common.cache.LoadingCache;
import com.google.common.cache.RemovalListener;
import com.google.common.cache.RemovalListeners;
import com.google.common.cache.RemovalNotification;
-
+import fr.xephi.authme.ConsoleLogger;
import fr.xephi.authme.cache.auth.PlayerAuth;
import fr.xephi.authme.cache.auth.PlayerCache;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.concurrent.TimeUnit;
+
/**
*/
public class CacheDataSource implements DataSource {
@@ -233,7 +233,12 @@ public class CacheDataSource implements DataSource {
*/
@Override
public synchronized void close() {
- exec.shutdown();
+ try {
+ exec.shutdown();
+ exec.awaitTermination(8, TimeUnit.SECONDS);
+ } catch (InterruptedException e) {
+ ConsoleLogger.writeStackTrace(e);
+ }
source.close();
}
From 5ec1b67e0357431fb7789201465d5709cb934919 Mon Sep 17 00:00:00 2001
From: ljacqu
Date: Mon, 4 Jan 2016 21:51:28 +0100
Subject: [PATCH 20/24] Fix #408 Player quit location is not updated - Ensure
that the cache data source updates the quit location on the actual source
---
.../authme/datasource/CacheDataSource.java | 209 +-----------------
.../fr/xephi/authme/datasource/SQLite.java | 191 ----------------
2 files changed, 1 insertion(+), 399 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
index 9b346bcba..cfb17c06f 100644
--- a/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
+++ b/src/main/java/fr/xephi/authme/datasource/CacheDataSource.java
@@ -52,44 +52,17 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method isAuthAvailable.
- *
- * @param user String
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#isAuthAvailable(String)
- */
@Override
public synchronized boolean isAuthAvailable(String user) {
return getAuth(user) != null;
}
- /**
- * Method getAuth.
- *
- * @param user String
- *
- * @return PlayerAuth
- *
- * @see fr.xephi.authme.datasource.DataSource#getAuth(String)
- */
@Override
public synchronized PlayerAuth getAuth(String user) {
user = user.toLowerCase();
return cachedAuths.getUnchecked(user).orNull();
}
- /**
- * Method saveAuth.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#saveAuth(PlayerAuth)
- */
@Override
public synchronized boolean saveAuth(PlayerAuth auth) {
boolean result = source.saveAuth(auth);
@@ -99,15 +72,6 @@ public class CacheDataSource implements DataSource {
return result;
}
- /**
- * Method updatePassword.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#updatePassword(PlayerAuth)
- */
@Override
public synchronized boolean updatePassword(PlayerAuth auth) {
boolean result = source.updatePassword(auth);
@@ -117,15 +81,6 @@ public class CacheDataSource implements DataSource {
return result;
}
- /**
- * Method updateSession.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#updateSession(PlayerAuth)
- */
@Override
public boolean updateSession(PlayerAuth auth) {
boolean result = source.updateSession(auth);
@@ -135,47 +90,20 @@ public class CacheDataSource implements DataSource {
return result;
}
- /**
- * Method updateQuitLoc.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#updateQuitLoc(PlayerAuth)
- */
@Override
public boolean updateQuitLoc(final PlayerAuth auth) {
- boolean result = source.updateSession(auth);
+ boolean result = source.updateQuitLoc(auth);
if (result) {
cachedAuths.refresh(auth.getNickname());
}
return result;
}
- /**
- * Method getIps.
- *
- * @param ip String
- *
- * @return int
- *
- * @see fr.xephi.authme.datasource.DataSource#getIps(String)
- */
@Override
public int getIps(String ip) {
return source.getIps(ip);
}
- /**
- * Method purgeDatabase.
- *
- * @param until long
- *
- * @return int
- *
- * @see fr.xephi.authme.datasource.DataSource#purgeDatabase(long)
- */
@Override
public int purgeDatabase(long until) {
int cleared = source.purgeDatabase(until);
@@ -189,15 +117,6 @@ public class CacheDataSource implements DataSource {
return cleared;
}
- /**
- * Method autoPurgeDatabase.
- *
- * @param until long
- *
- * @return List
- *
- * @see fr.xephi.authme.datasource.DataSource#autoPurgeDatabase(long)
- */
@Override
public List autoPurgeDatabase(long until) {
List cleared = source.autoPurgeDatabase(until);
@@ -207,15 +126,6 @@ public class CacheDataSource implements DataSource {
return cleared;
}
- /**
- * Method removeAuth.
- *
- * @param name String
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#removeAuth(String)
- */
@Override
public synchronized boolean removeAuth(String name) {
name = name.toLowerCase();
@@ -226,11 +136,6 @@ public class CacheDataSource implements DataSource {
return result;
}
- /**
- * Method close.
- *
- * @see fr.xephi.authme.datasource.DataSource#close()
- */
@Override
public synchronized void close() {
try {
@@ -242,11 +147,6 @@ public class CacheDataSource implements DataSource {
source.close();
}
- /**
- * Method reload.
- *
- * @see fr.xephi.authme.datasource.DataSource#reload()
- */
@Override
public void reload() { // unused method
exec.execute(new Runnable() {
@@ -258,15 +158,6 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method updateEmail.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#updateEmail(PlayerAuth)
- */
@Override
public synchronized boolean updateEmail(final PlayerAuth auth) {
boolean result = source.updateEmail(auth);
@@ -276,55 +167,21 @@ public class CacheDataSource implements DataSource {
return result;
}
- /**
- * Method getAllAuthsByName.
- *
- * @param auth PlayerAuth
- *
- * @return List
- *
- * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByName(PlayerAuth)
- */
@Override
public synchronized List getAllAuthsByName(PlayerAuth auth) {
return source.getAllAuthsByName(auth);
}
- /**
- * Method getAllAuthsByIp.
- *
- * @param ip String
- *
- * @return List
- *
- * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByIp(String)
- */
@Override
public synchronized List getAllAuthsByIp(final String ip) {
return source.getAllAuthsByIp(ip);
}
- /**
- * Method getAllAuthsByEmail.
- *
- * @param email String
- *
- * @return List
- *
- * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByEmail(String)
- */
@Override
public synchronized List getAllAuthsByEmail(final String email) {
return source.getAllAuthsByEmail(email);
}
- /**
- * Method purgeBanned.
- *
- * @param banned List of String
- *
- * @see fr.xephi.authme.datasource.DataSource#purgeBanned(List)
- */
@Override
public synchronized void purgeBanned(final List banned) {
exec.execute(new Runnable() {
@@ -336,39 +193,16 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method getType.
- *
- * @return DataSourceType
- *
- * @see fr.xephi.authme.datasource.DataSource#getType()
- */
@Override
public DataSourceType getType() {
return source.getType();
}
- /**
- * Method isLogged.
- *
- * @param user String
- *
- * @return boolean
- *
- * @see fr.xephi.authme.datasource.DataSource#isLogged(String)
- */
@Override
public boolean isLogged(String user) {
return PlayerCache.getInstance().isAuthenticated(user);
}
- /**
- * Method setLogged.
- *
- * @param user String
- *
- * @see fr.xephi.authme.datasource.DataSource#setLogged(String)
- */
@Override
public void setLogged(final String user) {
exec.execute(new Runnable() {
@@ -379,13 +213,6 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method setUnlogged.
- *
- * @param user String
- *
- * @see fr.xephi.authme.datasource.DataSource#setUnlogged(String)
- */
@Override
public void setUnlogged(final String user) {
exec.execute(new Runnable() {
@@ -396,11 +223,6 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method purgeLogged.
- *
- * @see fr.xephi.authme.datasource.DataSource#purgeLogged()
- */
@Override
public void purgeLogged() {
exec.execute(new Runnable() {
@@ -412,26 +234,11 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method getAccountsRegistered.
- *
- * @return int
- *
- * @see fr.xephi.authme.datasource.DataSource#getAccountsRegistered()
- */
@Override
public int getAccountsRegistered() {
return source.getAccountsRegistered();
}
- /**
- * Method updateName.
- *
- * @param oldOne String
- * @param newOne String
- *
- * @see fr.xephi.authme.datasource.DataSource#updateName(String, String)
- */
@Override
public void updateName(final String oldOne, final String newOne) {
exec.execute(new Runnable() {
@@ -443,25 +250,11 @@ public class CacheDataSource implements DataSource {
});
}
- /**
- * Method getAllAuths.
- *
- * @return List
- *
- * @see fr.xephi.authme.datasource.DataSource#getAllAuths()
- */
@Override
public List getAllAuths() {
return source.getAllAuths();
}
- /**
- * Method getLoggedPlayers.
- *
- * @return List
- *
- * @see fr.xephi.authme.datasource.DataSource#getLoggedPlayers()
- */
@Override
public List getLoggedPlayers() {
return new ArrayList<>(PlayerCache.getInstance().getCache().values());
diff --git a/src/main/java/fr/xephi/authme/datasource/SQLite.java b/src/main/java/fr/xephi/authme/datasource/SQLite.java
index e068daf8a..a04bb7f91 100644
--- a/src/main/java/fr/xephi/authme/datasource/SQLite.java
+++ b/src/main/java/fr/xephi/authme/datasource/SQLite.java
@@ -70,12 +70,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method connect.
- *
- * @throws ClassNotFoundException
- * @throws SQLException
- */
private synchronized void connect() throws ClassNotFoundException, SQLException {
Class.forName("org.sqlite.JDBC");
ConsoleLogger.info("SQLite driver loaded");
@@ -83,11 +77,6 @@ public class SQLite implements DataSource {
}
- /**
- * Method setup.
- *
- * @throws SQLException
- */
private synchronized void setup() throws SQLException {
Statement st = null;
ResultSet rs = null;
@@ -149,14 +138,6 @@ public class SQLite implements DataSource {
ConsoleLogger.info("SQLite Setup finished");
}
- /**
- * Method isAuthAvailable.
- *
- * @param user String
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#isAuthAvailable(String)
- */
@Override
public synchronized boolean isAuthAvailable(String user) {
PreparedStatement pst = null;
@@ -175,14 +156,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getAuth.
- *
- * @param user String
- *
- * @return PlayerAuth
- * @see fr.xephi.authme.datasource.DataSource#getAuth(String)
- */
@Override
public synchronized PlayerAuth getAuth(String user) {
PreparedStatement pst = null;
@@ -205,14 +178,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method saveAuth.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#saveAuth(PlayerAuth)
- */
@Override
public synchronized boolean saveAuth(PlayerAuth auth) {
PreparedStatement pst = null;
@@ -252,14 +217,6 @@ public class SQLite implements DataSource {
return true;
}
- /**
- * Method updatePassword.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#updatePassword(PlayerAuth)
- */
@Override
public synchronized boolean updatePassword(PlayerAuth auth) {
PreparedStatement pst = null;
@@ -287,14 +244,6 @@ public class SQLite implements DataSource {
return true;
}
- /**
- * Method updateSession.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#updateSession(PlayerAuth)
- */
@Override
public boolean updateSession(PlayerAuth auth) {
PreparedStatement pst = null;
@@ -314,14 +263,6 @@ public class SQLite implements DataSource {
return true;
}
- /**
- * Method purgeDatabase.
- *
- * @param until long
- *
- * @return int
- * @see fr.xephi.authme.datasource.DataSource#purgeDatabase(long)
- */
@Override
public int purgeDatabase(long until) {
PreparedStatement pst = null;
@@ -338,14 +279,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method autoPurgeDatabase.
- *
- * @param until long
- *
- * @return List of String
- * @see fr.xephi.authme.datasource.DataSource#autoPurgeDatabase(long)
- */
@Override
public List autoPurgeDatabase(long until) {
PreparedStatement pst = null;
@@ -368,14 +301,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method removeAuth.
- *
- * @param user String
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#removeAuth(String)
- */
@Override
public synchronized boolean removeAuth(String user) {
PreparedStatement pst = null;
@@ -392,14 +317,6 @@ public class SQLite implements DataSource {
return true;
}
- /**
- * Method updateQuitLoc.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#updateQuitLoc(PlayerAuth)
- */
@Override
public boolean updateQuitLoc(PlayerAuth auth) {
PreparedStatement pst = null;
@@ -420,14 +337,6 @@ public class SQLite implements DataSource {
return true;
}
- /**
- * Method getIps.
- *
- * @param ip String
- *
- * @return int
- * @see fr.xephi.authme.datasource.DataSource#getIps(String)
- */
@Override
public int getIps(String ip) {
PreparedStatement pst = null;
@@ -451,14 +360,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method updateEmail.
- *
- * @param auth PlayerAuth
- *
- * @return boolean
- * @see fr.xephi.authme.datasource.DataSource#updateEmail(PlayerAuth)
- */
@Override
public boolean updateEmail(PlayerAuth auth) {
PreparedStatement pst = null;
@@ -476,11 +377,6 @@ public class SQLite implements DataSource {
return true;
}
- /**
- * Method close.
- *
- * @see fr.xephi.authme.datasource.DataSource#close()
- */
@Override
public synchronized void close() {
try {
@@ -490,20 +386,10 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method reload.
- *
- * @see fr.xephi.authme.datasource.DataSource#reload()
- */
@Override
public void reload() {
}
- /**
- * Method close.
- *
- * @param st Statement
- */
private void close(Statement st) {
if (st != null) {
try {
@@ -514,11 +400,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method close.
- *
- * @param rs ResultSet
- */
private void close(ResultSet rs) {
if (rs != null) {
try {
@@ -529,14 +410,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getAllAuthsByName.
- *
- * @param auth PlayerAuth
- *
- * @return List of String
- * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByName(PlayerAuth)
- */
@Override
public List getAllAuthsByName(PlayerAuth auth) {
PreparedStatement pst = null;
@@ -561,14 +434,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getAllAuthsByIp.
- *
- * @param ip String
- *
- * @return List of String
- * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByIp(String)
- */
@Override
public List getAllAuthsByIp(String ip) {
PreparedStatement pst = null;
@@ -593,14 +458,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getAllAuthsByEmail.
- *
- * @param email String
- *
- * @return List of String
- * @see fr.xephi.authme.datasource.DataSource#getAllAuthsByEmail(String)
- */
@Override
public List getAllAuthsByEmail(String email) {
PreparedStatement pst = null;
@@ -641,24 +498,11 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getType.
- *
- * @return DataSourceType
- * @see fr.xephi.authme.datasource.DataSource#getType()
- */
@Override
public DataSourceType getType() {
return DataSourceType.SQLITE;
}
- /**
- * Method isLogged.
- *
- * @param user String
- *
- * @return boolean * @see fr.xephi.authme.datasource.DataSource#isLogged(String)
- */
@Override
public boolean isLogged(String user) {
PreparedStatement pst = null;
@@ -679,13 +523,6 @@ public class SQLite implements DataSource {
return false;
}
- /**
- * Method setLogged.
- *
- * @param user String
- *
- * @see fr.xephi.authme.datasource.DataSource#setLogged(String)
- */
@Override
public void setLogged(String user) {
PreparedStatement pst = null;
@@ -701,13 +538,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method setUnlogged.
- *
- * @param user String
- *
- * @see fr.xephi.authme.datasource.DataSource#setUnlogged(String)
- */
@Override
public void setUnlogged(String user) {
PreparedStatement pst = null;
@@ -724,11 +554,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method purgeLogged.
- *
- * @see fr.xephi.authme.datasource.DataSource#purgeLogged()
- */
@Override
public void purgeLogged() {
PreparedStatement pst = null;
@@ -744,12 +569,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getAccountsRegistered.
- *
- * @return int
- * @see fr.xephi.authme.datasource.DataSource#getAccountsRegistered()
- */
@Override
public int getAccountsRegistered() {
int result = 0;
@@ -785,11 +604,6 @@ public class SQLite implements DataSource {
}
}
- /**
- * Method getAllAuths.
- *
- * @return List of PlayerAuth
- */
@Override
public List getAllAuths() {
List auths = new ArrayList<>();
@@ -811,11 +625,6 @@ public class SQLite implements DataSource {
return auths;
}
- /**
- * Method getLoggedPlayers.
- *
- * @return List of PlayerAuth
- */
@Override
public List getLoggedPlayers() {
List auths = new ArrayList<>();
From 627db6b9cf2fc13702338cce6f14ad762ce44368 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Tue, 5 Jan 2016 06:33:43 +0700
Subject: [PATCH 21/24] Attempt to Fix #407
---
.../authme/listener/AuthMePlayerListener.java | 39 +++++++++----------
1 file changed, 19 insertions(+), 20 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
index 4f6e17794..2e365e932 100644
--- a/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
+++ b/src/main/java/fr/xephi/authme/listener/AuthMePlayerListener.java
@@ -193,7 +193,7 @@ public class AuthMePlayerListener implements Listener {
}
if (Settings.isForceSurvivalModeEnabled
- && !player.hasPermission(PlayerPermission.BYPASS_FORCE_SURVIVAL.getNode())) {
+ && !player.hasPermission(PlayerPermission.BYPASS_FORCE_SURVIVAL.getNode())) {
player.setGameMode(GameMode.SURVIVAL);
}
@@ -221,7 +221,7 @@ public class AuthMePlayerListener implements Listener {
PlayerAuth auth = plugin.getDataSource().getAuth(event.getName());
if (Settings.preventOtherCase && auth != null && auth.getRealName() != null) {
String realName = auth.getRealName();
- if(!realName.isEmpty() && !realName.equals("Player") && !realName.equals(event.getName())) {
+ if (!realName.isEmpty() && !realName.equals("Player") && !realName.equals(event.getName())) {
event.setLoginResult(AsyncPlayerPreLoginEvent.Result.KICK_OTHER);
// TODO: Add a message like : MessageKey.INVALID_NAME_CASE
event.setKickMessage("You should join using username: " + ChatColor.AQUA + realName +
@@ -274,21 +274,26 @@ public class AuthMePlayerListener implements Listener {
// Get the permissions manager
PermissionsManager permsMan = plugin.getPermissionsManager();
- if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL
- && permsMan.hasPermission(player, PlayerPermission.IS_VIP)) {
- int playersOnline = Utils.getOnlinePlayers().size();
- if (playersOnline > plugin.getServer().getMaxPlayers()) {
- event.allow();
- } else {
- Player pl = plugin.generateKickPlayer(Utils.getOnlinePlayers());
- if (pl != null) {
- pl.kickPlayer(m.retrieveSingle(MessageKey.KICK_FOR_VIP));
+ if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL) {
+ if (permsMan.hasPermission(player, PlayerPermission.IS_VIP)) {
+ int playersOnline = Utils.getOnlinePlayers().size();
+ if (playersOnline > plugin.getServer().getMaxPlayers()) {
event.allow();
} else {
- ConsoleLogger.info("The player " + event.getPlayer().getName() + " tried to join, but the server was full");
- event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
- event.setResult(PlayerLoginEvent.Result.KICK_FULL);
+ Player pl = plugin.generateKickPlayer(Utils.getOnlinePlayers());
+ if (pl != null) {
+ pl.kickPlayer(m.retrieveSingle(MessageKey.KICK_FOR_VIP));
+ event.allow();
+ } else {
+ ConsoleLogger.info("The player " + event.getPlayer().getName() + " tried to join, but the server was full");
+ event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
+ event.setResult(PlayerLoginEvent.Result.KICK_FULL);
+ }
}
+ } else {
+ event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
+ event.setResult(PlayerLoginEvent.Result.KICK_FULL);
+ return;
}
}
@@ -296,12 +301,6 @@ public class AuthMePlayerListener implements Listener {
return;
}
- if (event.getResult() == PlayerLoginEvent.Result.KICK_FULL && !permsMan.hasPermission(player, PlayerPermission.IS_VIP)) {
- event.setKickMessage(m.retrieveSingle(MessageKey.KICK_FULL_SERVER));
- event.setResult(PlayerLoginEvent.Result.KICK_FULL);
- return;
- }
-
final String name = player.getName().toLowerCase();
boolean isAuthAvailable = plugin.getDataSource().isAuthAvailable(name);
From fd73ce156271283b3ebecf38e6a138462debd05d Mon Sep 17 00:00:00 2001
From: DNx5
Date: Tue, 5 Jan 2016 07:21:24 +0700
Subject: [PATCH 22/24] Attempt to Fix permissions wildcard problem.
---
.../authme/permission/PermissionsManager.java | 4 +-
src/main/resources/plugin.yml | 156 +++++-------------
2 files changed, 41 insertions(+), 119 deletions(-)
diff --git a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
index ef58b5694..9078b1ab7 100644
--- a/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
+++ b/src/main/java/fr/xephi/authme/permission/PermissionsManager.java
@@ -298,8 +298,8 @@ public class PermissionsManager implements PermissionsService {
}
Player player = (Player) sender;
- return hasPermission(player, permissionNode.getNode(), def)
- || hasPermission(player, permissionNode.getWildcardNode().getNode(), def);
+ return hasPermission(player, permissionNode.getNode(), def);
+ // || hasPermission(player, permissionNode.getWildcardNode().getNode(), def);
}
public boolean hasPermission(Player player, Iterable nodes, boolean def) {
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index ec382c7c9..e8d72a5ee 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -45,120 +45,42 @@ commands:
usage: /converter
permissions:
authme.admin.*:
- description: Gives access to all authme admin commands
- children:
- authme.admin.reload: true
- authme.admin.register: true
- authme.admin.changepassword: true
- authme.admin.unregister: true
- authme.admin.purge: true
- authme.seeOtherAccounts: true # This isn't a child of the admin section! Probably doesn't work.
- authme.admin.lastlogin: true
- authme.admin.getemail: true
- authme.admin.chgemail: true
- authme.admin.purgelastpos: true
- authme.admin.switchantibot: true
- authme.bypassantibot: true # This isn't a child of the admin section! Probably doesn't work.
- authme.admin.getip: true
- authme.admin.converter: true
- authme.admin.resetposition: true
- authme.admin.forcelogin: true
- authme.register:
- description: Register an account
- default: true
- authme.login:
- description: Login into a account
- default: true
- authme.changepassword:
- description: Change password of a account
- default: true
- authme.logout:
- description: Logout
- default: true
- authme.email:
- description: Email
- default: true
- authme.allow2accounts:
- description: allow more accounts for same ip
- default: false
- authme.seeOtherAccounts:
- description: display other accounts about a player when he logs in
- default: false
- authme.unregister:
- description: unregister your account
- default: true
- authme.admin.reload:
- description: AuthMe reload commands
- default: op
- authme.admin.register:
- description: AuthMe register command
- default: op
- authme.admin.changepassword:
- description: AuthMe changepassword command
- default: op
- authme.admin.unregister:
- description: AuthMe unregister command
- default: op
- authme.admin.purge:
- description: AuthMe unregister command
- default: op
- authme.admin.lastlogin:
- description: Get last login date about a player
- default: op
- authme.admin.getemail:
- description: Get last email about a player
- default: op
- authme.admin.chgemail:
- description: Change a player email
- default: op
- authme.admin.accounts:
- description: Display Players Accounts
- default: op
- authme.captcha:
- description: Captcha
- default: true
- authme.admin.setspawn:
- description: Set the AuthMe spawn point
- default: op
- authme.admin.spawn:
- description: Teleport to AuthMe spawn point
- default: op
- authme.vip:
- description: Allow vip slot when the server is full
- default: op
- authme.admin.purgebannedplayers:
- description: Purge banned players
- default: op
- authme.bypassforcesurvival:
- description: Bypass all ForceSurvival features
- default: false
- authme.admin.purgelastpos:
- description: Purge last pos of players
- default: op
- authme.admin.switchantibot:
- description: Switch AntiBot mode on/off
- default: op
- authme.bypassantibot:
- description: Bypass the AntiBot check
- default: op
- authme.admin.setfirstspawn:
- description: Set the AuthMe First Spawn Point
- default: op
- authme.admin.firstspawn:
- description: Teleport to AuthMe First Spawn Point
- default: op
- authme.admin.getip:
- description: Get IP from a player ( fake and real )
- default: op
- authme.admin.converter:
- description: Allow /converter command
- default: op
- 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
+ description: Give access to all admin commands.
+ children:
+ authme.admin.accounts: true
+ authme.admin.changemail: true
+ authme.admin.changepassword: true
+ authme.admin.converter: true
+ authme.admin.firstspawn: true
+ authme.admin.forcelogin: true
+ authme.admin.getemail: true
+ authme.admin.getip: true
+ authme.admin.lastlogin: true
+ authme.admin.purge: true
+ authme.admin.purgebannedplayers: true
+ authme.admin.purgelastpos: true
+ authme.admin.register: true
+ authme.admin.reload: true
+ authme.admin.setfirstspawn: true
+ authme.admin.setspawn: true
+ authme.admin.spawn: true
+ authme.admin.switchantibot: true
+ authme.admin.unregister: true
+ authme.player.*:
+ description: Permission to use all player (non-admin) commands.
+ children:
+ authme.player.allow2accounts: true
+ authme.player.bypassantibot: true
+ authme.player.bypassforcesurvival: true
+ authme.player.canbeforced: true
+ authme.player.captcha: true
+ authme.player.changepassword: true
+ authme.player.email.add: true
+ authme.player.email.change: true
+ authme.player.email.recover: true
+ authme.player.login: true
+ authme.player.logout: true
+ authme.player.register: true
+ authme.player.seeotheraccounts: true
+ authme.player.unregister: true
+ authme.player.vip: true
From 44d35154aad5422149ea7df06cac8ec35380c6bb Mon Sep 17 00:00:00 2001
From: DNx5
Date: Wed, 6 Jan 2016 10:02:32 +0700
Subject: [PATCH 23/24] Register permissions properly in "plugin.yml". so
permissions manager plugin can read what available permissions for AuthMe
---
src/main/resources/plugin.yml | 102 ++++++++++++++++++++++++++++++++++
1 file changed, 102 insertions(+)
diff --git a/src/main/resources/plugin.yml b/src/main/resources/plugin.yml
index e8d72a5ee..69e954e36 100644
--- a/src/main/resources/plugin.yml
+++ b/src/main/resources/plugin.yml
@@ -66,6 +66,63 @@ permissions:
authme.admin.spawn: true
authme.admin.switchantibot: true
authme.admin.unregister: true
+ authme.admin.register:
+ description: Administrator command to register a new user.
+ default: op
+ authme.admin.unregister:
+ description: Administrator command to unregister an existing user.
+ default: op
+ authme.admin.forcelogin:
+ description: Administrator command to force-login an existing user.
+ default: op
+ authme.admin.changepassword:
+ description: Administrator command to change the password of a user.
+ default: op
+ authme.admin.lastlogin:
+ description: Administrator command to see the last login date and time of a user.
+ default: op
+ authme.admin.accounts:
+ description: Administrator command to see all accounts associated with a user.
+ default: op
+ authme.admin.getemail:
+ description: Administrator command to get the email address of a user, if set.
+ default: op
+ authme.admin.changemail:
+ description: Administrator command to set or change the email address of a user.
+ default: op
+ authme.admin.getip:
+ description: Administrator command to get the last known IP of a user.
+ default: op
+ authme.admin.spawn:
+ description: Administrator command to teleport to the AuthMe spawn.
+ default: op
+ authme.admin.setspawn:
+ description: Administrator command to set the AuthMe spawn.
+ default: op
+ authme.admin.firstspawn:
+ description: Administrator command to teleport to the first AuthMe spawn.
+ default: op
+ authme.admin.setfirstspawn:
+ description: Administrator command to set the first AuthMe spawn.
+ default: op
+ authme.admin.purge:
+ description: Administrator command to purge old user data.
+ default: op
+ authme.admin.purgelastpos:
+ description: Administrator command to purge the last position of a user.
+ default: op
+ authme.admin.purgebannedplayers:
+ description: Administrator command to purge all data associated with banned players.
+ default: op
+ authme.admin.switchantibot:
+ description: Administrator command to toggle the AntiBot protection status.
+ default: op
+ authme.admin.converter:
+ description: Administrator command to convert old or other data to AuthMe data.
+ default: op
+ authme.admin.reload:
+ description: Administrator command to reload the plugin configuration.
+ default: op
authme.player.*:
description: Permission to use all player (non-admin) commands.
children:
@@ -84,3 +141,48 @@ permissions:
authme.player.seeotheraccounts: true
authme.player.unregister: true
authme.player.vip: true
+ authme.player.bypassantibot:
+ description: Permission node to bypass AntiBot protection.
+ default: false
+ authme.player.vip:
+ description: Permission node to identify VIP users.
+ default: false
+ authme.player.login:
+ description: Command permission to login.
+ default: true
+ authme.player.logout:
+ description: Command permission to logout.
+ default: true
+ authme.player.register:
+ description: Command permission to register.
+ default: true
+ authme.player.unregister:
+ description: Command permission to unregister.
+ default: true
+ authme.player.changepassword:
+ description: Command permission to change the password.
+ default: true
+ authme.player.email.add:
+ description: Command permission to add an email address.
+ default: false
+ authme.player.email.change:
+ description: Command permission to change the email address.
+ default: false
+ authme.player.email.recover:
+ description: Command permission to recover an account using it's email address.
+ default: false
+ authme.player.captcha:
+ description: Command permission to use captcha.
+ default: false
+ authme.player.canbeforced:
+ description: Permission for users a login can be forced to.
+ default: false
+ authme.player.bypassforcesurvival:
+ description: Permission for users to bypass force-survival mode.
+ default: false
+ authme.player.allow2accounts:
+ description: Permission for users to allow two accounts.
+ default: false
+ authme.player.seeotheraccounts:
+ description: Permission for user to see other accounts.
+ default: false
From 2081fd7e344d1e5d6006789821269bb54f16ba06 Mon Sep 17 00:00:00 2001
From: DNx5
Date: Wed, 6 Jan 2016 10:24:46 +0700
Subject: [PATCH 24/24] Removed AuthMeServerStop shutdown hook. - Players now
will be kicked if AuthMe was disabled. - Fix #413
---
src/main/java/fr/xephi/authme/AuthMe.java | 16 +++-------
.../authme/listener/AuthMeServerStop.java | 30 -------------------
2 files changed, 4 insertions(+), 42 deletions(-)
delete mode 100644 src/main/java/fr/xephi/authme/listener/AuthMeServerStop.java
diff --git a/src/main/java/fr/xephi/authme/AuthMe.java b/src/main/java/fr/xephi/authme/AuthMe.java
index cdaceb19e..70c8bfd6b 100644
--- a/src/main/java/fr/xephi/authme/AuthMe.java
+++ b/src/main/java/fr/xephi/authme/AuthMe.java
@@ -32,7 +32,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.listener.AuthMeServerStop;
import fr.xephi.authme.listener.AuthMeTabCompletePacketAdapter;
import fr.xephi.authme.mail.SendMailSSL;
import fr.xephi.authme.modules.ModuleManager;
@@ -307,13 +306,6 @@ public class AuthMe extends JavaPlugin {
// Show settings warnings
showSettingsWarnings();
- // Register a server shutdown hook
- try {
- Runtime.getRuntime().addShutdownHook(new AuthMeServerStop(this));
- } catch (Exception e) {
- e.printStackTrace();
- }
-
// Sponsor messages
ConsoleLogger.info("AuthMe hooks perfectly with the VeryGames server hosting!");
ConsoleLogger.info("Development builds are available on our jenkins, thanks to f14stelt.");
@@ -521,10 +513,10 @@ public class AuthMe extends JavaPlugin {
public void onDisable() {
// Save player data
Collection extends Player> players = Utils.getOnlinePlayers();
- if (players != null) {
- for (Player player : players) {
- this.savePlayer(player);
- }
+ for (Player player : players) {
+ savePlayer(player);
+ // TODO: add a MessageKey
+ player.kickPlayer("Server is restarting or AuthMe plugin was disabled.");
}
// Do backup on stop if enabled
diff --git a/src/main/java/fr/xephi/authme/listener/AuthMeServerStop.java b/src/main/java/fr/xephi/authme/listener/AuthMeServerStop.java
deleted file mode 100644
index eed3bd908..000000000
--- a/src/main/java/fr/xephi/authme/listener/AuthMeServerStop.java
+++ /dev/null
@@ -1,30 +0,0 @@
-package fr.xephi.authme.listener;
-
-import org.bukkit.entity.Player;
-
-import fr.xephi.authme.AuthMe;
-import fr.xephi.authme.settings.Settings;
-
-public class AuthMeServerStop extends Thread {
-
- private AuthMe plugin;
-
- public AuthMeServerStop(AuthMe plugin) {
- this.plugin = plugin;
- }
-
- public void run() {
- // TODO: add a MessageKey
- if (Settings.kickPlayersBeforeStopping) {
- plugin.getServer().getScheduler().scheduleSyncDelayedTask(plugin, new Runnable()
- {
- @Override
- public void run() {
- for (Player p : plugin.getServer().getOnlinePlayers()) {
- p.kickPlayer("Server is restarting");
- }
- }
- });
- }
- }
-}