Date: Thu, 31 Dec 2015 13:32:41 +0100
Subject: [PATCH 04/12] 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 d398af67..22a3f05c 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 3d6d3d24..e3ab671b 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 f8b7f852..08a2790e 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 7f19a4f0..520eec24 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 5792dd97..2d7aca0b 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 f515717e..bf179fff 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 85ad0608..0723a4dd 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 e57a0c40..4b832a68 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 7d6b225c..40b923fa 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 ecf37a98..c11c335a 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 9acc3c25..ef78c5fd 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/12] 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 269c1365..cd8af924 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 85789b88..4abfe5d4 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 97418640..555f3213 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 6cc12300..28e97585 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 00000000..2996fd8c
--- /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 00000000..07c588ea
--- /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 00000000..5213d6b7
--- /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 00000000..45aaf448
--- /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 00000000..c1123728
--- /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 00000000..411d1127
--- /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/12] 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 2996fd8c..60a011b4 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 c1123728..b466eeeb 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/12] 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 3e602e5f..26ec824f 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/12] 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 00000000..7cee6a52
--- /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 00000000..27792efd
--- /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 00000000..c3c20c6b
--- /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 00000000..d6cc3675
--- /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 00000000..307c7906
--- /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 00000000..e8e2d059
--- /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 00000000..3b85e2fb
--- /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 00000000..3166cbe2
--- /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 00000000..d711a194
--- /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 00000000..aae0af52
--- /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/12] 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 7cee6a52..00000000
--- 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 27792efd..00000000
--- 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 c3c20c6b..00000000
--- 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 d6cc3675..00000000
--- 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 307c7906..00000000
--- 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 e8e2d059..00000000
--- 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 3b85e2fb..00000000
--- 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 3166cbe2..00000000
--- 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 d711a194..00000000
--- 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 aae0af52..00000000
--- 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/12] 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 26ec824f..3243c21d 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/12] 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 e28ddc3f..ac520763 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/12] 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 ac520763..cfb28f75 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) {