Merge pull request #80 from AuthMe-Team/tools
#313 Create a tools folder
This commit is contained in:
commit
979c4b5a85
@ -81,7 +81,7 @@ public enum PlayerPermission implements PermissionNode {
|
|||||||
SEE_OTHER_ACCOUNTS("authme.player.seeotheraccounts"),
|
SEE_OTHER_ACCOUNTS("authme.player.seeotheraccounts"),
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
* Permission to use all player (non-admin) commands.
|
||||||
*/
|
*/
|
||||||
ALL_COMMANDS("authme.player.*");
|
ALL_COMMANDS("authme.player.*");
|
||||||
|
|
||||||
|
|||||||
3
src/tools/README.md
Normal file
3
src/tools/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# About src/tools
|
||||||
|
This _tools_ folder provides helpers and extended tests useful during the development of AuthMe.
|
||||||
|
This folder is not included during the build of AuthMe.
|
||||||
43
src/tools/docs/permission_nodes.md
Normal file
43
src/tools/docs/permission_nodes.md
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<!-- AUTO-GENERATED FILE! Do not edit this directly -->
|
||||||
|
<!-- File auto-generated on Sat Dec 05 21:18:25 CET 2015. See permissions/permission_nodes.tpl.md -->
|
||||||
|
|
||||||
|
## AuthMe Permission Nodes
|
||||||
|
The following are the permission nodes that are currently supported by the latest dev builds.
|
||||||
|
|
||||||
|
- **authme.admin.*** – Give access to all admin commands.
|
||||||
|
- **authme.admin.accounts** – Administrator command to see all accounts associated with a user.
|
||||||
|
- **authme.admin.changemail** – Administrator command to set or change the email address of a user.
|
||||||
|
- **authme.admin.changepassword** – Administrator command to change the password of a user.
|
||||||
|
- **authme.admin.converter** – Administrator command to convert old or other data to AuthMe data.
|
||||||
|
- **authme.admin.firstspawn** – Administrator command to teleport to the first AuthMe spawn.
|
||||||
|
- **authme.admin.forcelogin** – Administrator command to force-login an existing user.
|
||||||
|
- **authme.admin.getemail** – Administrator command to get the email address of a user, if set.
|
||||||
|
- **authme.admin.getip** – Administrator command to get the last known IP of a user.
|
||||||
|
- **authme.admin.lastlogin** – Administrator command to see the last login date and time of a user.
|
||||||
|
- **authme.admin.purge** – Administrator command to purge old user data.
|
||||||
|
- **authme.admin.purgebannedplayers** – Administrator command to purge all data associated with banned players.
|
||||||
|
- **authme.admin.purgelastpos** – Administrator command to purge the last position of a user.
|
||||||
|
- **authme.admin.register** – Administrator command to register a new user.
|
||||||
|
- **authme.admin.reload** – Administrator command to reload the plugin configuration.
|
||||||
|
- **authme.admin.setfirstspawn** – Administrator command to set the first AuthMe spawn.
|
||||||
|
- **authme.admin.setspawn** – Administrator command to set the AuthMe spawn.
|
||||||
|
- **authme.admin.spawn** – Administrator command to teleport to the AuthMe spawn.
|
||||||
|
- **authme.admin.switchantibot** – Administrator command to toggle the AntiBot protection status.
|
||||||
|
- **authme.admin.unregister** – Administrator command to unregister an existing user.
|
||||||
|
- **authme.player.*** – Permission to use all player (non-admin) commands.
|
||||||
|
- **authme.player.allow2accounts** – Permission for users to allow two accounts.
|
||||||
|
- **authme.player.bypassantibot** – Permission node to bypass AntiBot protection.
|
||||||
|
- **authme.player.bypassforcesurvival** – Permission for users to bypass force-survival mode.
|
||||||
|
- **authme.player.canbeforced** – Permission for users a login can be forced to.
|
||||||
|
- **authme.player.captcha** – Command permission to use captcha.
|
||||||
|
- **authme.player.changepassword** – Command permission to change the password.
|
||||||
|
- **authme.player.email.add** – Command permission to add an email address.
|
||||||
|
- **authme.player.email.change** – Command permission to change the email address.
|
||||||
|
- **authme.player.email.recover** – Command permission to recover an account using it's email address.
|
||||||
|
- **authme.player.login** – Command permission to login.
|
||||||
|
- **authme.player.logout** – Command permission to logout.
|
||||||
|
- **authme.player.register** – Command permission to register.
|
||||||
|
- **authme.player.seeotheraccounts** – Permission for user to see other accounts.
|
||||||
|
- **authme.player.unregister** – Command permission to unregister.
|
||||||
|
- **authme.player.vip** – Permission node to identify VIP users.
|
||||||
|
|
||||||
113
src/tools/permissions/PermissionNodesGatherer.java
Normal file
113
src/tools/permissions/PermissionNodesGatherer.java
Normal file
@ -0,0 +1,113 @@
|
|||||||
|
package permissions;
|
||||||
|
|
||||||
|
import fr.xephi.authme.permission.AdminPermission;
|
||||||
|
import fr.xephi.authme.permission.PermissionNode;
|
||||||
|
import fr.xephi.authme.permission.PlayerPermission;
|
||||||
|
import fr.xephi.authme.util.StringUtils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.EnumSet;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
import java.util.TreeMap;
|
||||||
|
import java.util.TreeSet;
|
||||||
|
import java.util.regex.Matcher;
|
||||||
|
import java.util.regex.Pattern;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gatherer to generate up-to-date lists of the AuthMe permission nodes.
|
||||||
|
*/
|
||||||
|
public class PermissionNodesGatherer {
|
||||||
|
|
||||||
|
/** The folder in which the implementations of {@link PermissionNode} reside. */
|
||||||
|
private static final String PERMISSION_NODE_SOURCE_FOLDER =
|
||||||
|
"src/main/java/fr/xephi/authme/permission/";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Regular expression that should match the JavaDoc comment above an enum, <i>including</i>
|
||||||
|
* the name of the enum value. The first group (i.e. {@code \\1}) should be the JavaDoc description;
|
||||||
|
* the second group should contain the enum value.
|
||||||
|
*/
|
||||||
|
private static final Pattern JAVADOC_WITH_ENUM_PATTERN = Pattern.compile(
|
||||||
|
"/\\*\\*\\s+\\*" // Match starting '/**' and the '*' on the next line
|
||||||
|
+ "(.*?)\\s+\\*/" // Capture everything until we encounter '*/'
|
||||||
|
+ "\\s+([A-Z_]+)\\("); // Match the enum name (e.g. 'LOGIN'), until before the first '('
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a sorted collection of all permission nodes.
|
||||||
|
*
|
||||||
|
* @return AuthMe permission nodes sorted alphabetically
|
||||||
|
*/
|
||||||
|
public Set<String> gatherNodes() {
|
||||||
|
Set<String> nodes = new TreeSet<>();
|
||||||
|
for (PermissionNode perm : PlayerPermission.values()) {
|
||||||
|
nodes.add(perm.getNode());
|
||||||
|
}
|
||||||
|
for (PermissionNode perm : AdminPermission.values()) {
|
||||||
|
nodes.add(perm.getNode());
|
||||||
|
}
|
||||||
|
return nodes;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a sorted collection of all permission nodes, including its JavaDoc description.
|
||||||
|
*
|
||||||
|
* @return Ordered map whose keys are the permission nodes and the values the associated JavaDoc
|
||||||
|
*/
|
||||||
|
public Map<String, String> gatherNodesWithJavaDoc() {
|
||||||
|
Map<String, String> result = new TreeMap<>();
|
||||||
|
addDescriptionsForClass(PlayerPermission.class, result);
|
||||||
|
addDescriptionsForClass(AdminPermission.class, result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
private <T extends Enum<T> & PermissionNode> void addDescriptionsForClass(Class<T> clazz,
|
||||||
|
Map<String, String> descriptions) {
|
||||||
|
String classSource = getSourceForClass(clazz);
|
||||||
|
Map<String, String> sourceDescriptions = extractJavaDocFromSource(classSource);
|
||||||
|
|
||||||
|
for (T perm : EnumSet.allOf(clazz)) {
|
||||||
|
String description = sourceDescriptions.get(perm.name());
|
||||||
|
if (description == null) {
|
||||||
|
System.out.println("Note: Could not retrieve description for "
|
||||||
|
+ clazz.getSimpleName() + "#" + perm.name());
|
||||||
|
description = "";
|
||||||
|
}
|
||||||
|
descriptions.put(perm.getNode(), description.trim());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Map<String, String> extractJavaDocFromSource(String source) {
|
||||||
|
Map<String, String> allMatches = new HashMap<>();
|
||||||
|
Matcher matcher = JAVADOC_WITH_ENUM_PATTERN.matcher(source);
|
||||||
|
while (matcher.find()) {
|
||||||
|
String description = matcher.group(1);
|
||||||
|
String enumValue = matcher.group(2);
|
||||||
|
allMatches.put(enumValue, description);
|
||||||
|
}
|
||||||
|
return allMatches;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the Java source code for the given implementation of {@link PermissionNode}.
|
||||||
|
*
|
||||||
|
* @param clazz The clazz to the get the source for
|
||||||
|
* @param <T> The concrete class
|
||||||
|
* @return Source code of the file
|
||||||
|
*/
|
||||||
|
private static <T extends Enum<T> & PermissionNode> String getSourceForClass(Class<T> clazz) {
|
||||||
|
String classFile = PERMISSION_NODE_SOURCE_FOLDER + clazz.getSimpleName() + ".java";
|
||||||
|
Charset cs = Charset.forName("utf-8");
|
||||||
|
try {
|
||||||
|
return StringUtils.join("\n",
|
||||||
|
Files.readAllLines(Paths.get(classFile), cs));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to get the source for class '" + clazz.getSimpleName() + "'");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
86
src/tools/permissions/PermissionsListWriter.java
Normal file
86
src/tools/permissions/PermissionsListWriter.java
Normal file
@ -0,0 +1,86 @@
|
|||||||
|
package permissions;
|
||||||
|
|
||||||
|
import utils.ANewMap;
|
||||||
|
import utils.GeneratedFileWriter;
|
||||||
|
import utils.TagReplacer;
|
||||||
|
import utils.ToolsConstants;
|
||||||
|
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Scanner;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible for formatting a permissions node list and
|
||||||
|
* for writing it to a file if desired.
|
||||||
|
*/
|
||||||
|
public class PermissionsListWriter {
|
||||||
|
|
||||||
|
private static final String PERMISSIONS_OUTPUT_FILE = ToolsConstants.DOCS_FOLDER + "permission_nodes.md";
|
||||||
|
|
||||||
|
public static void main(String[] args) {
|
||||||
|
// Ask if result should be written to file
|
||||||
|
Scanner scanner = new Scanner(System.in);
|
||||||
|
System.out.println("Include description? [Enter 'n' for no]");
|
||||||
|
boolean includeDescription = !matches("n", scanner);
|
||||||
|
|
||||||
|
if (!includeDescription) {
|
||||||
|
outputSimpleList();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
System.out.println("Write to file? [Enter 'n' for console output]");
|
||||||
|
boolean writeToFile = !matches("n", scanner);
|
||||||
|
scanner.close();
|
||||||
|
|
||||||
|
|
||||||
|
if (writeToFile) {
|
||||||
|
generateAndWriteFile();
|
||||||
|
} else {
|
||||||
|
System.out.println(generatePermissionsList());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private static void generateAndWriteFile() {
|
||||||
|
final String permissionsTagValue = generatePermissionsList();
|
||||||
|
|
||||||
|
Map<String, Object> tags = ANewMap.<String, Object>with("permissions", permissionsTagValue).build();
|
||||||
|
GeneratedFileWriter.generateFileFromTemplate(
|
||||||
|
ToolsConstants.TOOLS_SOURCE_ROOT + "permissions/permission_nodes.tpl.md", PERMISSIONS_OUTPUT_FILE, tags);
|
||||||
|
System.out.println("Wrote to '" + PERMISSIONS_OUTPUT_FILE + "'");
|
||||||
|
System.out.println("Before committing, please verify the output!");
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String generatePermissionsList() {
|
||||||
|
PermissionNodesGatherer gatherer = new PermissionNodesGatherer();
|
||||||
|
Map<String, String> permissions = gatherer.gatherNodesWithJavaDoc();
|
||||||
|
|
||||||
|
final String template = GeneratedFileWriter.readFromToolsFile("permissions/permission_node_entry.tpl.md");
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
|
||||||
|
for (Map.Entry<String, String> entry : permissions.entrySet()) {
|
||||||
|
Map<String, Object> tags = ANewMap.<String, Object>
|
||||||
|
with("node", entry.getKey())
|
||||||
|
.and("description", entry.getValue())
|
||||||
|
.build();
|
||||||
|
sb.append(TagReplacer.applyReplacements(template, tags));
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void outputSimpleList() {
|
||||||
|
PermissionNodesGatherer gatherer = new PermissionNodesGatherer();
|
||||||
|
Set<String> nodes = gatherer.gatherNodes();
|
||||||
|
for (String node : nodes) {
|
||||||
|
System.out.println(node);
|
||||||
|
}
|
||||||
|
System.out.println();
|
||||||
|
System.out.println("Total: " + nodes.size());
|
||||||
|
}
|
||||||
|
|
||||||
|
private static boolean matches(String answer, Scanner sc) {
|
||||||
|
String userInput = sc.nextLine();
|
||||||
|
return answer.equalsIgnoreCase(userInput);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
2
src/tools/permissions/README.md
Normal file
2
src/tools/permissions/README.md
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# About
|
||||||
|
Helper script to generate a page with an up-to-date list of permission nodes.
|
||||||
1
src/tools/permissions/permission_node_entry.tpl.md
Normal file
1
src/tools/permissions/permission_node_entry.tpl.md
Normal file
@ -0,0 +1 @@
|
|||||||
|
- **{node}** – {description}
|
||||||
7
src/tools/permissions/permission_nodes.tpl.md
Normal file
7
src/tools/permissions/permission_nodes.tpl.md
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
<!-- {gen_warning} -->
|
||||||
|
<!-- File auto-generated on {gen_date}. See permissions/permission_nodes.tpl.md -->
|
||||||
|
|
||||||
|
## AuthMe Permission Nodes
|
||||||
|
The following are the permission nodes that are currently supported by the latest dev builds.
|
||||||
|
|
||||||
|
{permissions}
|
||||||
36
src/tools/utils/ANewMap.java
Normal file
36
src/tools/utils/ANewMap.java
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A map builder for the lazy.
|
||||||
|
* <p />
|
||||||
|
* Sample usage:
|
||||||
|
* <code>
|
||||||
|
* Map<String, Integer> map = ANewMap
|
||||||
|
* .with("test", 123)
|
||||||
|
* .and("text", 938)
|
||||||
|
* .and("abc", 456)
|
||||||
|
* .build();
|
||||||
|
* </code>
|
||||||
|
*/
|
||||||
|
public class ANewMap<K, V> {
|
||||||
|
|
||||||
|
private Map<K, V> map = new HashMap<>();
|
||||||
|
|
||||||
|
public static <K, V> ANewMap<K, V> with(K key, V value) {
|
||||||
|
ANewMap<K, V> instance = new ANewMap<>();
|
||||||
|
return instance.and(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public ANewMap<K, V> and(K key, V value) {
|
||||||
|
map.put(key, value);
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Map<K, V> build() {
|
||||||
|
return map;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
47
src/tools/utils/GeneratedFileWriter.java
Normal file
47
src/tools/utils/GeneratedFileWriter.java
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.Charset;
|
||||||
|
import java.nio.file.Files;
|
||||||
|
import java.nio.file.Paths;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Utility class for writing a generated file with a timestamp.
|
||||||
|
*/
|
||||||
|
public final class GeneratedFileWriter {
|
||||||
|
|
||||||
|
private final static Charset CHARSET = Charset.forName("utf-8");
|
||||||
|
|
||||||
|
private GeneratedFileWriter() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void generateFileFromTemplate(String templateFile, String destinationFile, Map<String, Object> tags) {
|
||||||
|
String template = readFromFile(templateFile);
|
||||||
|
String result = TagReplacer.applyReplacements(template, tags);
|
||||||
|
|
||||||
|
writeToFile(destinationFile, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void writeToFile(String outputFile, String contents) {
|
||||||
|
try {
|
||||||
|
Files.write(Paths.get(outputFile), contents.getBytes());
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Failed to write to file '" + outputFile + "'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readFromFile(String file) {
|
||||||
|
try {
|
||||||
|
return new String(Files.readAllBytes(Paths.get(file)), CHARSET);
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException("Could not read from file '" + file + "'", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String readFromToolsFile(String file) {
|
||||||
|
return readFromFile(ToolsConstants.TOOLS_SOURCE_ROOT + file);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
46
src/tools/utils/TagReplacer.java
Normal file
46
src/tools/utils/TagReplacer.java
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
import java.util.Date;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class responsible for replacing template tags to actual content.
|
||||||
|
* For all files, the following tags are defined:
|
||||||
|
* <ul>
|
||||||
|
* <li>{gen_date} – the generation date</li>
|
||||||
|
* <li>{gen_warning} - warning not to edit the generated file directly</li>
|
||||||
|
* </ul>
|
||||||
|
*/
|
||||||
|
public class TagReplacer {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Replace a template with default tags and custom ones supplied by a map.
|
||||||
|
*
|
||||||
|
* @param template The template to process
|
||||||
|
* @param tags Map with additional tags, e.g. a map entry with key "foo" and value "bar" will replace
|
||||||
|
* any occurrences of "{foo}" to "bar".
|
||||||
|
* @return The filled template
|
||||||
|
*/
|
||||||
|
public static String applyReplacements(String template, Map<String, Object> tags) {
|
||||||
|
String result = template;
|
||||||
|
for (Map.Entry<String, Object> tagRule : tags.entrySet()) {
|
||||||
|
result = result.replace("{" + tagRule.getKey() + "}", tagRule.getValue().toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
return applyReplacements(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Apply the default tag replacements.
|
||||||
|
*
|
||||||
|
* @param template The template to process
|
||||||
|
* @return The filled template
|
||||||
|
*/
|
||||||
|
public static String applyReplacements(String template) {
|
||||||
|
return template
|
||||||
|
.replace("{gen_date}", new Date().toString())
|
||||||
|
.replace("{gen_warning}", "AUTO-GENERATED FILE! Do not edit this directly");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
17
src/tools/utils/ToolsConstants.java
Normal file
17
src/tools/utils/ToolsConstants.java
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
package utils;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constants for the src/tools folder.
|
||||||
|
*/
|
||||||
|
public final class ToolsConstants {
|
||||||
|
|
||||||
|
private ToolsConstants() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static final String MAIN_SOURCE_ROOT = "src/main/java/";
|
||||||
|
|
||||||
|
public static final String TOOLS_SOURCE_ROOT = "src/tools/";
|
||||||
|
|
||||||
|
public static final String DOCS_FOLDER = TOOLS_SOURCE_ROOT + "docs/";
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user